On Sat, Jan 27, 2024 at 02:59:57PM +0100, Ondrej Zajicek wrote: > On Sat, Jan 27, 2024 at 01:42:57PM +0100, Marcel Menzel via Bird-users wrote: > > Hello List, > > > > I am doing a test setup with the new MPLS L3VPN feature (for background > > information: I am running IPsec with L2TP on top, with OSPF as IGP and iBGP > > between loopbacks) > > with one router receiving an IPv6 fulltable via eBGP and the other one > > establishing the BGP session through a tunnel described above, and I noticed > > periodic high CPU usage on the router receiving the routes at the end of the > > tunnel. > > > > It seems, that BIRD keeps exporting the whole table to the kernel every 30 > > seconds, as it is configured in the kernel protocol scan time with the "vrf" > > directive set: > > Hello > > It is possible that BIRD exports some route but receives back from kernel > something slightly different than it expected, so it will try to re-send > it during the scan. > > ... and i just noticed that the bug manifests even in my test case, so > i will check it.
Fixed: https://gitlab.nic.cz/labs/bird/-/commit/f40e2bc270d3635be518ae80251ce0b5c519c6f4 You can try attached patch. -- Elen sila lumenn' omentielvo Ondrej 'Santiago' Zajicek (email: santi...@crfreenet.org) "To err is human -- to blame it on a computer is even more so."
commit f40e2bc270d3635be518ae80251ce0b5c519c6f4 Author: Ondrej Zajicek <santi...@crfreenet.org> Date: Sat Jan 27 17:38:06 2024 +0100 Nest: Fix bug in recursive routes with MPLS-labeled nexthops When a recursive route with MPLS-labeled nexthop was exported to kernel and read back, the nexthop_same() failed due to different labels_orig field and kernel protocol reinstalled it unnecessarily. For comparing hext hops, route cache has to distinguish ones with different labels_orig, but KRT has to ignore that, so we need two nexthop compare functions. Thanks to Marcel Menzel for the bugreport. diff --git a/nest/route.h b/nest/route.h index d26a4b8c..e6f6c64a 100644 --- a/nest/route.h +++ b/nest/route.h @@ -694,6 +694,9 @@ static inline size_t nexthop_size(const struct nexthop *nh) int nexthop__same(struct nexthop *x, struct nexthop *y); /* Compare multipath nexthops */ static inline int nexthop_same(struct nexthop *x, struct nexthop *y) { return (x == y) || nexthop__same(x, y); } +int nexthop_equal_(struct nexthop *x, struct nexthop *y); /* Compare multipath nexthops, ignore labels_orig */ +static inline int nexthop_equal(struct nexthop *x, struct nexthop *y) +{ return (x == y) || nexthop_equal_(x, y); } struct nexthop *nexthop_merge(struct nexthop *x, struct nexthop *y, int rx, int ry, int max, linpool *lp); struct nexthop *nexthop_sort(struct nexthop *x); static inline void nexthop_link(struct rta *a, const struct nexthop *from) diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 7f3645ee..af864bdf 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -185,20 +185,40 @@ nexthop_hash(struct nexthop *x) return h; } +static inline int +nexthop_equal_1(struct nexthop *x, struct nexthop *y) +{ + if (!ipa_equal(x->gw, y->gw) || (x->iface != y->iface) || + (x->flags != y->flags) || (x->weight != y->weight) || + (x->labels != y->labels)) + return 0; + + for (int i = 0; i < x->labels; i++) + if (x->label[i] != y->label[i]) + return 0; + + return 1; +} + int -nexthop__same(struct nexthop *x, struct nexthop *y) +nexthop_equal_(struct nexthop *x, struct nexthop *y) { + /* Like nexthop_same(), but ignores difference between local labels and labels from hostentry */ + for (; x && y; x = x->next, y = y->next) - { - if (!ipa_equal(x->gw, y->gw) || (x->iface != y->iface) || - (x->flags != y->flags) || (x->weight != y->weight) || - (x->labels_orig != y->labels_orig) || (x->labels != y->labels)) + if (!nexthop_equal_1(x, y)) return 0; - for (int i = 0; i < x->labels; i++) - if (x->label[i] != y->label[i]) - return 0; - } + return x == y; +} + +int +nexthop__same(struct nexthop *x, struct nexthop *y) +{ + for (; x && y; x = x->next, y = y->next) + if (!nexthop_equal_1(x, y) || + (x->labels_orig != y->labels_orig)) + return 0; return x == y; } diff --git a/sysdep/unix/krt.c b/sysdep/unix/krt.c index 3a4b24dc..7a078fb9 100644 --- a/sysdep/unix/krt.c +++ b/sysdep/unix/krt.c @@ -619,7 +619,7 @@ krt_same_dest(rte *k, rte *e) return 0; if (ka->dest == RTD_UNICAST) - return nexthop_same(&(ka->nh), &(ea->nh)); + return nexthop_equal(&(ka->nh), &(ea->nh)); return 1; }