<HTML><BODY>Hello.<br><br>Recently I spot following issue with BIRD:<br>  kernel syncer does not learn routes with RTPROT_KERNEL even with<br>    "learn" and "device routes" turned on.<br><br>Config is wery simple:<br><br># Main routing table (master), mapped to ipt_main kernel table.<br># ipt_main == 254 (see /etc/iproute2/rt_tables)<br>protocol kernel kernel254 {<br>        persist no;<br>        scan time 120;<br>        learn yes;<br>        device routes yes;<br>        kernel table ipt_main;<br>        import all;<br>        export all;<br>}<br><br>$ birdc 'show route'<br>BIRD 1.3.10 ready.<br><br>$ ip -4 route show table main<br>172.16.1.0/24 dev lo255  proto kernel  scope link  src 172.16.1.254<br><br>Can some one explain why this was done, and is there any way<br>other than patching BIRD (at least sysdep/linux/netlink.c does checking and ignoring<br>and sysdep/unix/krt.c makes its final verdict to ignore such route).<br><br>Background of problem or why this might be important (at least for me).<br>There is lot of text, and no need to read it, however it describes why learning<br>routes with RTPROT_KENREL might be important.<br>-----------------------------------------------------------------------------------------------<br><br>There is requirement to create separate Linux kernel RIB and install<br>rules to direct traffic to it (ip-rules(8)). This is an PBR (Policy-Based Routing)<br><br>BIRD has all necessary means to do that:<br>  protocols direct - to learn directly connected routes and<br>  pipe to import from main (master in BIRD) routing table some routes.<br><br>And everything works as expected, except that protocol direct "imports"<br>(better to say create may be?) routes based on interface ip address configuration.<br>Contrary to this, kernel installs such directly connected routes with some attributes:<br>like proto kernel, and very important as I discover src (krt_prefsrc attribute in BIRD).<br><br>Actually attribute perfsrc used in kernel to determine outgoning source for packets<br>that has no src addresses in it (application does not call bind(2), which is common for UDP).<br><br>Without prefsrc on route, kernel uses fallback mechanism to find source:<br>this is inet_select_addr() function, which is not ideal in functionality (in some cases<br>strange source address might be choosen), and all it does it looks outgoing interface itself for<br>primary address and other interfaces if interface has no such one).<br><br>Recent kernels (linux-2.6.39+) has implemented genid table to cache information from<br>inet_select_addr()<br>(commits 436c3b66ec98 "ipv4: Invalidate nexthop cache nh_saddr more correctly." and<br> 1fc050a13473 "ipv4: Cache source address in nexthop entries.")<br>lookups, but implementation has also wholes (for example if interface has zero ip address<br>on it and host on lan referenced by a route with interface as nexthop (so called ip unnumbered<br>in proven vendor terms) as only event to regenerate (and thus recall inet_select_addr())<br>genid is changing state of the interface (i.e. changing route pointing to device has no chance<br>to regenerate genid and packets might still go with source from previous call to inet_select_addr()).<br><br>Some distributions with longterm support still provides 2.6.32 kernels.<br><br>Having system with thousands interfaces and sending UDP for example over all of it<br>is wery expensive in CPU terms. Thus I decided to learn routes from kernel protocol<br>and then pass them trought pipe and install it in new kernel table for PBR.<br><br>--
<br>SP5474-RIPE
<br>Sergey Popovich<br></BODY></HTML>