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 @@ -179,15 +179,6 @@ return (groups_mask); } -static void -nl_send_one_group(struct nl_writer *nw, struct nl_buf *nb, struct nlpcb *nlp) -{ - if (__predict_false(nlp->nl_flags & NLF_MSG_INFO)) - nl_add_msg_info(nb); - nw->buf = nb; - (void)nl_send_one(nw); -} - static struct nl_buf * nl_buf_copy(struct nl_buf *nb) { @@ -197,13 +188,6 @@ if (__predict_false(copy == NULL)) return (NULL); memcpy(copy, nb, sizeof(*nb) + nb->buflen); - if (nb->control != NULL) { - copy->control = m_copym(nb->control, 0, M_COPYALL, M_NOWAIT); - if (__predict_false(copy->control == NULL)) { - nl_buf_free(copy); - return (NULL); - } - } return (copy); } @@ -248,7 +232,8 @@ copy = nl_buf_copy(nb); if (copy != NULL) { - nl_send_one_group(nw, copy, nlp_last); + nw->buf = copy; + (void)nl_send_one(nw); } else { NLP_LOCK(nlp_last); if (nlp_last->nl_socket != NULL) @@ -259,9 +244,10 @@ nlp_last = nlp; } } - if (nlp_last != NULL) - nl_send_one_group(nw, nb, nlp_last); - else + if (nlp_last != NULL) { + nw->buf = nb; + (void)nl_send_one(nw); + } else nl_buf_free(nb); NLCTL_RUNLOCK(ctl); @@ -657,6 +643,30 @@ return (error); } +/* Create control data for recvmsg(2) on Netlink socket. */ +static struct mbuf * +nl_createcontrol(struct nlpcb *nlp) +{ + 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, + }, + }; + + return (sbcreatecontrol(data, sizeof(data), NETLINK_MSG_INFO, + SOL_NETLINK, M_WAITOK)); +} + static int nl_soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio, struct mbuf **mp, struct mbuf **controlp, int *flagsp) @@ -667,6 +677,7 @@ .nl_pid = 0 /* comes from the kernel */ }; struct sockbuf *sb = &so->so_rcv; + struct nlpcb *nlp = sotonlpcb(so); struct nl_buf *first, *last, *nb, *next; struct nlmsghdr *hdr; int flags, error; @@ -681,6 +692,9 @@ *psa = sodupsockaddr((const struct sockaddr *)&nl_empty_src, M_WAITOK); + if (controlp != NULL && (nlp->nl_flags & NLF_MSG_INFO)) + *controlp = nl_createcontrol(nlp); + flags = flagsp != NULL ? *flagsp & ~MSG_TRUNC : 0; trunc = flagsp != NULL ? *flagsp & MSG_TRUNC : false; nonblock = (so->so_state & SS_NBIO) || @@ -691,9 +705,6 @@ if (__predict_false(error)) return (error); - if (controlp != NULL) - *controlp = NULL; - len = 0; overflow = 0; msgrcv = 0; @@ -798,13 +809,6 @@ for (nb = first; nb != last; nb = next) { next = TAILQ_NEXT(nb, tailq); - - /* XXXGL multiple controls??? */ - if (controlp != NULL && *controlp == NULL && - nb->control != NULL && !peek) { - *controlp = nb->control; - nb->control = NULL; - } if (__predict_true(error == 0)) error = uiomove(&nb->data[nb->offset], (int)(nb->datalen - nb->offset), uio); 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 @@ -62,7 +62,6 @@ if (__predict_true(nb != NULL)) { nb->buflen = len; nb->datalen = nb->offset = 0; - nb->control = NULL; } return (nb); @@ -72,51 +71,9 @@ nl_buf_free(struct nl_buf *nb) { - if (nb->control) - m_freem(nb->control); free(nb, M_NETLINK); } -void -nl_add_msg_info(struct nl_buf *nb) -{ - /* XXXGL pass nlp as arg? */ - 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, - }, - }; - - - nb->control = sbcreatecontrol(data, sizeof(data), - NETLINK_MSG_INFO, SOL_NETLINK, M_NOWAIT); - - if (__predict_true(nb->control != NULL)) - NL_LOG(LOG_DEBUG2, "Storing %u bytes of control data, ctl: %p", - (unsigned)sizeof(data), nb->control); - else - NL_LOG(LOG_DEBUG2, "Failed to allocate %u bytes of control", - (unsigned)sizeof(data)); -} - void nl_schedule_taskqueue(struct nlpcb *nlp) { 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 @@ -45,7 +45,6 @@ struct nl_buf { TAILQ_ENTRY(nl_buf) tailq; - struct mbuf *control; u_int buflen; u_int datalen; u_int offset; @@ -142,7 +141,6 @@ void nl_schedule_taskqueue(struct nlpcb *nlp); 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 nl_buf *nb); struct nl_buf *nl_buf_alloc(size_t len, int mflag); void nl_buf_free(struct nl_buf *nb);