[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