]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
KRT: Allow to learn routes with RTPROT_KERNEL
authorPavel Šorejs <mail@sorejs.eu>
Fri, 6 Oct 2023 02:31:19 +0000 (04:31 +0200)
committerOndrej Zajicek <santiago@crfreenet.org>
Fri, 6 Oct 2023 02:55:56 +0000 (04:55 +0200)
The Kernel protocol, even with the option 'learn' enabled, ignores
direct routes created by the OS kernel (on Linux these are routes
with rtm_protocol == RTPROT_KERNEL).

Implement optional behavior where both OS kernel and third-party routes
are learned, it can be enabled by 'learn all' option.

Minor changes by committer.

doc/bird.sgml
sysdep/linux/netlink.c
sysdep/unix/krt.Y
sysdep/unix/krt.c
sysdep/unix/krt.h

index 5e795450dbf4f08d612c33f810462d5a482530ae..d5bc8d5701b5ee4e9fffacbd7ddb27d11a4f6156 100644 (file)
@@ -3764,9 +3764,8 @@ on the <cf/learn/ switch, such routes are either ignored or accepted to our
 table).
 
 <p>Note that routes created by OS kernel itself, namely direct routes
-representing IP subnets of associated interfaces, are not imported even with
-<cf/learn/ enabled. You can use <ref id="direct" name="Direct protocol"> to
-generate these direct routes.
+representing IP subnets of associated interfaces, are imported only with
+<cf/learn all/ enabled.
 
 <p>If your OS supports only a single routing table, you can configure only one
 instance of the Kernel protocol. If it supports multiple tables (in order to
@@ -3797,10 +3796,12 @@ channels.
        Time in seconds between two consecutive scans of the kernel routing
        table.
 
-       <tag><label id="krt-learn">learn <m/switch/</tag>
+       <tag><label id="krt-learn">learn <m/switch/|all</tag>
        Enable learning of routes added to the kernel routing tables by other
        routing daemons or by the system administrator. This is possible only on
-       systems which support identification of route authorship.
+       systems which support identification of route authorship. By default,
+       routes created by kernel (marked as "proto kernel") are not imported.
+       Use <cf/learn all/ option to import even these routes.
 
        <tag><label id="krt-kernel-table">kernel table <m/number/</tag>
        Select which kernel table should this particular instance of the Kernel
index 1af78766b9d4c088c74d9ea25fc3f114b50bcbac..29446cab3899bfa02fa43411f31a5245b5b0e571 100644 (file)
@@ -1598,7 +1598,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
 
     case RTPROT_KERNEL:
       krt_src = KRT_SRC_KERNEL;
-      return;
+      break;
 
     case RTPROT_BIRD:
       if (!s->scan)
index 5af6a4c8bd03d049eaf1ab982aad74551bb8ca97..90297d3ff663b5e5c0fa05c20e12e83a1eef1251 100644 (file)
@@ -32,6 +32,7 @@ CF_DECLS
 CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES, GRACEFUL, RESTART, KRT_SOURCE, KRT_METRIC, MERGE, PATHS)
 CF_KEYWORDS(INTERFACE, PREFERRED)
 
+%type <i> kern_learn
 %type <i> kern_mp_limit
 %type <cc> kern_channel
 
@@ -49,6 +50,11 @@ kern_proto_start: proto_start KERNEL {
 kern_proto: kern_proto_start proto_name '{' ;
 kern_proto: kern_proto kern_item ';' ;
 
+kern_learn:
+   bool { $$ = $1 ? KRT_LEARN_ALIEN : KRT_LEARN_NONE; }
+ | ALL  { $$ = KRT_LEARN_ALL; }
+ ;
+
 kern_mp_limit:
    /* empty */ { $$ = KRT_DEFAULT_ECMP_LIMIT; }
  | LIMIT expr  { $$ = $2; if (($2 <= 0) || ($2 > 255)) cf_error("Merge paths limit must be in range 1-255"); }
@@ -68,7 +74,7 @@ kern_item:
       /* Scan time of 0 means scan on startup only */
       THIS_KRT->scan_time = $3 S_;
    }
- | LEARN bool {
+ | LEARN kern_learn {
       THIS_KRT->learn = $2;
 #ifndef KRT_ALLOW_LEARN
       if ($2)
index 9f95247fe5484c57e6d8196c47ba16a39c5d5464..3a4b24dceb050fce31d06eb3ec922d0e026b1048 100644 (file)
@@ -639,12 +639,14 @@ krt_got_route(struct krt_proto *p, rte *e, s8 src)
 #ifdef KRT_ALLOW_LEARN
   switch (src)
     {
-    case KRT_SRC_KERNEL:
-      goto ignore;
-
     case KRT_SRC_REDIRECT:
       goto delete;
 
+    case KRT_SRC_KERNEL:
+      if (KRT_CF->learn != KRT_LEARN_ALL)
+        goto ignore;
+      /* fallthrough */
+
     case  KRT_SRC_ALIEN:
       if (KRT_CF->learn)
        krt_learn_scan(p, e);
@@ -780,6 +782,11 @@ krt_got_route_async(struct krt_proto *p, rte *e, int new, s8 src)
       break;
 
 #ifdef KRT_ALLOW_LEARN
+    case KRT_SRC_KERNEL:
+      if (KRT_CF->learn != KRT_LEARN_ALL)
+        break;
+      /* fallthrough */
+
     case KRT_SRC_ALIEN:
       if (KRT_CF->learn)
        {
index 18a206e68c2a6db8a629dc9ff1789c1a3f5c52cd..e25f0b125f0e40d3982036d1312067cf7d808400 100644 (file)
@@ -27,6 +27,10 @@ struct kif_proto;
 #define KRT_REF_SEEN   0x1     /* Seen in table */
 #define KRT_REF_BEST   0x2     /* Best in table */
 
+#define KRT_LEARN_NONE 0       /* Do not learn */
+#define KRT_LEARN_ALIEN        1       /* Learn KRT_SRC_ALIEN routes */
+#define KRT_LEARN_ALL  2       /* Learn both KRT_SRC_ALIEN and KRT_SRC_KERNEL routes */
+
 /* Whenever we recognize our own routes, we allow learing of foreign routes */
 
 #ifdef CONFIG_SELF_CONSCIOUS