xref: /freebsd/sys/netlink/netlink_var.h (revision be181ee2a28aa2b4b0e76684bce9f673ef668874)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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 struct ucred;
43 
44 struct nl_io_queue {
45 	STAILQ_HEAD(, mbuf)	head;
46 	int			length;
47 	int			hiwat;
48 };
49 
50 struct nlpcb {
51         struct socket           *nl_socket;
52 	uint64_t	        nl_groups;
53 	uint32_t                nl_port;
54 	uint32_t	        nl_flags;
55 	uint32_t	        nl_process_id;
56         int                     nl_proto;
57         bool			nl_active;
58 	bool			nl_bound;
59         bool			nl_task_pending;
60 	bool			nl_tx_blocked; /* No new requests accepted */
61 	bool			nl_linux; /* true if running under compat */
62 	struct nl_io_queue	rx_queue;
63 	struct nl_io_queue	tx_queue;
64 	struct taskqueue	*nl_taskqueue;
65 	struct task		nl_task;
66 	struct ucred		*nl_cred; /* Copy of nl_socket->so_cred */
67 	uint64_t		nl_dropped_bytes;
68 	uint64_t		nl_dropped_messages;
69         CK_LIST_ENTRY(nlpcb)    nl_next;
70         CK_LIST_ENTRY(nlpcb)    nl_port_next;
71 	volatile u_int		nl_refcount;
72 	struct mtx		nl_lock;
73 	struct epoch_context	nl_epoch_ctx;
74 };
75 #define sotonlpcb(so)       ((struct nlpcb *)(so)->so_pcb)
76 
77 #define	NLP_LOCK_INIT(_nlp)	mtx_init(&((_nlp)->nl_lock), "nlp mtx", NULL, MTX_DEF)
78 #define	NLP_LOCK_DESTROY(_nlp)	mtx_destroy(&((_nlp)->nl_lock))
79 #define	NLP_LOCK(_nlp)		mtx_lock(&((_nlp)->nl_lock))
80 #define	NLP_UNLOCK(_nlp)	mtx_unlock(&((_nlp)->nl_lock))
81 
82 #define	ALIGNED_NL_SZ(_data)	roundup2((((struct nlmsghdr *)(_data))->nlmsg_len), 16)
83 
84 /* nl_flags */
85 #define NLF_CAP_ACK             0x01 /* Do not send message body with errmsg */
86 #define NLF_EXT_ACK             0x02 /* Allow including extended TLVs in ack */
87 #define	NLF_STRICT		0x04 /* Perform strict header checks */
88 
89 SYSCTL_DECL(_net_netlink);
90 
91 struct nl_io {
92 	struct callout				callout;
93 	struct mbuf				*head;
94 	struct mbuf 				*last;
95 	int64_t					length;
96 };
97 
98 struct nl_control {
99 	CK_LIST_HEAD(nl_pid_head, nlpcb)	ctl_port_head;
100 	CK_LIST_HEAD(nlpcb_head, nlpcb)		ctl_pcb_head;
101 	CK_LIST_ENTRY(nl_control)		ctl_next;
102 	struct nl_io				ctl_io;
103 	struct rmlock				ctl_lock;
104 };
105 VNET_DECLARE(struct nl_control *, nl_ctl);
106 #define	V_nl_ctl	VNET(nl_ctl)
107 
108 
109 struct sockaddr_nl;
110 struct sockaddr;
111 struct nlmsghdr;
112 
113 /* netlink_module.c */
114 struct nl_control *vnet_nl_ctl_init(void);
115 
116 int nl_verify_proto(int proto);
117 const char *nl_get_proto_name(int proto);
118 
119 extern int netlink_unloading;
120 
121 struct nl_proto_handler {
122 	nl_handler_f	cb;
123 	const char	*proto_name;
124 };
125 extern struct nl_proto_handler *nl_handlers;
126 
127 /* netlink_domain.c */
128 void nl_send_group(struct mbuf *m, int cnt, int proto, int group_id);
129 
130 /* netlink_io.c */
131 #define	NL_IOF_UNTRANSLATED	0x01
132 #define	NL_IOF_IGNORE_LIMIT	0x02
133 bool nl_send_one(struct mbuf *m, struct nlpcb *nlp, int cnt, int io_flags);
134 void nlmsg_ack(struct nlpcb *nlp, int error, struct nlmsghdr *nlmsg,
135     struct nl_pstate *npt);
136 void nl_on_transmit(struct nlpcb *nlp);
137 void nl_init_io(struct nlpcb *nlp);
138 void nl_free_io(struct nlpcb *nlp);
139 
140 void nl_taskqueue_handler(void *_arg, int pending);
141 int nl_receive_async(struct mbuf *m, struct socket *so);
142 void nl_process_receive_locked(struct nlpcb *nlp);
143 
144 #endif
145 #endif
146