Confusing IPv6 route(8) results

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Confusing IPv6 route(8) results

David Higgs
I am using route(8) in a script but found some odd behavior when
querying routes for some IPv6 addresses - lookups seem to fail if the
trailing address bytes are zero (implicit or explicitly) as shown
below.  However, the routing table still seems to be forwarding
traffic correctly, as shown in my final example.

Can anyone shed light on this, perhaps explain how I'm misusing route(8)?

This is on amd64 running 6.3-stable.

Thanks.

--david


$ route -n get 2607:f8b0:4004:805::2004
   route to: 2607:f8b0:4004:805::2004
destination: ::
       mask: ::
    gateway: fe80:1::201:5cff:fe86:7046%em0
  interface: em0
 if address: fe80::5e8c:75d:e349:26fd%em0
   priority: 56 (default)
      flags: <UP,GATEWAY,DONE,STATIC>
      label: slaacd
     use       mtu    expire
  220369         0         0
sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA,LABEL>

$ route -n get 2607:f8b0:4004:805::
get net 2607:f8b0:4004:805::: not in table

$ route -n get 2600:1901:0:94b6::
get net 2600:1901:0:94b6::: not in table

$ ping6 2600:1901:0:94b6::
PING 2600:1901:0:94b6:: (2600:1901:0:94b6::): 56 data bytes
64 bytes from 2600:1901:0:94b6::: icmp_seq=0 hlim=54 time=10.302 ms
64 bytes from 2600:1901:0:94b6::: icmp_seq=1 hlim=54 time=11.270 ms

Reply | Threaded
Open this post in threaded view
|

Re: Confusing IPv6 route(8) results

Denis Fondras-3
Hi,

On Wed, May 23, 2018 at 10:34:19PM -0400, David Higgs wrote:
> I am using route(8) in a script but found some odd behavior when
> querying routes for some IPv6 addresses - lookups seem to fail if the
> trailing address bytes are zero (implicit or explicitly) as shown
> below.  However, the routing table still seems to be forwarding
> traffic correctly, as shown in my final example.
>
> Can anyone shed light on this, perhaps explain how I'm misusing route(8)?
>

route is getting confused between host address and network address.
Try with route -n get 2607:f8b0:4004:805::/128


> This is on amd64 running 6.3-stable.
>
> Thanks.
>
> --david
>
>
> $ route -n get 2607:f8b0:4004:805::2004
>    route to: 2607:f8b0:4004:805::2004
> destination: ::
>        mask: ::
>     gateway: fe80:1::201:5cff:fe86:7046%em0
>   interface: em0
>  if address: fe80::5e8c:75d:e349:26fd%em0
>    priority: 56 (default)
>       flags: <UP,GATEWAY,DONE,STATIC>
>       label: slaacd
>      use       mtu    expire
>   220369         0         0
> sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA,LABEL>
>
> $ route -n get 2607:f8b0:4004:805::
> get net 2607:f8b0:4004:805::: not in table
>
> $ route -n get 2600:1901:0:94b6::
> get net 2600:1901:0:94b6::: not in table
>
> $ ping6 2600:1901:0:94b6::
> PING 2600:1901:0:94b6:: (2600:1901:0:94b6::): 56 data bytes
> 64 bytes from 2600:1901:0:94b6::: icmp_seq=0 hlim=54 time=10.302 ms
> 64 bytes from 2600:1901:0:94b6::: icmp_seq=1 hlim=54 time=11.270 ms
>

Reply | Threaded
Open this post in threaded view
|

Re: Confusing IPv6 route(8) results

David Higgs
On Thu, May 24, 2018 at 5:35 AM Denis Fondras <[hidden email]> wrote:

> Hi,
>
> On Wed, May 23, 2018 at 10:34:19PM -0400, David Higgs wrote:
> > I am using route(8) in a script but found some odd behavior when
> > querying routes for some IPv6 addresses - lookups seem to fail if the
> > trailing address bytes are zero (implicit or explicitly) as shown
> > below.  However, the routing table still seems to be forwarding
> > traffic correctly, as shown in my final example.
> >
> > Can anyone shed light on this, perhaps explain how I'm misusing route(8)?
> >
>
> route is getting confused between host address and network address.
> Try with route -n get 2607:f8b0:4004:805::/128


Awesome, that should fix my script.

But shouldn’t the answer be the same, since I have a valid default route?

—david
Reply | Threaded
Open this post in threaded view
|

Re: Confusing IPv6 route(8) results

Denis Fondras-3
On Thu, May 24, 2018 at 07:04:04AM -0400, David Higgs wrote:
> But shouldn’t the answer be the same, since I have a valid default route?
>

It should but that's not how route(8) works for now :)

Barely tested diff, assumes that no netmask means /128 (similar to IPv4 handling
where no netmask means /32)

Index: route.c
===================================================================
RCS file: /cvs/src/sbin/route/route.c,v
retrieving revision 1.214
diff -u -p -r1.214 route.c
--- route.c 1 May 2018 18:14:10 -0000 1.214
+++ route.c 24 May 2018 15:54:37 -0000
@@ -800,13 +800,8 @@ inet6_makenetandmask(struct sockaddr_in6
  if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
     sin6->sin6_scope_id == 0) {
  plen = "0";
- } else if ((sin6->sin6_addr.s6_addr[0] & 0xe0) == 0x20) {
- /* aggregatable global unicast - RFC2374 */
- memset(&in6, 0, sizeof(in6));
- if (!memcmp(&sin6->sin6_addr.s6_addr[8],
-    &in6.s6_addr[8], 8))
- plen = "64";
- }
+ } else
+ plen = "128";
  }
 
  if (!plen || strcmp(plen, "128") == 0)

