]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
KRT: Fixes learning of preferred kernel routes.
authorOndrej Zajicek <santiago@crfreenet.org>
Sat, 25 Apr 2015 18:43:43 +0000 (20:43 +0200)
committerPavel Tvrdík <pawel.tvrdik@gmail.cz>
Wed, 29 Apr 2015 11:43:15 +0000 (13:43 +0200)
When a new route was imported from kernel and chosen as preferred, then
the old best route was propagated as a withdraw to the kernel protocol.
Under some circumstances such withdraw propagated to the BSD kernel could
remove the new alien route and thus reverting the import.

sysdep/cf/README
sysdep/cf/bsd-v6.h
sysdep/cf/bsd.h
sysdep/unix/krt.c

index 768a37272b4251ae5ecea8ad42abc8c07d1f936a..e62c348194ddce07ffef25fc3114cb26ae7a667b 100644 (file)
@@ -5,6 +5,7 @@ CONFIG_AUTO_ROUTES      Device routes are added automagically by the kernel
 CONFIG_SELF_CONSCIOUS  We're able to recognize whether route was installed by us
 CONFIG_MULTIPLE_TABLES The kernel supports multiple routing tables
 CONFIG_ALL_TABLES_AT_ONCE      Kernel scanner wants to process all tables at once
+CONFIG_SINGLE_ROUTE    There is only one route per network
 
 CONFIG_MC_PROPER_SRC   Multicast packets have source address according to socket saddr field
 CONFIG_SKIP_MC_BIND    Don't call bind on multicast socket (def for *BSD)
index 47a7c7ff4e7b36242cb6c90cd3006940ecbcd268..745dfba3cd088e7b076687664d41e7340cfb32bd 100644 (file)
@@ -11,6 +11,7 @@
 #define CONFIG_AUTO_ROUTES
 #define CONFIG_SELF_CONSCIOUS
 #define CONFIG_MULTIPLE_TABLES
+#define CONFIG_SINGLE_ROUTE
 
 #define CONFIG_SKIP_MC_BIND
 #define CONFIG_NO_IFACE_BIND
index df199199a840a25610bdbbc670e780bca72c7ab7..51beb42bd22b576746632851ddfae51497ccaac8 100644 (file)
@@ -9,6 +9,7 @@
 #define CONFIG_AUTO_ROUTES
 #define CONFIG_SELF_CONSCIOUS
 #define CONFIG_MULTIPLE_TABLES
+#define CONFIG_SINGLE_ROUTE
 
 #define CONFIG_SKIP_MC_BIND
 #define CONFIG_NO_IFACE_BIND
index 0a223a4f8223999efb71bf517e731fa81fcd59f1..7cec28c8dfae2946555331f11609e6cf42ae09b1 100644 (file)
@@ -961,7 +961,21 @@ krt_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool *
   rte *e = *new;
 
   if (e->attrs->src->proto == P)
+  {
+#ifdef CONFIG_SINGLE_ROUTE
+    /*
+     * Implicit withdraw - when the imported kernel route becomes the best one,
+     * we know that the previous one exported to the kernel was already removed,
+     * but if we processed the update as usual, we would send withdraw to the
+     * kernel, which would remove the new imported route instead.
+     *
+     * We will remove KRT_INSTALLED flag, which stops such withdraw to be
+     * processed in krt_rt_notify() and krt_replace_rte().
+     */
+    e->net->n.flags &= ~KRF_INSTALLED;
+#endif
     return -1;
+  }
 
   if (!KRT_CF->devroutes &&
       (e->attrs->dest == RTD_DEVICE) &&