[quagga-dev 1815] Bug in routing table update code

Alexander Gall gall at switch.ch
Tue Nov 9 11:01:53 GMT 2004


I have noticed two bugs that prevent IPv6 routes to be added to the
host's routing table on Solaris 9 (and probably other platforms
without HAVE_SIN_LEN).  The bugs are present in the 0.97.2 release as
well as the latest CVS snapshot (20041106).

The first problem is fairly obvious.  The macro SOCKADDRSET in
rtm_write() does not determine the size of the address correctly in
case HAVE_SIN_LEN is undefined.  Use of SAROUNDUP instead of ROUNDUP
seems appropriate.  BTW, I believe that this is clumsy and one should
use struct sockaddr_storage throughout instead.  I think this has been
brought up on the list before.

The second issue might actually be a bug in Solaris 9.  The zebra
daemon explicitely sets the address family of the netmask to AF_UNSPEC
for both IPv4 and IPv6 in rt_socket.c, but the Solaris kernel refuses
to add an IPv6 route unless the address family of the mask is
AF_INET6.  I'm not familiar with the RT API, so I can't say which
behaviour is correct.  AF_UNSPEC works fine for IPv4.  I would find it
natural that the mask must have the proper family set, though.

The attached patch is against the 20041106 snapshot.

On a side note, I noticed that ospfd and ospf6d behave differently
when shutting down.  When ospfd terminates, the routes are removed
immediately, while when ospf6d terminates, the routes remain installed
until zebra terminates.  I think ospf6d should behave like ospfd.

Cheers,
Alex

--- zebra/kernel_socket.c.orig	2004-07-13 18:45:54.000000000 +0200
+++ zebra/kernel_socket.c	2004-11-09 11:36:36.548468000 +0100
@@ -774,7 +774,7 @@
 #define SOCKADDRSET(X,R) \
   if (msg.rtm.rtm_addrs & (R)) \
     { \
-      int len = ROUNDUP (sizeof((X)->sa)); \
+      int len = SAROUNDUP (X); \
       memcpy (pnt, (caddr_t)(X), len); \
       pnt += len; \
     }
--- zebra/rt_socket.c.orig	2004-03-04 18:45:02.000000000 +0100
+++ zebra/rt_socket.c	2004-11-09 11:53:38.258672000 +0100
@@ -290,7 +290,7 @@
   else
     {
       masklen2ip6 (dest->prefixlen, &sin_mask.sin6_addr);
-      sin_mask.sin6_family = AF_UNSPEC;
+      sin_mask.sin6_family = AF_INET6;
 #ifdef SIN6_LEN
       sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr);
 #endif /* SIN6_LEN */
@@ -400,7 +400,7 @@
       else
 	{
 	  masklen2ip6 (p->prefixlen, &sin_mask.sin6_addr);
-	  sin_mask.sin6_family = AF_UNSPEC;
+	  sin_mask.sin6_family = AF_INET6;
 #ifdef SIN6_LEN
 	  sin_mask.sin6_len = sin6_masklen (sin_mask.sin6_addr);
 #endif /* SIN6_LEN */




More information about the Quagga-dev mailing list