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/iprule.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/ip/iprule.c b/ip/iprule.c index 96695d8..2da18f6 100644 --- a/ip/iprule.c +++ b/ip/iprule.c @@ -76,8 +76,6 @@ static struct static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) { struct rtmsg *r = NLMSG_DATA(n); - inet_prefix src = { .family = r->rtm_family }; - inet_prefix dst = { .family = r->rtm_family }; __u32 table; if (preferred_family != AF_UNSPEC && r->rtm_family != preferred_family) @@ -90,25 +88,35 @@ static bool filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len) return false; if (filter.src.family) { - if (tb[FRA_SRC]) { - memcpy(&src.data, RTA_DATA(tb[FRA_SRC]), - (r->rtm_src_len + 7) / 8); - } - if (filter.src.family != r->rtm_family || - filter.src.bitlen > r->rtm_src_len || - inet_addr_match(&src, &filter.src, filter.src.bitlen)) + struct rtattr *rta = tb[FRA_SRC]; + inet_prefix src, *f_src = &filter.src; + + if (f_src->family != r->rtm_family || + f_src->bitlen > r->rtm_src_len) return false; + + if (rta) { + if (get_addr_rta(&src, rta, f_src->family)) + return false; + if (inet_addr_match(&src, f_src, f_src->bitlen)) + return false; + } } if (filter.dst.family) { - if (tb[FRA_DST]) { - memcpy(&dst.data, RTA_DATA(tb[FRA_DST]), - (r->rtm_dst_len + 7) / 8); - } - if (filter.dst.family != r->rtm_family || - filter.dst.bitlen > r->rtm_dst_len || - inet_addr_match(&dst, &filter.dst, filter.dst.bitlen)) + struct rtattr *rta = tb[FRA_DST]; + inet_prefix dst, *f_dst = &filter.dst; + + if (f_dst->family != r->rtm_family || + f_dst->bitlen > r->rtm_dst_len) return false; + + if (rta) { + if (get_addr_rta(&dst, rta, f_dst->family)) + return false; + if (inet_addr_match(&dst, f_dst, f_dst->bitlen)) + return false; + } } if (filter.tosmask && filter.tos ^ r->rtm_tos) -- 1.7.10.4