Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F154736550
D39391.id119781.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D39391.id119781.diff
View Options
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
@@ -405,9 +405,8 @@
snprintf(buf + sz, bufsize - sz, "/%d", plen);
}
-
static int
-print_line_prefix(const char *cmd, const char *name)
+print_line_prefix(struct nlmsghdr *hdr, const char *cmd, const char *name)
{
struct timespec tp;
struct tm tm;
@@ -417,7 +416,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,
+ hdr->nlmsg_pid, cmd, name);
return (len);
}
@@ -480,7 +480,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, cmd, "route");
char buf[128];
print_prefix(h, buf, sizeof(buf), r.rta_dst, r.rtm_dst_len);
@@ -545,7 +545,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, cmd, "iface");
printf("iface#%u %s ", l.ifi_index, l.ifla_ifname);
printf("admin %s ", (l.ifi_flags & IFF_UP) ? "UP" : "DOWN");
@@ -568,7 +568,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, cmd, "addr");
char buf[128];
struct sockaddr *addr = attrs.ifa_local ? attrs.ifa_local : attrs.ifa_address;
@@ -617,7 +617,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, cmd, "neigh");
char buf[128];
print_prefix(h, buf, sizeof(buf), attrs.nda_dst, -1);
@@ -719,6 +719,10 @@
#endif
};
+ int optval = 1;
+ socklen_t optlen = sizeof(optval);
+ setsockopt(ss_event.fd, SOL_NETLINK, NETLINK_MONITOR, &optval, optlen);
+
for (unsigned int i = 0; i < NL_ARRAY_LEN(groups); i++) {
int error;
int optval = groups[i];
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_MONITOR 257 /* Receive originator nl_pid in the notifications */
/*
* RFC 3549, 2.3.2 Netlink Message Header
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_MONITOR))
+ nl_set_source_metadata(m, num_messages);
+ 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_MONITOR:
+ return (NLF_MONITOR);
}
return (0);
@@ -630,6 +676,7 @@
case NETLINK_CAP_ACK:
case NETLINK_EXT_ACK:
case NETLINK_GET_STRICT_CHK:
+ case NETLINK_MONITOR:
error = sooptcopyin(sopt, &optval, sizeof(optval), sizeof(optval));
if (error != 0)
break;
@@ -642,6 +689,8 @@
else
nlp->nl_flags &= ~flag;
NLCTL_WUNLOCK(ctl);
+ if (sopt->sopt_name == NETLINK_MONITOR && optval)
+ NLP_LOG(LOG_DEBUG, nlp, "MONITOR option set");
break;
default:
error = ENOPROTOOPT;
@@ -658,6 +707,7 @@
case NETLINK_CAP_ACK:
case NETLINK_EXT_ACK:
case NETLINK_GET_STRICT_CHK:
+ case NETLINK_MONITOR:
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
@@ -257,10 +257,39 @@
{
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))
;
}
+void
+nl_set_source_metadata(struct mbuf *m, int num_messages)
+{
+ struct nlpcb *nlp = nl_get_thread_nlp(curthread);
+ NL_LOG(LOG_DEBUG, "Trying to recover nlp from thread %p: %p",
+ curthread, nlp);
+
+ if (nlp == NULL)
+ return;
+
+ int max_off = M_TRAILINGSPACE(m);
+ for (int off = 0, count = 0; (count < num_messages) && (off < max_off); ) {
+ /* Update source PID for each of the messages */
+ struct nlmsghdr *hdr = mtodo(m, off);
+ hdr->nlmsg_pid = nlp->nl_port ? nlp->nl_port : nlp->nl_process_id;
+ NL_LOG(LOG_DEBUG, "Setting PID for message %u to %u",
+ hdr->nlmsg_type, hdr->nlmsg_pid);
+ off += NLMSG_ALIGN(hdr->nlmsg_len);
+ count++;
+ }
+}
+
void
nl_init_io(struct nlpcb *nlp)
{
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_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_MONITOR 0x08 /* Send original nl_pid in 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,7 @@
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);
/* netlink_generic.c */
struct genl_family {
@@ -185,6 +191,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
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 30, 8:26 AM (21 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32478937
Default Alt Text
D39391.id119781.diff (10 KB)
Attached To
Mode
D39391: route: show originator PID in netlink monitor
Attached
Detach File
Event Timeline
Log In to Comment