[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openbsd-tech
Subject:    Re: route(8): /prefixlen syntax for -inet6
From:       Florian Obser <florian () narrans ! de>
Date:       2012-06-28 21:41:39
Message-ID: 20120628214138.GA5567 () michelangelo ! narrans ! de
[Download RAW message or body]

On Thu, Jun 28, 2012 at 09:55:57AM +0100, Stuart Henderson wrote:
[...]
> # route add -inet6 ff55::1/96 ::1
> add net ff55::1/96: gateway ::1
> 
> # route delete -inet6 ff55::1/96
> route: writing to routing socket: No such process
> delete net ff55::1/96: not in table
> 
> # route delete -inet6 ff55::/96
> delete net ff55::/96
> 
> I think the address should be masked in the same way for both v4 and v6.
> 

$ sudo ./route add -inet6 ff55::1/96 ::1                                        
add net ff55::1/96: gateway ::1
$ sudo ./route delete -inet6 ff55::1/96
delete net ff55::1/96

However, this remains broken (it's broken for v4 as well):

$ sudo ./route add -inet6 ff55::1 -prefixlen 96 ::1
add net ff55::1: gateway ::1
$ sudo ./route delete -inet6 ff55::1 -prefixlen 96  
route: writing to routing socket: No such process
delete net ff55::1: not in table

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	28 Jun 2012 21:36:58 -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	28 Jun 2012 21:36:58 -0000
@@ -93,7 +93,7 @@
 void	 pmsg_addrs(char *, int);
 void	 bprintf(FILE *, int, char *);
 void	 mask_addr(union sockunion *, union sockunion *, int);
-int	 inet6_makenetandmask(struct sockaddr_in6 *);
+int	 inet6_makenetandmask(struct sockaddr_in6 *, char *);
 int	 getaddr(int, char *, struct hostent **);
 void	 getmplslabel(char *, int);
 int	 rtmsg(int, int, int, u_char);
@@ -737,19 +737,23 @@
  * XXX the function may need more improvement...
  */
 int
-inet6_makenetandmask(struct sockaddr_in6 *sin6)
+inet6_makenetandmask(struct sockaddr_in6 *sin6, char *plen)
 {
-	char *plen = NULL;
 	struct in6_addr in6;
+	const char *errstr;
+	int i, len, q, r;
 
-	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";
+	if (NULL==plen) {
+		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";
+		}
 	}
 
 	if (!plen || strcmp(plen, "128") == 0)
@@ -757,6 +761,20 @@
 	else {
 		rtm_addrs |= RTA_NETMASK;
 		prefixlen(plen);
+
+		len = strtonum(plen, 0, 128, &errstr);
+		if (errstr)
+			errx(1, "prefixlen %s is %s", s, errstr);
+
+		q = (128-len) >> 3;
+		r = (128-len) & 7;
+		i = 15;
+
+		while (q-- > 0)
+			sin6->sin6_addr.s6_addr[i--] = 0;
+		if (r > 0)
+			sin6->sin6_addr.s6_addr[i] &= 0xff << r;
+
 		return (0);
 	}
 }
@@ -824,14 +842,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 +879,7 @@
 		}
 		if (hints.ai_flags == AI_NUMERICHOST) {
 			if (which == RTA_DST)
-				return (inet6_makenetandmask(&su->sin6));
+				return (inet6_makenetandmask(&su->sin6, sep));
 			return (0);
 		} else
 			return (1);

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic