[patch] kernel protocol learn on FreeBSD 7
Hello bird-users readers! I'm trying to use bird on PPP access-server running FreeBSD 7. The first problem I've met was bird not learning routes that are added and removed by ppp daemon based on Radius user-data. I've made a simple patch but not sure if it is full and correct. Can anyone review it? Especially I'm not sure what should be marked as KRT_SRC_REDIRECT and what are the consequences of not using this value. --- sysdep/bsd/krt-sock.c.old 2009-11-09 17:42:47.000000000 +0200 +++ sysdep/bsd/krt-sock.c 2009-11-09 17:48:58.000000000 +0200 @@ -269,6 +269,8 @@ 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)) @@ -375,6 +377,12 @@ } src = KRT_SRC_UNKNOWN; /* FIXME */ + src = KRT_SRC_ALIEN; + my_pid = getpid(); + if (sender_pid == my_pid) + { + src = KRT_SRC_BIRD; + } e = rte_get_temp(&a); e->net = net; +++ sysdep/cf/bsd.h.old 2009-11-09 18:06:53.000000000 +0200 --- sysdep/cf/bsd.h 2009-11-09 17:38:21.000000000 +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 -- Eugene Perevyazko
On Mon, Nov 09, 2009 at 07:27:06PM +0200, Eugene Perevyazko wrote:
The first problem I've met was bird not learning routes that are added and removed by ppp daemon based on Radius user-data.
I've made a simple patch but not sure if it is full and correct. Can anyone review it? Especially I'm not sure what should be marked as KRT_SRC_REDIRECT and what are the consequences of not using this value.
Now I see that async alien routes are added, but not deleted. They are deleted only on rescan. Is sysdep/bsd/krt.c missing something related to async deleting of alien routes or is the patch faulty in some way? -- Eugene Perevyazko
On Mon, Nov 09, 2009 at 07:57:01PM +0200, Eugene Perevyazko wrote:
Now I see that async alien routes are added, but not deleted. They are deleted only on rescan. Is sysdep/bsd/krt.c missing something related to async deleting of alien routes or is the patch faulty in some way?
Hmm, i don't know. It is possible that async deletion event handling is not implemented in BSD code. -- Elen sila lumenn' omentielvo Ondrej 'SanTiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
On Mon, Nov 09, 2009 at 07:10:17PM +0100, Ondrej Zajicek wrote:
On Mon, Nov 09, 2009 at 07:57:01PM +0200, Eugene Perevyazko wrote:
Now I see that async alien routes are added, but not deleted. They are deleted only on rescan. Is sysdep/bsd/krt.c missing something related to async deleting of alien routes or is the patch faulty in some way?
Hmm, i don't know. It is possible that async deletion event handling is not implemented in BSD code.
I've traced the problem down to this condition in krt_read_rt() in sysdep/bsd/krt-sock.c: if (!(flags & RTF_UP)) { DBG("Down.\n"); return; } Shouldn't it be !(flags & RTF_DONE) ? Or maybe even check rtm.errno first? To show the details I used next commands: # route add 10.0.1.0/24 192.168.200.2 add net 10.0.1.0: gateway 192.168.200.2 # route delete 10.0.1.0/24 192.168.200.2 delete net 10.0.1.0: gateway 192.168.200.2 # route delete 10.0.1.0/24 192.168.200.2 route: writing to routing socket: No such process delete net 10.0.1.0: gateway 192.168.200.2: not in table # route add 10.0.1.0/24 192.168.200.2 add net 10.0.1.0: gateway 192.168.200.2 # route delete 10.0.1.0/24 delete net 10.0.1.0 # route delete 10.0.1.0/24 route: writing to routing socket: No such process delete net 10.0.1.0: not in table And here is what route monitor shows for them: # route monitor got message of size 132 on Tue Nov 10 13:21:18 2009 RTM_ADD: Add Route: len 132, pid: 25159, seq 1, errno 0, flags:<UP,GATEWAY,DONE,STATIC> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> 10.0.1.0 192.168.200.2 (0) 0 ffff ff got message of size 132 on Tue Nov 10 13:21:30 2009 RTM_DELETE: Delete Route: len 132, pid: 25160, seq 1, errno 0, flags:<GATEWAY,DONE,STATIC> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> 10.0.1.0 192.168.200.2 (255) ffff ffff ff got message of size 132 on Tue Nov 10 13:21:30 2009 RTM_DELETE: Delete Route: len 132, pid: 25161, seq 1, errno 3, flags:<UP,GATEWAY,STATIC> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> 10.0.1.0 192.168.200.2 (0) 0 ffff ff got message of size 132 on Tue Nov 10 13:21:35 2009 RTM_ADD: Add Route: len 132, pid: 25162, seq 1, errno 0, flags:<UP,GATEWAY,DONE,STATIC> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> 10.0.1.0 192.168.200.2 (0) 0 ffff ff got message of size 132 on Tue Nov 10 13:21:38 2009 RTM_DELETE: Delete Route: len 132, pid: 25163, seq 1, errno 0, flags:<GATEWAY,DONE,STATIC> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> 10.0.1.0 192.168.200.2 (255) ffff ffff ff got message of size 116 on Tue Nov 10 13:21:39 2009 RTM_DELETE: Delete Route: len 116, pid: 25164, seq 1, errno 3, flags:<UP,GATEWAY,STATIC> locks: inits: sockaddrs: <DST,NETMASK> 10.0.1.0 (0) 0 ffff ff -- Eugene Perevyazko
On Tue, Nov 10, 2009 at 01:34:18PM +0200, Eugene Perevyazko wrote:
On Mon, Nov 09, 2009 at 07:10:17PM +0100, Ondrej Zajicek wrote:
On Mon, Nov 09, 2009 at 07:57:01PM +0200, Eugene Perevyazko wrote:
Now I see that async alien routes are added, but not deleted. They are deleted only on rescan. Is sysdep/bsd/krt.c missing something related to async deleting of alien routes or is the patch faulty in some way?
Hmm, i don't know. It is possible that async deletion event handling is not implemented in BSD code.
I've traced the problem down to this condition in krt_read_rt() in sysdep/bsd/krt-sock.c: if (!(flags & RTF_UP)) { DBG("Down.\n"); return; } Shouldn't it be !(flags & RTF_DONE) ? Or maybe even check rtm.errno first?
Well, I'm getting deeper understanding how this stuff works :) This is my current version of the patch, that looks like works in both async learn and scan modes. --- sysdep/bsd/krt-sock.c.orig 2009-10-02 11:08:51.000000000 +0300 +++ sysdep/bsd/krt-sock.c 2009-11-10 15:33:24.000000000 +0200 @@ -269,11 +269,18 @@ 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 ( (!(flags & RTF_UP)) && scan ) { - DBG("Down.\n"); + DBG("Not up in scan.\n"); + return; + } + if ( (!(flags & RTF_DONE)) && !scan ) + { + DBG("Not done async.\n"); return; } @@ -375,6 +382,12 @@ } src = KRT_SRC_UNKNOWN; /* FIXME */ + src = KRT_SRC_ALIEN; + my_pid = getpid(); + if (sender_pid == my_pid) + { + src = KRT_SRC_BIRD; + } e = rte_get_temp(&a); e->net = net; --- sysdep/cf/bsd.h.orig 2009-06-28 10:33:51.000000000 +0300 +++ sysdep/cf/bsd.h 2009-11-09 19:32:24.000000000 +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 -- Eugene Perevyazko
On Tue, Nov 10, 2009 at 03:40:53PM +0200, Eugene Perevyazko wrote:
On Tue, Nov 10, 2009 at 01:34:18PM +0200, Eugene Perevyazko wrote:
On Mon, Nov 09, 2009 at 07:10:17PM +0100, Ondrej Zajicek wrote:
On Mon, Nov 09, 2009 at 07:57:01PM +0200, Eugene Perevyazko wrote:
Now I see that async alien routes are added, but not deleted. They are deleted only on rescan. Is sysdep/bsd/krt.c missing something related to async deleting of alien routes or is the patch faulty in some way?
Hmm, i don't know. It is possible that async deletion event handling is not implemented in BSD code.
I've traced the problem down to this condition in krt_read_rt() in sysdep/bsd/krt-sock.c: if (!(flags & RTF_UP)) { DBG("Down.\n"); return; } Shouldn't it be !(flags & RTF_DONE) ? Or maybe even check rtm.errno first?
Well, I'm getting deeper understanding how this stuff works :) This is my current version of the patch, that looks like works in both async learn and scan modes.
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? -- Elen sila lumenn' omentielvo Ondrej 'SanTiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
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
On Mon, Nov 09, 2009 at 07:27:06PM +0200, Eugene Perevyazko wrote:
Hello bird-users readers!
I'm trying to use bird on PPP access-server running FreeBSD 7.
The first problem I've met was bird not learning routes that are added and removed by ppp daemon based on Radius user-data.
I've made a simple patch but not sure if it is full and correct. Can anyone review it? Especially I'm not sure what should be marked as KRT_SRC_REDIRECT and what are the consequences of not using this value.
Thank you for the patch, i will look at it. KRT_SRC_REDIRECT should be used for kernel routes that are the result of ICMP redirect message. Routes that are configured by some tools (like route command, other routing software or pppd in your case) should be marked as KRT_SRC_ALIEN. Consequence of not using KRT_SRC_REDIRECT is that such route will be handled as configured by other tool. -- Elen sila lumenn' omentielvo Ondrej 'SanTiago' Zajicek (email: santiago@crfreenet.org) OpenPGP encrypted e-mails preferred (KeyID 0x11DEADC3, wwwkeys.pgp.net) "To err is human -- to blame it on a computer is even more so."
participants (2)
-
Eugene Perevyazko -
Ondrej Zajicek