[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1513508940-29430-1-git-send-email-green@msu.ru>
Date: Sun, 17 Dec 2017 12:09:00 +0100
From: Alexander Zubkov <green@....ru>
To: stephen@...workplumber.org
Cc: zubkov318@...il.com, netdev@...r.kernel.org,
Alexander Zubkov <green@....ru>
Subject: [PATCH] iproute: "list/flush/save default" selected all of the routes
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@....ru>
---
ip/iproute.c | 65 ++++++++++++++++++++++++++++++++++++++++++------------------
lib/utils.c | 1 +
2 files changed, 47 insertions(+), 19 deletions(-)
diff --git a/ip/iproute.c b/ip/iproute.c
index 16eadab..5e96783 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -190,20 +190,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;
@@ -220,7 +242,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);
}
@@ -240,15 +264,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;
diff --git a/lib/utils.c b/lib/utils.c
index 7ced8c0..3d26375 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -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;
}
--
1.9.1
Powered by blists - more mailing lists