Setting ->family in @inet_prefix seems pointless: inet_addr_match() does not consider it's value: better is to force get_addr_rta() to use address family from filter to ensure we get correct one.
Signed-off-by: Serhey Popovych <serhe.popov...@gmail.com> --- ip/ipaddress.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/ip/ipaddress.c b/ip/ipaddress.c index ba60125..38d994e 100644 --- a/ip/ipaddress.c +++ b/ip/ipaddress.c @@ -1523,19 +1523,20 @@ int print_addrinfo(const struct sockaddr_nl *who, struct nlmsghdr *n, if (fnmatch(filter.label, label, 0) != 0) return 0; } - if (filter.pfx.family) { - if (rta_tb[IFA_LOCAL]) { - inet_prefix dst = { .family = ifa->ifa_family }; - - memcpy(&dst.data, RTA_DATA(rta_tb[IFA_LOCAL]), RTA_PAYLOAD(rta_tb[IFA_LOCAL])); - if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) - return 0; - } - } if (filter.family && filter.family != ifa->ifa_family) return 0; + if (filter.pfx.family && rta_tb[IFA_LOCAL]) { + struct rtattr *rta = rta_tb[IFA_LOCAL]; + inet_prefix dst, *f_pfx = &filter.pfx; + + if (get_addr_rta(&dst, rta, f_pfx->family)) + return 0; + if (inet_addr_match(&dst, f_pfx, f_pfx->bitlen)) + return 0; + } + if (filter.flushb) { struct nlmsghdr *fn; @@ -1893,12 +1894,12 @@ static void ipaddr_filter(struct nlmsg_chain *linfo, struct nlmsg_chain *ainfo) tb[IFA_LOCAL] = tb[IFA_ADDRESS]; if (filter.pfx.family && tb[IFA_LOCAL]) { - inet_prefix dst = { - .family = ifa->ifa_family - }; + struct rtattr *rta = tb[IFA_LOCAL]; + inet_prefix dst, *f_pfx = &filter.pfx; - memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL])); - if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen)) + if (get_addr_rta(&dst, rta, f_pfx->family)) + continue; + if (inet_addr_match(&dst, f_pfx, f_pfx->bitlen)) continue; } if (filter.label) { -- 1.7.10.4