diff --git a/src/net/linux/addrs.c b/src/net/linux/addrs.c index 96c01b1a7..1caf4c6ef 100644 --- a/src/net/linux/addrs.c +++ b/src/net/linux/addrs.c @@ -33,7 +33,7 @@ static void parse_rtattr(struct rtattr *tb[], struct rtattr *rta, int len) } -static bool is_deprecated(uint32_t flags) +static bool is_ipv6_deprecated(uint32_t flags) { if (flags & (IFA_F_TENTATIVE | IFA_F_OPTIMISTIC | IFA_F_DADFAILED | IFA_F_DEPRECATED)) @@ -42,9 +42,8 @@ static bool is_deprecated(uint32_t flags) return false; } - -static int parse_msg(struct nlmsghdr *msg, size_t len, net_ifaddr_h *ifh, - void *arg) +static bool parse_msg(struct nlmsghdr *msg, int len, net_ifaddr_h *ifh, + void *arg) { struct nlmsghdr *nlh; for (nlh = msg; NLMSG_OK(nlh, len); nlh = NLMSG_NEXT(nlh, len)) { @@ -53,24 +52,25 @@ static int parse_msg(struct nlmsghdr *msg, size_t len, net_ifaddr_h *ifh, char if_name[IF_NAMESIZE]; if (nlh->nlmsg_type == NLMSG_DONE) { - return 0; + return true; } if (nlh->nlmsg_type == NLMSG_ERROR) { DEBUG_WARNING("netlink recv error\n"); - return EBADMSG; + return false; } struct ifaddrmsg *ifa = NLMSG_DATA(nlh); struct rtattr *rta_tb[IFA_MAX + 1]; + parse_rtattr(rta_tb, IFA_RTA(ifa), nlh->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa))); if (!rta_tb[IFA_ADDRESS]) continue; - if (rta_tb[IFA_FLAGS]) { + if (rta_tb[IFA_FLAGS] && ifa->ifa_family == AF_INET6) { flags = *(uint32_t *)RTA_DATA(rta_tb[IFA_FLAGS]); - if (is_deprecated(flags)) + if (is_ipv6_deprecated(flags)) continue; } @@ -90,10 +90,10 @@ static int parse_msg(struct nlmsghdr *msg, size_t len, net_ifaddr_h *ifh, continue; if (ifh(if_name, &sa, arg)) - break; + return true; } - return EAGAIN; + return false; } @@ -102,11 +102,12 @@ int net_netlink_addrs(net_ifaddr_h *ifh, void *arg) int err = 0; char buffer[8192]; re_sock_t sock; + int len; + struct { struct nlmsghdr nlh; struct ifaddrmsg ifa; } req; - size_t len; if (!ifh) return EINVAL; @@ -117,6 +118,9 @@ int net_netlink_addrs(net_ifaddr_h *ifh, void *arg) return err; } + struct timeval timeout = {5, 0}; + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + memset(&req, 0, sizeof(req)); req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); req.nlh.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP; @@ -128,10 +132,9 @@ int net_netlink_addrs(net_ifaddr_h *ifh, void *arg) goto out; } - while ((len = recv(sock, buffer, sizeof(buffer), 0)) > 0) { - err = parse_msg((struct nlmsghdr *)buffer, len, ifh, arg); - if (!err) - goto out; + while ((len = (int)recv(sock, buffer, sizeof(buffer), 0)) > 0) { + if (parse_msg((struct nlmsghdr *)buffer, len, ifh, arg)) + break; } out: