diff options
| author | Alexander V. Chernikov <melifaro@FreeBSD.org> | 2023-04-28 12:44:04 +0000 |
|---|---|---|
| committer | Alexander V. Chernikov <melifaro@FreeBSD.org> | 2023-04-28 13:54:54 +0000 |
| commit | 30d7e724db0c9805c9cafdd70a33f546df168d8c (patch) | |
| tree | f44993e126d8a419dd444e2493b541e0efc8436b /sys/netlink/netlink_domain.c | |
| parent | 9e79038c502433f077b4d3b5bb1c0838329f1ebc (diff) | |
Diffstat (limited to 'sys/netlink/netlink_domain.c')
| -rw-r--r-- | sys/netlink/netlink_domain.c | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/sys/netlink/netlink_domain.c b/sys/netlink/netlink_domain.c index 8b0d09ac0b66..9cc2a5073fdd 100644 --- 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_OID(_net_netlink, OID_AUTO, nl_maxsockbuf, 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_DEBUG2, 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 @@ nl_get_groups_compat(struct nlpcb *nlp) 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 @@ nl_send_group(struct mbuf *m, int num_messages, int proto, int group_id) 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 @@ nl_send_group(struct mbuf *m, int num_messages, int proto, int group_id) } } 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 @@ nl_pru_attach(struct socket *so, int proto, struct thread *td) 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 @@ nl_getoptflag(int sopt_name) return (NLF_EXT_ACK); case NETLINK_GET_STRICT_CHK: return (NLF_STRICT); + case NETLINK_MSG_INFO: + return (NLF_MSG_INFO); } return (0); @@ -630,12 +676,18 @@ nl_ctloutput(struct socket *so, struct sockopt *sopt) 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; @@ -658,6 +710,7 @@ nl_ctloutput(struct socket *so, struct sockopt *sopt) 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); |
