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