diff options
Diffstat (limited to 'libnetutils')
-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 85ff070a7..eae32ce36 100644 --- a/libnetutils/ifc_utils.c +++ b/libnetutils/ifc_utils.c | |||
@@ -267,10 +267,12 @@ int ifc_act_on_address(int action, const char *name, const char *address, | |||
267 | struct { | 267 | struct { |
268 | struct nlmsghdr n; | 268 | struct nlmsghdr n; |
269 | struct ifaddrmsg r; | 269 | struct ifaddrmsg r; |
270 | // Allow for IPv6 address, headers, and padding. | 270 | // Allow for IPv6 address, headers, IPv4 broadcast addr and padding. |
271 | char attrbuf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + | 271 | char attrbuf[NLMSG_ALIGN(sizeof(struct nlmsghdr)) + |
272 | NLMSG_ALIGN(sizeof(struct rtattr)) + | 272 | NLMSG_ALIGN(sizeof(struct rtattr)) + |
273 | NLMSG_ALIGN(INET6_ADDRLEN)]; | 273 | NLMSG_ALIGN(INET6_ADDRLEN) + |
274 | NLMSG_ALIGN(sizeof(struct rtattr)) + | ||
275 | NLMSG_ALIGN(INET_ADDRLEN)]; | ||
274 | } req; | 276 | } req; |
275 | struct rtattr *rta; | 277 | struct rtattr *rta; |
276 | struct nlmsghdr *nh; | 278 | struct nlmsghdr *nh; |
@@ -325,6 +327,16 @@ int ifc_act_on_address(int action, const char *name, const char *address, | |||
325 | req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + RTA_LENGTH(addrlen); | 327 | req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + RTA_LENGTH(addrlen); |
326 | memcpy(RTA_DATA(rta), addr, addrlen); | 328 | memcpy(RTA_DATA(rta), addr, addrlen); |
327 | 329 | ||
330 | // Add an explicit IFA_BROADCAST for IPv4 RTM_NEWADDRs. | ||
331 | if (ss.ss_family == AF_INET && action == RTM_NEWADDR) { | ||
332 | rta = (struct rtattr *) (((char *) &req) + NLMSG_ALIGN(req.n.nlmsg_len)); | ||
333 | rta->rta_type = IFA_BROADCAST; | ||
334 | rta->rta_len = RTA_LENGTH(addrlen); | ||
335 | req.n.nlmsg_len = NLMSG_ALIGN(req.n.nlmsg_len) + RTA_LENGTH(addrlen); | ||
336 | ((struct in_addr *)addr)->s_addr |= htonl((1<<(32-prefixlen))-1); | ||
337 | memcpy(RTA_DATA(rta), addr, addrlen); | ||
338 | } | ||
339 | |||
328 | s = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); | 340 | s = socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE); |
329 | if (s < 0) { | 341 | if (s < 0) { |
330 | return -errno; | 342 | return -errno; |