From: Maria Matejka Date: Sat, 20 Mar 2021 20:14:54 +0000 (+0100) Subject: KRT: Using obligatory export table when non-trivial filters are applied. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f60491520095526868f04aaf3a80aa6f6cc15562;p=thirdparty%2Fbird.git KRT: Using obligatory export table when non-trivial filters are applied. When the kernel filter is anything more sophisticated than FILTER_ACCEPT or FILTER_REJECT, we should ensure that the old route being sent to the kernel protocol is really what was sent there before. This fixes the old misbehavior when an unfiltered old route was used. --- diff --git a/filter/filter.h b/filter/filter.h index 26c1037b7..77d39bbff 100644 --- a/filter/filter.h +++ b/filter/filter.h @@ -68,6 +68,8 @@ void filters_dump_all(void); #define FILTER_REJECT ((struct filter *) 1) #define FILTER_UNDEF ((struct filter *) 2) /* Used in BGP */ +#define TRIVIAL_FILTER(f) (((f) == FILTER_REJECT) || ((f) == FILTER_ACCEPT)) + #define FF_SILENT 2 /* Silent filter execution */ /* Custom route attributes */ diff --git a/nest/protocol.h b/nest/protocol.h index 817fd35a3..ef7334adc 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -471,7 +471,7 @@ struct channel_class { #endif }; -extern struct channel_class channel_bgp; +extern struct channel_class channel_bgp, channel_krt; struct channel_config { node n; diff --git a/sysdep/unix/krt.Y b/sysdep/unix/krt.Y index 95b54d65d..623cbd92d 100644 --- a/sysdep/unix/krt.Y +++ b/sysdep/unix/krt.Y @@ -33,6 +33,7 @@ CF_KEYWORDS(KERNEL, PERSIST, SCAN, TIME, LEARN, DEVICE, ROUTES, GRACEFUL, RESTAR CF_KEYWORDS(INTERFACE, PREFERRED) %type kern_mp_limit +%type kern_channel_start kern_proto_channel CF_GRAMMAR @@ -53,9 +54,17 @@ kern_mp_limit: | LIMIT expr { $$ = $2; if (($2 <= 0) || ($2 > 255)) cf_error("Merge paths limit must be in range 1-255"); } ; +kern_channel_start: net_type +{ + $$ = this_channel = channel_config_get(&channel_krt, net_label[$1], $1, this_proto); + this_proto->net_type = $1; +}; + +kern_proto_channel: kern_channel_start channel_opt_list channel_end; + kern_item: proto_item - | proto_channel { this_proto->net_type = $1->net_type; } + | kern_proto_channel | PERSIST bool { THIS_KRT->persist = $2; } | SCAN TIME expr { /* Scan time of 0 means scan on startup only */ diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 9485e02e3..527d8b3ff 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -1033,6 +1033,11 @@ krt_start(struct proto *P) default: log(L_ERR "KRT: Tried to start with strange net type: %d", p->p.net_type); return PS_START; break; } + /* If it is needed, setup out table automagically */ + if (!TRIVIAL_FILTER(p->p.main_channel->out_filter)) + channel_setup_out_table(p->p.main_channel); + + bmap_init(&p->sync_map, p->p.pool, 1024); bmap_init(&p->seen_map, p->p.pool, 1024); add_tail(&krt_proto_list, &p->krt_node); @@ -1079,6 +1084,15 @@ krt_shutdown(struct proto *P) return PS_DOWN; } +static int +krt_channel_reconfigure(struct channel *C, struct channel_config *CC, int *import_changed UNUSED, int *export_changed) +{ + if (!*export_changed) + return 1; + + return (TRIVIAL_FILTER(C->out_filter) == TRIVIAL_FILTER(CC->out_filter)); +} + static int krt_reconfigure(struct proto *p, struct proto_config *CF) { @@ -1151,6 +1165,12 @@ krt_get_attr(const eattr *a, byte *buf, int buflen) #define MAYBE_MPLS 0 #endif +struct channel_class channel_krt = { + .channel_size = sizeof(struct channel), + .config_size = sizeof(struct channel_config), + .reconfigure = krt_channel_reconfigure, +}; + struct protocol proto_unix_kernel = { .name = "Kernel", .template = "kernel%d",