diff options
author | Erik Kline <ek@google.com> | 2016-03-30 18:57:13 +0900 |
---|---|---|
committer | Erik Kline <ek@google.com> | 2016-03-30 20:06:36 +0900 |
commit | 06cb8e92034274c6f803e97a17cd07fedf99bde5 (patch) | |
tree | 810a53d217cb4e246a833fa5ba71bfb53c1a5880 /libnetutils/ifc_utils.c | |
parent | b3cf2e0f3d3b9ba328921cd1c9c3839ea70a1ab1 (diff) | |
download | core-06cb8e92034274c6f803e97a17cd07fedf99bde5.tar.gz core-06cb8e92034274c6f803e97a17cd07fedf99bde5.tar.bz2 core-06cb8e92034274c6f803e97a17cd07fedf99bde5.zip |
Set IFA_BROADCAST during IPv4 RTM_NEWADDRs
Bug: 27194345
Bug: 27732412
Bug: 27786864
Change-Id: I5a5b41422bbaab4582c268c213b788f61cb0e169
Diffstat (limited to 'libnetutils/ifc_utils.c')
-rw-r--r-- | libnetutils/ifc_utils.c | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c index e0a9f7f88..f9f62f8ce 100644 --- a/libnetutils/ifc_utils.c +++ b/libnetutils/ifc_utils.c @@ -259,10 +259,12 @@ int ifc_act_on_address(int action, const char *name, const char *address, struct { struct nlmsghdr n; struct ifaddrmsg r; - // Allow for IPv6 address, headers, and padding. + // Allow for IPv6 address, headers, IPv4 broadcast addr and padding. char attrbuf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + NLMSG_ALIGN(sizeof(struct rtattr)) + - NLMSG_ALIGN(INET6_ADDRLEN)]; + NLMSG_ALIGN(INET6_ADDRLEN) + + NLMSG_ALIGN(sizeof(struct rtattr)) + + NLMSG_ALIGN(INET_ADDRLEN)]; } req; struct rtattr *rta; struct nlmsghdr *nh; @@ -317,6 +319,16 @@ int ifc_act_on_address(int action, const char *name, const char *address, req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + RTA_LENGTH(addrlen); memcpy(RTA_DATA(rta), addr, addrlen); + // Add an explicit IFA_BROADCAST for IPv4 RTM_NEWADDRs. + if (ss.ss_family == AF_INET && action == RTM_NEWADDR) { + rta = (struct rtattr *) (((char *) &req) + NLMSG_ALIGN(req.n.nlmsg_len)); + rta->rta_type = IFA_BROADCAST; + rta->rta_len = RTA_LENGTH(addrlen); + req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + RTA_LENGTH(addrlen); + ((struct in_addr *)addr)->s_addr |= htonl((1<<(32-prefixlen))-1); + memcpy(RTA_DATA(rta), addr, addrlen); + } + s = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); if (s < 0) { return -errno; |