xref: /freebsd/sys/netlink/netlink_var.h (revision 09fa78d4)
17e5bf684SAlexander V. Chernikov /*-
24d846d26SWarner Losh  * SPDX-License-Identifier: BSD-2-Clause
37e5bf684SAlexander V. Chernikov  *
47e5bf684SAlexander V. Chernikov  * Copyright (c) 2021 Ng Peng Nam Sean
57e5bf684SAlexander V. Chernikov  * Copyright (c) 2022 Alexander V. Chernikov <melifaro@FreeBSD.org>
67e5bf684SAlexander V. Chernikov  *
77e5bf684SAlexander V. Chernikov  * Redistribution and use in source and binary forms, with or without
87e5bf684SAlexander V. Chernikov  * modification, are permitted provided that the following conditions
97e5bf684SAlexander V. Chernikov  * are met:
107e5bf684SAlexander V. Chernikov  * 1. Redistributions of source code must retain the above copyright
117e5bf684SAlexander V. Chernikov  *    notice, this list of conditions and the following disclaimer.
127e5bf684SAlexander V. Chernikov  * 2. Redistributions in binary form must reproduce the above copyright
137e5bf684SAlexander V. Chernikov  *    notice, this list of conditions and the following disclaimer in the
147e5bf684SAlexander V. Chernikov  *    documentation and/or other materials provided with the distribution.
157e5bf684SAlexander V. Chernikov  *
167e5bf684SAlexander V. Chernikov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
177e5bf684SAlexander V. Chernikov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
187e5bf684SAlexander V. Chernikov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
197e5bf684SAlexander V. Chernikov  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
207e5bf684SAlexander V. Chernikov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
217e5bf684SAlexander V. Chernikov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
227e5bf684SAlexander V. Chernikov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
237e5bf684SAlexander V. Chernikov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
247e5bf684SAlexander V. Chernikov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
257e5bf684SAlexander V. Chernikov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
267e5bf684SAlexander V. Chernikov  * SUCH DAMAGE.
277e5bf684SAlexander V. Chernikov  */
287e5bf684SAlexander V. Chernikov #ifndef _NETLINK_NETLINK_VAR_H_
297e5bf684SAlexander V. Chernikov #define _NETLINK_NETLINK_VAR_H_
307e5bf684SAlexander V. Chernikov 
31dddafa8dSAlexander V. Chernikov #ifdef _KERNEL
32dddafa8dSAlexander V. Chernikov 
337e5bf684SAlexander V. Chernikov #include <sys/ck.h>
347e5bf684SAlexander V. Chernikov #include <sys/epoch.h>
357e5bf684SAlexander V. Chernikov #include <sys/sysctl.h>
367e5bf684SAlexander V. Chernikov #include <sys/taskqueue.h>
377e5bf684SAlexander V. Chernikov #include <net/vnet.h>
387e5bf684SAlexander V. Chernikov 
397e5bf684SAlexander V. Chernikov #define	NLSNDQ  	65536 /* Default socket sendspace */
407e5bf684SAlexander V. Chernikov #define	NLRCVQ		65536 /* Default socket recvspace */
417e5bf684SAlexander V. Chernikov 
42d1871547SAlexander V. Chernikov #define	NLMBUFSIZE	2048	/* External storage size for Netlink mbufs */
43d1871547SAlexander V. Chernikov 
447e5bf684SAlexander V. Chernikov struct ucred;
457e5bf684SAlexander V. Chernikov 
46660bd40aSGleb Smirnoff struct nl_buf {
47660bd40aSGleb Smirnoff 	TAILQ_ENTRY(nl_buf)	tailq;
48660bd40aSGleb Smirnoff 	u_int			buflen;
49660bd40aSGleb Smirnoff 	u_int			datalen;
50660bd40aSGleb Smirnoff 	u_int			offset;
51660bd40aSGleb Smirnoff 	char			data[];
52660bd40aSGleb Smirnoff };
53660bd40aSGleb Smirnoff 
544dfd380eSAlexander V. Chernikov #define	NLP_MAX_GROUPS		128
554dfd380eSAlexander V. Chernikov 
567e5bf684SAlexander V. Chernikov struct nlpcb {
577e5bf684SAlexander V. Chernikov         struct socket           *nl_socket;
584dfd380eSAlexander V. Chernikov 	uint64_t	        nl_groups[NLP_MAX_GROUPS / 64];
597e5bf684SAlexander V. Chernikov 	uint32_t                nl_port;
607e5bf684SAlexander V. Chernikov 	uint32_t	        nl_flags;
617e5bf684SAlexander V. Chernikov 	uint32_t	        nl_process_id;
627e5bf684SAlexander V. Chernikov         int                     nl_proto;
637e5bf684SAlexander V. Chernikov 	bool			nl_bound;
647e5bf684SAlexander V. Chernikov         bool			nl_task_pending;
657e5bf684SAlexander V. Chernikov 	bool			nl_tx_blocked; /* No new requests accepted */
667e5bf684SAlexander V. Chernikov 	bool			nl_linux; /* true if running under compat */
6704f75b98SAlexander V. Chernikov 	bool			nl_unconstrained_vnet; /* true if running under VNET jail (or without jail) */
6830d7e724SAlexander V. Chernikov 	bool			nl_need_thread_setup;
697e5bf684SAlexander V. Chernikov 	struct taskqueue	*nl_taskqueue;
707e5bf684SAlexander V. Chernikov 	struct task		nl_task;
717e5bf684SAlexander V. Chernikov 	struct ucred		*nl_cred; /* Copy of nl_socket->so_cred */
727e5bf684SAlexander V. Chernikov 	uint64_t		nl_dropped_bytes;
737e5bf684SAlexander V. Chernikov 	uint64_t		nl_dropped_messages;
747e5bf684SAlexander V. Chernikov         CK_LIST_ENTRY(nlpcb)    nl_next;
757e5bf684SAlexander V. Chernikov         CK_LIST_ENTRY(nlpcb)    nl_port_next;
767e5bf684SAlexander V. Chernikov 	volatile u_int		nl_refcount;
777e5bf684SAlexander V. Chernikov 	struct mtx		nl_lock;
787e5bf684SAlexander V. Chernikov 	struct epoch_context	nl_epoch_ctx;
797e5bf684SAlexander V. Chernikov };
807e5bf684SAlexander V. Chernikov #define sotonlpcb(so)       ((struct nlpcb *)(so)->so_pcb)
817e5bf684SAlexander V. Chernikov 
827e5bf684SAlexander V. Chernikov #define	NLP_LOCK_INIT(_nlp)	mtx_init(&((_nlp)->nl_lock), "nlp mtx", NULL, MTX_DEF)
837e5bf684SAlexander V. Chernikov #define	NLP_LOCK_DESTROY(_nlp)	mtx_destroy(&((_nlp)->nl_lock))
847e5bf684SAlexander V. Chernikov #define	NLP_LOCK(_nlp)		mtx_lock(&((_nlp)->nl_lock))
857e5bf684SAlexander V. Chernikov #define	NLP_UNLOCK(_nlp)	mtx_unlock(&((_nlp)->nl_lock))
867e5bf684SAlexander V. Chernikov 
877e5bf684SAlexander V. Chernikov #define	ALIGNED_NL_SZ(_data)	roundup2((((struct nlmsghdr *)(_data))->nlmsg_len), 16)
887e5bf684SAlexander V. Chernikov 
897e5bf684SAlexander V. Chernikov /* nl_flags */
907e5bf684SAlexander V. Chernikov #define NLF_CAP_ACK             0x01 /* Do not send message body with errmsg */
917e5bf684SAlexander V. Chernikov #define NLF_EXT_ACK             0x02 /* Allow including extended TLVs in ack */
927e5bf684SAlexander V. Chernikov #define	NLF_STRICT		0x04 /* Perform strict header checks */
9330d7e724SAlexander V. Chernikov #define	NLF_MSG_INFO		0x08 /* Send caller info along with the notifications */
947e5bf684SAlexander V. Chernikov 
957e5bf684SAlexander V. Chernikov SYSCTL_DECL(_net_netlink);
9619e43c16SAlexander V. Chernikov SYSCTL_DECL(_net_netlink_debug);
977e5bf684SAlexander V. Chernikov 
987e5bf684SAlexander V. Chernikov struct nl_control {
997e5bf684SAlexander V. Chernikov 	CK_LIST_HEAD(nl_pid_head, nlpcb)	ctl_port_head;
1007e5bf684SAlexander V. Chernikov 	CK_LIST_HEAD(nlpcb_head, nlpcb)		ctl_pcb_head;
1017e5bf684SAlexander V. Chernikov 	CK_LIST_ENTRY(nl_control)		ctl_next;
1027e5bf684SAlexander V. Chernikov 	struct rmlock				ctl_lock;
1037e5bf684SAlexander V. Chernikov };
1047e5bf684SAlexander V. Chernikov VNET_DECLARE(struct nl_control *, nl_ctl);
1057e5bf684SAlexander V. Chernikov #define	V_nl_ctl	VNET(nl_ctl)
1067e5bf684SAlexander V. Chernikov 
1077e5bf684SAlexander V. Chernikov 
1087e5bf684SAlexander V. Chernikov struct sockaddr_nl;
1097e5bf684SAlexander V. Chernikov struct sockaddr;
1107e5bf684SAlexander V. Chernikov struct nlmsghdr;
1117e5bf684SAlexander V. Chernikov 
1127e5bf684SAlexander V. Chernikov /* netlink_module.c */
1137e5bf684SAlexander V. Chernikov struct nl_control *vnet_nl_ctl_init(void);
1147e5bf684SAlexander V. Chernikov 
1157e5bf684SAlexander V. Chernikov int nl_verify_proto(int proto);
1167e5bf684SAlexander V. Chernikov const char *nl_get_proto_name(int proto);
1177e5bf684SAlexander V. Chernikov 
1187e5bf684SAlexander V. Chernikov extern int netlink_unloading;
1197e5bf684SAlexander V. Chernikov 
1207e5bf684SAlexander V. Chernikov struct nl_proto_handler {
1217e5bf684SAlexander V. Chernikov 	nl_handler_f	cb;
1227e5bf684SAlexander V. Chernikov 	const char	*proto_name;
1237e5bf684SAlexander V. Chernikov };
1247e5bf684SAlexander V. Chernikov extern struct nl_proto_handler *nl_handlers;
1257e5bf684SAlexander V. Chernikov 
1267e5bf684SAlexander V. Chernikov /* netlink_domain.c */
12717083b94SGleb Smirnoff bool nl_send_group(struct nl_writer *);
12830d7e724SAlexander V. Chernikov void nl_osd_register(void);
12930d7e724SAlexander V. Chernikov void nl_osd_unregister(void);
13030d7e724SAlexander V. Chernikov void nl_set_thread_nlp(struct thread *td, struct nlpcb *nlp);
1317e5bf684SAlexander V. Chernikov 
1327e5bf684SAlexander V. Chernikov /* netlink_io.c */
13309fa78d4SGleb Smirnoff bool nl_send(struct nl_writer *, struct nlpcb *);
1347e5bf684SAlexander V. Chernikov void nlmsg_ack(struct nlpcb *nlp, int error, struct nlmsghdr *nlmsg,
1357e5bf684SAlexander V. Chernikov     struct nl_pstate *npt);
1367e5bf684SAlexander V. Chernikov void nl_on_transmit(struct nlpcb *nlp);
1377e5bf684SAlexander V. Chernikov 
1387e5bf684SAlexander V. Chernikov void nl_taskqueue_handler(void *_arg, int pending);
139660bd40aSGleb Smirnoff void nl_schedule_taskqueue(struct nlpcb *nlp);
1407e5bf684SAlexander V. Chernikov void nl_process_receive_locked(struct nlpcb *nlp);
14130d7e724SAlexander V. Chernikov void nl_set_source_metadata(struct mbuf *m, int num_messages);
14217083b94SGleb Smirnoff struct nl_buf *nl_buf_alloc(size_t len, int mflag);
14317083b94SGleb Smirnoff void nl_buf_free(struct nl_buf *nb);
144d1871547SAlexander V. Chernikov 
14519e43c16SAlexander V. Chernikov /* netlink_generic.c */
14619e43c16SAlexander V. Chernikov struct genl_family {
14719e43c16SAlexander V. Chernikov 	const char	*family_name;
14819e43c16SAlexander V. Chernikov 	uint16_t	family_hdrsize;
14919e43c16SAlexander V. Chernikov 	uint16_t	family_id;
15019e43c16SAlexander V. Chernikov 	uint16_t	family_version;
15119e43c16SAlexander V. Chernikov 	uint16_t	family_attr_max;
15219e43c16SAlexander V. Chernikov 	uint16_t	family_cmd_size;
15319e43c16SAlexander V. Chernikov 	uint16_t	family_num_groups;
15419e43c16SAlexander V. Chernikov 	struct genl_cmd	*family_cmds;
15519e43c16SAlexander V. Chernikov };
15619e43c16SAlexander V. Chernikov 
15719e43c16SAlexander V. Chernikov struct genl_group {
15819e43c16SAlexander V. Chernikov 	struct genl_family	*group_family;
15919e43c16SAlexander V. Chernikov 	const char		*group_name;
16019e43c16SAlexander V. Chernikov };
16119e43c16SAlexander V. Chernikov 
16219e43c16SAlexander V. Chernikov struct genl_family *genl_get_family(uint32_t family_id);
16319e43c16SAlexander V. Chernikov struct genl_group *genl_get_group(uint32_t group_id);
16419e43c16SAlexander V. Chernikov 
16519e43c16SAlexander V. Chernikov #define	MAX_FAMILIES	20
16619e43c16SAlexander V. Chernikov #define	MAX_GROUPS	64
16719e43c16SAlexander V. Chernikov 
16819e43c16SAlexander V. Chernikov #define	MIN_GROUP_NUM	48
16919e43c16SAlexander V. Chernikov 
17019e43c16SAlexander V. Chernikov #define	CTRL_FAMILY_NAME	"nlctrl"
17119e43c16SAlexander V. Chernikov 
172089104e0SAlexander V. Chernikov struct ifnet;
173089104e0SAlexander V. Chernikov struct nl_parsed_link;
174089104e0SAlexander V. Chernikov struct nlattr_bmask;
175089104e0SAlexander V. Chernikov struct nl_pstate;
176089104e0SAlexander V. Chernikov 
17719e43c16SAlexander V. Chernikov /* Function map */
17819e43c16SAlexander V. Chernikov struct nl_function_wrapper {
17919e43c16SAlexander V. Chernikov 	bool (*nlmsg_add)(struct nl_writer *nw, uint32_t portid, uint32_t seq, uint16_t type,
18019e43c16SAlexander V. Chernikov 	    uint16_t flags, uint32_t len);
18119e43c16SAlexander V. Chernikov 	bool (*nlmsg_refill_buffer)(struct nl_writer *nw, int required_len);
18219e43c16SAlexander V. Chernikov 	bool (*nlmsg_flush)(struct nl_writer *nw);
18319e43c16SAlexander V. Chernikov 	bool (*nlmsg_end)(struct nl_writer *nw);
18419e43c16SAlexander V. Chernikov 	void (*nlmsg_abort)(struct nl_writer *nw);
18519e43c16SAlexander V. Chernikov 	void (*nlmsg_ignore_limit)(struct nl_writer *nw);
18619e43c16SAlexander V. Chernikov 	bool (*nlmsg_get_unicast_writer)(struct nl_writer *nw, int size, struct nlpcb *nlp);
18719e43c16SAlexander V. Chernikov 	bool (*nlmsg_get_group_writer)(struct nl_writer *nw, int size, int protocol, int group_id);
18819e43c16SAlexander V. Chernikov 	bool (*nlmsg_get_chain_writer)(struct nl_writer *nw, int size, struct mbuf **pm);
18919e43c16SAlexander V. Chernikov 	bool (*nlmsg_end_dump)(struct nl_writer *nw, int error, struct nlmsghdr *hdr);
190089104e0SAlexander V. Chernikov 	int (*nl_modify_ifp_generic)(struct ifnet *ifp, struct nl_parsed_link *lattrs,
191089104e0SAlexander V. Chernikov 	    const struct nlattr_bmask *bm, struct nl_pstate *npt);
192089104e0SAlexander V. Chernikov 	void (*nl_store_ifp_cookie)(struct nl_pstate *npt, struct ifnet *ifp);
19330d7e724SAlexander V. Chernikov 	struct nlpcb * (*nl_get_thread_nlp)(struct  thread *td);
19419e43c16SAlexander V. Chernikov };
19519e43c16SAlexander V. Chernikov void nl_set_functions(const struct nl_function_wrapper *nl);
19619e43c16SAlexander V. Chernikov 
197089104e0SAlexander V. Chernikov 
198089104e0SAlexander V. Chernikov 
1997e5bf684SAlexander V. Chernikov #endif
200dddafa8dSAlexander V. Chernikov #endif
201