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)
#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
#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
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) &&