Commit c5ff44a7 authored by Ondrej Zajicek's avatar Ondrej Zajicek
Browse files

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.
parent 90097f4f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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)
+1 −0
Original line number Diff line number Diff line
@@ -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
+1 −0
Original line number Diff line number Diff line
@@ -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
+14 −0
Original line number Diff line number Diff line
@@ -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) &&