summaryrefslogtreecommitdiff
path: root/bgpd/bgp_nht.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2023-05-11 17:11:14 +0200
committerPhilippe Guibert <philippe.guibert@6wind.com>2023-07-13 12:05:15 +0200
commit58592be57783a3b24e7351af2a5afc61299768df (patch)
tree9d2e62cd4365eb05d4719941171a523e39c6a27f /bgpd/bgp_nht.c
parent1b34877af6f1f0b2f922a62ad60c933e7a1683c3 (diff)
bgpd: upon if event, evaluate bnc with matching nexthop
In BGP, when an interface event is detected or triggered, the BNC that have a next-hop that matches the interface are not evaluated. The paths attached to the bnc context are evaluated in the following situation: - In the up event case, if at least one next-hop interface matched the event interface. - In the down event case, if there is no alternate next-hop that does not use the event interface. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'bgpd/bgp_nht.c')
-rw-r--r--bgpd/bgp_nht.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index fbb8831acd..992a7c1cda 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -717,11 +717,48 @@ static void bgp_nht_ifp_table_handle(struct bgp *bgp,
struct interface *ifp, bool up)
{
struct bgp_nexthop_cache *bnc;
+ struct nexthop *nhop;
+ uint8_t other_nh_count;
+ bool nhop_ll_found;
+ bool nhop_found;
frr_each (bgp_nexthop_cache, table, bnc) {
- if (bnc->ifindex_ipv6_ll != ifp->ifindex)
+ other_nh_count = 0;
+ nhop_ll_found = bnc->ifindex_ipv6_ll == ifp->ifindex;
+ for (nhop = bnc->nexthop; nhop; nhop = nhop->next) {
+ if (nhop->ifindex == bnc->ifindex_ipv6_ll)
+ continue;
+
+ if (nhop->ifindex != ifp->ifindex) {
+ other_nh_count++;
+ continue;
+ }
+ if (nhop->vrf_id != ifp->vrf->vrf_id) {
+ other_nh_count++;
+ continue;
+ }
+ nhop_found = true;
+ }
+
+ if (!nhop_found && !nhop_ll_found)
+ /* The event interface does not match the nexthop cache
+ * entry */
+ continue;
+
+ if (!up && other_nh_count > 0)
+ /* Down event ignored in case of multiple next-hop
+ * interfaces. The other might interfaces might be still
+ * up. The cases where all interfaces are down or a bnc
+ * is invalid are processed by a separate zebra rnh
+ * messages.
+ */
continue;
+ if (!nhop_ll_found) {
+ evaluate_paths(bnc);
+ continue;
+ }
+
bnc->last_update = monotime(NULL);
bnc->change_flags = 0;
@@ -734,6 +771,7 @@ static void bgp_nht_ifp_table_handle(struct bgp *bgp,
if (up) {
SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
SET_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED);
+ /* change nexthop number only for ll */
bnc->nexthop_num = 1;
} else {
UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);