]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
iproute: "list/flush/save default" selected all of the routes
authorAlexander Zubkov <green@msu.ru>
Sun, 17 Dec 2017 11:09:00 +0000 (12:09 +0100)
committerStephen Hemminger <stephen@networkplumber.org>
Tue, 19 Dec 2017 16:23:09 +0000 (08:23 -0800)
When running "ip route list default" and not specifying address family,
one will get all of the routes instead of just default only. The same
is for "exact default" and "match default".

It behaves in such a way because default route with unspecified family
has the same all-zeroes value like no prefix specified at all. Thus
following code blindly ignores the fact, that prefix was actually
specified.

This patch adds the flag PREFIXLEN_SPECIFIED to the default route too.
And then checks its value when filtering routes.

Signed-off-by: Alexander Zubkov <green@msu.ru>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
ip/iproute.c
lib/utils.c

index 32c93ed5abd9c1878fc9cde0ea23124682fedf7e..bf886fda9d761cbb86fe740aadf0d08106854dd5 100644 (file)
@@ -191,20 +191,42 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
                return 0;
        if ((filter.tos^r->rtm_tos)&filter.tosmask)
                return 0;
-       if (filter.rdst.family &&
-           (r->rtm_family != filter.rdst.family || filter.rdst.bitlen > r->rtm_dst_len))
-               return 0;
-       if (filter.mdst.family &&
-           (r->rtm_family != filter.mdst.family ||
-            (filter.mdst.bitlen >= 0 && filter.mdst.bitlen < r->rtm_dst_len)))
-               return 0;
-       if (filter.rsrc.family &&
-           (r->rtm_family != filter.rsrc.family || filter.rsrc.bitlen > r->rtm_src_len))
-               return 0;
-       if (filter.msrc.family &&
-           (r->rtm_family != filter.msrc.family ||
-            (filter.msrc.bitlen >= 0 && filter.msrc.bitlen < r->rtm_src_len)))
-               return 0;
+       if (filter.rdst.family) {
+               if (r->rtm_family != filter.rdst.family ||
+                   filter.rdst.bitlen > r->rtm_dst_len)
+                       return 0;
+       } else if (filter.rdst.flags & PREFIXLEN_SPECIFIED) {
+               if (filter.rdst.bitlen > r->rtm_dst_len)
+                       return 0;
+       }
+       if (filter.mdst.family) {
+               if (r->rtm_family != filter.mdst.family ||
+                   (filter.mdst.bitlen >= 0 &&
+                    filter.mdst.bitlen < r->rtm_dst_len))
+                       return 0;
+       } else if (filter.mdst.flags & PREFIXLEN_SPECIFIED) {
+               if (filter.mdst.bitlen >= 0 &&
+                   filter.mdst.bitlen < r->rtm_dst_len)
+                       return 0;
+       }
+       if (filter.rsrc.family) {
+               if (r->rtm_family != filter.rsrc.family ||
+                   filter.rsrc.bitlen > r->rtm_src_len)
+                       return 0;
+       } else if (filter.rsrc.flags & PREFIXLEN_SPECIFIED) {
+               if (filter.rsrc.bitlen > r->rtm_src_len)
+                       return 0;
+       }
+       if (filter.msrc.family) {
+               if (r->rtm_family != filter.msrc.family ||
+                   (filter.msrc.bitlen >= 0 &&
+                    filter.msrc.bitlen < r->rtm_src_len))
+                       return 0;
+       } else if (filter.msrc.flags & PREFIXLEN_SPECIFIED) {
+               if (filter.msrc.bitlen >= 0 &&
+                   filter.msrc.bitlen < r->rtm_src_len)
+                       return 0;
+       }
        if (filter.rvia.family) {
                int family = r->rtm_family;
 
@@ -221,7 +243,9 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
 
        if (tb[RTA_DST])
                memcpy(&dst.data, RTA_DATA(tb[RTA_DST]), (r->rtm_dst_len+7)/8);
-       if (filter.rsrc.family || filter.msrc.family) {
+       if (filter.rsrc.family || filter.msrc.family ||
+           filter.rsrc.flags & PREFIXLEN_SPECIFIED ||
+           filter.msrc.flags & PREFIXLEN_SPECIFIED) {
                if (tb[RTA_SRC])
                        memcpy(&src.data, RTA_DATA(tb[RTA_SRC]), (r->rtm_src_len+7)/8);
        }
@@ -241,15 +265,18 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
                        memcpy(&prefsrc.data, RTA_DATA(tb[RTA_PREFSRC]), host_len/8);
        }
 
-       if (filter.rdst.family && inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen))
+       if ((filter.rdst.family || filter.rdst.flags & PREFIXLEN_SPECIFIED) &&
+           inet_addr_match(&dst, &filter.rdst, filter.rdst.bitlen))
                return 0;
-       if (filter.mdst.family && filter.mdst.bitlen >= 0 &&
+       if ((filter.mdst.family || filter.mdst.flags & PREFIXLEN_SPECIFIED) &&
            inet_addr_match(&dst, &filter.mdst, r->rtm_dst_len))
                return 0;
 
-       if (filter.rsrc.family && inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen))
+       if ((filter.rsrc.family || filter.rsrc.flags & PREFIXLEN_SPECIFIED) &&
+           inet_addr_match(&src, &filter.rsrc, filter.rsrc.bitlen))
                return 0;
-       if (filter.msrc.family && filter.msrc.bitlen >= 0 &&
+       if ((filter.msrc.family || filter.msrc.flags & PREFIXLEN_SPECIFIED) &&
+           filter.msrc.bitlen >= 0 &&
            inet_addr_match(&src, &filter.msrc, r->rtm_src_len))
                return 0;
 
index df1f3b1238c029a073534c43690b72b53d9e95d2..9fa522047fdcabbf3166b16bf4053534c228deb4 100644 (file)
@@ -658,6 +658,7 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family)
                dst->family = family;
                dst->bytelen = 0;
                dst->bitlen = 0;
+               dst->flags |= PREFIXLEN_SPECIFIED;
                return 0;
        }