From 7696f1097f79be2ce5984a8a16103fd17391cac2 Mon Sep 17 00:00:00 2001 From: Alexander Zubkov Date: Sun, 18 Mar 2018 17:50:25 +0100 Subject: [PATCH] treat "default" and "all"/"any" addresses differenty Debian maintainer found that basic command: # ip route flush all No longer worked as expected which breaks user scripts and expectations. It no longer flushed all IPv4 routes. Recently behavior of "default" prefix parameter was corrected. But at the same time behavior of "all"/"any" was altered too, because they were the same branch of the code. As those parameters mean different, they need to be treated differently in code too. This patch reflects the difference. Also after mentioned change, address parsing code was changed more and address family was set explicitly even for "all"/"any" addresses. And that broke matching conditions further. This patch fixes that too and returns AF_UNSPEC to "all"/"any" address. Now "default" is treated as top-level prefix (for example 0.0.0.0/0 in IPv4) and "all"/"any" always matches anything in exact, root and match modes. Reported-by: Luca Boccassi Signed-off-by: Alexander Zubkov --- lib/utils.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/lib/utils.c b/lib/utils.c index 87b609f2..4fe4ac1e 100644 --- a/lib/utils.c +++ b/lib/utils.c @@ -560,14 +560,23 @@ static int __get_addr_1(inet_prefix *addr, const char *name, int family) { memset(addr, 0, sizeof(*addr)); - if (strcmp(name, "default") == 0 || - strcmp(name, "all") == 0 || - strcmp(name, "any") == 0) { + if (strcmp(name, "default") == 0) { if ((family == AF_DECnet) || (family == AF_MPLS)) return -1; addr->family = (family != AF_UNSPEC) ? family : AF_INET; addr->bytelen = af_byte_len(addr->family); addr->bitlen = -2; + addr->flags |= PREFIXLEN_SPECIFIED; + return 0; + } + + if (strcmp(name, "all") == 0 || + strcmp(name, "any") == 0) { + if ((family == AF_DECnet) || (family == AF_MPLS)) + return -1; + addr->family = AF_UNSPEC; + addr->bytelen = 0; + addr->bitlen = -2; return 0; } @@ -708,7 +717,7 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family) bitlen = af_bit_len(dst->family); - flags = PREFIXLEN_SPECIFIED; + flags = 0; if (slash) { unsigned int plen; @@ -719,12 +728,11 @@ int get_prefix_1(inet_prefix *dst, char *arg, int family) if (plen > bitlen) return -1; + flags |= PREFIXLEN_SPECIFIED; bitlen = plen; } else { if (dst->bitlen == -2) bitlen = 0; - else - flags = 0; } dst->flags |= flags;