summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLahav Schlesinger <lschlesinger@drivenets.com>2021-07-15 17:38:56 +0300
committerStephen Hemminger <stephen@networkplumber.org>2021-07-17 11:13:36 -0700
commitf760bff328316244b510986cf0ed7ee1c3c689ef (patch)
tree0e9a464c346f7899455a085fd593237b19dac4c4
parent7a7e9ed98fd93eae01ada48ef46909401f148a47 (diff)
downloadiproute2-f760bff328316244b510986cf0ed7ee1c3c689ef.tar.gz
ipmonitor: Fix recvmsg with ancillary data
A successful call to recvmsg() causes msg.msg_controllen to contain the length of the received ancillary data. However, the current code in the 'ip' utility doesn't reset this value after each recvmsg(). This means that if a call to recvmsg() doesn't have ancillary data, then 'msg.msg_controllen' will be set to 0, causing future recvmsg() which do contain ancillary data to get MSG_CTRUNC set in msg.msg_flags. This fixes 'ip monitor' running with the all-nsid option - With this option the kernel passes the nsid as ancillary data. If while 'ip monitor' is running an even on the current netns is received, then no ancillary data will be sent, causing 'msg.msg_controllen' to be set to 0, which causes 'ip monitor' to indefinitely print "[nsid current]" instead of the real nsid. Fixes: 449b824ad196 ("ipmonitor: allows to monitor in several netns") Cc: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: Lahav Schlesinger <lschlesinger@drivenets.com> Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
-rw-r--r--lib/libnetlink.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 6836c21c..7e977a67 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -1175,16 +1175,16 @@ int rtnl_listen(struct rtnl_handle *rtnl,
char buf[16384];
char cmsgbuf[BUFSIZ];
- if (rtnl->flags & RTNL_HANDLE_F_LISTEN_ALL_NSID) {
- msg.msg_control = &cmsgbuf;
- msg.msg_controllen = sizeof(cmsgbuf);
- }
-
iov.iov_base = buf;
while (1) {
struct rtnl_ctrl_data ctrl;
struct cmsghdr *cmsg;
+ if (rtnl->flags & RTNL_HANDLE_F_LISTEN_ALL_NSID) {
+ msg.msg_control = &cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ }
+
iov.iov_len = sizeof(buf);
status = recvmsg(rtnl->fd, &msg, 0);