0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-11-09 12:48:43 +00:00

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.
This commit is contained in:
Pavel Šorejs 2023-10-06 04:31:19 +02:00 committed by Ondrej Zajicek
parent 57aa077227
commit e83beb70bd
5 changed files with 28 additions and 10 deletions

View File

@ -3764,9 +3764,8 @@ on the <cf/learn/ switch, such routes are either ignored or accepted to our
table). table).
<p>Note that routes created by OS kernel itself, namely direct routes <p>Note that routes created by OS kernel itself, namely direct routes
representing IP subnets of associated interfaces, are not imported even with representing IP subnets of associated interfaces, are imported only with
<cf/learn/ enabled. You can use <ref id="direct" name="Direct protocol"> to <cf/learn all/ enabled.
generate these direct routes.
<p>If your OS supports only a single routing table, you can configure only one <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 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 Time in seconds between two consecutive scans of the kernel routing
table. 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 Enable learning of routes added to the kernel routing tables by other
routing daemons or by the system administrator. This is possible only on 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> <tag><label id="krt-kernel-table">kernel table <m/number/</tag>
Select which kernel table should this particular instance of the Kernel Select which kernel table should this particular instance of the Kernel

View File

@ -1598,7 +1598,7 @@ nl_parse_route(struct nl_parse_state *s, struct nlmsghdr *h)
case RTPROT_KERNEL: case RTPROT_KERNEL:
krt_src = KRT_SRC_KERNEL; krt_src = KRT_SRC_KERNEL;
return; break;
case RTPROT_BIRD: case RTPROT_BIRD:
if (!s->scan) if (!s->scan)

View 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(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES, GRACEFUL, RESTART, KRT_SOURCE, KRT_METRIC, MERGE, PATHS)
CF_KEYWORDS(INTERFACE, PREFERRED) CF_KEYWORDS(INTERFACE, PREFERRED)
%type <i> kern_learn
%type <i> kern_mp_limit %type <i> kern_mp_limit
%type <cc> kern_channel %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_start proto_name '{' ;
kern_proto: kern_proto kern_item ';' ; kern_proto: kern_proto kern_item ';' ;
kern_learn:
bool { $$ = $1 ? KRT_LEARN_ALIEN : KRT_LEARN_NONE; }
| ALL { $$ = KRT_LEARN_ALL; }
;
kern_mp_limit: kern_mp_limit:
/* empty */ { $$ = KRT_DEFAULT_ECMP_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"); } | 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 */ /* Scan time of 0 means scan on startup only */
THIS_KRT->scan_time = $3 S_; THIS_KRT->scan_time = $3 S_;
} }
| LEARN bool { | LEARN kern_learn {
THIS_KRT->learn = $2; THIS_KRT->learn = $2;
#ifndef KRT_ALLOW_LEARN #ifndef KRT_ALLOW_LEARN
if ($2) if ($2)

View File

@ -639,12 +639,14 @@ krt_got_route(struct krt_proto *p, rte *e, s8 src)
#ifdef KRT_ALLOW_LEARN #ifdef KRT_ALLOW_LEARN
switch (src) switch (src)
{ {
case KRT_SRC_KERNEL:
goto ignore;
case KRT_SRC_REDIRECT: case KRT_SRC_REDIRECT:
goto delete; goto delete;
case KRT_SRC_KERNEL:
if (KRT_CF->learn != KRT_LEARN_ALL)
goto ignore;
/* fallthrough */
case KRT_SRC_ALIEN: case KRT_SRC_ALIEN:
if (KRT_CF->learn) if (KRT_CF->learn)
krt_learn_scan(p, e); krt_learn_scan(p, e);
@ -780,6 +782,11 @@ krt_got_route_async(struct krt_proto *p, rte *e, int new, s8 src)
break; break;
#ifdef KRT_ALLOW_LEARN #ifdef KRT_ALLOW_LEARN
case KRT_SRC_KERNEL:
if (KRT_CF->learn != KRT_LEARN_ALL)
break;
/* fallthrough */
case KRT_SRC_ALIEN: case KRT_SRC_ALIEN:
if (KRT_CF->learn) if (KRT_CF->learn)
{ {

View File

@ -27,6 +27,10 @@ struct kif_proto;
#define KRT_REF_SEEN 0x1 /* Seen in table */ #define KRT_REF_SEEN 0x1 /* Seen in table */
#define KRT_REF_BEST 0x2 /* Best 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 */ /* Whenever we recognize our own routes, we allow learing of foreign routes */
#ifdef CONFIG_SELF_CONSCIOUS #ifdef CONFIG_SELF_CONSCIOUS