Reply | Threaded
Open this post in threaded view
|

Re: Confusing IPv6 route(8) results

Sebastian Benoit
Denis Fondras([hidden email]) on 2018.05.24 17:57:19 +0200:
> On Thu, May 24, 2018 at 07:04:04AM -0400, David Higgs wrote:
> > But shouldn???t the answer be the same, since I have a valid default route?
> >
>
> It should but that's not how route(8) works for now :)
>
> Barely tested diff, assumes that no netmask means /128 (similar to IPv4 handling
> where no netmask means /32)

But it doesn't:

[benoit@blap:~]$ doas route add 192.168.5 10.8.0.137
[benoit@blap:~]$ doas route -n get 192.168.5.33
   route to: 192.168.5.33
destination: 192.168.5.0
       mask: 255.255.255.0
    gateway: 10.8.0.137

---> 192.168.5 is interpreted as /24

[benoit@blap:~]$ doas route delete 192.168.5 10.8.0.137
delete net 192.168.5: gateway 10.8.0.137

---> 192.168.5.0/24 is deleted

Indeed, if i do

[benoit@blap:~]$ doas route add 192.168.5.66 10.8.0.137  
add host 192.168.5.66: gateway 10.8.0.137

i get a /32 route

[benoit@blap:~]$ doas route -n get 192.168.5.66        
   route to: 192.168.5.66
destination: 192.168.5.66
       mask: 255.255.255.255
    gateway: 10.8.0.137

but thats equivalent to doing

[benoit@blap:~]$ route add 2607:f8b0:4004:805::2004 ::

Now. for ipv6 the spec says what 2607:f8b0:4004:805::
means, whereas for ipv4 its just historical accident that

192.168.5 is interpreded in some way.

So i think the answer to the OP is: always use a netmask, except when you
specify full host address.

/Benno

> Index: route.c
> ===================================================================
> RCS file: /cvs/src/sbin/route/route.c,v
> retrieving revision 1.214
> diff -u -p -r1.214 route.c
> --- route.c 1 May 2018 18:14:10 -0000 1.214
> +++ route.c 24 May 2018 15:54:37 -0000
> @@ -800,13 +800,8 @@ inet6_makenetandmask(struct sockaddr_in6
>   if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
>      sin6->sin6_scope_id == 0) {
>   plen = "0";
> - } else if ((sin6->sin6_addr.s6_addr[0] & 0xe0) == 0x20) {
> - /* aggregatable global unicast - RFC2374 */
> - memset(&in6, 0, sizeof(in6));
> - if (!memcmp(&sin6->sin6_addr.s6_addr[8],
> -    &in6.s6_addr[8], 8))
> - plen = "64";
> - }
> + } else
> + plen = "128";
>   }
>  
>   if (!plen || strcmp(plen, "128") == 0)
>

--

Reply | Threaded
Open this post in threaded view
|

Re: Confusing IPv6 route(8) results

Denis Fondras-3
On Thu, May 24, 2018 at 08:43:30PM +0200, Sebastian Benoit wrote:

> Denis Fondras([hidden email]) on 2018.05.24 17:57:19 +0200:
> > On Thu, May 24, 2018 at 07:04:04AM -0400, David Higgs wrote:
> > > But shouldn???t the answer be the same, since I have a valid default route?
> > >
> >
> > It should but that's not how route(8) works for now :)
> >
> > Barely tested diff, assumes that no netmask means /128 (similar to IPv4 handling
> > where no netmask means /32)
>
> But it doesn't:
>

Well, my words didn't translate my thought.

$ route -n get 192.168.5.33
is equivalent to
$ route -n get 192.168.5.33/32

So :
$ route -n get 2001:db8::
should be equivalent to
$ route -n get 2001:db8::/128

By what rule should it stick to /64 ?

Though I agree we should always specify the mask length.

Reply | Threaded
Open this post in threaded view
|

Re: Confusing IPv6 route(8) results

Sebastian Benoit
Denis Fondras([hidden email]) on 2018.05.24 22:09:30 +0200:

> On Thu, May 24, 2018 at 08:43:30PM +0200, Sebastian Benoit wrote:
> > Denis Fondras([hidden email]) on 2018.05.24 17:57:19 +0200:
> > > On Thu, May 24, 2018 at 07:04:04AM -0400, David Higgs wrote:
> > > > But shouldn???t the answer be the same, since I have a valid default route?
> > > >
> > >
> > > It should but that's not how route(8) works for now :)
> > >
> > > Barely tested diff, assumes that no netmask means /128 (similar to IPv4 handling
> > > where no netmask means /32)
> >
> > But it doesn't:
> >
>
> Well, my words didn't translate my thought.
>
> $ route -n get 192.168.5.33
> is equivalent to
> $ route -n get 192.168.5.33/32
>
> So :
> $ route -n get 2001:db8::
> should be equivalent to
> $ route -n get 2001:db8::/128

yes
 
> By what rule should it stick to /64 ?

<joking>by the same unwritten rule that says 192.168.5 is a /24</joking>

Existing hostname.if files and scripts might depend on it.

Actually since the prefixlen argument only sets the correct prefixlen if it
follows the ip, i know for sure that there are configurations out the where

  route add -inet6 -prefixlen 56 2a00:16a8:b:100:: ::1 -blackhole

will configure a /64 route (because the mask set by prefixlenis overwritten
(actually by the code you are changing there ;)). I once had the pleasure to
fix quite a few of those, that went unnoticed (because who cares about
-blackhole routes) until one bad day...

With your diff that will be a /128 suddenly?

I'm not totaly against it, but it at least requires a note in current.html.

Maybe you should post your diff on tech@ for more review.

> Though I agree we should always specify the mask length.

the 1980s just called, they want their route(8) code back.