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_buf {
47	TAILQ_ENTRY(nl_buf)	tailq;
48	u_int			buflen;
49	u_int			datalen;
50	u_int			offset;
51	char			data[];
52};
53
54#define	NLP_MAX_GROUPS		128
55
56struct nlpcb {
57        struct socket           *nl_socket;
58	uint64_t	        nl_groups[NLP_MAX_GROUPS / 64];
59	uint32_t                nl_port;
60	uint32_t	        nl_flags;
61	uint32_t	        nl_process_id;
62        int                     nl_proto;
63	bool			nl_bound;
64        bool			nl_task_pending;
65	bool			nl_tx_blocked; /* No new requests accepted */
66	bool			nl_linux; /* true if running under compat */
67	bool			nl_unconstrained_vnet; /* true if running under VNET jail (or without jail) */
68	bool			nl_need_thread_setup;
69	struct taskqueue	*nl_taskqueue;
70	struct task		nl_task;
71	struct ucred		*nl_cred; /* Copy of nl_socket->so_cred */
72	uint64_t		nl_dropped_bytes;
73	uint64_t		nl_dropped_messages;
74        CK_LIST_ENTRY(nlpcb)    nl_next;
75        CK_LIST_ENTRY(nlpcb)    nl_port_next;
76	volatile u_int		nl_refcount;
77	struct mtx		nl_lock;
78	struct epoch_context	nl_epoch_ctx;
79};
80#define sotonlpcb(so)       ((struct nlpcb *)(so)->so_pcb)
81
82#define	NLP_LOCK_INIT(_nlp)	mtx_init(&((_nlp)->nl_lock), "nlp mtx", NULL, MTX_DEF)
83#define	NLP_LOCK_DESTROY(_nlp)	mtx_destroy(&((_nlp)->nl_lock))
84#define	NLP_LOCK(_nlp)		mtx_lock(&((_nlp)->nl_lock))
85#define	NLP_UNLOCK(_nlp)	mtx_unlock(&((_nlp)->nl_lock))
86
87#define	ALIGNED_NL_SZ(_data)	roundup2((((struct nlmsghdr *)(_data))->nlmsg_len), 16)
88
89/* nl_flags */
90#define NLF_CAP_ACK             0x01 /* Do not send message body with errmsg */
91#define NLF_EXT_ACK             0x02 /* Allow including extended TLVs in ack */
92#define	NLF_STRICT		0x04 /* Perform strict header checks */
93#define	NLF_MSG_INFO		0x08 /* Send caller info along with the notifications */
94
95SYSCTL_DECL(_net_netlink);
96SYSCTL_DECL(_net_netlink_debug);
97
98struct 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 rmlock				ctl_lock;
103};
104VNET_DECLARE(struct nl_control *, nl_ctl);
105#define	V_nl_ctl	VNET(nl_ctl)
106
107
108struct sockaddr_nl;
109struct sockaddr;
110struct nlmsghdr;
111
112/* netlink_module.c */
113struct nl_control *vnet_nl_ctl_init(void);
114
115int nl_verify_proto(int proto);
116const char *nl_get_proto_name(int proto);
117
118extern int netlink_unloading;
119
120struct nl_proto_handler {
121	nl_handler_f	cb;
122	const char	*proto_name;
123};
124extern struct nl_proto_handler *nl_handlers;
125
126/* netlink_domain.c */
127bool nl_send_group(struct nl_writer *);
128void nl_osd_register(void);
129void nl_osd_unregister(void);
130void nl_set_thread_nlp(struct thread *td, struct nlpcb *nlp);
131
132/* netlink_io.c */
133bool nl_send(struct nl_writer *, struct nlpcb *);
134void nlmsg_ack(struct nlpcb *nlp, int error, struct nlmsghdr *nlmsg,
135    struct nl_pstate *npt);
136void nl_on_transmit(struct nlpcb *nlp);
137
138void nl_taskqueue_handler(void *_arg, int pending);
139void nl_schedule_taskqueue(struct nlpcb *nlp);
140void nl_process_receive_locked(struct nlpcb *nlp);
141void nl_set_source_metadata(struct mbuf *m, int num_messages);
142struct nl_buf *nl_buf_alloc(size_t len, int mflag);
143void nl_buf_free(struct nl_buf *nb);
144
145/* netlink_generic.c */
146struct genl_family {
147	const char	*family_name;
148	uint16_t	family_hdrsize;
149	uint16_t	family_id;
150	uint16_t	family_version;
151	uint16_t	family_attr_max;
152	uint16_t	family_cmd_size;
153	uint16_t	family_num_groups;
154	struct genl_cmd	*family_cmds;
155};
156
157struct genl_group {
158	struct genl_family	*group_family;
159	const char		*group_name;
160};
161
162struct genl_family *genl_get_family(uint32_t family_id);
163struct genl_group *genl_get_group(uint32_t group_id);
164
165#define	MAX_FAMILIES	20
166#define	MAX_GROUPS	64
167
168#define	MIN_GROUP_NUM	48
169
170#define	CTRL_FAMILY_NAME	"nlctrl"
171
172struct ifnet;
173struct nl_parsed_link;
174struct nlattr_bmask;
175struct nl_pstate;
176
177/* Function map */
178struct nl_function_wrapper {
179	bool (*nlmsg_add)(struct nl_writer *nw, uint32_t portid, uint32_t seq, uint16_t type,
180	    uint16_t flags, uint32_t len);
181	bool (*nlmsg_refill_buffer)(struct nl_writer *nw, int required_len);
182	bool (*nlmsg_flush)(struct nl_writer *nw);
183	bool (*nlmsg_end)(struct nl_writer *nw);
184	void (*nlmsg_abort)(struct nl_writer *nw);
185	void (*nlmsg_ignore_limit)(struct nl_writer *nw);
186	bool (*nlmsg_get_unicast_writer)(struct nl_writer *nw, int size, struct nlpcb *nlp);
187	bool (*nlmsg_get_group_writer)(struct nl_writer *nw, int size, int protocol, int group_id);
188	bool (*nlmsg_get_chain_writer)(struct nl_writer *nw, int size, struct mbuf **pm);
189	bool (*nlmsg_end_dump)(struct nl_writer *nw, int error, struct nlmsghdr *hdr);
190	int (*nl_modify_ifp_generic)(struct ifnet *ifp, struct nl_parsed_link *lattrs,
191	    const struct nlattr_bmask *bm, struct nl_pstate *npt);
192	void (*nl_store_ifp_cookie)(struct nl_pstate *npt, struct ifnet *ifp);
193	struct nlpcb * (*nl_get_thread_nlp)(struct  thread *td);
194};
195void nl_set_functions(const struct nl_function_wrapper *nl);
196
197
198
199#endif
200#endif
201