diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2024-01-11 04:51:53 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2024-01-11 04:51:53 +0000 |
commit | f75d7fac109bf8e322b07456c5361ee62f5635c2 (patch) | |
tree | 043e1350bdb7db020afaeb5b0029ff6c695226d6 | |
parent | e6f4c31460658697827aed7f29ec6e960d6f0a87 (diff) | |
download | src-f75d7fac109bf8e322b07456c5361ee62f5635c2.tar.gz src-f75d7fac109bf8e322b07456c5361ee62f5635c2.zip |
netlink: avoid putting empty mbufs on the socket queue
When processing incoming Netlink messages in nl_process_nbuf() kernel
always allocates a writer with a buffer to put generated reply to.
However, certain messages aren't replied. That makes nlmsg_flush()
to put an empty buffer to the socket. Avoid doing that because avoiding
is much easier than dealing with empty buffers on the receiver side.
-rw-r--r-- | sys/netlink/netlink_domain.c | 7 | ||||
-rw-r--r-- | sys/netlink/netlink_io.c | 2 | ||||
-rw-r--r-- | sys/netlink/netlink_message_writer.c | 11 |
3 files changed, 12 insertions, 8 deletions
diff --git a/sys/netlink/netlink_domain.c b/sys/netlink/netlink_domain.c index 94989af73dfe..7ecafbf99d26 100644 --- a/sys/netlink/netlink_domain.c +++ b/sys/netlink/netlink_domain.c @@ -740,12 +740,7 @@ nl_soreceive(struct socket *so, struct sockaddr **psa, struct uio *uio, TAILQ_FOREACH(nb, &sb->nl_queue, tailq) { u_int offset; - /* - * XXXGL: zero length buffer may be at the tail of a queue - * when a writer overflows socket buffer. When this is - * improved, use MPASS(nb->offset < nb->datalen). - */ - MPASS(nb->offset <= nb->datalen); + MPASS(nb->offset < nb->datalen); offset = nb->offset; while (offset < nb->datalen) { hdr = (struct nlmsghdr *)&nb->data[offset]; diff --git a/sys/netlink/netlink_io.c b/sys/netlink/netlink_io.c index 5f50c40f71d8..61d9d657556a 100644 --- a/sys/netlink/netlink_io.c +++ b/sys/netlink/netlink_io.c @@ -201,6 +201,8 @@ nl_send(struct nl_writer *nw, struct nlpcb *nlp) struct nl_buf *nb; MPASS(nw->hdr == NULL); + MPASS(nw->buf != NULL); + MPASS(nw->buf->datalen > 0); IF_DEBUG_LEVEL(LOG_DEBUG2) { struct nlmsghdr *hdr = (struct nlmsghdr *)nw->buf->data; diff --git a/sys/netlink/netlink_message_writer.c b/sys/netlink/netlink_message_writer.c index 50305e3d9d80..59bc6aabaa3f 100644 --- a/sys/netlink/netlink_message_writer.c +++ b/sys/netlink/netlink_message_writer.c @@ -100,6 +100,7 @@ _nlmsg_ignore_limit(struct nl_writer *nw) bool _nlmsg_flush(struct nl_writer *nw) { + bool result; if (__predict_false(nw->hdr != NULL)) { /* Last message has not been completed, skip it. */ @@ -109,8 +110,14 @@ _nlmsg_flush(struct nl_writer *nw) nw->hdr = NULL; } - NL_LOG(LOG_DEBUG2, "OUT"); - bool result = nw->cb(nw); + if (nw->buf->datalen == 0) { + MPASS(nw->num_messages == 0); + nl_buf_free(nw->buf); + nw->buf = NULL; + return (true); + } + + result = nw->cb(nw); nw->num_messages = 0; if (!result) { |