From c5ff44a703e4ab810a5bd45cf9140643a50fb3ec Mon Sep 17 00:00:00 2001 From: Ondrej Zajicek Date: Sat, 25 Apr 2015 20:43:43 +0200 Subject: 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. --- sysdep/unix/krt.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'sysdep/unix/krt.c') 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) && -- cgit v1.2.3