From a13313ad2fe17ea58c0abb8aae0860491b85003d Mon Sep 17 00:00:00 2001 From: david Date: Sat, 3 Sep 2011 17:22:07 +0000 Subject: [PATCH] Don't double-count RTA_LENGTH in netlink messages. For each rtattr we add to the netlink message, we were adding RTA_LENGTH(rtattr->rta_len) to the length of the netlink message. But rtattr->rta_len was already calculated as RTA_LENGTH of something, and doing RTA_LENGTH twice made the length 4 bytes longer than it should be. This caused a log in dmesg: netlink: 4 bytes leftover after parsing attributes. or netlink: 8 bytes leftover after parsing attributes. if there was an IPv6 scope ID (because that causes two rtattrs instead of one). The new code is consistent with the rtnetlink(3) man page, which does rta->rta_len = sizeof(unsigned int); req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + RTA_LENGTH(sizeof(unsigned int)); We do the equivalent rta->rta_len = sizeof(unsigned int); req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + rta->rta_len; --- libnetutil/netutil.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libnetutil/netutil.cc b/libnetutil/netutil.cc index 5128736ba..9725ff6df 100644 --- a/libnetutil/netutil.cc +++ b/libnetutil/netutil.cc @@ -2965,7 +2965,7 @@ static int route_dst_netlink(const struct sockaddr_storage *dst, rtattr->rta_len = RTA_LENGTH(addrlen); assert(RTA_OK(rtattr, len)); memcpy(RTA_DATA(rtattr), addr, addrlen); - nlmsg->nlmsg_len = NLMSG_ALIGN(nlmsg->nlmsg_len) + RTA_LENGTH(rtattr->rta_len); + nlmsg->nlmsg_len = NLMSG_ALIGN(nlmsg->nlmsg_len) + rtattr->rta_len; /* Specific interface (sin6_scope_id) requested? */ if (ifindex > 0) { @@ -2975,7 +2975,7 @@ static int route_dst_netlink(const struct sockaddr_storage *dst, rtattr->rta_len = RTA_LENGTH(sizeof(uint32_t)); assert(RTA_OK(rtattr, len)); *(uint32_t *) RTA_DATA(rtattr) = ifindex; - nlmsg->nlmsg_len = NLMSG_ALIGN(nlmsg->nlmsg_len) + RTA_LENGTH(rtattr->rta_len); + nlmsg->nlmsg_len = NLMSG_ALIGN(nlmsg->nlmsg_len) + rtattr->rta_len; } iov.iov_base = nlmsg;