aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2024-01-11 04:51:53 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2024-01-11 04:51:53 +0000
commitf75d7fac109bf8e322b07456c5361ee62f5635c2 (patch)
tree043e1350bdb7db020afaeb5b0029ff6c695226d6
parente6f4c31460658697827aed7f29ec6e960d6f0a87 (diff)
downloadsrc-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.c7
-rw-r--r--sys/netlink/netlink_io.c2
-rw-r--r--sys/netlink/netlink_message_writer.c11
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) {