[prev in list] [next in list] [prev in thread] [next in thread] 

List:       bird-users
Subject:    Re: kernel: does not learn routes with RTPROT_KERNEL
From:       Pavel_Ĺ orejs_via_Bird-users <bird-users () network ! cz>
Date:       2023-08-29 14:16:16
Message-ID: d9a469aa-2506-4942-a78f-4a9123c14684 () sorejs ! eu
[Download RAW message or body]

Here it is

On 8/29/23 14:02, Ondrej Zajicek wrote:
> On Thu, Aug 24, 2023 at 01:38:12AM +0200, Pavel Ĺ orejs via Bird-users wrote:
>> Here is first version - based on master
> Hi
>
> Seems like your patch is mangled (likely lines wrapped by e-mail client).
> Could you send it as an attachment?
>
["learn-all.patch" (text/x-patch)]

diff --git a/doc/bird.sgml b/doc/bird.sgml
index 29e12b7a..af87d5dc 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -3454,9 +3454,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
@@ -3487,10 +3486,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/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 <m/all/
+	option to import these routes.
 
 	<tag><label id="krt-kernel-table">kernel table <m/number/</tag>
 	Select which kernel table should this particular instance of the Kernel
diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c
index 1af78766..29446cab 100644
--- a/sysdep/linux/netlink.c
+++ b/sysdep/linux/netlink.c
@@ -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)
diff --git a/sysdep/unix/krt.Y b/sysdep/unix/krt.Y
index 95b54d65..f3eb1393 100644
--- a/sysdep/unix/krt.Y
+++ b/sysdep/unix/krt.Y
@@ -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
 
 CF_GRAMMAR
@@ -48,6 +49,10 @@ 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_SOME : 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"); } @@ -61,7 +66,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)
diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c
index 9f95247f..3288fd0c 100644
--- a/sysdep/unix/krt.c
+++ b/sysdep/unix/krt.c
@@ -638,13 +638,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;
+      // fall through
     case  KRT_SRC_ALIEN:
       if (KRT_CF->learn)
 	krt_learn_scan(p, e);
@@ -780,6 +781,12 @@ 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)
+	{
+	  krt_learn_async(p, e, new);
+	}
+  break;
     case KRT_SRC_ALIEN:
       if (KRT_CF->learn)
 	{
diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h
index 18a206e6..694ebd34 100644
--- a/sysdep/unix/krt.h
+++ b/sysdep/unix/krt.h
@@ -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 /* Don't learn */
+#define KRT_LEARN_SOME 1 /* Learn some routes (excluding RTPROT_KERNEL) */
+#define KRT_LEARN_ALL 2 /* Learn all routes */
+
 /* Whenever we recognize our own routes, we allow learing of foreign routes */
 
 #ifdef CONFIG_SELF_CONSCIOUS



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic