Hi,

<rant>
so route(8) drives me crazy. For some reason I always put -prefixlen
before the address when adding IPv6 routes and route(8) happily
accepts that:

$ sudo route add -inet6 -prefixlen 32 2001:db8:: ::1 -blackhole                 
 
add net 2001:db8::: gateway ::1
$ route -n show -inet6 | fgrep 2001:db8
2001:db8::/64      ::1                UGBS       0        0     -     8 lo0

Where is my /32 blackhole route?!

Even this is valid syntax:

$ sudo route add -inet -prefixlen 24 10.10.10.0/23 -prefixlen 22 \
  127.0.0.1 -blackhole
add net 10.10.10.0/23: gateway 127.0.0.1
$ route -n show -inet | fgrep 10.10
10.10.8/22         127.0.0.1          UGBS       0        0 33196     8 lo0

Here it tells me it added a /23 route when in fact it added a /22
route. argharghargh!

One can argue that this is (subtly) documented in the man page.

Looking at the option / argument parser in
int
newroute(int argc, char **argv)
I decided that I'm not capable of fixing this and went for the low
hanging fruit.
</rant>

With the following patch this is valid syntax:
$ sudo route add -inet6 2001:db8::/32 ::1 -blackhole
add net 2001:db8::/32: gateway ::1
$ route -n get -inet6 2001:db8::/32
   route to: 2001:db8::
destination: 2001:db8::
       mask: ffff:ffff::
    gateway: ::1
  interface: lo0
 if address: ::1
   priority: 8 (static)
      flags: <UP,GATEWAY,DONE,STATIC,BLACKHOLE>
     use       mtu    expire
       0         0         0 
$ sudo route delete -inet6 2001:db8::/32
delete net 2001:db8::/32

I kept the inet6_makenetandmask() call but in my understanding of the
code it's not necessary in the else block. Is it correct to remove
that call?
+                               else {
+                                       inet6_makenetandmask(&su->sin6);
+                                       return prefixlen(sep);                  
 
+                               }

Btw. the strlcpy / strchr dance is from inet_net_pton which I'm not
calling because it can't handle scoped addresses according to inet(3).

Thanks,
Florian

Index: sbin/route/route.8
===================================================================
RCS file: /opt/OpenBSD-CVS/src/sbin/route/route.8,v
retrieving revision 1.69
diff -u -r1.69 route.8
--- sbin/route/route.8  3 Sep 2011 22:59:08 -0000       1.69
+++ sbin/route/route.8  27 Jun 2012 22:19:50 -0000
@@ -240,6 +240,13 @@
 is the number of bits in the network portion of the address
 and is less than 32)
 .It
+it is an IPv6 address with a
+.Dq / Ns Em XX
+suffix (where
+.Em XX
+is the number of bits in the network portion of the address
+and is less than 128)
+.It
 it is the symbolic name of a network.
 .El
 .Pp
Index: sbin/route/route.c
===================================================================
RCS file: /opt/OpenBSD-CVS/src/sbin/route/route.c,v
retrieving revision 1.156
diff -u -r1.156 route.c
--- sbin/route/route.c  17 Mar 2012 10:16:40 -0000      1.156
+++ sbin/route/route.c  27 Jun 2012 22:10:52 -0000
@@ -824,14 +824,25 @@
        case AF_INET6:
            {
                struct addrinfo hints, *res;
+               char            buf[
+                  sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255:255:255:255/128")
+               ];
+               char           *sep;
 
+               if (strlcpy(buf, s, sizeof buf) >= sizeof buf) {
+                       errx(1, "%s: bad value", s);
+               }
+
+               sep = strchr(buf, '/');
+               if (sep != NULL)
+                       *sep++ = '\0';
                memset(&hints, 0, sizeof(hints));
                hints.ai_family = afamily;      /*AF_INET6*/
                hints.ai_flags = AI_NUMERICHOST;
                hints.ai_socktype = SOCK_DGRAM;         /*dummy*/
-               if (getaddrinfo(s, "0", &hints, &res) != 0) {
+               if (getaddrinfo(buf, "0", &hints, &res) != 0) {
                        hints.ai_flags = 0;
-                       if (getaddrinfo(s, "0", &hints, &res) != 0)
+                       if (getaddrinfo(buf, "0", &hints, &res) != 0)
                                errx(1, "%s: bad value", s);
                }
                if (sizeof(su->sin6) != res->ai_addrlen)
@@ -850,7 +861,12 @@
                }
                if (hints.ai_flags == AI_NUMERICHOST) {
                        if (which == RTA_DST)
-                               return (inet6_makenetandmask(&su->sin6));
+                               if (sep == NULL)
+                                       return 
(inet6_makenetandmask(&su->sin6));
+                               else {
+                                       inet6_makenetandmask(&su->sin6);
+                                       return prefixlen(sep);
+                               }
                        return (0);
                } else
                        return (1);

Reply via email to