diff mbox series

[iproute2] treat "default" and "all"/"any" addresses differenty

Message ID 1521391825-28636-1-git-send-email-green@msu.ru
State Accepted, archived
Delegated to: stephen hemminger
Headers show
Series [iproute2] treat "default" and "all"/"any" addresses differenty | expand

Commit Message

Alexander Zubkov March 18, 2018, 4:50 p.m. UTC
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 <bluca@debian.org>
Signed-off-by: Alexander Zubkov <green@msu.ru>
---
 lib/utils.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

Comments

Alexander Zubkov March 18, 2018, 5:02 p.m. UTC | #1
This version of patch is for master now.

18.03.2018, 17:50, "Alexander Zubkov" <green@msu.ru>:
> 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 <bluca@debian.org>
> Signed-off-by: Alexander Zubkov <green@msu.ru>
> ---
>  lib/utils.c | 20 ++++++++++++++------
>  1 file changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/lib/utils.c b/lib/utils.c
> index 379739d..eba4fa7 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;
>          }
>
> @@ -695,7 +704,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;
>
> @@ -706,12 +715,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;
> --
> 1.9.1
diff mbox series

Patch

diff --git a/lib/utils.c b/lib/utils.c
index 379739d..eba4fa7 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;
 	}
 
@@ -695,7 +704,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;
 
@@ -706,12 +715,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;