master
  1/*-
  2 * SPDX-License-Identifier: BSD-2-Clause
  3 *
  4 * Copyright (c) 2021 Ng Peng Nam Sean
  5 * Copyright (c) 2022 Alexander V. Chernikov <melifaro@FreeBSD.org>
  6 *
  7 * Redistribution and use in source and binary forms, with or without
  8 * modification, are permitted provided that the following conditions
  9 * are met:
 10 * 1. Redistributions of source code must retain the above copyright
 11 *    notice, this list of conditions and the following disclaimer.
 12 * 2. Redistributions in binary form must reproduce the above copyright
 13 *    notice, this list of conditions and the following disclaimer in the
 14 *    documentation and/or other materials provided with the distribution.
 15 *
 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 26 * SUCH DAMAGE.
 27 */
 28#ifndef _NETLINK_NETLINK_VAR_H_
 29#define _NETLINK_NETLINK_VAR_H_
 30
 31#ifdef _KERNEL
 32
 33#include <sys/ck.h>
 34#include <sys/epoch.h>
 35#include <sys/sysctl.h>
 36#include <sys/taskqueue.h>
 37#include <net/vnet.h>
 38
 39#define	NLSNDQ  	65536 /* Default socket sendspace */
 40#define	NLRCVQ		65536 /* Default socket recvspace */
 41
 42#define	NLMBUFSIZE	2048	/* External storage size for Netlink mbufs */
 43
 44struct ucred;
 45
 46struct nl_io_queue {
 47	STAILQ_HEAD(, mbuf)	head;
 48	int			length;
 49	int			hiwat;
 50};
 51
 52#define	NLP_MAX_GROUPS		128
 53
 54struct nlpcb {
 55        struct socket           *nl_socket;
 56	uint64_t	        nl_groups[NLP_MAX_GROUPS / 64];
 57	uint32_t                nl_port;
 58	uint32_t	        nl_flags;
 59	uint32_t	        nl_process_id;
 60        int                     nl_proto;
 61        bool			nl_active;
 62	bool			nl_bound;
 63        bool			nl_task_pending;
 64	bool			nl_tx_blocked; /* No new requests accepted */
 65	bool			nl_linux; /* true if running under compat */
 66	bool			nl_unconstrained_vnet; /* true if running under VNET jail (or without jail) */
 67	bool			nl_need_thread_setup;
 68	struct nl_io_queue	rx_queue;
 69	struct nl_io_queue	tx_queue;
 70	struct taskqueue	*nl_taskqueue;
 71	struct task		nl_task;
 72	struct ucred		*nl_cred; /* Copy of nl_socket->so_cred */
 73	uint64_t		nl_dropped_bytes;
 74	uint64_t		nl_dropped_messages;
 75        CK_LIST_ENTRY(nlpcb)    nl_next;
 76        CK_LIST_ENTRY(nlpcb)    nl_port_next;
 77	volatile u_int		nl_refcount;
 78	struct mtx		nl_lock;
 79	struct epoch_context	nl_epoch_ctx;
 80};
 81#define sotonlpcb(so)       ((struct nlpcb *)(so)->so_pcb)
 82
 83#define	NLP_LOCK_INIT(_nlp)	mtx_init(&((_nlp)->nl_lock), "nlp mtx", NULL, MTX_DEF)
 84#define	NLP_LOCK_DESTROY(_nlp)	mtx_destroy(&((_nlp)->nl_lock))
 85#define	NLP_LOCK(_nlp)		mtx_lock(&((_nlp)->nl_lock))
 86#define	NLP_UNLOCK(_nlp)	mtx_unlock(&((_nlp)->nl_lock))
 87
 88#define	ALIGNED_NL_SZ(_data)	roundup2((((struct nlmsghdr *)(_data))->nlmsg_len), 16)
 89
 90/* nl_flags */
 91#define NLF_CAP_ACK             0x01 /* Do not send message body with errmsg */
 92#define NLF_EXT_ACK             0x02 /* Allow including extended TLVs in ack */
 93#define	NLF_STRICT		0x04 /* Perform strict header checks */
 94#define	NLF_MSG_INFO		0x08 /* Send caller info along with the notifications */
 95
 96SYSCTL_DECL(_net_netlink);
 97SYSCTL_DECL(_net_netlink_debug);
 98
 99struct nl_io {
100	struct callout				callout;
101	struct mbuf				*head;
102	struct mbuf 				*last;
103	int64_t					length;
104};
105
106struct nl_control {
107	CK_LIST_HEAD(nl_pid_head, nlpcb)	ctl_port_head;
108	CK_LIST_HEAD(nlpcb_head, nlpcb)		ctl_pcb_head;
109	CK_LIST_ENTRY(nl_control)		ctl_next;
110	struct nl_io				ctl_io;
111	struct rmlock				ctl_lock;
112};
113VNET_DECLARE(struct nl_control *, nl_ctl);
114#define	V_nl_ctl	VNET(nl_ctl)
115
116
117struct sockaddr_nl;
118struct sockaddr;
119struct nlmsghdr;
120
121/* netlink_module.c */
122struct nl_control *vnet_nl_ctl_init(void);
123
124int nl_verify_proto(int proto);
125const char *nl_get_proto_name(int proto);
126
127extern int netlink_unloading;
128
129struct nl_proto_handler {
130	nl_handler_f	cb;
131	const char	*proto_name;
132};
133extern struct nl_proto_handler *nl_handlers;
134
135/* netlink_domain.c */
136void nl_send_group(struct mbuf *m, int cnt, int proto, int group_id);
137void nl_osd_register(void);
138void nl_osd_unregister(void);
139void nl_set_thread_nlp(struct thread *td, struct nlpcb *nlp);
140
141/* netlink_io.c */
142#define	NL_IOF_UNTRANSLATED	0x01
143#define	NL_IOF_IGNORE_LIMIT	0x02
144bool nl_send_one(struct mbuf *m, struct nlpcb *nlp, int cnt, int io_flags);
145void nlmsg_ack(struct nlpcb *nlp, int error, struct nlmsghdr *nlmsg,
146    struct nl_pstate *npt);
147void nl_on_transmit(struct nlpcb *nlp);
148void nl_init_io(struct nlpcb *nlp);
149void nl_free_io(struct nlpcb *nlp);
150
151void nl_taskqueue_handler(void *_arg, int pending);
152int nl_receive_async(struct mbuf *m, struct socket *so);
153void nl_process_receive_locked(struct nlpcb *nlp);
154void nl_set_source_metadata(struct mbuf *m, int num_messages);
155void nl_add_msg_info(struct mbuf *m);
156
157/* netlink_message_writer.c */
158void nl_init_msg_zone(void);
159void nl_destroy_msg_zone(void);
160
161/* netlink_generic.c */
162struct genl_family {
163	const char	*family_name;
164	uint16_t	family_hdrsize;
165	uint16_t	family_id;
166	uint16_t	family_version;
167	uint16_t	family_attr_max;
168	uint16_t	family_cmd_size;
169	uint16_t	family_num_groups;
170	struct genl_cmd	*family_cmds;
171};
172
173struct genl_group {
174	struct genl_family	*group_family;
175	const char		*group_name;
176};
177
178struct genl_family *genl_get_family(uint32_t family_id);
179struct genl_group *genl_get_group(uint32_t group_id);
180
181#define	MAX_FAMILIES	20
182#define	MAX_GROUPS	64
183
184#define	MIN_GROUP_NUM	48
185
186#define	CTRL_FAMILY_NAME	"nlctrl"
187
188struct ifnet;
189struct nl_parsed_link;
190struct nlattr_bmask;
191struct nl_pstate;
192
193/* Function map */
194struct nl_function_wrapper {
195	bool (*nlmsg_add)(struct nl_writer *nw, uint32_t portid, uint32_t seq, uint16_t type,
196	    uint16_t flags, uint32_t len);
197	bool (*nlmsg_refill_buffer)(struct nl_writer *nw, int required_len);
198	bool (*nlmsg_flush)(struct nl_writer *nw);
199	bool (*nlmsg_end)(struct nl_writer *nw);
200	void (*nlmsg_abort)(struct nl_writer *nw);
201	void (*nlmsg_ignore_limit)(struct nl_writer *nw);
202	bool (*nlmsg_get_unicast_writer)(struct nl_writer *nw, int size, struct nlpcb *nlp);
203	bool (*nlmsg_get_group_writer)(struct nl_writer *nw, int size, int protocol, int group_id);
204	bool (*nlmsg_get_chain_writer)(struct nl_writer *nw, int size, struct mbuf **pm);
205	bool (*nlmsg_end_dump)(struct nl_writer *nw, int error, struct nlmsghdr *hdr);
206	int (*nl_modify_ifp_generic)(struct ifnet *ifp, struct nl_parsed_link *lattrs,
207	    const struct nlattr_bmask *bm, struct nl_pstate *npt);
208	void (*nl_store_ifp_cookie)(struct nl_pstate *npt, struct ifnet *ifp);
209	struct nlpcb * (*nl_get_thread_nlp)(struct  thread *td);
210};
211void nl_set_functions(const struct nl_function_wrapper *nl);
212
213
214
215#endif
216#endif