diff options
author | Pavel Ĺ orejs <mail@sorejs.eu> | 2023-10-06 04:31:19 +0200 |
---|---|---|
committer | Ondrej Zajicek <santiago@crfreenet.org> | 2023-10-06 04:55:56 +0200 |
commit | e83beb70bd14923cece5b35411606ade6fb8fbee (patch) | |
tree | 7433fd0d7a57c5d2190ece9b43516f132976a880 | |
parent | 57aa077227d1f2440dc1b2bb6cbbebd418a6b898 (diff) |
KRT: Allow to learn routes with RTPROT_KERNEL
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.
-rw-r--r-- | doc/bird.sgml | 11 | ||||
-rw-r--r-- | sysdep/linux/netlink.c | 2 | ||||
-rw-r--r-- | sysdep/unix/krt.Y | 8 | ||||
-rw-r--r-- | sysdep/unix/krt.c | 13 | ||||
-rw-r--r-- | sysdep/unix/krt.h | 4 |
5 files changed, 28 insertions, 10 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml index 5e795450..d5bc8d57 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -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 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 5af6a4c8..90297d3f 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 %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) diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 9f95247f..3a4b24dc 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -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) { diff --git a/sysdep/unix/krt.h b/sysdep/unix/krt.h index 18a206e6..e25f0b12 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 /* 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 |