[patch] kernel protocol learn on FreeBSD 7

Eugene Perevyazko john at dnepro.net
Tue Mar 2 20:04:20 CET 2010


On Fri, Feb 26, 2010 at 02:36:00PM +0100, Ondrej Zajicek wrote:
> 
> Hello
> 
> Thank you for the patch. I finally dared to rewrite parts of BSD kernel
> syncing code to make it more featureful and implement proper importing
> of alien routes. I used slightly different approach (checking RTF_PROTO1
> flag instead of PID, because of we want to have a proper cleanup of our
> routes even when BIRD crashed and is restarted.), so i used just a half
> of our patch (RTF_UP/RTF_DONE flag handling).
> 
> Are you using BIRD with PPP access-server on FreeBSD, as you wrote
> in the original e-mail? What flags have the routes added by the PPP
> daemon?
> 

  Yes, I'm using BIRD with OSPF in production on 2 PPPoE access-servers 
and 1 router. It's 1.1.4 with modified patch - I've got lost in bird/kernel
interaction and left it in "somehow it works" state.
Something's definitely wrong with it, because there are lots of errors
like "KIF: error 17 writting cmd 1 route to socket (192.168.67.55/32)"
on every rescan of kernel proto.
Here is this patch, maybe you can make some use of it.
And in release 8 of FreeBSD routing subsystem has been changed a lot,
I don't know if it will work on 8...

diff -U 3 -r sysdep1/bsd/krt-sock.c sysdep/bsd/krt-sock.c
--- sysdep1/bsd/krt-sock.c	2010-03-02 20:42:59.000000000 +0200
+++ sysdep/bsd/krt-sock.c	2009-12-17 12:23:36.000000000 +0200
@@ -10,6 +10,7 @@
 #include <ctype.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include <errno.h>
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -198,7 +199,7 @@
   msg.rtm.rtm_msglen = l;
 
   if ((l = write(rt_sock, (char *)&msg, l)) < 0) {
-          log(L_ERR "KIF: error writting route to socket (%I/%d)", net->n.prefix, net->n.pxlen);
+          log(L_ERR "KIF: error %d writting cmd %d route to socket (%I/%d)", errno, cmd, net->n.prefix, net->n.pxlen);
   }
 }
 
@@ -208,6 +209,7 @@
   if (old)
     {
       DBG("krt_remove_route(%I/%d)\n", net->n.prefix, net->n.pxlen);
+      log(L_WARN "krt_remove_route(%I/%d)\n", net->n.prefix, net->n.pxlen);
       krt_sock_send(RTM_DELETE, old);
     }
   if (new)
@@ -269,11 +271,19 @@
   int src;
   int flags = msg->rtm.rtm_flags;
   int addrs = msg->rtm.rtm_addrs;
+  pid_t sender_pid = msg->rtm.rtm_pid;
+  pid_t my_pid;
   int masklen = -1;
 
-  if (!(flags & RTF_UP))
+  if (msg->rtm.rtm_errno)
   {
-    DBG("Down.\n");
+    DBG("Error message.\n");
+    return;
+  }
+
+  if ( (!(flags & RTF_UP)) && scan )
+  {
+    DBG("Not up in scan.\n");
     return;
   }
 
@@ -340,8 +350,14 @@
       a.iface = ng->iface;
     else
       {
-	log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d", igate, net->n.prefix, net->n.pxlen);
-	return;
+	if (ng)
+	{
+	  log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d (bad scope)", igate, net->n.prefix, net->n.pxlen);
+	  return;
+	} else {
+	  log(L_WARN "Kernel told us to use non-neighbor %I for %I/%d (no such neighbor)", igate, net->n.prefix, net->n.pxlen);
+	  return;
+	}
       }
 
     a.dest = RTD_ROUTER;
@@ -374,7 +390,24 @@
     return;
   }
 
-  src = KRT_SRC_UNKNOWN;	/* FIXME */
+  if (scan)
+  {
+    log(L_TRACE "Kernel scanned route pid %d", sender_pid);
+    src = KRT_SRC_UNKNOWN;	/* FIXME */
+    src = KRT_SRC_ALIEN;
+  }
+  else				/* !scan - async msg contains pid of sender */
+  {
+    src = KRT_SRC_ALIEN;
+    my_pid = getpid();
+    if (sender_pid == my_pid)
+    {
+      src = KRT_SRC_BIRD; 
+      /* filter out to save some allocation/freeing work */
+      DBG("Echo of our own route, ignoring\n");
+      return;
+    }
+  }
 
   e = rte_get_temp(&a);
   e->net = net;
@@ -504,10 +537,17 @@
   ifa.pxlen = masklen;
   memcpy(&ifa.brd, &ibrd, sizeof(ip_addr));
 
-  scope = ipa_classify(ifa.ip);
-
-  ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen));
+  if (iface->flags & IF_MULTIACCESS)
+  {
+    ifa.prefix = ipa_and(ifa.ip, ipa_mkmask(masklen));
+  }
+  else		/* PtP iface */
+  {
+    ifa.prefix = ifa.opposite = ifa.brd;
+  }
 
+  scope = ipa_classify(ifa.ip);
+  
   if (scope < 0)
   {
     log(L_ERR "KIF: Invalid interface address %I for %s", ifa.ip, iface->name);
@@ -581,6 +621,7 @@
 {
   byte *next;
   int mib[6], on;
+  int msgs_count = 0;
   size_t obl, needed;
   struct ks_msg *m;
 
@@ -612,14 +653,18 @@
   if( sysctl(mib, 6 , *buf, &needed, NULL, 0) < 0)
   {
     if(on != needed) return; 	/* The buffer size changed since last sysctl */
-    die("RT scan 2");
+    log(L_ERR "Sysctl scan error: %d, bufsize=%d", errno, on);
+//    die("RT scan 2");
+return;
   }
 
   for (next = *buf; next < (*buf + needed); next += m->rtm.rtm_msglen)
   {
     m = (struct ks_msg *)next;
     krt_read_msg(p, m, 1);
+    msgs_count++;
   }
+  log(L_TRACE "Kernel scanned (cmd %d, %d bytes, %d msgs).", cmd, needed, msgs_count);
 }
 
 void
diff -U 3 -r sysdep1/cf/bsd.h sysdep/cf/bsd.h
--- sysdep1/cf/bsd.h	2010-03-02 20:42:59.000000000 +0200
+++ sysdep/cf/bsd.h	2009-11-11 22:18:41.621053000 +0200
@@ -7,7 +7,7 @@
  */
 
 #define CONFIG_AUTO_ROUTES
-#undef CONFIG_SELF_CONSCIOUS
+#define CONFIG_SELF_CONSCIOUS
 #undef CONFIG_MULTIPLE_TABLES
 
 #undef CONFIG_UNIX_IFACE
diff -U 3 -r sysdep1/unix/krt.c sysdep/unix/krt.c
--- sysdep1/unix/krt.c	2010-03-02 20:42:59.000000000 +0200
+++ sysdep/unix/krt.c	2009-11-13 17:38:41.000000000 +0200
@@ -688,7 +688,7 @@
   switch (src)
     {
     case KRT_SRC_BIRD:
-      ASSERT(0);			/* Should be filtered by the back end */
+      break;			/* filter out echoes of our activity */
     case KRT_SRC_REDIRECT:
       DBG("It's a redirect, kill him! Kill! Kill!\n");
       krt_set_notify(p, net, NULL, e);

-- 
Eugene Perevyazko



More information about the Bird-users mailing list