Page MenuHomeFreeBSD

D39391.id119987.diff
No OneTemporary

D39391.id119987.diff

diff --git a/sbin/route/route_netlink.c b/sbin/route/route_netlink.c
--- a/sbin/route/route_netlink.c
+++ b/sbin/route/route_netlink.c
@@ -39,8 +39,11 @@
void monitor_nl(int fib);
struct nl_helper;
-static void print_getmsg(struct nl_helper *h, struct nlmsghdr *hdr, struct sockaddr *dst);
-static void print_nlmsg(struct nl_helper *h, struct nlmsghdr *hdr);
+struct snl_msg_info;
+static void print_getmsg(struct nl_helper *h, struct nlmsghdr *hdr,
+ struct sockaddr *dst);
+static void print_nlmsg(struct nl_helper *h, struct nlmsghdr *hdr,
+ struct snl_msg_info *cinfo);
#define s6_addr32 __u6_addr.__u6_addr32
#define bitcount32(x) __bitcount32((uint32_t)(x))
@@ -417,9 +420,9 @@
snprintf(buf + sz, bufsize - sz, "/%d", plen);
}
-
static int
-print_line_prefix(const char *cmd, const char *name)
+print_line_prefix(struct nlmsghdr *hdr, struct snl_msg_info *cinfo,
+ const char *cmd, const char *name)
{
struct timespec tp;
struct tm tm;
@@ -429,7 +432,8 @@
localtime_r(&tp.tv_sec, &tm);
strftime(buf, sizeof(buf), "%T", &tm);
- int len = printf("%s.%03ld %s %s ", buf, tp.tv_nsec / 1000000, cmd, name);
+ int len = printf("%s.%03ld PID %4u %s %s ", buf, tp.tv_nsec / 1000000,
+ cinfo->process_id, cmd, name);
return (len);
}
@@ -481,7 +485,8 @@
}
static void
-print_nlmsg_route(struct nl_helper *h, struct nlmsghdr *hdr)
+print_nlmsg_route(struct nl_helper *h, struct nlmsghdr *hdr,
+ struct snl_msg_info *cinfo)
{
struct snl_parsed_route r = { .rtax_weight = RT_DEFAULT_WEIGHT };
struct snl_state *ss = &h->ss_cmd;
@@ -492,7 +497,7 @@
// 20:19:41.333 add route 10.0.0.0/24 gw 10.0.0.1 ifp vtnet0 mtu 1500 table inet.0
const char *cmd = get_action_name(hdr, RTM_NEWROUTE);
- int len = print_line_prefix(cmd, "route");
+ int len = print_line_prefix(hdr, cinfo, cmd, "route");
char buf[128];
print_prefix(h, buf, sizeof(buf), r.rta_dst, r.rtm_dst_len);
@@ -547,7 +552,8 @@
};
static void
-print_nlmsg_link(struct nl_helper *h, struct nlmsghdr *hdr)
+print_nlmsg_link(struct nl_helper *h, struct nlmsghdr *hdr,
+ struct snl_msg_info *cinfo)
{
struct snl_parsed_link l = {};
struct snl_state *ss = &h->ss_cmd;
@@ -557,7 +563,7 @@
// 20:19:41.333 add iface#3 vtnet0 admin UP oper UP mtu 1500 table inet.0
const char *cmd = get_action_name(hdr, RTM_NEWLINK);
- print_line_prefix(cmd, "iface");
+ print_line_prefix(hdr, cinfo, cmd, "iface");
printf("iface#%u %s ", l.ifi_index, l.ifla_ifname);
printf("admin %s ", (l.ifi_flags & IFF_UP) ? "UP" : "DOWN");
@@ -570,7 +576,8 @@
}
static void
-print_nlmsg_addr(struct nl_helper *h, struct nlmsghdr *hdr)
+print_nlmsg_addr(struct nl_helper *h, struct nlmsghdr *hdr,
+ struct snl_msg_info *cinfo)
{
struct snl_parsed_addr attrs = {};
struct snl_state *ss = &h->ss_cmd;
@@ -580,7 +587,7 @@
// add addr 192.168.1.1/24 iface vtnet0
const char *cmd = get_action_name(hdr, RTM_NEWADDR);
- print_line_prefix(cmd, "addr");
+ print_line_prefix(hdr, cinfo, cmd, "addr");
char buf[128];
struct sockaddr *addr = attrs.ifa_local ? attrs.ifa_local : attrs.ifa_address;
@@ -619,7 +626,8 @@
static void
-print_nlmsg_neigh(struct nl_helper *h, struct nlmsghdr *hdr)
+print_nlmsg_neigh(struct nl_helper *h, struct nlmsghdr *hdr,
+ struct snl_msg_info *cinfo)
{
struct snl_parsed_neigh attrs = {};
struct snl_state *ss = &h->ss_cmd;
@@ -629,7 +637,7 @@
// add addr 192.168.1.1 state %s lladdr %s iface vtnet0
const char *cmd = get_action_name(hdr, RTM_NEWNEIGH);
- print_line_prefix(cmd, "neigh");
+ print_line_prefix(hdr, cinfo, cmd, "neigh");
char buf[128];
print_prefix(h, buf, sizeof(buf), attrs.nda_dst, -1);
@@ -677,32 +685,35 @@
}
static void
-print_nlmsg_generic(struct nl_helper *h, struct nlmsghdr *hdr)
+print_nlmsg_generic(struct nl_helper *h, struct nlmsghdr *hdr, struct snl_msg_info *cinfo)
{
+ const char *cmd = get_action_name(hdr, 0);
+ print_line_prefix(hdr, cinfo, cmd, "unknown message");
+ printf(" type %u\n", hdr->nlmsg_type);
}
static void
-print_nlmsg(struct nl_helper *h, struct nlmsghdr *hdr)
+print_nlmsg(struct nl_helper *h, struct nlmsghdr *hdr, struct snl_msg_info *cinfo)
{
switch (hdr->nlmsg_type) {
case RTM_NEWLINK:
case RTM_DELLINK:
- print_nlmsg_link(h, hdr);
+ print_nlmsg_link(h, hdr, cinfo);
break;
case RTM_NEWADDR:
case RTM_DELADDR:
- print_nlmsg_addr(h, hdr);
+ print_nlmsg_addr(h, hdr, cinfo);
break;
case RTM_NEWROUTE:
case RTM_DELROUTE:
- print_nlmsg_route(h, hdr);
+ print_nlmsg_route(h, hdr, cinfo);
break;
case RTM_NEWNEIGH:
case RTM_DELNEIGH:
- print_nlmsg_neigh(h, hdr);
+ print_nlmsg_neigh(h, hdr, cinfo);
break;
default:
- print_nlmsg_generic(h, hdr);
+ print_nlmsg_generic(h, hdr, cinfo);
}
snl_clear_lb(&h->ss_cmd);
@@ -731,6 +742,10 @@
#endif
};
+ int optval = 1;
+ socklen_t optlen = sizeof(optval);
+ setsockopt(ss_event.fd, SOL_NETLINK, NETLINK_MSG_INFO, &optval, optlen);
+
for (unsigned int i = 0; i < NL_ARRAY_LEN(groups); i++) {
int error;
int optval = groups[i];
@@ -741,11 +756,11 @@
warn("Unable to subscribe to group %d", optval);
}
+ struct snl_msg_info attrs = {};
struct nlmsghdr *hdr;
- while ((hdr = snl_read_message(&ss_event)) != NULL)
+ while ((hdr = snl_read_message_dbg(&ss_event, &attrs)) != NULL)
{
- // printf("-- MSG type %d--\n", hdr->nlmsg_type);
- print_nlmsg(&h, hdr);
+ print_nlmsg(&h, hdr, &attrs);
snl_clear_lb(&h.ss_cmd);
snl_clear_lb(&ss_event);
}
@@ -798,8 +813,10 @@
return (true);
};
- if (verbose)
- print_nlmsg(h, hdr);
+ if (verbose) {
+ struct snl_msg_info attrs = {};
+ print_nlmsg(h, hdr, &attrs);
+ }
else {
if (r->rta_multipath != NULL) {
for (int i = 0; i < r->rta_multipath->num_nhops; i++) {
@@ -847,8 +864,10 @@
if (!snl_parse_nlmsg(&ss, hdr, &snl_rtm_route_parser, &r))
continue;
- if (verbose)
- print_nlmsg(&h, hdr);
+ if (verbose) {
+ struct snl_msg_info attrs = {};
+ print_nlmsg(&h, hdr, &attrs);
+ }
if (r.rta_table != (uint32_t)fib || r.rtm_family != af)
continue;
if ((r.rta_rtflags & RTF_GATEWAY) == 0)
diff --git a/sys/netlink/netlink.h b/sys/netlink/netlink.h
--- a/sys/netlink/netlink.h
+++ b/sys/netlink/netlink.h
@@ -89,6 +89,7 @@
#define NETLINK_EXT_ACK 11 /* Ack support for receiving additional TLVs in ack */
#define NETLINK_GET_STRICT_CHK 12 /* Strict header checking */
+#define NETLINK_MSG_INFO 257 /* (FreeBSD-specific) Receive message originator data in cmsg */
/*
* RFC 3549, 2.3.2 Netlink Message Header
@@ -183,6 +184,15 @@
NLMSGERR_ATTR_MAX = __NLMSGERR_ATTR_MAX - 1
};
+/* FreeBSD-specific debugging info */
+
+enum nlmsginfo_attrs {
+ NLMSGINFO_ATTR_UNUSED,
+ NLMSGINFO_ATTR_PROCESS_ID = 1, /* u32, source process PID */
+ NLMSGINFO_ATTR_PORT_ID = 2, /* u32, source socket nl_pid */
+ NLMSGINFO_ATTR_SEQ_ID = 3, /* u32, source message seq_id */
+};
+
#ifndef roundup2
#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
diff --git a/sys/netlink/netlink_ctl.h b/sys/netlink/netlink_ctl.h
--- a/sys/netlink/netlink_ctl.h
+++ b/sys/netlink/netlink_ctl.h
@@ -108,5 +108,22 @@
typedef void (*genl_family_event_handler_t)(void *arg, const struct genl_family *gf, int action);
EVENTHANDLER_DECLARE(genl_family_event, genl_family_event_handler_t);
+struct thread;
+#if defined(NETLINK) || defined(NETLINK_MODULE)
+/* Provide optimized calls to the functions inside the same linking unit */
+struct nlpcb *_nl_get_thread_nlp(struct thread *td);
+
+static inline struct nlpcb *
+nl_get_thread_nlp(struct thread *td)
+{
+ return (_nl_get_thread_nlp(td));
+}
+
+#else
+/* Provide access to the functions via netlink_glue.c */
+struct nlpcb *nl_get_thread_nlp(struct thread *td);
+
+#endif
+
#endif
#endif
diff --git a/sys/netlink/netlink_domain.c b/sys/netlink/netlink_domain.c
--- a/sys/netlink/netlink_domain.c
+++ b/sys/netlink/netlink_domain.c
@@ -38,6 +38,7 @@
#include <sys/domain.h>
#include <sys/jail.h>
#include <sys/mbuf.h>
+#include <sys/osd.h>
#include <sys/protosw.h>
#include <sys/proc.h>
#include <sys/ck.h>
@@ -84,6 +85,38 @@
sysctl_handle_nl_maxsockbuf, "LU",
"Maximum Netlink socket buffer size");
+
+static unsigned int osd_slot_id = 0;
+
+void
+nl_osd_register(void)
+{
+ osd_slot_id = osd_register(OSD_THREAD, NULL, NULL);
+}
+
+void
+nl_osd_unregister(void)
+{
+ osd_deregister(OSD_THREAD, osd_slot_id);
+}
+
+struct nlpcb *
+_nl_get_thread_nlp(struct thread *td)
+{
+ return (osd_get(OSD_THREAD, &td->td_osd, osd_slot_id));
+}
+
+void
+nl_set_thread_nlp(struct thread *td, struct nlpcb *nlp)
+{
+ NLP_LOG(LOG_DEBUG, nlp, "Set thread %p nlp to %p (slot %u)", td, nlp, osd_slot_id);
+ if (osd_set(OSD_THREAD, &td->td_osd, osd_slot_id, nlp) == 0)
+ return;
+ /* Failed, need to realloc */
+ void **rsv = osd_reserve(osd_slot_id);
+ osd_set_reserved(OSD_THREAD, &td->td_osd, osd_slot_id, rsv, nlp);
+}
+
/*
* Looks up a nlpcb struct based on the @portid. Need to claim nlsock_mtx.
* Returns nlpcb pointer if present else NULL
@@ -144,6 +177,15 @@
return (groups_mask);
}
+static void
+nl_send_one_group(struct mbuf *m, struct nlpcb *nlp, int num_messages,
+ int io_flags)
+{
+ if (__predict_false(nlp->nl_flags & NLF_MSG_INFO))
+ nl_add_msg_info(m);
+ nl_send_one(m, nlp, num_messages, io_flags);
+}
+
/*
* Broadcasts message @m to the protocol @proto group specified by @group_id
*/
@@ -180,7 +222,8 @@
struct mbuf *m_copy;
m_copy = m_copym(m, 0, M_COPYALL, M_NOWAIT);
if (m_copy != NULL)
- nl_send_one(m_copy, nlp_last, num_messages, io_flags);
+ nl_send_one_group(m_copy, nlp_last,
+ num_messages, io_flags);
else {
NLP_LOCK(nlp_last);
if (nlp_last->nl_socket != NULL)
@@ -192,7 +235,7 @@
}
}
if (nlp_last != NULL)
- nl_send_one(m, nlp_last, num_messages, io_flags);
+ nl_send_one_group(m, nlp_last, num_messages, io_flags);
else
m_freem(m);
@@ -296,6 +339,7 @@
nlp->nl_linux = is_linux;
nlp->nl_active = true;
nlp->nl_unconstrained_vnet = !jailed_without_vnet(so->so_cred);
+ nlp->nl_need_thread_setup = true;
NLP_LOCK_INIT(nlp);
refcount_init(&nlp->nl_refcount, 1);
nl_init_io(nlp);
@@ -589,6 +633,8 @@
return (NLF_EXT_ACK);
case NETLINK_GET_STRICT_CHK:
return (NLF_STRICT);
+ case NETLINK_MSG_INFO:
+ return (NLF_MSG_INFO);
}
return (0);
@@ -630,19 +676,24 @@
case NETLINK_CAP_ACK:
case NETLINK_EXT_ACK:
case NETLINK_GET_STRICT_CHK:
+ case NETLINK_MSG_INFO:
error = sooptcopyin(sopt, &optval, sizeof(optval), sizeof(optval));
if (error != 0)
break;
flag = nl_getoptflag(sopt->sopt_name);
+ if ((flag == NLF_MSG_INFO) && nlp->nl_linux) {
+ error = EINVAL;
+ break;
+ }
+
NLCTL_WLOCK(ctl);
if (optval != 0)
nlp->nl_flags |= flag;
else
nlp->nl_flags &= ~flag;
NLCTL_WUNLOCK(ctl);
- break;
default:
error = ENOPROTOOPT;
}
@@ -658,6 +709,7 @@
case NETLINK_CAP_ACK:
case NETLINK_EXT_ACK:
case NETLINK_GET_STRICT_CHK:
+ case NETLINK_MSG_INFO:
NLCTL_RLOCK(ctl);
optval = (nlp->nl_flags & nl_getoptflag(sopt->sopt_name)) != 0;
NLCTL_RUNLOCK(ctl);
diff --git a/sys/netlink/netlink_glue.c b/sys/netlink/netlink_glue.c
--- a/sys/netlink/netlink_glue.c
+++ b/sys/netlink/netlink_glue.c
@@ -177,6 +177,12 @@
return (false);
}
+static struct nlpcb *
+nl_get_thread_nlp_stub(struct thread *td __unused)
+{
+ return (NULL);
+}
+
const static struct nl_function_wrapper nl_stub = {
.nlmsg_add = nlmsg_add_stub,
.nlmsg_refill_buffer = nlmsg_refill_buffer_stub,
@@ -188,6 +194,7 @@
.nlmsg_get_group_writer = nlmsg_get_group_writer_stub,
.nlmsg_get_chain_writer = nlmsg_get_chain_writer_stub,
.nlmsg_end_dump = nlmsg_end_dump_stub,
+ .nl_get_thread_nlp = nl_get_thread_nlp_stub,
};
/*
@@ -262,5 +269,12 @@
{
return (_nl->nlmsg_end_dump(nw, error, hdr));
}
+
+struct nlpcb *
+nl_get_thread_nlp(struct thread *td)
+{
+ return (_nl->nl_get_thread_nlp(td));
+}
+
#endif /* !NETLINK */
diff --git a/sys/netlink/netlink_io.c b/sys/netlink/netlink_io.c
--- a/sys/netlink/netlink_io.c
+++ b/sys/netlink/netlink_io.c
@@ -125,6 +125,55 @@
q->length = 0;
}
+void
+nl_add_msg_info(struct mbuf *m)
+{
+ struct nlpcb *nlp = nl_get_thread_nlp(curthread);
+ NL_LOG(LOG_DEBUG2, "Trying to recover nlp from thread %p: %p",
+ curthread, nlp);
+
+ if (nlp == NULL)
+ return;
+
+ /* Prepare what we want to encode - PID, socket PID & msg seq */
+ struct {
+ struct nlattr nla;
+ uint32_t val;
+ } data[] = {
+ {
+ .nla.nla_len = sizeof(struct nlattr) + sizeof(uint32_t),
+ .nla.nla_type = NLMSGINFO_ATTR_PROCESS_ID,
+ .val = nlp->nl_process_id,
+ },
+ {
+ .nla.nla_len = sizeof(struct nlattr) + sizeof(uint32_t),
+ .nla.nla_type = NLMSGINFO_ATTR_PORT_ID,
+ .val = nlp->nl_port,
+ },
+ };
+
+
+ while (m->m_next != NULL)
+ m = m->m_next;
+ m->m_next = sbcreatecontrol(data, sizeof(data),
+ NETLINK_MSG_INFO, SOL_NETLINK, 0);
+
+ NL_LOG(LOG_DEBUG2, "Storing %lu bytes of data, ctl: %p", sizeof(data), m->m_next);
+}
+
+static __noinline struct mbuf *
+extract_msg_info(struct mbuf *m)
+{
+ while (m->m_next != NULL) {
+ if (m->m_next->m_type == MT_CONTROL) {
+ struct mbuf *ctl = m->m_next;
+ m->m_next = NULL;
+ return (ctl);
+ }
+ m = m->m_next;
+ }
+ return (NULL);
+}
static void
nl_schedule_taskqueue(struct nlpcb *nlp)
@@ -181,10 +230,16 @@
while (true) {
struct mbuf *m = queue_head(&nlp->tx_queue);
- if (m && sbappendaddr_locked(sb, nl_empty_src, m, NULL) != 0) {
- /* appended successfully */
- queue_pop(&nlp->tx_queue);
- appended = true;
+ if (m != NULL) {
+ struct mbuf *ctl = NULL;
+ if (__predict_false(m->m_next != NULL))
+ ctl = extract_msg_info(m);
+ if (sbappendaddr_locked(sb, nl_empty_src, m, ctl) != 0) {
+ /* appended successfully */
+ queue_pop(&nlp->tx_queue);
+ appended = true;
+ } else
+ break;
} else
break;
}
@@ -257,6 +312,13 @@
{
NL_LOG(LOG_DEBUG3, "taskqueue called");
+ if (__predict_false(nlp->nl_need_thread_setup)) {
+ nl_set_thread_nlp(curthread, nlp);
+ NLP_LOCK(nlp);
+ nlp->nl_need_thread_setup = false;
+ NLP_UNLOCK(nlp);
+ }
+
while (nl_process_received_one(nlp))
;
}
@@ -374,7 +436,10 @@
}
struct socket *so = nlp->nl_socket;
- if (sbappendaddr(&so->so_rcv, nl_empty_src, m, NULL) != 0) {
+ struct mbuf *ctl = NULL;
+ if (__predict_false(m->m_next != NULL))
+ ctl = extract_msg_info(m);
+ if (sbappendaddr(&so->so_rcv, nl_empty_src, m, ctl) != 0) {
sorwakeup(so);
NLP_LOG(LOG_DEBUG3, nlp, "appended data & woken up");
} else {
diff --git a/sys/netlink/netlink_module.c b/sys/netlink/netlink_module.c
--- a/sys/netlink/netlink_module.c
+++ b/sys/netlink/netlink_module.c
@@ -219,6 +219,7 @@
switch (what) {
case MOD_LOAD:
NL_LOG(LOG_DEBUG2, "Loading");
+ nl_osd_register();
#if !defined(NETLINK) && defined(NETLINK_MODULE)
nl_set_functions(&nl_module);
#endif
@@ -232,6 +233,7 @@
#if !defined(NETLINK) && defined(NETLINK_MODULE)
nl_set_functions(NULL);
#endif
+ nl_osd_unregister();
} else
ret = EBUSY;
break;
diff --git a/sys/netlink/netlink_snl.h b/sys/netlink/netlink_snl.h
--- a/sys/netlink/netlink_snl.h
+++ b/sys/netlink/netlink_snl.h
@@ -271,6 +271,55 @@
return (++ss->seq);
}
+struct snl_msg_info {
+ int cmsg_type;
+ int cmsg_level;
+ uint32_t process_id;
+ uint8_t port_id;
+ uint8_t seq_id;
+};
+static inline bool parse_cmsg(struct snl_state *ss, const struct msghdr *msg,
+ struct snl_msg_info *attrs);
+
+static inline struct nlmsghdr *
+snl_read_message_dbg(struct snl_state *ss, struct snl_msg_info *cinfo)
+{
+ memset(cinfo, 0, sizeof(*cinfo));
+
+ if (ss->off == ss->datalen) {
+ struct sockaddr_nl nladdr;
+ char cbuf[64];
+
+ struct iovec iov = {
+ .iov_base = ss->buf,
+ .iov_len = ss->bufsize,
+ };
+ struct msghdr msg = {
+ .msg_name = &nladdr,
+ .msg_namelen = sizeof(nladdr),
+ .msg_iov = &iov,
+ .msg_iovlen = 1,
+ .msg_control = cbuf,
+ .msg_controllen = sizeof(cbuf),
+ };
+ ss->off = 0;
+ ss->datalen = 0;
+ for (;;) {
+ ssize_t datalen = recvmsg(ss->fd, &msg, 0);
+ if (datalen > 0) {
+ ss->datalen = datalen;
+ parse_cmsg(ss, &msg, cinfo);
+ break;
+ } else if (errno != EINTR)
+ return (NULL);
+ }
+ }
+ struct nlmsghdr *hdr = (struct nlmsghdr *)(void *)&ss->buf[ss->off];
+ ss->off += NLMSG_ALIGN(hdr->nlmsg_len);
+ return (hdr);
+}
+
+
static inline struct nlmsghdr *
snl_read_message(struct snl_state *ss)
{
@@ -654,6 +703,33 @@
return (false);
}
+#define _OUT(_field) offsetof(struct snl_msg_info, _field)
+static const struct snl_attr_parser _nla_p_cinfo[] = {
+ { .type = NLMSGINFO_ATTR_PROCESS_ID, .off = _OUT(process_id), .cb = snl_attr_get_uint32 },
+ { .type = NLMSGINFO_ATTR_PORT_ID, .off = _OUT(port_id), .cb = snl_attr_get_uint32 },
+ { .type = NLMSGINFO_ATTR_SEQ_ID, .off = _OUT(seq_id), .cb = snl_attr_get_uint32 },
+};
+#undef _OUT
+SNL_DECLARE_ATTR_PARSER(snl_msg_info_parser, _nla_p_cinfo);
+
+static inline bool
+parse_cmsg(struct snl_state *ss, const struct msghdr *msg, struct snl_msg_info *attrs)
+{
+ for (struct cmsghdr *cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ if (cmsg->cmsg_level != SOL_NETLINK || cmsg->cmsg_type != NETLINK_MSG_INFO)
+ continue;
+
+ void *data = CMSG_DATA(cmsg);
+ int len = cmsg->cmsg_len - ((char *)data - (char *)cmsg);
+ const struct snl_hdr_parser *ps = &snl_msg_info_parser;
+
+ return (snl_parse_attrs_raw(ss, data, len, ps->np, ps->np_size, attrs));
+ }
+
+ return (false);
+}
+
/*
* Assumes e is zeroed
*/
diff --git a/sys/netlink/netlink_var.h b/sys/netlink/netlink_var.h
--- a/sys/netlink/netlink_var.h
+++ b/sys/netlink/netlink_var.h
@@ -62,6 +62,7 @@
bool nl_tx_blocked; /* No new requests accepted */
bool nl_linux; /* true if running under compat */
bool nl_unconstrained_vnet; /* true if running under VNET jail (or without jail) */
+ bool nl_need_thread_setup;
struct nl_io_queue rx_queue;
struct nl_io_queue tx_queue;
struct taskqueue *nl_taskqueue;
@@ -88,6 +89,7 @@
#define NLF_CAP_ACK 0x01 /* Do not send message body with errmsg */
#define NLF_EXT_ACK 0x02 /* Allow including extended TLVs in ack */
#define NLF_STRICT 0x04 /* Perform strict header checks */
+#define NLF_MSG_INFO 0x08 /* Send caller info along with the notifications */
SYSCTL_DECL(_net_netlink);
SYSCTL_DECL(_net_netlink_debug);
@@ -130,6 +132,9 @@
/* netlink_domain.c */
void nl_send_group(struct mbuf *m, int cnt, int proto, int group_id);
+void nl_osd_register(void);
+void nl_osd_unregister(void);
+void nl_set_thread_nlp(struct thread *td, struct nlpcb *nlp);
/* netlink_io.c */
#define NL_IOF_UNTRANSLATED 0x01
@@ -144,6 +149,8 @@
void nl_taskqueue_handler(void *_arg, int pending);
int nl_receive_async(struct mbuf *m, struct socket *so);
void nl_process_receive_locked(struct nlpcb *nlp);
+void nl_set_source_metadata(struct mbuf *m, int num_messages);
+void nl_add_msg_info(struct mbuf *m);
/* netlink_generic.c */
struct genl_family {
@@ -185,6 +192,7 @@
bool (*nlmsg_get_group_writer)(struct nl_writer *nw, int size, int protocol, int group_id);
bool (*nlmsg_get_chain_writer)(struct nl_writer *nw, int size, struct mbuf **pm);
bool (*nlmsg_end_dump)(struct nl_writer *nw, int error, struct nlmsghdr *hdr);
+ struct nlpcb * (*nl_get_thread_nlp)(struct thread *td);
};
void nl_set_functions(const struct nl_function_wrapper *nl);

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 29, 11:20 PM (14 h, 7 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32409867
Default Alt Text
D39391.id119987.diff (19 KB)

Event Timeline