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