diff --git a/share/man/man4/netlink.4 b/share/man/man4/netlink.4 --- a/share/man/man4/netlink.4 +++ b/share/man/man4/netlink.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 1, 2022 +.Dd November 30, 2022 .Dt NETLINK 4 .Os .Sh NAME @@ -212,11 +212,16 @@ socket option is not set, the remainder of the original message will follow. If the .Dv NETLINK_EXT_ACK -socket option is set, kernel may add a +socket option is set, the kernel may add a .Dv NLMSGERR_ATTR_MSG string TLV with the textual error description, optionally followed by the .Dv NLMSGERR_ATTR_OFFS TLV, indicating the offset from the message start that triggered an error. +If the operation reply is a multipart message, then no +.Dv NLMSG_ERROR +reply is generated, only a +.Dv NLMSG_DONE +message, closing multipart sequence. .Pp .Dv NLMSG_DONE indicates the end of the message group: typically, the end of the dump. 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 @@ -405,8 +405,9 @@ nl_handler_f handler = nl_handlers[nlp->nl_proto].cb; int error = 0; - NL_LOG(LOG_DEBUG2, "msg len: %d type: %d", hdr->nlmsg_len, - hdr->nlmsg_type); + NLP_LOG(LOG_DEBUG2, nlp, "msg len: %u type: %d: flags: 0x%X seq: %u pid: %u", + hdr->nlmsg_len, hdr->nlmsg_type, hdr->nlmsg_flags, hdr->nlmsg_seq, + hdr->nlmsg_pid); if (__predict_false(hdr->nlmsg_len > remaining_length)) { NLP_LOG(LOG_DEBUG, nlp, "message is not entirely present: want %d got %d", @@ -439,9 +440,10 @@ NL_LOG(LOG_DEBUG2, "retcode: %d", error); } if ((hdr->nlmsg_flags & NLM_F_ACK) || (error != 0 && error != EINTR)) { - NL_LOG(LOG_DEBUG3, "ack"); - nlmsg_ack(nlp, error, hdr, npt); - NL_LOG(LOG_DEBUG3, "done"); + if (!npt->nw->suppress_ack) { + NL_LOG(LOG_DEBUG3, "ack"); + nlmsg_ack(nlp, error, hdr, npt); + } } return (0); @@ -455,6 +457,7 @@ npt->err_msg = NULL; npt->err_off = 0; npt->hdr = NULL; + npt->nw->suppress_ack = false; } /* diff --git a/sys/netlink/netlink_message_writer.h b/sys/netlink/netlink_message_writer.h --- a/sys/netlink/netlink_message_writer.h +++ b/sys/netlink/netlink_message_writer.h @@ -55,6 +55,7 @@ uint8_t writer_target; /* NS_WRITER_TARGET_* */ bool ignore_limit; /* If true, ignores RCVBUF limit */ bool enomem; /* True if ENOMEM occured */ + bool suppress_ack; /* If true, don't send NLMSG_ERR */ }; #define NS_WRITER_TARGET_SOCKET 0 #define NS_WRITER_TARGET_GROUP 1 diff --git a/sys/netlink/netlink_message_writer.c b/sys/netlink/netlink_message_writer.c --- a/sys/netlink/netlink_message_writer.c +++ b/sys/netlink/netlink_message_writer.c @@ -600,6 +600,9 @@ } nw->hdr->nlmsg_len = (uint32_t)(nw->data + nw->offset - (char *)nw->hdr); + NL_LOG(LOG_DEBUG2, "wrote msg len: %u type: %d: flags: 0x%X seq: %u pid: %u", + nw->hdr->nlmsg_len, nw->hdr->nlmsg_type, nw->hdr->nlmsg_flags, + nw->hdr->nlmsg_seq, nw->hdr->nlmsg_pid); nw->hdr = NULL; nw->num_messages++; return (true); @@ -681,6 +684,7 @@ nw->offset, perror); *perror = error; nlmsg_end(nw); + nw->suppress_ack = true; return (true); }