Hello. I have found odd behaviour of ip route list command. It is reproducing at least on: - Ubuntu 14.04.5 with 4.4.0-57-generic kernel and iproute 3.12.0-2ubuntu1 - Gentoo system with 4.12.14 kernel and iproute2 4.11.0 So I suppose it should be so on different versions of kernel and iproute2. The problem is when ip specify "default" as a prefix in ip route list command - it shows all routes: ``` root@grape:~# ip route list default default via 192.168.0.1 dev eth0 default via 192.168.0.1 dev eth0 metric 2 192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.2 192.168.2.0/24 via 192.168.0.1 dev eth0 root@grape:~# ip route list exact default default via 192.168.0.1 dev eth0 default via 192.168.0.1 dev eth0 metric 2 192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.2 192.168.2.0/24 via 192.168.0.1 dev eth0 root@grape:~# ip route list match default default via 192.168.0.1 dev eth0 default via 192.168.0.1 dev eth0 metric 2 192.168.0.0/24 dev eth0 proto kernel scope link src 192.168.0.2 192.168.2.0/24 via 192.168.0.1 dev eth0 ``` It behaves correctly if I use 0/0 as a prefix or provide an ip family option: ``` root@grape:~# ip route list 0/0 default via 192.168.0.1 dev eth0 default via 192.168.0.1 dev eth0 metric 2 root@grape:~# ip -4 route list default default via 192.168.0.1 dev eth0 default via 192.168.0.1 dev eth0 metric 2 ```
iproute2, like the rest of the Linux kernel networking does not really use bugzilla to handle bugs. The commands are subtly different. $ ip route list default Means list all routes in any address family (ie same as any) but $ ip route list 0/0 Means list all routes for IPv4 default route. It probably is worth a man page warning, but changing semantics that have existed for many years is more likely to break some existing user.
> iproute2, like the rest of the Linux kernel networking does not really use > bugzilla to handle bugs. Excuse me for that, where is the best place to bring up this question? May be netdev@vger.kernel.org? > $ ip route list default > Means list all routes in any address family (ie same as any) Sorry, I still do not understand how it implies that it should print default and other routes too. This is not just default can be 0/0 or ::/0 (and this is written in man page).
Yes use netdev@vger.kernel.org $ ip route list default Sets filter as: if (strcmp(arg, "default") == 0 || strcmp(arg, "any") == 0 || strcmp(arg, "all") == 0) { if ((family == AF_DECnet) || (family == AF_MPLS)) return -1; dst->family = family; dst->bytelen = 0; dst->bitlen = 0; return 0; } Where 0/0 is from is ipv4 so dst->bitlen = 32 A 0 bit length prefix matches anything.
And what changes when I specify family: "ip -4 route list default"? And it looks like that bitlen is the mask lentght. So 0 is just normal here. Later that code sets: if (slash) { if (get_netmask(&plen, slash+1, 0) || plen > dst->bitlen) { err = -1; goto done; } dst->flags |= PREFIXLEN_SPECIFIED; dst->bitlen = plen; } So I suppose for 0/0 dst->bitlen should be 0 too. Yes 0/0 should match any ip or cover any prefix. It will be ok if it show all routes for "ip route show root default" command. But "ip route list" by default works in "exact mode": > And exact PREFIX (or just PREFIX) selects routes with this exact prefix. As you can see, even if I specify "exact" selector explicitly or use "match" selector, which should show equal or greater prefixes. It still shows all routes. root 0/0 - will show all prefixes exact or match 0/0 - will show only default (0/0) prefixes But default = root 0/0 exact default = root 0/0 root default = root 0/0 match default = root 0/0
I have added some debug output to print contents of filter.mdst for ip route list. Here is the results: user@grape:~/tmp/iproute2$ ./ip/ip route show default >/dev/null Dump prefix: flags=0, bytelen=0, bitlen=0, family=0 user@grape:~/tmp/iproute2$ ./ip/ip -4 route show default >/dev/null Dump prefix: flags=0, bytelen=0, bitlen=0, family=2 user@grape:~/tmp/iproute2$ ./ip/ip route show 0/0 >/dev/null Dump prefix: flags=1, bytelen=4, bitlen=0, family=2 So the difference is not in bitlen. Looks like family=0 works like match all not taking into the account the actual prefix parameters. But at the same time it outputs only inet4 routes. So it knows that it is working with inet4.
I take the liberty to change status here because patches have been merged actually.