diff options
author | Ondrej Zajicek <santiago@crfreenet.org> | 2015-04-25 20:43:43 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2015-04-25 20:43:43 +0200 |
commit | c5ff44a703e4ab810a5bd45cf9140643a50fb3ec (patch) | |
tree | 9da170899ebd1d1afea30a358c031bc704c47d0d /sysdep | |
parent | 90097f4fb924922b416247abf291fb21f39dc8e1 (diff) |
KRT: Fixes learning of preferred kernel routes.
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.
Diffstat (limited to 'sysdep')
-rw-r--r-- | sysdep/cf/README | 1 | ||||
-rw-r--r-- | sysdep/cf/bsd-v6.h | 1 | ||||
-rw-r--r-- | sysdep/cf/bsd.h | 1 | ||||
-rw-r--r-- | sysdep/unix/krt.c | 14 |
4 files changed, 17 insertions, 0 deletions
diff --git a/sysdep/cf/README b/sysdep/cf/README index 768a3727..e62c3481 100644 --- a/sysdep/cf/README +++ b/sysdep/cf/README @@ -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) diff --git a/sysdep/cf/bsd-v6.h b/sysdep/cf/bsd-v6.h index 47a7c7ff..745dfba3 100644 --- a/sysdep/cf/bsd-v6.h +++ b/sysdep/cf/bsd-v6.h @@ -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 diff --git a/sysdep/cf/bsd.h b/sysdep/cf/bsd.h index df199199..51beb42b 100644 --- a/sysdep/cf/bsd.h +++ b/sysdep/cf/bsd.h @@ -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 diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 0a223a4f..7cec28c8 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -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) && |