From 8b653646ade5e0f459f6f13c12ce4b3dae4b471e Mon Sep 17 00:00:00 2001 From: sudhanshukumar22 Date: Thu, 12 Sep 2024 02:09:11 -0700 Subject: [PATCH] upgrade FRR to version 10.0.1, upgrade libyang2 to 2.1.148. Tested using basic BGP neighborship formation with routes using BGP docker --- rules/frr.mk | 6 +- rules/libyang2.mk | 10 +- sonic-slave-bookworm/Dockerfile.j2 | 4 +- sonic-slave-bullseye/Dockerfile.j2 | 2 + src/libyang2/Makefile | 7 +- ...008-Use-vrf_id-for-vrf-not-tabled_id.patch | 30 +- ...og-level-for-graceful-restart-events.patch | 82 +- .../0025-bgp-community-memory-leak-fix.patch | 386 +--- ...re-Zebra-push-back-on-Buffer-Stream-.patch | 25 +- ...ssure-cleanup-bgp_zebra_XX-func-args.patch | 109 +- ...e-Handle-BGP-Zebra-Install-evt-Creat.patch | 246 +-- ...e-Handle-BGP-Zebra-EPVN-Install-evt-.patch | 1692 ++++++++++++++--- ...stall-uninstall-speed-of-evpn-vpn-vn.patch | 75 +- ...e-Fix-to-withdraw-evpn-type-5-routes.patch | 38 +- ...-Use-built-in-data-structure-counter.patch | 50 +- ...w-zebra-dplane-providers-to-give-mor.patch | 34 +- ...e-fix-to-properly-remove-dest-for-bg.patch | 28 +- ...pd-backpressure-Avoid-use-after-free.patch | 27 +- src/sonic-frr/patch/series | 19 - 19 files changed, 1828 insertions(+), 1042 deletions(-) diff --git a/rules/frr.mk b/rules/frr.mk index da42179a0312..d57ed10855dc 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,9 +1,9 @@ # FRRouting (frr) package -FRR_VERSION = 8.5.4 +FRR_VERSION = 10.0.1 FRR_SUBVERSION = 0 -FRR_BRANCH = frr/8.5 -FRR_TAG = frr-8.5.4 +FRR_BRANCH = frr/10.0.1 +FRR_TAG = frr-10.0.1 export FRR_VERSION FRR_SUBVERSION FRR_BRANCH FRR_TAG diff --git a/rules/libyang2.mk b/rules/libyang2.mk index ca6d611b52ee..5cfd31c3a6b4 100644 --- a/rules/libyang2.mk +++ b/rules/libyang2.mk @@ -1,8 +1,8 @@ # libyang2 -LIBYANG2_VERSION_BASE = 2.0 -LIBYANG2_VERSION = $(LIBYANG2_VERSION_BASE).112 -LIBYANG2_SUBVERSION = 6 +LIBYANG2_VERSION_BASE = 2.1 +LIBYANG2_VERSION = $(LIBYANG2_VERSION_BASE).148 +LIBYANG2_SUBVERSION = 0.1 LIBYANG2_FULLVERSION = $(LIBYANG2_VERSION)-$(LIBYANG2_SUBVERSION) export LIBYANG2_VERSION_BASE @@ -10,14 +10,14 @@ export LIBYANG2_VERSION export LIBYANG2_SUBVERSION export LIBYANG2_FULLVERSION -LIBYANG2 = libyang2_$(LIBYANG2_FULLVERSION)_$(CONFIGURED_ARCH).deb +LIBYANG2 = libyang2t64_$(LIBYANG2_FULLVERSION)_$(CONFIGURED_ARCH).deb $(LIBYANG2)_SRC_PATH = $(SRC_PATH)/libyang2 SONIC_MAKE_DEBS += $(LIBYANG2) LIBYANG2_DEV = libyang2-dev_$(LIBYANG2_FULLVERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBYANG2),$(LIBYANG2_DEV))) -LIBYANG2_DBG = libyang2-dbgsym_$(LIBYANG2_FULLVERSION)_$(CONFIGURED_ARCH).deb +LIBYANG2_DBG = libyang2t64-dbgsym_$(LIBYANG2_FULLVERSION)_$(CONFIGURED_ARCH).deb $(eval $(call add_derived_package,$(LIBYANG2),$(LIBYANG2_DBG))) diff --git a/sonic-slave-bookworm/Dockerfile.j2 b/sonic-slave-bookworm/Dockerfile.j2 index 92a15eaf9972..159bbfe3bf87 100644 --- a/sonic-slave-bookworm/Dockerfile.j2 +++ b/sonic-slave-bookworm/Dockerfile.j2 @@ -144,6 +144,8 @@ RUN apt-get update && apt-get install -y eatmydata && eatmydata apt-get install libjson-c-dev \ libsystemd-dev \ libcmocka-dev \ + libprotobuf-c-dev \ + protobuf-c-compiler \ #{%- if CROSS_BUILD_ENVIRON != "y" %} python3-all-dev \ python3-all-dbg \ @@ -750,4 +752,4 @@ RUN mkdir -p /.cargo && $RUST_ROOT/bin/rustup target add armv7-unknown-linux-gnu RUN mkdir -p /.cargo && $RUST_ROOT/bin/rustup target add aarch64-unknown-linux-gnu && echo "[target.aarch64-unknown-linux-gnu]\nlinker = \"aarch64-linux-gnu-gcc\"" >> /.cargo/config.toml {% endif -%} ENV RUSTUP_HOME $RUST_ROOT -ENV PATH $PATH:$RUST_ROOT/bin \ No newline at end of file +ENV PATH $PATH:$RUST_ROOT/bin diff --git a/sonic-slave-bullseye/Dockerfile.j2 b/sonic-slave-bullseye/Dockerfile.j2 index 1aca2a0ba5e3..b1a98863d3fc 100644 --- a/sonic-slave-bullseye/Dockerfile.j2 +++ b/sonic-slave-bullseye/Dockerfile.j2 @@ -148,6 +148,8 @@ RUN apt-get update && apt-get install -y eatmydata && eatmydata apt-get install libsystemd-dev \ python3-ipaddr \ libcmocka-dev \ + libprotobuf-c-dev \ + protobuf-c-compiler \ #{%- if CROSS_BUILD_ENVIRON != "y" %} python3-all-dev \ python3-all-dbg \ diff --git a/src/libyang2/Makefile b/src/libyang2/Makefile index fab24590a340..df338753f593 100644 --- a/src/libyang2/Makefile +++ b/src/libyang2/Makefile @@ -2,10 +2,10 @@ SHELL = /bin/bash .SHELLFLAGS += -e -LIBYANG_URL = https://sonicstorage.blob.core.windows.net/debian/pool/main/liby/libyang +LIBYANG_URL = https://deb.debian.org/debian/pool/main/liby/libyang2 DSC_FILE = libyang2_$(LIBYANG2_FULLVERSION).dsc -ORIG_FILE = libyang2_$(LIBYANG2_VERSION).orig.tar.gz +ORIG_FILE = libyang2_$(LIBYANG2_VERSION).orig.tar.xz DEBIAN_FILE = libyang2_$(LIBYANG2_FULLVERSION).debian.tar.xz DSC_FILE_URL = $(LIBYANG_URL)/$(DSC_FILE) @@ -26,6 +26,9 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% : dpkg-source -x libyang2_$(LIBYANG2_FULLVERSION).dsc pushd libyang2-$(LIBYANG2_VERSION) + #The package libyang2.1.148 is taken from debian trixie, which only has dpkg-dev version 1.21.22 + #The bullseye package has dpkg-dev version 1.20.13 + sed -i 's/dpkg-dev (>= 1.22.5)/dpkg-dev (>= 1.20.13)/' debian/control #sed -i 's/set(LIBYANG_MAJOR_SOVERSION 1)/set(LIBYANG_MAJOR_SOVERSION 2)/' CMakeLists.txt #sed -i 's/libyang2/libyang2/' debian/libyang2.install # Enable large file support for 32-bit arch diff --git a/src/sonic-frr/patch/0008-Use-vrf_id-for-vrf-not-tabled_id.patch b/src/sonic-frr/patch/0008-Use-vrf_id-for-vrf-not-tabled_id.patch index ae8b05f06bd0..a7e6075b1639 100644 --- a/src/sonic-frr/patch/0008-Use-vrf_id-for-vrf-not-tabled_id.patch +++ b/src/sonic-frr/patch/0008-Use-vrf_id-for-vrf-not-tabled_id.patch @@ -1,17 +1,9 @@ -From 44f3736ee601e06e43e978fa075402c3da4823bd Mon Sep 17 00:00:00 2001 -From: Stepan Blyschak -Date: Mon, 16 Jan 2023 11:45:19 +0000 -Subject: [PATCH] From 349e3f758860be0077b69919c39764d3486ec44a Mon Sep 17 - 00:00:00 2001 Subject: [PATCH] use vrf id instead of table id - -Signed-off-by: Stepan Blyschak - diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c -index 325199eff..587045eac 100644 +index b8d097e58..b81a9db6d 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c -@@ -406,6 +406,30 @@ vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) - return VRF_DEFAULT; +@@ -385,6 +385,31 @@ static inline int proto2zebra(int proto, int family, bool is_nexthop) + return proto; } +static uint32_t table_lookup_by_vrf(vrf_id_t vrf_id, ns_id_t ns_id) @@ -37,11 +29,12 @@ index 325199eff..587045eac 100644 + + return RT_TABLE_UNSPEC; +} ++ + /** * @parse_encap_mpls() - Parses encapsulated mpls attributes * @tb: Pointer to rtattr to look for nested items in. -@@ -782,14 +806,26 @@ int netlink_route_change_read_unicast_internal(struct nlmsghdr *h, +@@ -817,14 +842,26 @@ int netlink_route_change_read_unicast_internal(struct nlmsghdr *h, if (rtm->rtm_family == AF_MPLS) return 0; @@ -58,7 +51,7 @@ index 325199eff..587045eac 100644 + table = rtm->rtm_table; + + /* Map to VRF */ -+ vrf_id = vrf_lookup_by_table(table, ns_id); ++ vrf_id = zebra_vrf_lookup_by_table(table, ns_id); + } else { + /* With FPM, rtm_table contains vrf id, see netlink_route_multipath_msg_encode */ + if (tb[RTA_TABLE]) @@ -71,11 +64,11 @@ index 325199eff..587045eac 100644 + } - /* Map to VRF */ -- vrf_id = vrf_lookup_by_table(table, ns_id); +- vrf_id = zebra_vrf_lookup_by_table(table, ns_id); if (vrf_id == VRF_DEFAULT) { if (!is_zebra_valid_kernel_table(table) && !is_zebra_main_routing_table(table)) -@@ -2102,12 +2138,24 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, +@@ -2283,13 +2320,25 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, struct zebra_dplane_ctx *ctx /* Table corresponding to this route. */ table_id = dplane_ctx_get_table(ctx); @@ -85,6 +78,7 @@ index 325199eff..587045eac 100644 - req->r.rtm_table = RT_TABLE_UNSPEC; - if (!nl_attr_put32(&req->n, datalen, RTA_TABLE, table_id)) - return 0; +- } + if (!fpm) { + if (table_id < 256) + req->r.rtm_table = table_id; @@ -103,9 +97,7 @@ index 325199eff..587045eac 100644 + if (!nl_attr_put32(&req->n, datalen, RTA_TABLE, vrf)) + return 0; + } - } ++ } if (IS_ZEBRA_DEBUG_KERNEL) --- -2.17.1 - + zlog_debug( diff --git a/src/sonic-frr/patch/0010-bgpd-Change-log-level-for-graceful-restart-events.patch b/src/sonic-frr/patch/0010-bgpd-Change-log-level-for-graceful-restart-events.patch index 54fcc1575a75..dfd5d958410e 100644 --- a/src/sonic-frr/patch/0010-bgpd-Change-log-level-for-graceful-restart-events.patch +++ b/src/sonic-frr/patch/0010-bgpd-Change-log-level-for-graceful-restart-events.patch @@ -1,32 +1,23 @@ -From a05f213343ee7ee5dbfcfd1984c40db5c262db3c Mon Sep 17 00:00:00 2001 -From: stormliang -Date: Mon, 19 Jun 2023 13:57:01 +0000 -Subject: [PATCH] From c423bce4db804c1d07d65ce3d06a9e62c4eceb2b Mon Sep 17 - 00:00:00 2001 Subject: [PATCH] change log level for graceful restart events - - diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c -index 9624adfbe..74b4dfc4a 100644 +index 504343994..f58ab7c02 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c -@@ -778,10 +778,10 @@ static void bgp_graceful_restart_timer_expire(struct thread *thread) - - peer = THREAD_ARG(thread); +@@ -739,9 +739,9 @@ static void bgp_graceful_restart_timer_expire(struct event *thread) + afi_t afi; + safi_t safi; - if (bgp_debug_neighbor_events(peer)) { - zlog_debug("%pBP graceful restart timer expired", peer); - zlog_debug("%pBP graceful restart stalepath timer stopped", -- peer); + if (peer) { + zlog_info("%pBP graceful restart timer expired", peer); + zlog_info("%pBP graceful restart stalepath timer stopped", -+ peer); + peer); } - FOREACH_AFI_SAFI (afi, safi) { -@@ -842,8 +842,8 @@ static void bgp_graceful_stale_timer_expire(struct thread *thread) - - peer = THREAD_ARG(thread); +@@ -801,8 +801,8 @@ static void bgp_graceful_stale_timer_expire(struct event *thread) + afi_t afi; + safi_t safi; - if (bgp_debug_neighbor_events(peer)) - zlog_debug("%pBP graceful restart stalepath timer expired", @@ -35,17 +26,15 @@ index 9624adfbe..74b4dfc4a 100644 peer); /* NSF delete stale route */ -@@ -1412,20 +1412,17 @@ enum bgp_fsm_state_progress bgp_stop(struct peer *peer) +@@ -1380,20 +1380,17 @@ enum bgp_fsm_state_progress bgp_stop(struct peer_connection *connection) /* graceful restart */ - if (peer->t_gr_stale) { - THREAD_OFF(peer->t_gr_stale); + if (connection->t_gr_stale) { + EVENT_OFF(connection->t_gr_stale); - if (bgp_debug_neighbor_events(peer)) - zlog_debug( -- "%pBP graceful restart stalepath timer stopped", -- peer); -+ zlog_info( -+ "%pBP graceful restart stalepath timer stopped", -+ peer); ++ zlog_info( + "%pBP graceful restart stalepath timer stopped", + peer); } if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) { - if (bgp_debug_neighbor_events(peer)) { @@ -62,25 +51,23 @@ index 9624adfbe..74b4dfc4a 100644 + zlog_info( + "%pBP graceful restart stalepath timer started for %d sec", + peer, peer->bgp->stalepath_time); - BGP_TIMER_ON(peer->t_gr_restart, + BGP_TIMER_ON(connection->t_gr_restart, bgp_graceful_restart_timer_expire, peer->v_gr_restart); -@@ -2225,17 +2222,15 @@ static enum bgp_fsm_state_progress bgp_establish(struct peer *peer) +@@ -2216,8 +2213,7 @@ bgp_establish(struct peer_connection *connection) UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE); - if (peer->t_gr_stale) { - THREAD_OFF(peer->t_gr_stale); + if (connection->t_gr_stale) { + EVENT_OFF(connection->t_gr_stale); - if (bgp_debug_neighbor_events(peer)) - zlog_debug( -- "%pBP graceful restart stalepath timer stopped", -- peer); + zlog_info( -+ "%pBP graceful restart stalepath timer stopped", -+ peer); + "%pBP graceful restart stalepath timer stopped", + peer); } - } +@@ -2225,8 +2221,7 @@ bgp_establish(struct peer_connection *connection) - if (peer->t_gr_restart) { - THREAD_OFF(peer->t_gr_restart); + if (connection->t_gr_restart) { + EVENT_OFF(connection->t_gr_restart); - if (bgp_debug_neighbor_events(peer)) - zlog_debug("%pBP graceful restart timer stopped", peer); + zlog_info("%pBP graceful restart timer stopped", peer); @@ -88,29 +75,22 @@ index 9624adfbe..74b4dfc4a 100644 /* Reset uptime, turn on keepalives, send current table. */ diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 8b3a1e3dd..2f3b837a5 100644 +index d6d874be2..337879a2d 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c -@@ -2453,15 +2453,13 @@ void peer_nsf_stop(struct peer *peer) +@@ -2629,13 +2629,11 @@ void peer_nsf_stop(struct peer *peer) - if (peer->t_gr_restart) { - THREAD_OFF(peer->t_gr_restart); + if (peer->connection->t_gr_restart) { + EVENT_OFF(peer->connection->t_gr_restart); - if (bgp_debug_neighbor_events(peer)) - zlog_debug("%pBP graceful restart timer stopped", peer); + zlog_info("%pBP graceful restart timer stopped", peer); } - if (peer->t_gr_stale) { - THREAD_OFF(peer->t_gr_stale); + if (peer->connection->t_gr_stale) { + EVENT_OFF(peer->connection->t_gr_stale); - if (bgp_debug_neighbor_events(peer)) - zlog_debug( -- "%pBP graceful restart stalepath timer stopped", -- peer); + zlog_info( -+ "%pBP graceful restart stalepath timer stopped", -+ peer); + "%pBP graceful restart stalepath timer stopped", + peer); } - bgp_clear_route_all(peer); - } --- -2.17.1 - diff --git a/src/sonic-frr/patch/0025-bgp-community-memory-leak-fix.patch b/src/sonic-frr/patch/0025-bgp-community-memory-leak-fix.patch index f8215e07f0f8..cf2d8453a36f 100644 --- a/src/sonic-frr/patch/0025-bgp-community-memory-leak-fix.patch +++ b/src/sonic-frr/patch/0025-bgp-community-memory-leak-fix.patch @@ -1,186 +1,8 @@ -From 92323cf4b506c40376be74e955836da30980ae54 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Wed, 13 Mar 2024 10:26:58 -0400 -Subject: [PATCH 1/3] bgpd: Ensure that the correct aspath is free'd - -Currently in subgroup_default_originate the attr.aspath -is set in bgp_attr_default_set, which hashs the aspath -and creates a refcount for it. If this is a withdraw -the subgroup_announce_check and bgp_adj_out_set_subgroup -is called which will intern the attribute. This will -cause the the attr.aspath to be set to a new value -finally at the bottom of the function it intentionally -uninterns the aspath which is not the one that was -created for this function. This reduces the other -aspath's refcount by 1 and if a clear bgp * is issued -fast enough the aspath for that will be removed -and the system will crash. - -Signed-off-by: Donald Sharp ---- - bgpd/bgp_updgrp_adv.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c -index de2b3206b7..dcde4263da 100644 ---- a/bgpd/bgp_updgrp_adv.c -+++ b/bgpd/bgp_updgrp_adv.c -@@ -813,6 +813,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) - struct bgp *bgp; - struct attr attr; - struct attr *new_attr = &attr; -+ struct aspath *aspath; - struct prefix p; - struct peer *from; - struct bgp_dest *dest; -@@ -850,6 +851,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) - /* make coverity happy */ - assert(attr.aspath); - -+ aspath = attr.aspath; - attr.med = 0; - attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); - -@@ -1005,7 +1007,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) - } - } - -- aspath_unintern(&attr.aspath); -+ aspath_unintern(&aspath); - } - - /* --- -2.14.1 - - -From 07545c1879775f155f228c81393eed9697b699de Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Sat, 2 Mar 2024 09:42:30 -0500 -Subject: [PATCH 2/3] bgpd: Include unsuppress-map as a valid outgoing policy - -If unsuppress-map is setup for outgoing peers, consider that -policy is being applied as for RFC 8212. - -Signed-off-by: Donald Sharp ---- - bgpd/bgp_route.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index 473168d9be..fb14fc7f20 100644 ---- a/bgpd/bgp_route.c -+++ b/bgpd/bgp_route.c -@@ -5816,10 +5816,10 @@ bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter) - if (peer->sort == BGP_PEER_IBGP) - return true; - -- if (peer->sort == BGP_PEER_EBGP -- && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter) -- || FILTER_LIST_OUT_NAME(filter) -- || DISTRIBUTE_OUT_NAME(filter))) -+ if (peer->sort == BGP_PEER_EBGP && -+ (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter) || -+ FILTER_LIST_OUT_NAME(filter) || DISTRIBUTE_OUT_NAME(filter) || -+ UNSUPPRESS_MAP_NAME(filter))) - return true; - return false; - } --- -2.14.1 - - -From e3493d5be0156fa9c8c522b818ae6448dbe371f2 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Sat, 2 Mar 2024 09:50:38 -0500 -Subject: [PATCH 3/3] bgpd: Ensure community data is freed in some cases. - -Customer has this valgrind trace: - -Direct leak of 2829120 byte(s) in 70728 object(s) allocated from: - 0 in community_new ../bgpd/bgp_community.c:39 - 1 in community_uniq_sort ../bgpd/bgp_community.c:170 - 2 in route_set_community ../bgpd/bgp_routemap.c:2342 - 3 in route_map_apply_ext ../lib/routemap.c:2673 - 4 in subgroup_announce_check ../bgpd/bgp_route.c:2367 - 5 in subgroup_process_announce_selected ../bgpd/bgp_route.c:2914 - 6 in group_announce_route_walkcb ../bgpd/bgp_updgrp_adv.c:199 - 7 in hash_walk ../lib/hash.c:285 - 8 in update_group_af_walk ../bgpd/bgp_updgrp.c:2061 - 9 in group_announce_route ../bgpd/bgp_updgrp_adv.c:1059 - 10 in bgp_process_main_one ../bgpd/bgp_route.c:3221 - 11 in bgp_process_wq ../bgpd/bgp_route.c:3221 - 12 in work_queue_run ../lib/workqueue.c:282 - -The above leak detected by valgrind was from a screenshot so I copied it -by hand. Any mistakes in line numbers are purely from my transcription. -Additionally this is against a slightly modified 8.5.1 version of FRR. -Code inspection of 8.5.1 -vs- latest master shows the same problem -exists. Code should be able to be followed from there to here. - -What is happening: - -There is a route-map being applied that modifes the outgoing community -to a peer. This is saved in the attr copy created in -subgroup_process_announce_selected. This community pointer is not -interned. So the community->refcount is still 0. Normally when -a prefix is announced, the attr and the prefix are placed on a -adjency out structure where the attribute is interned. This will -cause the community to be saved in the community hash list as well. -In a non-normal operation when the decision to send is aborted after -the route-map application, the attribute is just dropped and the -pointer to the community is just dropped too, leading to situations -where the memory is leaked. The usage of bgp suppress-fib would -would be a case where the community is caused to be leaked. -Additionally the previous commit where an unsuppress-map is used -to modify the outgoing attribute but since unsuppress-map was -not considered part of outgoing policy the attribute would be dropped as -well. This pointer drop also extends to any dynamically allocated -memory saved by the attribute pointer that was not interned yet as well. - -So let's modify the return case where the decision is made to -not send the prefix to the peer to always just flush the attribute -to ensure memory is not leaked. - -Fixes: #15459 -Signed-off-by: Donald Sharp ---- - bgpd/bgp_conditional_adv.c | 5 ++-- - bgpd/bgp_route.c | 30 +++++++++++++----------- - bgpd/bgp_updgrp.h | 2 +- - bgpd/bgp_updgrp_adv.c | 58 +++++++++++++++++++++++++--------------------- - 4 files changed, 51 insertions(+), 44 deletions(-) - -diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c -index 24d822a745..edb9bc8bb7 100644 ---- a/bgpd/bgp_conditional_adv.c -+++ b/bgpd/bgp_conditional_adv.c -@@ -135,8 +135,9 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi, - if (update_type == UPDATE_TYPE_ADVERTISE && - subgroup_announce_check(dest, pi, subgrp, dest_p, - &attr, &advmap_attr)) { -- bgp_adj_out_set_subgroup(dest, subgrp, &attr, -- pi); -+ if (!bgp_adj_out_set_subgroup(dest, subgrp, -+ &attr, pi)) -+ bgp_attr_flush(&attr); - } else { - /* If default originate is enabled for - * the peer, do not send explicit diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index fb14fc7f20..2976042dda 100644 +index fc776a4fd..a0113c04e 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c -@@ -2879,7 +2879,7 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, - { - const struct prefix *p; - struct peer *onlypeer; -- struct attr attr; -+ struct attr attr = {0}, *pattr = &attr; - afi_t afi; - safi_t safi; - struct bgp *bgp; -@@ -2900,7 +2900,7 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, +@@ -3012,7 +3012,7 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, PEER_STATUS_ORF_WAIT_REFRESH)) return; @@ -189,207 +11,3 @@ index fb14fc7f20..2976042dda 100644 /* It's initialized in bgp_announce_check() */ /* Announcement to the subgroup. If the route is filtered withdraw it. -@@ -2911,32 +2911,34 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, - advertise = bgp_check_advertise(bgp, dest); - - if (selected) { -- if (subgroup_announce_check(dest, selected, subgrp, p, &attr, -+ if (subgroup_announce_check(dest, selected, subgrp, p, pattr, - NULL)) { - /* Route is selected, if the route is already installed - * in FIB, then it is advertised - */ - if (advertise) { - if (!bgp_check_withdrawal(bgp, dest)) { -- struct attr *adv_attr = -- bgp_attr_intern(&attr); -- -- bgp_adj_out_set_subgroup(dest, subgrp, -- adv_attr, -- selected); -- } else -+ if (!bgp_adj_out_set_subgroup( -+ dest, subgrp, pattr, -+ selected)) -+ bgp_attr_flush(pattr); -+ } else { - bgp_adj_out_unset_subgroup( - dest, subgrp, 1, addpath_tx_id); -- } -- } else -+ bgp_attr_flush(pattr); -+ } -+ } else -+ bgp_attr_flush(pattr); -+ } else { - bgp_adj_out_unset_subgroup(dest, subgrp, 1, - addpath_tx_id); -+ bgp_attr_flush(pattr); -+ } - } - - /* If selected is NULL we must withdraw the path using addpath_tx_id */ -- else { -+ else - bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id); -- } - } - - /* -diff --git a/bgpd/bgp_updgrp.h b/bgpd/bgp_updgrp.h -index e27c1e7b67..b7b6aa07e9 100644 ---- a/bgpd/bgp_updgrp.h -+++ b/bgpd/bgp_updgrp.h -@@ -458,7 +458,7 @@ extern struct bgp_adj_out *bgp_adj_out_alloc(struct update_subgroup *subgrp, - extern void bgp_adj_out_remove_subgroup(struct bgp_dest *dest, - struct bgp_adj_out *adj, - struct update_subgroup *subgrp); --extern void bgp_adj_out_set_subgroup(struct bgp_dest *dest, -+extern bool bgp_adj_out_set_subgroup(struct bgp_dest *dest, - struct update_subgroup *subgrp, - struct attr *attr, - struct bgp_path_info *path); -diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c -index dcde4263da..7902d40bd9 100644 ---- a/bgpd/bgp_updgrp_adv.c -+++ b/bgpd/bgp_updgrp_adv.c -@@ -454,7 +454,7 @@ bgp_advertise_clean_subgroup(struct update_subgroup *subgrp, - return next; - } - --void bgp_adj_out_set_subgroup(struct bgp_dest *dest, -+bool bgp_adj_out_set_subgroup(struct bgp_dest *dest, - struct update_subgroup *subgrp, struct attr *attr, - struct bgp_path_info *path) - { -@@ -474,7 +474,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, - bgp = SUBGRP_INST(subgrp); - - if (DISABLE_BGP_ANNOUNCE) -- return; -+ return false; - - /* Look for adjacency information. */ - adj = adj_lookup( -@@ -490,7 +490,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, - bgp_addpath_id_for_peer(peer, afi, safi, - &path->tx_addpath)); - if (!adj) -- return; -+ return false; - - subgrp->pscount++; - } -@@ -529,7 +529,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, - * will never be able to coalesce the 3rd peer down - */ - subgrp->version = MAX(subgrp->version, dest->version); -- return; -+ return false; - } - - if (adj->adv) -@@ -576,6 +576,8 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, - bgp_adv_fifo_add_tail(&subgrp->sync->update, adv); - - subgrp->version = MAX(subgrp->version, dest->version); -+ -+ return true; - } - - /* The only time 'withdraw' will be false is if we are sending -@@ -668,7 +670,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp, - { - struct bgp_dest *dest; - struct bgp_path_info *ri; -- struct attr attr; -+ struct attr attr = {0}, *pattr = &attr; - struct peer *peer; - afi_t afi; - safi_t safi; -@@ -712,24 +714,25 @@ void subgroup_announce_table(struct update_subgroup *subgrp, - continue; - - if (subgroup_announce_check(dest, ri, subgrp, dest_p, -- &attr, NULL)) { -+ pattr, NULL)) { - /* Check if route can be advertised */ - if (advertise) { - if (!bgp_check_withdrawal(bgp, dest)) { -- struct attr *adv_attr = -- bgp_attr_intern(&attr); -- -- bgp_adj_out_set_subgroup( -- dest, subgrp, adv_attr, -- ri); -- } else -+ if (!bgp_adj_out_set_subgroup( -+ dest, subgrp, pattr, -+ ri)) -+ bgp_attr_flush(pattr); -+ } else { - bgp_adj_out_unset_subgroup( - dest, subgrp, 1, - bgp_addpath_id_for_peer( - peer, afi, - safi_rib, - &ri->tx_addpath)); -- } -+ bgp_attr_flush(pattr); -+ } -+ } else -+ bgp_attr_flush(pattr); - } else { - /* If default originate is enabled for - * the peer, do not send explicit -@@ -748,6 +751,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp, - bgp_addpath_id_for_peer( - peer, afi, safi_rib, - &ri->tx_addpath)); -+ bgp_attr_flush(pattr); - } - } - } -@@ -811,7 +815,7 @@ void subgroup_announce_route(struct update_subgroup *subgrp) - void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) - { - struct bgp *bgp; -- struct attr attr; -+ struct attr attr = {0}; - struct attr *new_attr = &attr; - struct aspath *aspath; - struct prefix p; -@@ -952,18 +956,18 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) - if (dest) { - for (pi = bgp_dest_get_bgp_path_info(dest); pi; - pi = pi->next) { -- if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) -- if (subgroup_announce_check( -- dest, pi, subgrp, -- bgp_dest_get_prefix(dest), -- &attr, NULL)) { -- struct attr *default_attr = -- bgp_attr_intern(&attr); -- -- bgp_adj_out_set_subgroup( -- dest, subgrp, -- default_attr, pi); -- } -+ if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) -+ continue; -+ -+ if (subgroup_announce_check( -+ dest, pi, subgrp, -+ bgp_dest_get_prefix(dest), &attr, -+ NULL)) { -+ if (!bgp_adj_out_set_subgroup( -+ dest, subgrp, &attr, pi)) -+ bgp_attr_flush(&attr); -+ } else -+ bgp_attr_flush(&attr); - } - bgp_dest_unlock_node(dest); - } --- -2.14.1 - diff --git a/src/sonic-frr/patch/0030-zebra-backpressure-Zebra-push-back-on-Buffer-Stream-.patch b/src/sonic-frr/patch/0030-zebra-backpressure-Zebra-push-back-on-Buffer-Stream-.patch index 0bebd1ea12ba..21e8a74cd5df 100644 --- a/src/sonic-frr/patch/0030-zebra-backpressure-Zebra-push-back-on-Buffer-Stream-.patch +++ b/src/sonic-frr/patch/0030-zebra-backpressure-Zebra-push-back-on-Buffer-Stream-.patch @@ -50,10 +50,10 @@ Signed-off-by: Donald Sharp Signed-off-by: Rajasekar Raja diff --git a/zebra/zserv.c b/zebra/zserv.c -index 2024f34534..de6e404fc4 100644 +index 6a64176d9..488712397 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c -@@ -318,6 +318,14 @@ zwrite_fail: +@@ -306,6 +306,14 @@ zwrite_fail: * this task reschedules itself. * * Any failure in any of these actions is handled by terminating the client. @@ -66,9 +66,9 @@ index 2024f34534..de6e404fc4 100644 + * The main thread processes the items in ibuf_fifo and always signals the + * client IO thread. */ - static void zserv_read(struct thread *thread) + static void zserv_read(struct event *thread) { -@@ -325,15 +333,25 @@ static void zserv_read(struct thread *thread) +@@ -313,16 +321,26 @@ static void zserv_read(struct event *thread) int sock; size_t already; struct stream_fifo *cache; @@ -95,10 +95,12 @@ index 2024f34534..de6e404fc4 100644 + p2p = p2p_avail; cache = stream_fifo_new(); - p2p = p2p_orig; - sock = THREAD_FD(thread); +- sock = EVENT_FD(thread); ++ sock = EVENT_FD(thread); while (p2p) { -@@ -433,7 +451,7 @@ static void zserv_read(struct thread *thread) + ssize_t nb; +@@ -421,7 +439,7 @@ static void zserv_read(struct event *thread) p2p--; } @@ -107,7 +109,7 @@ index 2024f34534..de6e404fc4 100644 uint64_t time_now = monotime(NULL); /* update session statistics */ -@@ -447,19 +465,23 @@ static void zserv_read(struct thread *thread) +@@ -435,19 +453,23 @@ static void zserv_read(struct event *thread) while (cache->head) stream_fifo_push(client->ibuf_fifo, stream_fifo_pop(cache)); @@ -136,7 +138,7 @@ index 2024f34534..de6e404fc4 100644 stream_fifo_free(cache); -@@ -495,14 +517,20 @@ static void zserv_client_event(struct zserv *client, +@@ -483,14 +505,20 @@ static void zserv_client_event(struct zserv *client, * as the task argument. * * Each message is popped off the client's input queue and the action associated @@ -157,9 +159,9 @@ index 2024f34534..de6e404fc4 100644 + * items to the ibuf_fifo (until max limit) + * - the hidden config change (zebra zapi-packets <>) is taken into account. */ - static void zserv_process_messages(struct thread *thread) + static void zserv_process_messages(struct event *thread) { -@@ -538,6 +566,9 @@ static void zserv_process_messages(struct thread *thread) +@@ -524,6 +552,9 @@ static void zserv_process_messages(struct event *thread) /* Reschedule ourselves if necessary */ if (need_resched) zserv_event(client, ZSERV_PROCESS_MESSAGES); @@ -169,6 +171,3 @@ index 2024f34534..de6e404fc4 100644 } int zserv_send_message(struct zserv *client, struct stream *msg) --- -2.17.1 - diff --git a/src/sonic-frr/patch/0033-bgpd-backpressure-cleanup-bgp_zebra_XX-func-args.patch b/src/sonic-frr/patch/0033-bgpd-backpressure-cleanup-bgp_zebra_XX-func-args.patch index 16383dc95caa..9a4b689f7b48 100644 --- a/src/sonic-frr/patch/0033-bgpd-backpressure-cleanup-bgp_zebra_XX-func-args.patch +++ b/src/sonic-frr/patch/0033-bgpd-backpressure-cleanup-bgp_zebra_XX-func-args.patch @@ -1,7 +1,10 @@ -From 679ad9ee5f3c15570d697506183d37aa29f6ebf2 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Thu, 25 Jan 2024 13:07:37 -0500 -Subject: [PATCH 05/11] bgpd: backpressure - cleanup bgp_zebra_XX func args +From 0e22b69dc1809e00e547e47ab236ff1cc636a0aa Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Mon, 16 Sep 2024 01:50:39 -0700 +Subject: [PATCH] Date: Fri, 13 Sep 2024 09:36:37 +0000 Subject: [PATCH] From + 679ad9ee5f3c15570d697506183d37aa29f6ebf2 Mon Sep 17 00:00:00 2001 From: + Donald Sharp Date: Thu, 25 Jan 2024 13:07:37 -0500 + Subject: [PATCH 05/11] bgpd: backpressure - cleanup bgp_zebra_XX func args Since installing/withdrawing routes into zebra is going to be changed around to be dest based in a list, @@ -13,12 +16,22 @@ Ticket: #3390099 Signed-off-by: Donald Sharp Signed-off-by: Rajasekar Raja +--- + bgpd/bgp_route.c | 17 +++++++---------- + bgpd/bgp_zebra.c | 41 +++++++++++++++++++---------------------- + bgpd/bgp_zebra.h | 11 +++++------ + 3 files changed, 31 insertions(+), 38 deletions(-) +--- + bgpd/bgp_route.c | 17 +++++++---------- + bgpd/bgp_zebra.c | 45 +++++++++++++++++++++------------------------ + bgpd/bgp_zebra.h | 11 +++++------ + 3 files changed, 33 insertions(+), 40 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index 455cd6cdbb..d19f27110e 100644 +index a0113c04e..99fb021b1 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c -@@ -3214,8 +3214,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3419,8 +3419,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, || new_select->sub_type == BGP_ROUTE_IMPORTED)) @@ -29,7 +42,7 @@ index 455cd6cdbb..d19f27110e 100644 } } -@@ -3312,10 +3312,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3529,10 +3529,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, */ if (old_select && is_route_parent_evpn(old_select)) @@ -42,7 +55,7 @@ index 455cd6cdbb..d19f27110e 100644 } else { /* Withdraw the route from the kernel. */ if (old_select && old_select->type == ZEBRA_ROUTE_BGP -@@ -3323,8 +3322,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3540,8 +3539,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, || old_select->sub_type == BGP_ROUTE_AGGREGATE || old_select->sub_type == BGP_ROUTE_IMPORTED)) @@ -52,7 +65,7 @@ index 455cd6cdbb..d19f27110e 100644 } } -@@ -4203,7 +4201,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, +@@ -4446,7 +4444,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) { if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) /* remove from RIB previous entry */ @@ -61,7 +74,7 @@ index 455cd6cdbb..d19f27110e 100644 } if (peer->sort == BGP_PEER_EBGP) { -@@ -5867,8 +5865,7 @@ static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table, +@@ -6072,8 +6070,7 @@ static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table, || pi->sub_type == BGP_ROUTE_IMPORTED)) { if (bgp_fibupd_safi(safi)) @@ -70,33 +83,33 @@ index 455cd6cdbb..d19f27110e 100644 + bgp_zebra_withdraw(dest, pi, bgp); } - bgp_path_info_reap(dest, pi); + dest = bgp_path_info_reap(dest, pi); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c -index 69240a3b83..920df835a4 100644 +index fe29662e2..43447d528 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c -@@ -1292,9 +1292,8 @@ static bool bgp_zebra_use_nhop_weighted(struct bgp *bgp, struct attr *attr, - return true; +@@ -1507,9 +1507,8 @@ static void bgp_debug_zebra_nh(struct zapi_route *api) + } } -void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, - struct bgp_path_info *info, struct bgp *bgp, afi_t afi, - safi_t safi) -+void bgp_zebra_announce(struct bgp_dest *dest, struct bgp_path_info *info, ++void bgp_zebra_announce(struct bgp_dest *dest, struct bgp_path_info *info, + struct bgp *bgp) { + struct bgp_path_info *bpi_ultimate; struct zapi_route api = { 0 }; - struct zapi_nexthop *api_nh; -@@ -1321,6 +1320,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, - uint32_t ttl = 0; - uint32_t bos = 0; - uint32_t exp = 0; +@@ -1522,6 +1521,8 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, + bool is_add; + uint32_t nhg_id = 0; + uint32_t recursion_flag = 0; + struct bgp_table *table = bgp_dest_table(dest); + const struct prefix *p = bgp_dest_get_prefix(dest); /* * BGP is installing this route and bgp has been configured -@@ -1339,9 +1340,9 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, +@@ -1540,16 +1541,16 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, if (bgp->main_zebra_update_hold) return; @@ -105,11 +118,11 @@ index 69240a3b83..920df835a4 100644 - safi, true); + if (table->safi == SAFI_FLOWSPEC) { + bgp_pbr_update_entry(bgp, p, info, table->afi, table->safi, -+ true); ++ true); return; - } +- } ++ } -@@ -1354,7 +1355,7 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, /* Make Zebra API structure. */ api.vrf_id = bgp->vrf_id; api.type = ZEBRA_ROUTE_BGP; @@ -118,23 +131,16 @@ index 69240a3b83..920df835a4 100644 api.prefix = *p; SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP); -@@ -1458,12 +1459,13 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, - } - } +@@ -1586,7 +1587,7 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, + metric = info->attr->med; + + bgp_zebra_announce_parse_nexthop(info, p, bgp, &api, &valid_nh_count, +- afi, safi, &nhg_id, &metric, &tag, ++ table->afi, table->safi, &nhg_id, &metric, &tag, + &allow_recursion); -- if (bgp->table_map[afi][safi].name) { -+ if (bgp->table_map[table->afi][table->safi].name) { - /* Copy info and attributes, so the route-map - apply doesn't modify the BGP route info. */ - local_attr = *mpinfo->attr; - mpinfo_cp->attr = &local_attr; -- if (!bgp_table_map_apply(bgp->table_map[afi][safi].map, -+ if (!bgp_table_map_apply(bgp->table_map[table->afi] -+ [table->safi].map, - p, mpinfo_cp)) - continue; - -@@ -1619,7 +1621,7 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, + is_add = (valid_nh_count || nhg_id) ? true : false; +@@ -1640,7 +1641,7 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, api.tag = tag; } @@ -143,7 +149,7 @@ index 69240a3b83..920df835a4 100644 if (distance) { SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE); api.distance = distance; -@@ -1731,9 +1733,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi) +@@ -1689,9 +1690,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi) && (pi->sub_type == BGP_ROUTE_NORMAL || pi->sub_type == BGP_ROUTE_IMPORTED))) @@ -154,7 +160,7 @@ index 69240a3b83..920df835a4 100644 } /* Announce routes of any bgp subtype of a table to zebra */ -@@ -1755,16 +1755,16 @@ void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, +@@ -1713,17 +1712,16 @@ void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) && pi->type == ZEBRA_ROUTE_BGP) @@ -171,12 +177,13 @@ index 69240a3b83..920df835a4 100644 { struct zapi_route api; struct peer *peer; +- + struct bgp_table *table = bgp_dest_table(dest); + const struct prefix *p = bgp_dest_get_prefix(dest); - /* * If we are withdrawing the route, we don't need to have this -@@ -1778,16 +1778,17 @@ void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info, + * flag set. So unset it. +@@ -1736,16 +1734,16 @@ void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info, if (!bgp_install_info_to_zebra(bgp)) return; @@ -184,8 +191,7 @@ index 69240a3b83..920df835a4 100644 + if (table->safi == SAFI_FLOWSPEC) { peer = info->peer; - bgp_pbr_update_entry(peer->bgp, p, info, afi, safi, false); -+ bgp_pbr_update_entry(peer->bgp, p, info, table->afi, -+ table->safi, false); ++ bgp_pbr_update_entry(peer->bgp, p, info, table->afi, table->safi, false); return; } @@ -197,7 +203,7 @@ index 69240a3b83..920df835a4 100644 api.prefix = *p; if (info->attr->rmap_table_id) { -@@ -1820,8 +1821,7 @@ void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t sa +@@ -1778,8 +1776,7 @@ void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t sa for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) && (pi->type == ZEBRA_ROUTE_BGP)) @@ -208,11 +214,11 @@ index 69240a3b83..920df835a4 100644 } } diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h -index a5fe8d7ace..b77e423f8f 100644 +index 396c8335f..61a49bfa5 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h -@@ -43,13 +43,11 @@ extern void bgp_zebra_destroy(void); - extern int bgp_zebra_get_table_range(uint32_t chunk_size, +@@ -28,13 +28,12 @@ extern void bgp_zebra_destroy(void); + extern int bgp_zebra_get_table_range(struct zclient *zc, uint32_t chunk_size, uint32_t *start, uint32_t *end); extern int bgp_if_update_all(void); -extern void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, @@ -220,6 +226,7 @@ index a5fe8d7ace..b77e423f8f 100644 - afi_t afi, safi_t safi); +extern void bgp_zebra_announce(struct bgp_dest *dest, + struct bgp_path_info *path, struct bgp *bgp); ++ extern void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi); -extern void bgp_zebra_withdraw(const struct prefix *p, - struct bgp_path_info *path, struct bgp *bgp, @@ -230,5 +237,5 @@ index a5fe8d7ace..b77e423f8f 100644 /* Announce routes of any bgp subtype of a table to zebra */ extern void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, -- -2.17.1 +This is a reformatted patch. The original creators are mentioned below. diff --git a/src/sonic-frr/patch/0034-gpd-backpressure-Handle-BGP-Zebra-Install-evt-Creat.patch b/src/sonic-frr/patch/0034-gpd-backpressure-Handle-BGP-Zebra-Install-evt-Creat.patch index 724cf1297a59..24dabbe30b3f 100644 --- a/src/sonic-frr/patch/0034-gpd-backpressure-Handle-BGP-Zebra-Install-evt-Creat.patch +++ b/src/sonic-frr/patch/0034-gpd-backpressure-Handle-BGP-Zebra-Install-evt-Creat.patch @@ -1,81 +1,69 @@ -From 6d5604a9315801e9380c11357d663ad6537ed8ab Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Fri, 26 Jan 2024 14:48:53 -0500 -Subject: [PATCH 06/11] bgpd : backpressure - Handle BGP-Zebra Install evt - Creation +From fd84bcf260ef2c1c5ef21ee2700ab8a39a70d5b8 Mon Sep 17 00:00:00 2001 +From: sk408845 +Date: Mon, 16 Sep 2024 12:43:49 +0000 +Subject: [PATCH] Update changelog for 10.0.1-sonic-0 release -BGP is now keeping a list of dests with the dest having a pointer -to the bgp_path_info that it will be working on. - -1) When bgp receives a prefix, process it, add the bgp_dest of the -prefix into the new Fifo list if not present, update the flags (Ex: -earlier if the prefix was advertised and now it is a withdrawn), -increment the ref_count and DO NOT advertise the install/withdraw -to zebra yet. - -2) Schedule an event to wake up to invoke the new function which will -walk the list one by one and installs/withdraws the routes into zebra. - a) if BUFFER_EMPTY, process the next item on the list - b) if BUFFER_PENDING, bail out and the callback in - zclient_flush_data() will invoke the same function when BUFFER_EMPTY - -Changes - - rename old bgp_zebra_announce to bgp_zebra_announce_actual - - rename old bgp_zebra_withdrw to bgp_zebra_withdraw_actual - - Handle new fifo list cleanup in bgp_exit() - - New funcs: bgp_handle_route_announcements_to_zebra() and - bgp_zebra_route_install() - - Define a callback function to invoke - bgp_handle_route_announcements_to_zebra() when BUFFER_EMPTY in - zclient_flush_data() - -The current change deals with bgp installing routes via -bgp_process_main_one() - -Ticket: #3390099 - -Signed-off-by: Donald Sharp -Signed-off-by: Rajasekar Raja +--- + bgpd/bgp_main.c | 2 + + bgpd/bgp_route.c | 14 +-- + bgpd/bgp_table.h | 7 ++ + bgpd/bgp_zebra.c | 219 ++++++++++++++++++++++++++++++++++++++--------- + bgpd/bgp_zebra.h | 10 ++- + bgpd/bgpd.c | 14 +++ + bgpd/bgpd.h | 7 ++ + lib/zclient.c | 1 + + 9 files changed, 226 insertions(+), 51 deletions(-) +diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c +index 851c4880c..44d5ee68c 100644 +--- a/bgpd/bgp_main.c ++++ b/bgpd/bgp_main.c +@@ -207,6 +207,8 @@ static __attribute__((__noreturn__)) void bgp_exit(int status) + bgp_evpn_mh_finish(); + bgp_nhg_finish(); + ++ zebra_announce_fini(&bm->zebra_announce_head); ++ + /* reverse bgp_dump_init */ + bgp_dump_finish(); + diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index d19f27110e..c29442d96c 100644 +index 99fb021b1..e45d4b1ff 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c -@@ -3214,8 +3214,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3419,8 +3419,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, || new_select->sub_type == BGP_ROUTE_IMPORTED)) - bgp_zebra_announce(dest, old_select, - bgp); -+ bgp_zebra_route_install( -+ dest, old_select, bgp, true); ++ bgp_zebra_route_install(dest, old_select, ++ bgp, true); } } -@@ -3312,9 +3312,10 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3529,9 +3529,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, */ if (old_select && is_route_parent_evpn(old_select)) - bgp_zebra_withdraw(dest, old_select, bgp); -+ bgp_zebra_route_install(dest, old_select, bgp, -+ false); ++ bgp_zebra_route_install(dest, old_select, bgp, false); - bgp_zebra_announce(dest, new_select, bgp); + bgp_zebra_route_install(dest, new_select, bgp, true); } else { /* Withdraw the route from the kernel. */ if (old_select && old_select->type == ZEBRA_ROUTE_BGP -@@ -3322,7 +3323,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3539,7 +3539,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, || old_select->sub_type == BGP_ROUTE_AGGREGATE || old_select->sub_type == BGP_ROUTE_IMPORTED)) - bgp_zebra_withdraw(dest, old_select, bgp); -+ bgp_zebra_route_install(dest, old_select, bgp, -+ false); ++ bgp_zebra_route_install(dest, old_select, bgp, false); } } -@@ -4201,7 +4203,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, +@@ -4444,7 +4444,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) { if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) /* remove from RIB previous entry */ @@ -84,54 +72,63 @@ index d19f27110e..c29442d96c 100644 } if (peer->sort == BGP_PEER_EBGP) { -@@ -5865,7 +5867,8 @@ static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table, +@@ -6070,7 +6070,7 @@ static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table, || pi->sub_type == BGP_ROUTE_IMPORTED)) { if (bgp_fibupd_safi(safi)) - bgp_zebra_withdraw(dest, pi, bgp); -+ bgp_zebra_withdraw_actual(dest, pi, -+ bgp); ++ bgp_zebra_withdraw_actual(dest, pi, bgp); } - bgp_path_info_reap(dest, pi); + dest = bgp_path_info_reap(dest, pi); diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h -index d43bf86eb9..45d61f8dfd 100644 +index 5b4c3be21..67431ea4f 100644 --- a/bgpd/bgp_table.h +++ b/bgpd/bgp_table.h -@@ -102,6 +102,7 @@ struct bgp_node { - STAILQ_ENTRY(bgp_dest) pq; +@@ -75,6 +75,9 @@ struct bgp_dest { + struct bgp_dest *pdest; - struct zebra_announce_item zai; + STAILQ_ENTRY(bgp_dest) pq; + struct bgp_path_info *za_bgp_pi; ++ ++ struct zebra_announce_item zai; uint64_t version; -@@ -117,6 +118,8 @@ struct bgp_node { - #define BGP_NODE_FIB_INSTALLED (1 << 6) +@@ -91,12 +94,16 @@ struct bgp_dest { #define BGP_NODE_LABEL_REQUESTED (1 << 7) #define BGP_NODE_SOFT_RECONFIG (1 << 8) + #define BGP_NODE_PROCESS_CLEAR (1 << 9) +#define BGP_NODE_SCHEDULE_FOR_INSTALL (1 << 10) +#define BGP_NODE_SCHEDULE_FOR_DELETE (1 << 11) struct bgp_addpath_node_data tx_addpath; + enum bgp_path_selection_reason reason; + }; + ++DECLARE_LIST(zebra_announce, struct bgp_dest, zai); ++ + extern void bgp_delete_listnode(struct bgp_dest *dest); + /* + * bgp_table_iter_t diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c -index 920df835a4..1162941ef1 100644 +index 43447d528..064f23350 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c -@@ -1292,8 +1292,9 @@ static bool bgp_zebra_use_nhop_weighted(struct bgp *bgp, struct attr *attr, - return true; +@@ -1507,8 +1507,9 @@ static void bgp_debug_zebra_nh(struct zapi_route *api) + } } --void bgp_zebra_announce(struct bgp_dest *dest, struct bgp_path_info *info, +-void bgp_zebra_announce(struct bgp_dest *dest, struct bgp_path_info *info, - struct bgp *bgp) +static enum zclient_send_status +bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info, + struct bgp *bgp) { + struct bgp_path_info *bpi_ultimate; struct zapi_route api = { 0 }; - struct zapi_nexthop *api_nh; -@@ -1323,27 +1324,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, struct bgp_path_info *info, +@@ -1524,27 +1525,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, struct bgp_path_info *info, struct bgp_table *table = bgp_dest_table(dest); const struct prefix *p = bgp_dest_get_prefix(dest); @@ -154,27 +151,22 @@ index 920df835a4..1162941ef1 100644 - if (table->safi == SAFI_FLOWSPEC) { bgp_pbr_update_entry(bgp, p, info, table->afi, table->safi, - true); + true); - return; + return ZCLIENT_SEND_SUCCESS; - } + } - /* -@@ -1704,10 +1688,11 @@ void bgp_zebra_announce(struct bgp_dest *dest, struct bgp_path_info *info, + /* Make Zebra API structure. */ +@@ -1661,7 +1645,7 @@ void bgp_zebra_announce(struct bgp_dest *dest, struct bgp_path_info *info, zlog_debug("%s: %pFX: announcing to zebra (recursion %sset)", __func__, p, (recursion_flag ? "" : "NOT ")); } - zclient_route_send(is_add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, -- zclient, &api); + return zclient_route_send(is_add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, -+ zclient, &api); + zclient, &api); } -+ - /* Announce all routes of a table to zebra */ - void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi) - { -@@ -1733,7 +1718,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi) +@@ -1690,7 +1674,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi) && (pi->sub_type == BGP_ROUTE_NORMAL || pi->sub_type == BGP_ROUTE_IMPORTED))) @@ -183,7 +175,7 @@ index 920df835a4..1162941ef1 100644 } /* Announce routes of any bgp subtype of a table to zebra */ -@@ -1755,34 +1740,23 @@ void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, +@@ -1712,32 +1696,23 @@ void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) && pi->type == ZEBRA_ROUTE_BGP) @@ -193,6 +185,7 @@ index 920df835a4..1162941ef1 100644 -void bgp_zebra_withdraw(struct bgp_dest *dest, struct bgp_path_info *info, - struct bgp *bgp) ++ +enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest, + struct bgp_path_info *info, + struct bgp *bgp) @@ -201,7 +194,6 @@ index 920df835a4..1162941ef1 100644 struct peer *peer; struct bgp_table *table = bgp_dest_table(dest); const struct prefix *p = bgp_dest_get_prefix(dest); - - /* - * If we are withdrawing the route, we don't need to have this - * flag set. So unset it. @@ -213,17 +205,16 @@ index 920df835a4..1162941ef1 100644 - */ - if (!bgp_install_info_to_zebra(bgp)) - return; -- + if (table->safi == SAFI_FLOWSPEC) { peer = info->peer; - bgp_pbr_update_entry(peer->bgp, p, info, table->afi, - table->safi, false); + bgp_pbr_update_entry(peer->bgp, p, info, table->afi, table->safi, false); - return; + return ZCLIENT_SEND_SUCCESS; } memset(&api, 0, sizeof(api)); -@@ -1800,7 +1774,172 @@ void bgp_zebra_withdraw(struct bgp_dest *dest, struct bgp_path_info *info, +@@ -1755,7 +1730,172 @@ void bgp_zebra_withdraw(struct bgp_dest *dest, struct bgp_path_info *info, zlog_debug("Tx route delete VRF %u %pFX", bgp->vrf_id, &api.prefix); @@ -291,7 +282,7 @@ index 920df835a4..1162941ef1 100644 + + if (status != ZCLIENT_SEND_BUFFERED && + zebra_announce_count(&bm->zebra_announce_head)) -+ thread_add_event(bm->master, ++ event_add_event(bm->master, + bgp_handle_route_announcements_to_zebra, NULL, + 0, &bm->t_bgp_zebra_route); +} @@ -392,12 +383,12 @@ index 920df835a4..1162941ef1 100644 + SET_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_DELETE); + } + -+ thread_add_event(bm->master, bgp_handle_route_announcements_to_zebra, ++ event_add_event(bm->master, bgp_handle_route_announcements_to_zebra, + NULL, 0, &bm->t_bgp_zebra_route); } /* Withdraw all entries in a BGP instances RIB table from Zebra */ -@@ -1821,7 +1960,7 @@ void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t sa +@@ -1776,7 +1916,7 @@ void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t sa for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) && (pi->type == ZEBRA_ROUTE_BGP)) @@ -406,20 +397,20 @@ index 920df835a4..1162941ef1 100644 } } } -@@ -3470,6 +3609,7 @@ void bgp_zebra_init(struct thread_master *master, unsigned short instance) +@@ -3449,6 +3589,7 @@ void bgp_zebra_init(struct event_loop *master, unsigned short instance) zclient = zclient_new(master, &zclient_options_default, bgp_handlers, array_size(bgp_handlers)); zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs); + zclient->zebra_buffer_write_ready = bgp_zebra_buffer_write_ready; zclient->zebra_connected = bgp_zebra_connected; - zclient->instance = instance; - } + zclient->zebra_capabilities = bgp_zebra_capabilities; + zclient->nexthop_update = bgp_nexthop_update; diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h -index b77e423f8f..45fcf7f514 100644 +index 61a49bfa5..83197c28e 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h -@@ -43,11 +43,10 @@ extern void bgp_zebra_destroy(void); - extern int bgp_zebra_get_table_range(uint32_t chunk_size, +@@ -28,12 +28,14 @@ extern void bgp_zebra_destroy(void); + extern int bgp_zebra_get_table_range(struct zclient *zc, uint32_t chunk_size, uint32_t *start, uint32_t *end); extern int bgp_if_update_all(void); -extern void bgp_zebra_announce(struct bgp_dest *dest, @@ -427,25 +418,21 @@ index b77e423f8f..45fcf7f514 100644 +extern void bgp_zebra_route_install(struct bgp_dest *dest, + struct bgp_path_info *path, struct bgp *bgp, + bool install); + extern void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi); -extern void bgp_zebra_withdraw(struct bgp_dest *dest, - struct bgp_path_info *path, struct bgp *bgp); - - /* Announce routes of any bgp subtype of a table to zebra */ - extern void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, -@@ -131,4 +130,7 @@ extern int bgp_zebra_update(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type); - extern int bgp_zebra_stale_timer_update(struct bgp *bgp); - extern int bgp_zebra_srv6_manager_get_locator_chunk(const char *name); - extern int bgp_zebra_srv6_manager_release_locator_chunk(const char *name); +extern enum zclient_send_status +bgp_zebra_withdraw_actual(struct bgp_dest *dest, struct bgp_path_info *info, + struct bgp *bgp); - #endif /* _QUAGGA_BGP_ZEBRA_H */ + + /* Announce routes of any bgp subtype of a table to zebra */ + extern void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 392423e028..da133d71c1 100644 +index 337879a2d..88d4201a9 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c -@@ -3688,10 +3688,20 @@ int bgp_delete(struct bgp *bgp) +@@ -3867,10 +3867,20 @@ int bgp_delete(struct bgp *bgp) afi_t afi; safi_t safi; int i; @@ -466,41 +453,66 @@ index 392423e028..da133d71c1 100644 bgp_soft_reconfig_table_task_cancel(bgp, NULL, NULL); /* make sure we withdraw any exported routes */ -@@ -8035,6 +8045,7 @@ void bgp_master_init(struct thread_master *master, const int buffer_size, - bm->tcp_dscp = IPTOS_PREC_INTERNETCONTROL; - bm->inq_limit = BM_DEFAULT_Q_LIMIT; +@@ -8296,6 +8306,8 @@ void bgp_master_init(struct event_loop *master, const int buffer_size, + memset(&bgp_master, 0, sizeof(bgp_master)); + + bm = &bgp_master; ++ ++ zebra_announce_init(&bm->zebra_announce_head); + bm->bgp = list_new(); + bm->listen_sockets = list_new(); + bm->port = BGP_PORT_DEFAULT; +@@ -8314,6 +8326,7 @@ void bgp_master_init(struct event_loop *master, const int buffer_size, bm->outq_limit = BM_DEFAULT_Q_LIMIT; + bm->t_bgp_sync_label_manager = NULL; + bm->t_bgp_start_label_manager = NULL; + bm->t_bgp_zebra_route = NULL; bgp_mac_init(); /* init the rd id space. -@@ -8278,6 +8289,7 @@ void bgp_terminate(void) - list_delete(&bm->listen_sockets); - - THREAD_OFF(bm->t_rmap_update); -+ THREAD_OFF(bm->t_bgp_zebra_route); +@@ -8564,6 +8577,7 @@ void bgp_terminate(void) + EVENT_OFF(bm->t_rmap_update); + EVENT_OFF(bm->t_bgp_sync_label_manager); + EVENT_OFF(bm->t_bgp_start_label_manager); ++ EVENT_OFF(bm->t_bgp_zebra_route); bgp_mac_finish(); } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h -index 55f53bf9d3..bdf31f5161 100644 +index 0f6909532..a088a2e11 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h -@@ -182,6 +182,8 @@ struct bgp_master { +@@ -18,6 +18,8 @@ + #include "iana_afi.h" + #include "asn.h" + ++PREDECL_LIST(zebra_announce); ++ + /* For union sockunion. */ + #include "queue.h" + #include "sockunion.h" +@@ -170,10 +172,15 @@ struct bgp_master { uint32_t inq_limit; uint32_t outq_limit; -+ struct thread *t_bgp_zebra_route; ++ struct event *t_bgp_zebra_route; + - /* To preserve ordering of installations into zebra across all Vrfs */ - struct zebra_announce_head zebra_announce_head; + struct event *t_bgp_sync_label_manager; + struct event *t_bgp_start_label_manager; + + bool v6_with_v4_nexthops; ++ ++ /* To preserve ordering of installations into zebra across all Vrfs */ ++ struct zebra_announce_head zebra_announce_head; + QOBJ_FIELDS; + }; diff --git a/lib/zclient.c b/lib/zclient.c -index 0082b21485..c48c1c6ee4 100644 +index 6b35b569d..64515c754 100644 --- a/lib/zclient.c +++ b/lib/zclient.c -@@ -285,6 +285,7 @@ static void zclient_flush_data(struct thread *thread) - zclient->sock, &zclient->t_write); +@@ -282,6 +282,7 @@ static void zclient_flush_data(struct event *thread) + zclient->sock, &zclient->t_write); break; case BUFFER_EMPTY: + /* Currently only Sharpd and Bgpd has callbacks defined */ @@ -508,5 +520,5 @@ index 0082b21485..c48c1c6ee4 100644 (*zclient->zebra_buffer_write_ready)(); break; -- -2.17.1 +2.39.4 diff --git a/src/sonic-frr/patch/0035-bgpd-backpressure-Handle-BGP-Zebra-EPVN-Install-evt-.patch b/src/sonic-frr/patch/0035-bgpd-backpressure-Handle-BGP-Zebra-EPVN-Install-evt-.patch index e83526b6e8ef..10ccbd0cce0f 100644 --- a/src/sonic-frr/patch/0035-bgpd-backpressure-Handle-BGP-Zebra-EPVN-Install-evt-.patch +++ b/src/sonic-frr/patch/0035-bgpd-backpressure-Handle-BGP-Zebra-EPVN-Install-evt-.patch @@ -1,7 +1,10 @@ -From 84f7778808b7fee771f26c3cae46292ef85f06c0 Mon Sep 17 00:00:00 2001 -From: Rajasekar Raja -Date: Thu, 15 Feb 2024 11:23:51 -0800 -Subject: [PATCH 07/11] bgpd : backpressure - Handle BGP-Zebra(EPVN) Install +From 2552ac0c492cdec01e36b48b63c057c6ad162701 Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Mon, 16 Sep 2024 23:08:55 -0700 +Subject: [PATCH] Subject: [PATCH] From + 84f7778808b7fee771f26c3cae46292ef85f06c0 Mon Sep 17 00:00:00 2001 From: + Rajasekar Raja Date: Thu, 15 Feb 2024 11:23:51 -0800 + Subject: [PATCH 07/11] bgpd : backpressure - Handle BGP-Zebra(EPVN) Install evt Creation Current changes deals with EVPN routes installation to zebra. @@ -16,31 +19,328 @@ of the code. Ticket: #3390099 Signed-off-by: Rajasekar Raja +--- + bgpd/bgp_evpn.c | 447 ++++++++++++++++++++++++++------------------- + bgpd/bgp_evpn.h | 8 + + bgpd/bgp_evpn_mh.c | 88 +++++---- + bgpd/bgp_evpn_mh.h | 10 +- + bgpd/bgp_route.c | 10 +- + bgpd/bgp_table.h | 6 +- + bgpd/bgp_zebra.c | 52 ++++-- + bgpd/bgp_zebra.h | 2 +- + bgpd/bgpd.h | 1 + + 9 files changed, 377 insertions(+), 247 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c -index 2b2cfa0f4c..622fd6afd2 100644 +index a846484f0..79e16d8f9 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c -@@ -863,11 +863,10 @@ struct bgp_dest *bgp_evpn_vni_node_lookup(const struct bgpevpn *vpn, +@@ -55,27 +55,25 @@ DEFINE_MTYPE_STATIC(BGPD, VRF_ROUTE_TARGET, "L3 Route Target"); + /* + * Static function declarations + */ +-static void bgp_evpn_remote_ip_hash_init(struct bgpevpn *evpn); +-static void bgp_evpn_remote_ip_hash_destroy(struct bgpevpn *evpn); +-static void bgp_evpn_remote_ip_hash_add(struct bgpevpn *vpn, ++void bgp_evpn_remote_ip_hash_init(struct bgpevpn *evpn); ++void bgp_evpn_remote_ip_hash_destroy(struct bgpevpn *evpn); ++void bgp_evpn_remote_ip_hash_add(struct bgpevpn *vpn, + struct bgp_path_info *pi); +-static void bgp_evpn_remote_ip_hash_del(struct bgpevpn *vpn, ++void bgp_evpn_remote_ip_hash_del(struct bgpevpn *vpn, + struct bgp_path_info *pi); +-static void bgp_evpn_remote_ip_hash_iterate(struct bgpevpn *vpn, +- void (*func)(struct hash_bucket *, +- void *), +- void *arg); +-static void bgp_evpn_link_to_vni_svi_hash(struct bgp *bgp, struct bgpevpn *vpn); +-static void bgp_evpn_unlink_from_vni_svi_hash(struct bgp *bgp, ++void bgp_evpn_remote_ip_hash_iterate(struct bgpevpn *vpn, ++ void (*func)(struct hash_bucket *,void *), void *arg); ++void bgp_evpn_link_to_vni_svi_hash(struct bgp *bgp, struct bgpevpn *vpn); ++void bgp_evpn_unlink_from_vni_svi_hash(struct bgp *bgp, + struct bgpevpn *vpn); +-static unsigned int vni_svi_hash_key_make(const void *p); +-static bool vni_svi_hash_cmp(const void *p1, const void *p2); +-static void bgp_evpn_remote_ip_process_nexthops(struct bgpevpn *vpn, ++unsigned int vni_svi_hash_key_make(const void *p); ++bool vni_svi_hash_cmp(const void *p1, const void *p2); ++void bgp_evpn_remote_ip_process_nexthops(struct bgpevpn *vpn, + struct ipaddr *addr, + bool resolve); +-static void bgp_evpn_remote_ip_hash_link_nexthop(struct hash_bucket *bucket, ++void bgp_evpn_remote_ip_hash_link_nexthop(struct hash_bucket *bucket, + void *args); +-static void bgp_evpn_remote_ip_hash_unlink_nexthop(struct hash_bucket *bucket, ++void bgp_evpn_remote_ip_hash_unlink_nexthop(struct hash_bucket *bucket, + void *args); + static struct in_addr zero_vtep_ip; + +@@ -86,7 +84,7 @@ static struct in_addr zero_vtep_ip; + /* + * Make vni hash key. + */ +-static unsigned int vni_hash_key_make(const void *p) ++unsigned int vni_hash_key_make(const void *p) + { + const struct bgpevpn *vpn = p; + return (jhash_1word(vpn->vni, 0)); +@@ -95,7 +93,7 @@ static unsigned int vni_hash_key_make(const void *p) + /* + * Comparison function for vni hash + */ +-static bool vni_hash_cmp(const void *p1, const void *p2) ++bool vni_hash_cmp(const void *p1, const void *p2) + { + const struct bgpevpn *vpn1 = p1; + const struct bgpevpn *vpn2 = p2; +@@ -114,7 +112,7 @@ int vni_list_cmp(void *p1, void *p2) + /* + * Make vrf import route target hash key. + */ +-static unsigned int vrf_import_rt_hash_key_make(const void *p) ++unsigned int vrf_import_rt_hash_key_make(const void *p) + { + const struct vrf_irt_node *irt = p; + const char *pnt = irt->rt.val; +@@ -125,7 +123,7 @@ static unsigned int vrf_import_rt_hash_key_make(const void *p) + /* + * Comparison function for vrf import rt hash + */ +-static bool vrf_import_rt_hash_cmp(const void *p1, const void *p2) ++bool vrf_import_rt_hash_cmp(const void *p1, const void *p2) + { + const struct vrf_irt_node *irt1 = p1; + const struct vrf_irt_node *irt2 = p2; +@@ -136,7 +134,7 @@ static bool vrf_import_rt_hash_cmp(const void *p1, const void *p2) + /* + * Create a new vrf import_rt in evpn instance + */ +-static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt) ++struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt) + { + struct bgp *bgp_evpn = NULL; + struct vrf_irt_node *irt; +@@ -163,7 +161,7 @@ static struct vrf_irt_node *vrf_import_rt_new(struct ecommunity_val *rt) + /* + * Free the vrf import rt node + */ +-static void vrf_import_rt_free(struct vrf_irt_node *irt) ++void vrf_import_rt_free(struct vrf_irt_node *irt) + { + struct bgp *bgp_evpn = NULL; + +@@ -179,7 +177,7 @@ static void vrf_import_rt_free(struct vrf_irt_node *irt) + XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt); + } + +-static void hash_vrf_import_rt_free(struct vrf_irt_node *irt) ++void hash_vrf_import_rt_free(struct vrf_irt_node *irt) + { + XFREE(MTYPE_BGP_EVPN_VRF_IMPORT_RT, irt); + } +@@ -188,7 +186,7 @@ static void hash_vrf_import_rt_free(struct vrf_irt_node *irt) + * Function to lookup Import RT node - used to map a RT to set of + * VNIs importing routes with that RT. + */ +-static struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt) ++struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt) + { + struct bgp *bgp_evpn = NULL; + struct vrf_irt_node *irt; +@@ -211,7 +209,7 @@ static struct vrf_irt_node *lookup_vrf_import_rt(struct ecommunity_val *rt) + /* + * Is specified VRF present on the RT's list of "importing" VRFs? + */ +-static int is_vrf_present_in_irt_vrfs(struct list *vrfs, struct bgp *bgp_vrf) ++int is_vrf_present_in_irt_vrfs(struct list *vrfs, struct bgp *bgp_vrf) + { + struct listnode *node = NULL, *nnode = NULL; + struct bgp *tmp_bgp_vrf = NULL; +@@ -226,7 +224,7 @@ static int is_vrf_present_in_irt_vrfs(struct list *vrfs, struct bgp *bgp_vrf) + /* + * Make import route target hash key. + */ +-static unsigned int import_rt_hash_key_make(const void *p) ++unsigned int import_rt_hash_key_make(const void *p) + { + const struct irt_node *irt = p; + const char *pnt = irt->rt.val; +@@ -237,7 +235,7 @@ static unsigned int import_rt_hash_key_make(const void *p) + /* + * Comparison function for import rt hash + */ +-static bool import_rt_hash_cmp(const void *p1, const void *p2) ++bool import_rt_hash_cmp(const void *p1, const void *p2) + { + const struct irt_node *irt1 = p1; + const struct irt_node *irt2 = p2; +@@ -248,7 +246,7 @@ static bool import_rt_hash_cmp(const void *p1, const void *p2) + /* + * Create a new import_rt + */ +-static struct irt_node *import_rt_new(struct bgp *bgp, ++struct irt_node *import_rt_new(struct bgp *bgp, + struct ecommunity_val *rt) + { + struct irt_node *irt; +@@ -267,14 +265,14 @@ static struct irt_node *import_rt_new(struct bgp *bgp, + /* + * Free the import rt node + */ +-static void import_rt_free(struct bgp *bgp, struct irt_node *irt) ++void import_rt_free(struct bgp *bgp, struct irt_node *irt) + { + hash_release(bgp->import_rt_hash, irt); + list_delete(&irt->vnis); + XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt); + } + +-static void hash_import_rt_free(struct irt_node *irt) ++void hash_import_rt_free(struct irt_node *irt) + { + XFREE(MTYPE_BGP_EVPN_IMPORT_RT, irt); + } +@@ -283,7 +281,7 @@ static void hash_import_rt_free(struct irt_node *irt) + * Function to lookup Import RT node - used to map a RT to set of + * VNIs importing routes with that RT. + */ +-static struct irt_node *lookup_import_rt(struct bgp *bgp, ++struct irt_node *lookup_import_rt(struct bgp *bgp, + struct ecommunity_val *rt) + { + struct irt_node *irt; +@@ -298,7 +296,7 @@ static struct irt_node *lookup_import_rt(struct bgp *bgp, + /* + * Is specified VNI present on the RT's list of "importing" VNIs? + */ +-static int is_vni_present_in_irt_vnis(struct list *vnis, struct bgpevpn *vpn) ++int is_vni_present_in_irt_vnis(struct list *vnis, struct bgpevpn *vpn) + { + struct listnode *node, *nnode; + struct bgpevpn *tmp_vpn; +@@ -384,7 +382,7 @@ int bgp_evpn_route_target_cmp(struct ecommunity *ecom1, + /* + * Compare L3 Route Targets. + */ +-static int evpn_vrf_route_target_cmp(struct vrf_route_target *rt1, ++int evpn_vrf_route_target_cmp(struct vrf_route_target *rt1, + struct vrf_route_target *rt2) + { + return bgp_evpn_route_target_cmp(rt1->ecom, rt2->ecom); +@@ -399,7 +397,7 @@ void bgp_evpn_xxport_delete_ecomm(void *val) + /* + * Delete l3 Route Target. + */ +-static void evpn_vrf_rt_del(void *val) ++void evpn_vrf_rt_del(void *val) + { + struct vrf_route_target *l3rt = val; + +@@ -411,7 +409,7 @@ static void evpn_vrf_rt_del(void *val) + /* + * Allocate a new l3 Route Target. + */ +-static struct vrf_route_target *evpn_vrf_rt_new(struct ecommunity *ecom) ++struct vrf_route_target *evpn_vrf_rt_new(struct ecommunity *ecom) + { + struct vrf_route_target *l3rt; + +@@ -446,7 +444,7 @@ static inline void mask_ecom_global_admin(struct ecommunity_val *dst, + * Converts the RT to Ecommunity Value and adjusts masking based + * on flags set for RT. + */ +-static void vrf_rt2ecom_val(struct ecommunity_val *to_eval, ++void vrf_rt2ecom_val(struct ecommunity_val *to_eval, + const struct vrf_route_target *l3rt, int iter) + { + const struct ecommunity_val *eval; +@@ -470,7 +468,7 @@ static void vrf_rt2ecom_val(struct ecommunity_val *to_eval, + * Map one RT to specified VRF. + * bgp_vrf = BGP vrf instance + */ +-static void map_vrf_to_rt(struct bgp *bgp_vrf, struct vrf_route_target *l3rt) ++void map_vrf_to_rt(struct bgp *bgp_vrf, struct vrf_route_target *l3rt) + { + uint32_t i = 0; + +@@ -499,7 +497,7 @@ static void map_vrf_to_rt(struct bgp *bgp_vrf, struct vrf_route_target *l3rt) + * VRFs for this RT, then the RT hash is deleted. + * bgp_vrf: BGP VRF specific instance + */ +-static void unmap_vrf_from_rt(struct bgp *bgp_vrf, ++void unmap_vrf_from_rt(struct bgp *bgp_vrf, + struct vrf_route_target *l3rt) + { + uint32_t i; +@@ -527,7 +525,7 @@ static void unmap_vrf_from_rt(struct bgp *bgp_vrf, + /* + * Map one RT to specified VNI. + */ +-static void map_vni_to_rt(struct bgp *bgp, struct bgpevpn *vpn, ++void map_vni_to_rt(struct bgp *bgp, struct bgpevpn *vpn, + struct ecommunity_val *eval) + { + struct irt_node *irt; +@@ -558,7 +556,7 @@ static void map_vni_to_rt(struct bgp *bgp, struct bgpevpn *vpn, + * Unmap specified VNI from specified RT. If there are no other + * VNIs for this RT, then the RT hash is deleted. + */ +-static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn, ++void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn, + struct irt_node *irt) + { + /* Delete VNI from hash list for this RT. */ +@@ -568,7 +566,7 @@ static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn, + } + } + +-static void bgp_evpn_get_rmac_nexthop(struct bgpevpn *vpn, ++void bgp_evpn_get_rmac_nexthop(struct bgpevpn *vpn, + const struct prefix_evpn *p, + struct attr *attr, uint8_t flags) + { +@@ -609,7 +607,7 @@ static void bgp_evpn_get_rmac_nexthop(struct bgpevpn *vpn, + * VNIs but the same across routers (in the same AS) for a particular + * VNI. + */ +-static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl, ++void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl, + bool is_l3) + { + struct ecommunity_val eval; +@@ -657,7 +655,7 @@ static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl, + * Derive RD and RT for a VNI automatically. Invoked at the time of + * creation of a VNI. + */ +-static void derive_rd_rt_for_vni(struct bgp *bgp, struct bgpevpn *vpn) ++void derive_rd_rt_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + { + bgp_evpn_derive_auto_rd(bgp, vpn); + bgp_evpn_derive_auto_rt_import(bgp, vpn); +@@ -667,7 +665,7 @@ static void derive_rd_rt_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + /* + * Convert nexthop (remote VTEP IP) into an IPv6 address. + */ +-static void evpn_convert_nexthop_to_ipv6(struct attr *attr) ++void evpn_convert_nexthop_to_ipv6(struct attr *attr) + { + if (BGP_ATTR_NEXTHOP_AFI_IP6(attr)) + return; +@@ -892,7 +890,7 @@ struct bgp_dest *bgp_evpn_vni_node_lookup(const struct bgpevpn *vpn, /* * Add (update) or delete MACIP from zebra. */ -static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, -- const struct prefix_evpn *p, -- const struct ethaddr *mac, -- struct in_addr remote_vtep_ip, int add, -- uint8_t flags, uint32_t seq, esi_t *esi) -+static enum zclient_send_status bgp_zebra_send_remote_macip( -+ struct bgp *bgp, struct bgpevpn *vpn, const struct prefix_evpn *p, -+ const struct ethaddr *mac, struct in_addr remote_vtep_ip, int add, -+ uint8_t flags, uint32_t seq, esi_t *esi) - { - struct stream *s; - uint16_t ipa_len; -@@ -875,8 +874,12 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, ++enum zclient_send_status bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, + const struct prefix_evpn *p, + const struct ethaddr *mac, + struct in_addr remote_vtep_ip, int add, +@@ -903,9 +901,12 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, + static struct in_addr zero_remote_vtep_ip; bool esi_valid; - /* Check socket. */ +- /* Check socket. */ - if (!zclient || zclient->sock < 0) - return 0; + if (!zclient || zclient->sock < 0) { @@ -52,7 +352,7 @@ index 2b2cfa0f4c..622fd6afd2 100644 /* Don't try to register if Zebra doesn't know of this instance. */ if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { -@@ -884,7 +887,7 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, +@@ -913,7 +914,7 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, zlog_debug( "%s: No zebra instance to talk to, not installing remote macip", __func__); @@ -61,21 +361,18 @@ index 2b2cfa0f4c..622fd6afd2 100644 } if (!esi) -@@ -956,15 +959,20 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, +@@ -988,15 +989,18 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn, /* * Add (update) or delete remote VTEP from zebra. */ -static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, -- const struct prefix_evpn *p, -- int flood_control, int add) -+static enum zclient_send_status -+bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, -+ const struct prefix_evpn *p, int flood_control, -+ int add) ++enum zclient_send_status bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, + const struct prefix_evpn *p, + int flood_control, int add) { struct stream *s; - /* Check socket. */ +- /* Check socket. */ - if (!zclient || zclient->sock < 0) - return 0; + if (!zclient || zclient->sock < 0) { @@ -87,7 +384,7 @@ index 2b2cfa0f4c..622fd6afd2 100644 /* Don't try to register if Zebra doesn't know of this instance. */ if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) { -@@ -972,7 +980,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, +@@ -1004,7 +1008,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, zlog_debug( "%s: No zebra instance to talk to, not installing remote vtep", __func__); @@ -96,71 +393,83 @@ index 2b2cfa0f4c..622fd6afd2 100644 } s = zclient->obuf; -@@ -989,7 +997,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, +@@ -1021,7 +1025,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, EC_BGP_VTEP_INVALID, "Bad remote IP when trying to %s remote VTEP for VNI %u", - add ? "ADD" : "DEL", vpn->vni); + add ? "ADD" : "DEL", (vpn ? vpn->vni : 0)); - return -1; + return ZCLIENT_SEND_FAILURE; } stream_putl(s, flood_control); -@@ -1222,14 +1230,15 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr) +@@ -1043,7 +1047,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn, + /* + * Build extended communities for EVPN prefix route. + */ +-static void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf, ++void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf, + struct attr *attr) + { + struct ecommunity ecom_encap; +@@ -1100,7 +1104,7 @@ static void build_evpn_type5_route_extcomm(struct bgp *bgp_vrf, + * added, if present, based on passed settings - only for non-link-local + * type-2 routes. + */ +-static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, ++void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, + int add_l3_ecomm, + struct ecommunity *macvrf_soo) + { +@@ -1209,7 +1213,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr, + /* + * Add MAC mobility extended community to attribute. + */ +-static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr) ++void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr) + { + struct ecommunity ecom_tmp; + struct ecommunity_val eval; +@@ -1263,14 +1267,14 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr) } /* Install EVPN route into zebra. */ -static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn, -- const struct prefix_evpn *p, -- struct bgp_path_info *pi) -+enum zclient_send_status evpn_zebra_install(struct bgp *bgp, -+ struct bgpevpn *vpn, -+ const struct prefix_evpn *p, -+ struct bgp_path_info *pi) ++enum zclient_send_status evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn, + const struct prefix_evpn *p, + struct bgp_path_info *pi) { - int ret; uint8_t flags; - int flood_control; + int flood_control = VXLAN_FLOOD_DISABLED; uint32_t seq; + enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS; if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) { flags = 0; -@@ -1302,6 +1311,7 @@ static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn, - flood_control = VXLAN_FLOOD_DISABLED; - break; - } -+ - ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, flood_control, 1); - } - -@@ -1309,11 +1319,13 @@ static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn, +@@ -1355,11 +1359,11 @@ static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn, } /* Uninstall EVPN route from zebra. */ -static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn, -- const struct prefix_evpn *p, -- struct bgp_path_info *pi, bool is_sync) -+enum zclient_send_status evpn_zebra_uninstall(struct bgp *bgp, -+ struct bgpevpn *vpn, -+ const struct prefix_evpn *p, -+ struct bgp_path_info *pi, -+ bool is_sync) ++enum zclient_send_status evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn, + const struct prefix_evpn *p, + struct bgp_path_info *pi, bool is_sync) { - int ret; + enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS; if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) ret = bgp_zebra_send_remote_macip( -@@ -1328,7 +1340,7 @@ static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn, - ret = bgp_evpn_remote_es_evi_del(bgp, vpn, p); - else - ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, -- VXLAN_FLOOD_DISABLED, 0); -+ VXLAN_FLOOD_DISABLED, 0); - - return ret; - } -@@ -1419,12 +1431,18 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, +@@ -1384,7 +1388,7 @@ static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn, + * by a "remote" best route. The prior route has to be deleted and withdrawn + * from peers. + */ +-static void evpn_delete_old_local_route(struct bgp *bgp, struct bgpevpn *vpn, ++void evpn_delete_old_local_route(struct bgp *bgp, struct bgpevpn *vpn, + struct bgp_dest *dest, + struct bgp_path_info *old_local, + struct bgp_path_info *new_select) +@@ -1465,12 +1469,17 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR) && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED) && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) { @@ -181,11 +490,10 @@ index 2b2cfa0f4c..622fd6afd2 100644 + bgp_zebra_route_install(dest, old_select, bgp, + true, vpn, false); + } -+ UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG); UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG); bgp_zebra_clear_route_change_flags(dest); -@@ -1456,10 +1474,14 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, +@@ -1502,10 +1511,14 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, if (new_select && new_select->type == ZEBRA_ROUTE_BGP && (new_select->sub_type == BGP_ROUTE_IMPORTED || bgp_evpn_attr_is_sync(new_select->attr))) { @@ -204,7 +512,7 @@ index 2b2cfa0f4c..622fd6afd2 100644 /* If an old best existed and it was a "local" route, the only * reason -@@ -1476,13 +1498,20 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, +@@ -1522,13 +1535,20 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, evpn_delete_old_local_route(bgp, vpn, dest, old_select, new_select); } else { @@ -232,7 +540,70 @@ index 2b2cfa0f4c..622fd6afd2 100644 } /* Clear any route change flags. */ -@@ -2012,9 +2041,19 @@ static void evpn_zebra_reinstall_best_route(struct bgp *bgp, +@@ -1541,7 +1561,7 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn, + return ret; + } + +-static struct bgp_path_info *bgp_evpn_route_get_local_path( ++struct bgp_path_info *bgp_evpn_route_get_local_path( + struct bgp *bgp, struct bgp_dest *dest) + { + struct bgp_path_info *tmp_pi; +@@ -1558,7 +1578,7 @@ static struct bgp_path_info *bgp_evpn_route_get_local_path( + return local_pi; + } + +-static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, ++int update_evpn_type5_route_entry(struct bgp *bgp_evpn, + struct bgp *bgp_vrf, afi_t afi, + safi_t safi, struct bgp_dest *dest, + struct attr *attr, int *route_changed) +@@ -1627,7 +1647,7 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn, + } + + /* update evpn type-5 route entry */ +-static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, ++int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, + struct attr *src_attr, afi_t src_afi, + safi_t src_safi) + { +@@ -1732,7 +1752,7 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp, + return 0; + } + +-static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi, ++void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi, + struct bgp_dest *dest, uint32_t loc_seq, + uint32_t *max_sync_seq, bool *active_on_peer, + bool *peer_router, bool *proxy_from_peer, +@@ -1809,7 +1829,7 @@ static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi, + * Note: The local path can only exist as a best path in the + * VPN route table. It will take precedence over all sync paths. + */ +-static void update_evpn_route_entry_sync_info(struct bgp *bgp, ++void update_evpn_route_entry_sync_info(struct bgp *bgp, + struct bgp_dest *dest, + struct attr *attr, + uint32_t loc_seq, bool setup_sync, +@@ -1879,7 +1899,7 @@ static void update_evpn_route_entry_sync_info(struct bgp *bgp, + * Create or update EVPN route entry. This could be in the VNI route tables + * or the global route table. + */ +-static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, ++int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, + afi_t afi, safi_t safi, + struct bgp_dest *dest, struct attr *attr, + const struct ethaddr *mac, +@@ -2044,7 +2064,7 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, + return route_change; + } + +-static void evpn_zebra_reinstall_best_route(struct bgp *bgp, ++void evpn_zebra_reinstall_best_route(struct bgp *bgp, + struct bgpevpn *vpn, + struct bgp_dest *dest) + { +@@ -2062,9 +2082,19 @@ static void evpn_zebra_reinstall_best_route(struct bgp *bgp, if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP && (curr_select->sub_type == BGP_ROUTE_IMPORTED || bgp_evpn_attr_is_sync(curr_select->attr))) @@ -255,7 +626,34 @@ index 2b2cfa0f4c..622fd6afd2 100644 } /* -@@ -2189,8 +2228,16 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, +@@ -2081,7 +2111,7 @@ static void evpn_zebra_reinstall_best_route(struct bgp *bgp, + * additional handling to prevent bgp from injecting and holding on to a + * non-best local path. + */ +-static struct bgp_dest * ++struct bgp_dest * + evpn_cleanup_local_non_best_route(struct bgp *bgp, struct bgpevpn *vpn, + struct bgp_dest *dest, + struct bgp_path_info *local_pi) +@@ -2099,7 +2129,7 @@ evpn_cleanup_local_non_best_route(struct bgp *bgp, struct bgpevpn *vpn, + return bgp_path_info_reap(dest, local_pi); + } + +-static inline bool bgp_evpn_route_add_l3_ecomm_ok(struct bgpevpn *vpn, ++inline bool bgp_evpn_route_add_l3_ecomm_ok(struct bgpevpn *vpn, + const struct prefix_evpn *p, + esi_t *esi) + { +@@ -2116,7 +2146,7 @@ static inline bool bgp_evpn_route_add_l3_ecomm_ok(struct bgpevpn *vpn, + * Create or update EVPN route (of type based on prefix) for specified VNI + * and schedule for processing. + */ +-static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, ++int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, + struct prefix_evpn *p, uint8_t flags, + uint32_t seq, esi_t *esi) + { +@@ -2245,8 +2275,16 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, * has been removed. */ new_is_sync = bgp_evpn_attr_is_sync(pi->attr); @@ -274,7 +672,33 @@ index 2b2cfa0f4c..622fd6afd2 100644 } } bgp_path_info_unlock(pi); -@@ -2444,8 +2491,16 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn, +@@ -2308,7 +2346,7 @@ void delete_evpn_route_entry(struct bgp *bgp, afi_t afi, safi_t safi, + } + + /* Delete EVPN type5 route */ +-static int delete_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp) ++int delete_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp) + { + afi_t afi = AFI_L2VPN; + safi_t safi = SAFI_EVPN; +@@ -2339,7 +2377,7 @@ static int delete_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp) + * Delete EVPN route (of type based on prefix) for specified VNI and + * schedule for processing. + */ +-static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, ++int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn, + struct prefix_evpn *p) + { + struct bgp_dest *dest, *global_dest; +@@ -2408,6 +2446,7 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn, + int route_change; + bool old_is_sync = false; + struct ecommunity *macvrf_soo = NULL; ++ struct prefix_evpn p; + + if (CHECK_FLAG(local_pi->flags, BGP_PATH_REMOVED)) + return; +@@ -2512,8 +2551,16 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn, * has been removed. */ new_is_sync = bgp_evpn_attr_is_sync(pi->attr); @@ -283,8 +707,8 @@ index 2b2cfa0f4c..622fd6afd2 100644 + if (!new_is_sync && old_is_sync) { + if (CHECK_FLAG(bgp->flags, + BGP_FLAG_DELETE_IN_PROGRESS)) -+ (void)evpn_zebra_uninstall( -+ bgp, vpn, &evp, pi, true); ++ evpn_zebra_uninstall(bgp, vpn, &p, pi, ++ true); + else + bgp_zebra_route_install(dest, pi, bgp, + false, vpn, @@ -293,7 +717,97 @@ index 2b2cfa0f4c..622fd6afd2 100644 } } -@@ -2701,7 +2756,22 @@ static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) +@@ -2541,7 +2588,7 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn, + aspath_unintern(&attr.aspath); + } + +-static void update_type2_route(struct bgp *bgp, struct bgpevpn *vpn, ++void update_type2_route(struct bgp *bgp, struct bgpevpn *vpn, + struct bgp_dest *dest) + { + struct bgp_path_info *tmp_pi; +@@ -2571,7 +2618,7 @@ static void update_type2_route(struct bgp *bgp, struct bgpevpn *vpn, + * Update all type-2 (MACIP) local routes for this VNI - these should also + * be scheduled for advertise to peers. + */ +-static void update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) ++void update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) + { + struct bgp_dest *dest; + +@@ -2592,7 +2639,7 @@ static void update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) + * Delete all type-2 (MACIP) local routes for this VNI - only from the + * global routing table. These are also scheduled for withdraw from peers. + */ +-static void delete_global_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) ++void delete_global_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) + { + afi_t afi; + safi_t safi; +@@ -2626,7 +2673,7 @@ static void delete_global_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) + } + } + +-static struct bgp_dest *delete_vni_type2_route(struct bgp *bgp, ++struct bgp_dest *delete_vni_type2_route(struct bgp *bgp, + struct bgp_dest *dest) + { + struct bgp_path_info *pi; +@@ -2648,7 +2695,7 @@ static struct bgp_dest *delete_vni_type2_route(struct bgp *bgp, + return dest; + } + +-static void delete_vni_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) ++void delete_vni_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) + { + struct bgp_dest *dest; + +@@ -2672,7 +2719,7 @@ static void delete_vni_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) + * Delete all type-2 (MACIP) local routes for this VNI - from the global + * table as well as the per-VNI route table. + */ +-static void delete_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) ++void delete_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) + { + /* First, walk the global route table for this VNI's type-2 local + * routes. +@@ -2685,7 +2732,7 @@ static void delete_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn) + /* + * Delete all routes in the per-VNI route table. + */ +-static void delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) ++void delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) + { + struct bgp_dest *dest; + struct bgp_path_info *pi, *nextpi; +@@ -2716,7 +2763,7 @@ static void delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) + } + + /* BUM traffic flood mode per-l2-vni */ +-static int bgp_evpn_vni_flood_mode_get(struct bgp *bgp, ++int bgp_evpn_vni_flood_mode_get(struct bgp *bgp, + struct bgpevpn *vpn) + { + /* if flooding has been globally disabled per-vni mode is +@@ -2766,7 +2813,7 @@ int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + /* Update Type-2/3 Routes for L2VNI. + * Called by hash_iterate() + */ +-static void update_routes_for_vni_hash(struct hash_bucket *bucket, ++void update_routes_for_vni_hash(struct hash_bucket *bucket, + struct bgp *bgp) + { + struct bgpevpn *vpn; +@@ -2784,7 +2831,7 @@ static void update_routes_for_vni_hash(struct hash_bucket *bucket, + * the per-VNI table. Invoked upon the VNI being deleted or EVPN + * (advertise-all-vni) being disabled. + */ +-static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) ++int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + { + int ret; + struct prefix_evpn p; +@@ -2795,7 +2842,22 @@ static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) delete_all_type2_routes(bgp, vpn); build_evpn_type3_prefix(&p, vpn->originator_ip); @@ -316,7 +830,518 @@ index 2b2cfa0f4c..622fd6afd2 100644 if (ret) return ret; -@@ -6028,6 +6098,17 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, +@@ -2809,7 +2871,7 @@ static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + * remove the type-3 route if any. A new type-3 route will be generated + * post tunnel_ip update if the new flood mode is head-end-replication. + */ +-static int bgp_evpn_mcast_grp_change(struct bgp *bgp, struct bgpevpn *vpn, ++int bgp_evpn_mcast_grp_change(struct bgp *bgp, struct bgpevpn *vpn, + struct in_addr mcast_grp) + { + struct prefix_evpn p; +@@ -2833,7 +2895,7 @@ static int bgp_evpn_mcast_grp_change(struct bgp *bgp, struct bgpevpn *vpn, + * Note: Route re-advertisement happens elsewhere after other processing + * other changes. + */ +-static void handle_tunnel_ip_change(struct bgp *bgp_vrf, struct bgp *bgp_evpn, ++void handle_tunnel_ip_change(struct bgp *bgp_vrf, struct bgp *bgp_evpn, + struct bgpevpn *vpn, + struct in_addr originator_ip) + { +@@ -2882,7 +2944,7 @@ static void handle_tunnel_ip_change(struct bgp *bgp_vrf, struct bgp *bgp_evpn, + return; + } + +-static struct bgp_path_info * ++struct bgp_path_info * + bgp_create_evpn_bgp_path_info(struct bgp_path_info *parent_pi, + struct bgp_dest *dest, struct attr *attr) + { +@@ -2918,7 +2980,7 @@ bgp_create_evpn_bgp_path_info(struct bgp_path_info *parent_pi, + /* + * Install route entry into the VRF routing table and invoke route selection. + */ +-static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, ++int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, + const struct prefix_evpn *evp, + struct bgp_path_info *parent_pi) + { +@@ -3102,7 +3164,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, + /* + * Common handling for vni route tables install/selection. + */ +-static int install_evpn_route_entry_in_vni_common( ++int install_evpn_route_entry_in_vni_common( + struct bgp *bgp, struct bgpevpn *vpn, const struct prefix_evpn *p, + struct bgp_dest *dest, struct bgp_path_info *parent_pi) + { +@@ -3202,7 +3264,7 @@ static int install_evpn_route_entry_in_vni_common( + /* + * Common handling for vni route tables uninstall/selection. + */ +-static int uninstall_evpn_route_entry_in_vni_common( ++int uninstall_evpn_route_entry_in_vni_common( + struct bgp *bgp, struct bgpevpn *vpn, const struct prefix_evpn *p, + struct bgp_dest *dest, struct bgp_path_info *parent_pi) + { +@@ -3243,7 +3305,7 @@ static int uninstall_evpn_route_entry_in_vni_common( + /* + * Install route entry into VNI IP table and invoke route selection. + */ +-static int install_evpn_route_entry_in_vni_ip(struct bgp *bgp, ++int install_evpn_route_entry_in_vni_ip(struct bgp *bgp, + struct bgpevpn *vpn, + const struct prefix_evpn *p, + struct bgp_path_info *parent_pi) +@@ -3270,7 +3332,7 @@ static int install_evpn_route_entry_in_vni_ip(struct bgp *bgp, + /* + * Install route entry into VNI MAC table and invoke route selection. + */ +-static int install_evpn_route_entry_in_vni_mac(struct bgp *bgp, ++int install_evpn_route_entry_in_vni_mac(struct bgp *bgp, + struct bgpevpn *vpn, + const struct prefix_evpn *p, + struct bgp_path_info *parent_pi) +@@ -3296,7 +3358,7 @@ static int install_evpn_route_entry_in_vni_mac(struct bgp *bgp, + /* + * Uninstall route entry from VNI IP table and invoke route selection. + */ +-static int uninstall_evpn_route_entry_in_vni_ip(struct bgp *bgp, ++int uninstall_evpn_route_entry_in_vni_ip(struct bgp *bgp, + struct bgpevpn *vpn, + const struct prefix_evpn *p, + struct bgp_path_info *parent_pi) +@@ -3325,7 +3387,7 @@ static int uninstall_evpn_route_entry_in_vni_ip(struct bgp *bgp, + /* + * Uninstall route entry from VNI IP table and invoke route selection. + */ +-static int ++int + uninstall_evpn_route_entry_in_vni_mac(struct bgp *bgp, struct bgpevpn *vpn, + const struct prefix_evpn *p, + struct bgp_path_info *parent_pi) +@@ -3353,7 +3415,7 @@ uninstall_evpn_route_entry_in_vni_mac(struct bgp *bgp, struct bgpevpn *vpn, + * Uninstall route entry from the VRF routing table and send message + * to zebra, if appropriate. + */ +-static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, ++int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, + const struct prefix_evpn *evp, + struct bgp_path_info *parent_pi) + { +@@ -3445,7 +3507,7 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, + /* + * Install route entry into the VNI routing tables. + */ +-static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, ++int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, + const struct prefix_evpn *p, + struct bgp_path_info *parent_pi) + { +@@ -3484,7 +3546,7 @@ static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, + /* + * Uninstall route entry from the VNI routing tables. + */ +-static int uninstall_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, ++int uninstall_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, + const struct prefix_evpn *p, + struct bgp_path_info *parent_pi) + { +@@ -3524,7 +3586,7 @@ static int uninstall_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, + * Given a route entry and a VRF, see if this route entry should be + * imported into the VRF i.e., RTs match + Site-of-Origin check passes. + */ +-static int is_route_matching_for_vrf(struct bgp *bgp_vrf, ++int is_route_matching_for_vrf(struct bgp *bgp_vrf, + struct bgp_path_info *pi) + { + struct attr *attr = pi->attr; +@@ -3591,7 +3653,7 @@ static int is_route_matching_for_vrf(struct bgp *bgp_vrf, + * Given a route entry and a VNI, see if this route entry should be + * imported into the VNI i.e., RTs match. + */ +-static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn, ++int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn, + struct bgp_path_info *pi) + { + struct attr *attr = pi->attr; +@@ -3654,7 +3716,7 @@ static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn, + return 0; + } + +-static bool bgp_evpn_route_matches_macvrf_soo(struct bgp_path_info *pi, ++bool bgp_evpn_route_matches_macvrf_soo(struct bgp_path_info *pi, + const struct prefix_evpn *evp) + { + struct bgp *bgp_evpn = bgp_get_evpn(); +@@ -3693,7 +3755,7 @@ static bool bgp_evpn_route_matches_macvrf_soo(struct bgp_path_info *pi, + * macthes with bgp instance router mac. It avoid installing + * route into bgp vrf table and remote rmac in bridge table. + */ +-static int bgp_evpn_route_rmac_self_check(struct bgp *bgp_vrf, ++int bgp_evpn_route_rmac_self_check(struct bgp *bgp_vrf, + const struct prefix_evpn *evp, + struct bgp_path_info *pi) + { +@@ -3722,7 +3784,7 @@ static int bgp_evpn_route_rmac_self_check(struct bgp *bgp_vrf, + } + + /* don't import hosts that are locally attached */ +-static inline bool ++inline bool + bgp_evpn_skip_vrf_import_of_local_es(struct bgp *bgp_vrf, + const struct prefix_evpn *evp, + struct bgp_path_info *pi, int install) +@@ -3799,7 +3861,7 @@ int bgp_evpn_route_entry_install_if_vrf_match(struct bgp *bgp_vrf, + * Install or uninstall mac-ip routes are appropriate for this + * particular VRF. + */ +-static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) ++int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) + { + afi_t afi; + safi_t safi; +@@ -3862,7 +3924,7 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) + * Install or uninstall routes of specified type that are appropriate for this + * particular VNI. + */ +-static int install_uninstall_routes_for_vni(struct bgp *bgp, ++int install_uninstall_routes_for_vni(struct bgp *bgp, + struct bgpevpn *vpn, + bgp_evpn_route_type rtype, + int install) +@@ -3948,7 +4010,7 @@ static int install_uninstall_routes_for_vni(struct bgp *bgp, + /* Install any existing remote routes applicable for this VRF into VRF RIB. This + * is invoked upon l3vni-add or l3vni import rt change + */ +-static int install_routes_for_vrf(struct bgp *bgp_vrf) ++int install_routes_for_vrf(struct bgp *bgp_vrf) + { + install_uninstall_routes_for_vrf(bgp_vrf, 1); + return 0; +@@ -3959,7 +4021,7 @@ static int install_routes_for_vrf(struct bgp *bgp_vrf) + * routing table. This is invoked when a VNI becomes "live" or its Import + * RT is changed. + */ +-static int install_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) ++int install_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + { + int ret; + +@@ -3981,7 +4043,7 @@ static int install_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + } + + /* uninstall routes from l3vni vrf. */ +-static int uninstall_routes_for_vrf(struct bgp *bgp_vrf) ++int uninstall_routes_for_vrf(struct bgp *bgp_vrf) + { + install_uninstall_routes_for_vrf(bgp_vrf, 0); + return 0; +@@ -3991,7 +4053,7 @@ static int uninstall_routes_for_vrf(struct bgp *bgp_vrf) + * Uninstall any existing remote routes for this VNI. One scenario in which + * this is invoked is upon an import RT change. + */ +-static int uninstall_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) ++int uninstall_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + { + int ret; + +@@ -4017,7 +4079,7 @@ static int uninstall_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + /* + * Install or uninstall route in matching VRFs (list). + */ +-static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi, ++int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi, + safi_t safi, struct prefix_evpn *evp, + struct bgp_path_info *pi, + struct list *vrfs, int install) +@@ -4066,7 +4128,7 @@ static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi, + /* + * Install or uninstall route in matching VNIs (list). + */ +-static int install_uninstall_route_in_vnis(struct bgp *bgp, afi_t afi, ++int install_uninstall_route_in_vnis(struct bgp *bgp, afi_t afi, + safi_t safi, struct prefix_evpn *evp, + struct bgp_path_info *pi, + struct list *vnis, int install) +@@ -4103,7 +4165,7 @@ static int install_uninstall_route_in_vnis(struct bgp *bgp, afi_t afi, + /* + * Install or uninstall route for appropriate VNIs/ESIs. + */ +-static int bgp_evpn_install_uninstall_table(struct bgp *bgp, afi_t afi, ++int bgp_evpn_install_uninstall_table(struct bgp *bgp, afi_t afi, + safi_t safi, const struct prefix *p, + struct bgp_path_info *pi, + int import, bool in_vni_rt, +@@ -4246,7 +4308,7 @@ static int bgp_evpn_install_uninstall_table(struct bgp *bgp, afi_t afi, + /* + * Install or uninstall route for appropriate VNIs/ESIs. + */ +-static int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi, ++int install_uninstall_evpn_route(struct bgp *bgp, afi_t afi, safi_t safi, + const struct prefix *p, + struct bgp_path_info *pi, int import) + { +@@ -4270,7 +4332,7 @@ void bgp_evpn_import_type2_route(struct bgp_path_info *pi, int import) + * delete and withdraw all ipv4 and ipv6 routes in the vrf table as type-5 + * routes + */ +-static void delete_withdraw_vrf_routes(struct bgp *bgp_vrf) ++void delete_withdraw_vrf_routes(struct bgp *bgp_vrf) + { + /* Delete ipv4 default route and withdraw from peers */ + if (evpn_default_originate_set(bgp_vrf, AFI_IP, SAFI_UNICAST)) +@@ -4329,7 +4391,7 @@ void update_advertise_vrf_routes(struct bgp *bgp_vrf) + * done in the global route table using the routes which already exist in the + * VRF routing table + */ +-static void update_router_id_vrf(struct bgp *bgp_vrf) ++void update_router_id_vrf(struct bgp *bgp_vrf) + { + /* skip if the RD is configured */ + if (is_vrf_rd_configured(bgp_vrf)) +@@ -4347,7 +4409,7 @@ static void update_router_id_vrf(struct bgp *bgp_vrf) + * This is invoked upon VRF RD change. The processing is done only from global + * table. + */ +-static void withdraw_router_id_vrf(struct bgp *bgp_vrf) ++void withdraw_router_id_vrf(struct bgp *bgp_vrf) + { + /* skip if the RD is configured */ + if (is_vrf_rd_configured(bgp_vrf)) +@@ -4357,7 +4419,7 @@ static void withdraw_router_id_vrf(struct bgp *bgp_vrf) + delete_withdraw_vrf_routes(bgp_vrf); + } + +-static void update_advertise_vni_route(struct bgp *bgp, struct bgpevpn *vpn, ++void update_advertise_vni_route(struct bgp *bgp, struct bgpevpn *vpn, + struct bgp_dest *dest) + { + struct bgp_dest *global_dest; +@@ -4440,7 +4502,7 @@ static void update_advertise_vni_route(struct bgp *bgp, struct bgpevpn *vpn, + * change. Note that the processing is done only on the global route table + * using routes that already exist in the per-VNI table. + */ +-static void update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) ++void update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) + { + struct prefix_evpn p; + struct bgp_dest *dest, *global_dest; +@@ -4501,7 +4563,7 @@ static void update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) + * Delete (and withdraw) local routes for a VNI - only from the global + * table. Invoked upon router-id change. + */ +-static int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) ++int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) + { + struct prefix_evpn p; + struct bgp_dest *global_dest; +@@ -4541,7 +4603,7 @@ static int delete_withdraw_vni_routes(struct bgp *bgp, struct bgpevpn *vpn) + * router-id. The routes in the per-VNI table are used to create routes in + * the global table and schedule them. + */ +-static void update_router_id_vni(struct hash_bucket *bucket, struct bgp *bgp) ++void update_router_id_vni(struct hash_bucket *bucket, struct bgp *bgp) + { + struct bgpevpn *vpn = (struct bgpevpn *)bucket->data; + +@@ -4559,7 +4621,7 @@ static void update_router_id_vni(struct hash_bucket *bucket, struct bgp *bgp) + * the router-id and is done only on the global route table, the routes + * are needed in the per-VNI table to re-advertise with new router id. + */ +-static void withdraw_router_id_vni(struct hash_bucket *bucket, struct bgp *bgp) ++void withdraw_router_id_vni(struct hash_bucket *bucket, struct bgp *bgp) + { + struct bgpevpn *vpn = (struct bgpevpn *)bucket->data; + +@@ -4574,7 +4636,7 @@ static void withdraw_router_id_vni(struct hash_bucket *bucket, struct bgp *bgp) + * Create RT-3 for a VNI and schedule for processing and advertisement. + * This is invoked upon flooding mode changing to head-end replication. + */ +-static void create_advertise_type3(struct hash_bucket *bucket, void *data) ++void create_advertise_type3(struct hash_bucket *bucket, void *data) + { + struct bgpevpn *vpn = bucket->data; + struct bgp *bgp = data; +@@ -4595,7 +4657,7 @@ static void create_advertise_type3(struct hash_bucket *bucket, void *data) + * Delete RT-3 for a VNI and schedule for processing and withdrawal. + * This is invoked upon flooding mode changing to drop BUM packets. + */ +-static void delete_withdraw_type3(struct hash_bucket *bucket, void *data) ++void delete_withdraw_type3(struct hash_bucket *bucket, void *data) + { + struct bgpevpn *vpn = bucket->data; + struct bgp *bgp = data; +@@ -4611,7 +4673,7 @@ static void delete_withdraw_type3(struct hash_bucket *bucket, void *data) + /* + * Process received EVPN type-2 route (advertise or withdraw). + */ +-static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, ++int process_type2_route(struct peer *peer, afi_t afi, safi_t safi, + struct attr *attr, uint8_t *pfx, int psize, + uint32_t addpath_id) + { +@@ -4740,7 +4802,7 @@ done: + /* + * Process received EVPN type-3 route (advertise or withdraw). + */ +-static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, ++int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, + struct attr *attr, uint8_t *pfx, int psize, + uint32_t addpath_id) + { +@@ -4821,7 +4883,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi, + /* + * Process received EVPN type-5 route (advertise or withdraw). + */ +-static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, ++int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, + struct attr *attr, uint8_t *pfx, int psize, + uint32_t addpath_id) + { +@@ -4963,7 +5025,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, + return 0; + } + +-static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p, ++void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p, + const struct prefix_rd *prd, + mpls_label_t *label, uint32_t num_labels, + struct attr *attr) +@@ -5022,7 +5084,7 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p, + /* + * Cleanup specific VNI upon EVPN (advertise-all-vni) being disabled. + */ +-static void cleanup_vni_on_disable(struct hash_bucket *bucket, struct bgp *bgp) ++void cleanup_vni_on_disable(struct hash_bucket *bucket, struct bgp *bgp) + { + struct bgpevpn *vpn = (struct bgpevpn *)bucket->data; + +@@ -5038,7 +5100,7 @@ static void cleanup_vni_on_disable(struct hash_bucket *bucket, struct bgp *bgp) + /* + * Free a VNI entry; iterator function called during cleanup. + */ +-static void free_vni_entry(struct hash_bucket *bucket, struct bgp *bgp) ++void free_vni_entry(struct hash_bucket *bucket, struct bgp *bgp) + { + struct bgpevpn *vpn = (struct bgpevpn *)bucket->data; + +@@ -5049,7 +5111,7 @@ static void free_vni_entry(struct hash_bucket *bucket, struct bgp *bgp) + /* + * Derive AUTO import RT for BGP VRF - L3VNI + */ +-static void evpn_auto_rt_import_add_for_vrf(struct bgp *bgp_vrf) ++void evpn_auto_rt_import_add_for_vrf(struct bgp *bgp_vrf) + { + struct bgp *bgp_evpn = NULL; + +@@ -5067,7 +5129,7 @@ static void evpn_auto_rt_import_add_for_vrf(struct bgp *bgp_vrf) + /* + * Delete AUTO import RT from BGP VRF - L3VNI + */ +-static void evpn_auto_rt_import_delete_for_vrf(struct bgp *bgp_vrf) ++void evpn_auto_rt_import_delete_for_vrf(struct bgp *bgp_vrf) + { + evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl, + true); +@@ -5076,7 +5138,7 @@ static void evpn_auto_rt_import_delete_for_vrf(struct bgp *bgp_vrf) + /* + * Derive AUTO export RT for BGP VRF - L3VNI + */ +-static void evpn_auto_rt_export_add_for_vrf(struct bgp *bgp_vrf) ++void evpn_auto_rt_export_add_for_vrf(struct bgp *bgp_vrf) + { + form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl, true); + } +@@ -5084,13 +5146,13 @@ static void evpn_auto_rt_export_add_for_vrf(struct bgp *bgp_vrf) + /* + * Delete AUTO export RT from BGP VRF - L3VNI + */ +-static void evpn_auto_rt_export_delete_for_vrf(struct bgp *bgp_vrf) ++void evpn_auto_rt_export_delete_for_vrf(struct bgp *bgp_vrf) + { + evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl, + true); + } + +-static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf) ++void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf) + { + struct bgp *bgp_evpn = NULL; + struct listnode *node = NULL; +@@ -5111,7 +5173,7 @@ static void bgp_evpn_handle_export_rt_change_for_vrf(struct bgp *bgp_vrf) + /* + * Handle autort change for a given VNI. + */ +-static void update_autort_vni(struct hash_bucket *bucket, struct bgp *bgp) ++void update_autort_vni(struct hash_bucket *bucket, struct bgp *bgp) + { + struct bgpevpn *vpn = bucket->data; + +@@ -5135,7 +5197,7 @@ static void update_autort_vni(struct hash_bucket *bucket, struct bgp *bgp) + /* + * Handle autort change for L3VNI. + */ +-static void update_autort_l3vni(struct bgp *bgp) ++void update_autort_l3vni(struct bgp *bgp) + { + if ((CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) + && (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD))) +@@ -5330,7 +5392,7 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi, + } + } + +-static void rt_list_remove_node(struct list *rt_list, ++void rt_list_remove_node(struct list *rt_list, + struct ecommunity *ecomdel, bool is_l3) + { + struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL; +@@ -5379,7 +5441,7 @@ void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl, + ecommunity_free(&ecom_auto); + } + +-static void evpn_vrf_rt_routes_map(struct bgp *bgp_vrf) ++void evpn_vrf_rt_routes_map(struct bgp *bgp_vrf) + { + /* map VRFs to its RTs and install routes matching this new RT */ + if (is_l3vni_live(bgp_vrf)) { +@@ -5388,7 +5450,7 @@ static void evpn_vrf_rt_routes_map(struct bgp *bgp_vrf) + } + } + +-static void evpn_vrf_rt_routes_unmap(struct bgp *bgp_vrf) ++void evpn_vrf_rt_routes_unmap(struct bgp *bgp_vrf) + { + /* uninstall routes from vrf */ + if (is_l3vni_live(bgp_vrf)) +@@ -5398,7 +5460,7 @@ static void evpn_vrf_rt_routes_unmap(struct bgp *bgp_vrf) + bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf); + } + +-static bool rt_list_has_cfgd_rt(struct list *rt_list) ++bool rt_list_has_cfgd_rt(struct list *rt_list) + { + struct listnode *node = NULL, *nnode = NULL; + struct vrf_route_target *l3rt = NULL; +@@ -5411,7 +5473,7 @@ static bool rt_list_has_cfgd_rt(struct list *rt_list) + return false; + } + +-static void unconfigure_import_rt_for_vrf_fini(struct bgp *bgp_vrf) ++void unconfigure_import_rt_for_vrf_fini(struct bgp *bgp_vrf) + { + if (!bgp_vrf->vrf_import_rtl) + return; /* this should never fail */ +@@ -5424,7 +5486,7 @@ static void unconfigure_import_rt_for_vrf_fini(struct bgp *bgp_vrf) + evpn_auto_rt_import_add_for_vrf(bgp_vrf); + } + +-static void unconfigure_export_rt_for_vrf_fini(struct bgp *bgp_vrf) ++void unconfigure_export_rt_for_vrf_fini(struct bgp *bgp_vrf) + { + + if (!bgp_vrf->vrf_export_rtl) +@@ -6262,6 +6324,16 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, */ void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn) { @@ -330,52 +1355,240 @@ index 2b2cfa0f4c..622fd6afd2 100644 + } else + zebra_announce_add_tail(&bm->zebra_announce_head, dest); + } -+ bgp_evpn_remote_ip_hash_destroy(vpn); bgp_evpn_vni_es_cleanup(vpn); bgpevpn_unlink_from_l3vni(vpn); +@@ -6279,7 +6351,7 @@ void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn) + XFREE(MTYPE_BGP_EVPN, vpn); + } + +-static void hash_evpn_free(struct bgpevpn *vpn) ++void hash_evpn_free(struct bgpevpn *vpn) + { + XFREE(MTYPE_BGP_EVPN, vpn); + } +@@ -6646,7 +6718,7 @@ int bgp_evpn_local_macip_add(struct bgp *bgp, vni_t vni, struct ethaddr *mac, + return 0; + } + +-static void link_l2vni_hash_to_l3vni(struct hash_bucket *bucket, ++void link_l2vni_hash_to_l3vni(struct hash_bucket *bucket, + struct bgp *bgp_vrf) + { + struct bgpevpn *vpn = (struct bgpevpn *)bucket->data; +@@ -7265,7 +7337,7 @@ bool bgp_evpn_is_prefix_nht_supported(const struct prefix *pfx) + return false; + } + +-static void *bgp_evpn_remote_ip_hash_alloc(void *p) ++void *bgp_evpn_remote_ip_hash_alloc(void *p) + { + const struct evpn_remote_ip *key = (const struct evpn_remote_ip *)p; + struct evpn_remote_ip *ip; +@@ -7277,7 +7349,7 @@ static void *bgp_evpn_remote_ip_hash_alloc(void *p) + return ip; + } + +-static unsigned int bgp_evpn_remote_ip_hash_key_make(const void *p) ++unsigned int bgp_evpn_remote_ip_hash_key_make(const void *p) + { + const struct evpn_remote_ip *ip = p; + const struct ipaddr *addr = &ip->addr; +@@ -7289,7 +7361,7 @@ static unsigned int bgp_evpn_remote_ip_hash_key_make(const void *p) + array_size(addr->ipaddr_v6.s6_addr32), 0); + } + +-static bool bgp_evpn_remote_ip_hash_cmp(const void *p1, const void *p2) ++bool bgp_evpn_remote_ip_hash_cmp(const void *p1, const void *p2) + { + const struct evpn_remote_ip *ip1 = p1; + const struct evpn_remote_ip *ip2 = p2; +@@ -7297,7 +7369,7 @@ static bool bgp_evpn_remote_ip_hash_cmp(const void *p1, const void *p2) + return !ipaddr_cmp(&ip1->addr, &ip2->addr); + } + +-static void bgp_evpn_remote_ip_hash_init(struct bgpevpn *vpn) ++void bgp_evpn_remote_ip_hash_init(struct bgpevpn *vpn) + { + if (!evpn_resolve_overlay_index()) + return; +@@ -7307,7 +7379,7 @@ static void bgp_evpn_remote_ip_hash_init(struct bgpevpn *vpn) + "BGP EVPN remote IP hash"); + } + +-static void bgp_evpn_remote_ip_hash_free(struct hash_bucket *bucket, void *args) ++void bgp_evpn_remote_ip_hash_free(struct hash_bucket *bucket, void *args) + { + struct evpn_remote_ip *ip = (struct evpn_remote_ip *)bucket->data; + struct bgpevpn *vpn = (struct bgpevpn *)args; +@@ -7320,7 +7392,7 @@ static void bgp_evpn_remote_ip_hash_free(struct hash_bucket *bucket, void *args) + XFREE(MTYPE_EVPN_REMOTE_IP, ip); + } + +-static void bgp_evpn_remote_ip_hash_destroy(struct bgpevpn *vpn) ++void bgp_evpn_remote_ip_hash_destroy(struct bgpevpn *vpn) + { + if (!evpn_resolve_overlay_index() || vpn->remote_ip_hash == NULL) + return; +@@ -7334,7 +7406,7 @@ static void bgp_evpn_remote_ip_hash_destroy(struct bgpevpn *vpn) + } + + /* Add a remote MAC/IP route to hash table */ +-static void bgp_evpn_remote_ip_hash_add(struct bgpevpn *vpn, ++void bgp_evpn_remote_ip_hash_add(struct bgpevpn *vpn, + struct bgp_path_info *pi) + { + struct evpn_remote_ip tmp; +@@ -7371,7 +7443,7 @@ static void bgp_evpn_remote_ip_hash_add(struct bgpevpn *vpn, + } + + /* Delete a remote MAC/IP route from hash table */ +-static void bgp_evpn_remote_ip_hash_del(struct bgpevpn *vpn, ++void bgp_evpn_remote_ip_hash_del(struct bgpevpn *vpn, + struct bgp_path_info *pi) + { + struct evpn_remote_ip tmp; +@@ -7403,7 +7475,7 @@ static void bgp_evpn_remote_ip_hash_del(struct bgpevpn *vpn, + } + } + +-static void bgp_evpn_remote_ip_hash_iterate(struct bgpevpn *vpn, ++void bgp_evpn_remote_ip_hash_iterate(struct bgpevpn *vpn, + void (*func)(struct hash_bucket *, + void *), + void *arg) +@@ -7414,7 +7486,7 @@ static void bgp_evpn_remote_ip_hash_iterate(struct bgpevpn *vpn, + hash_iterate(vpn->remote_ip_hash, func, arg); + } + +-static void show_remote_ip_entry(struct hash_bucket *bucket, void *args) ++void show_remote_ip_entry(struct hash_bucket *bucket, void *args) + { + char buf[INET6_ADDRSTRLEN]; + struct listnode *node = NULL; +@@ -7442,7 +7514,7 @@ void bgp_evpn_show_remote_ip_hash(struct hash_bucket *bucket, void *args) + vty_out(vty, "\n"); + } + +-static void bgp_evpn_remote_ip_hash_link_nexthop(struct hash_bucket *bucket, ++void bgp_evpn_remote_ip_hash_link_nexthop(struct hash_bucket *bucket, + void *args) + { + struct evpn_remote_ip *ip = (struct evpn_remote_ip *)bucket->data; +@@ -7451,7 +7523,7 @@ static void bgp_evpn_remote_ip_hash_link_nexthop(struct hash_bucket *bucket, + bgp_evpn_remote_ip_process_nexthops(vpn, &ip->addr, true); + } + +-static void bgp_evpn_remote_ip_hash_unlink_nexthop(struct hash_bucket *bucket, ++void bgp_evpn_remote_ip_hash_unlink_nexthop(struct hash_bucket *bucket, + void *args) + { + struct evpn_remote_ip *ip = (struct evpn_remote_ip *)bucket->data; +@@ -7460,14 +7532,14 @@ static void bgp_evpn_remote_ip_hash_unlink_nexthop(struct hash_bucket *bucket, + bgp_evpn_remote_ip_process_nexthops(vpn, &ip->addr, false); + } + +-static unsigned int vni_svi_hash_key_make(const void *p) ++unsigned int vni_svi_hash_key_make(const void *p) + { + const struct bgpevpn *vpn = p; + + return jhash_1word(vpn->svi_ifindex, 0); + } + +-static bool vni_svi_hash_cmp(const void *p1, const void *p2) ++bool vni_svi_hash_cmp(const void *p1, const void *p2) + { + const struct bgpevpn *vpn1 = p1; + const struct bgpevpn *vpn2 = p2; +@@ -7475,7 +7547,7 @@ static bool vni_svi_hash_cmp(const void *p1, const void *p2) + return (vpn1->svi_ifindex == vpn2->svi_ifindex); + } + +-static struct bgpevpn *bgp_evpn_vni_svi_hash_lookup(struct bgp *bgp, ++struct bgpevpn *bgp_evpn_vni_svi_hash_lookup(struct bgp *bgp, + ifindex_t svi) + { + struct bgpevpn *vpn; +@@ -7487,7 +7559,7 @@ static struct bgpevpn *bgp_evpn_vni_svi_hash_lookup(struct bgp *bgp, + return vpn; + } + +-static void bgp_evpn_link_to_vni_svi_hash(struct bgp *bgp, struct bgpevpn *vpn) ++void bgp_evpn_link_to_vni_svi_hash(struct bgp *bgp, struct bgpevpn *vpn) + { + if (vpn->svi_ifindex == 0) + return; +@@ -7495,7 +7567,7 @@ static void bgp_evpn_link_to_vni_svi_hash(struct bgp *bgp, struct bgpevpn *vpn) + (void)hash_get(bgp->vni_svi_hash, vpn, hash_alloc_intern); + } + +-static void bgp_evpn_unlink_from_vni_svi_hash(struct bgp *bgp, ++void bgp_evpn_unlink_from_vni_svi_hash(struct bgp *bgp, + struct bgpevpn *vpn) + { + if (vpn->svi_ifindex == 0) +@@ -7572,7 +7644,7 @@ bool bgp_evpn_is_gateway_ip_resolved(struct bgp_nexthop_cache *bnc) + } + + /* Resolve/Unresolve nexthops when a MAC/IP route is added/deleted */ +-static void bgp_evpn_remote_ip_process_nexthops(struct bgpevpn *vpn, ++void bgp_evpn_remote_ip_process_nexthops(struct bgpevpn *vpn, + struct ipaddr *addr, + bool resolve) + { +@@ -7695,7 +7767,7 @@ vni_t bgp_evpn_path_info_get_l3vni(const struct bgp_path_info *pi) + /* + * Returns true if the l3vni of any of this path doesn't match vrf's l3vni. + */ +-static bool bgp_evpn_path_is_dvni(const struct bgp *bgp_vrf, ++bool bgp_evpn_path_is_dvni(const struct bgp *bgp_vrf, + const struct bgp_path_info *pi) + { + vni_t vni = 0; +@@ -7781,4 +7853,5 @@ void bgp_aggr_supp_withdraw_from_evpn(struct bgp *bgp, afi_t afi, safi_t safi) + } + } + } +-} ++ return; ++} +\ No newline at end of file diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h -index 3cbc5af5af..bf1943a2db 100644 +index c641a64f6..db05293a4 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h -@@ -230,4 +230,12 @@ extern void +@@ -176,6 +176,14 @@ bgp_evpn_handle_resolve_overlay_index_set(struct hash_bucket *bucket, + extern void bgp_evpn_handle_resolve_overlay_index_unset(struct hash_bucket *bucket, void *arg); - +extern enum zclient_send_status evpn_zebra_install(struct bgp *bgp, -+ struct bgpevpn *vpn, -+ const struct prefix_evpn *p, -+ struct bgp_path_info *pi); ++ struct bgpevpn *vpn, ++ const struct prefix_evpn *p, ++ struct bgp_path_info *pi); +extern enum zclient_send_status +evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn, + const struct prefix_evpn *p, struct bgp_path_info *pi, + bool is_sync); - #endif /* _QUAGGA_BGP_EVPN_H */ + extern mpls_label_t *bgp_evpn_path_info_labels_get_l3vni(mpls_label_t *labels, + uint32_t num_labels); + extern vni_t bgp_evpn_path_info_get_l3vni(const struct bgp_path_info *pi); diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c -index 552365959d..40687c558d 100644 +index d88c52d1f..f36d109b6 100644 --- a/bgpd/bgp_evpn_mh.c +++ b/bgpd/bgp_evpn_mh.c -@@ -56,13 +56,14 @@ static void bgp_evpn_local_es_down(struct bgp *bgp, - struct bgp_evpn_es *es); - static void bgp_evpn_local_type1_evi_route_del(struct bgp *bgp, - struct bgp_evpn_es *es); --static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp, -+static struct bgp_evpn_es_vtep * -+bgp_evpn_es_vtep_add(struct bgp *bgp, struct bgp_evpn_es *es, -+ struct in_addr vtep_ip, bool esr, uint8_t df_alg, -+ uint16_t df_pref, int *zret); -+static enum zclient_send_status bgp_evpn_es_vtep_del(struct bgp *bgp, +@@ -49,8 +49,8 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp, struct bgp_evpn_es *es, struct in_addr vtep_ip, -- bool esr, uint8_t df_alg, + bool esr, uint8_t df_alg, - uint16_t df_pref); -static void bgp_evpn_es_vtep_del(struct bgp *bgp, -- struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr); -+ bool esr); ++ uint16_t df_pref, int *zret); ++static enum zclient_send_status bgp_evpn_es_vtep_del(struct bgp *bgp, + struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr); static void bgp_evpn_es_cons_checks_pend_add(struct bgp_evpn_es *es); static void bgp_evpn_es_cons_checks_pend_del(struct bgp_evpn_es *es); - static struct bgp_evpn_es_evi * -@@ -105,6 +106,7 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp, +@@ -94,6 +94,7 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp, struct bgp_dest *dest) { int ret = 0; @@ -383,7 +1596,7 @@ index 552365959d..40687c558d 100644 afi_t afi = AFI_L2VPN; safi_t safi = SAFI_EVPN; struct bgp_path_info *old_select; /* old best */ -@@ -131,7 +133,7 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp, +@@ -120,7 +121,7 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp, bgp_evpn_es_vtep_add(bgp, es, old_select->attr->nexthop, true /*esr*/, old_select->attr->df_alg, @@ -392,7 +1605,7 @@ index 552365959d..40687c558d 100644 } UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG); bgp_zebra_clear_route_change_flags(dest); -@@ -160,7 +162,7 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp, +@@ -149,7 +150,7 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp, && new_select->sub_type == BGP_ROUTE_IMPORTED) { bgp_evpn_es_vtep_add(bgp, es, new_select->attr->nexthop, true /*esr */, new_select->attr->df_alg, @@ -401,30 +1614,19 @@ index 552365959d..40687c558d 100644 } else { if (old_select && old_select->type == ZEBRA_ROUTE_BGP && old_select->sub_type == BGP_ROUTE_IMPORTED) -@@ -447,7 +449,7 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es, - &attr->mp_nexthop_global_in); - } - -- /* Return back the route entry. */ -+ /* Return back th*e route entry. */ - *ri = tmp_pi; - return 0; - } -@@ -1366,23 +1368,28 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_find(struct bgp_evpn_es *es, +@@ -1371,23 +1372,26 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_find(struct bgp_evpn_es *es, } /* Send the remote ES to zebra for NHG programming */ -static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp, -- struct bgp_evpn_es_vtep *es_vtep, bool add) -+static enum zclient_send_status -+bgp_zebra_send_remote_es_vtep(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep, -+ bool add) ++static enum zclient_send_status bgp_zebra_send_remote_es_vtep(struct bgp *bgp, + struct bgp_evpn_es_vtep *es_vtep, bool add) { struct bgp_evpn_es *es = es_vtep->es; struct stream *s; uint32_t flags = 0; - /* Check socket. */ +- /* Check socket. */ - if (!zclient || zclient->sock < 0) - return 0; + if (!zclient || zclient->sock < 0) { @@ -444,15 +1646,14 @@ index 552365959d..40687c558d 100644 } if (es_vtep->flags & BGP_EVPNES_VTEP_ESR) -@@ -1413,12 +1420,12 @@ static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp, +@@ -1418,12 +1422,13 @@ static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp, return zclient_send_message(zclient); } -static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp, -- struct bgp_evpn_es_vtep *es_vtep, -- bool param_change) -+static enum zclient_send_status bgp_evpn_es_vtep_re_eval_active( -+ struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep, bool param_change) ++static enum zclient_send_status bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp, + struct bgp_evpn_es_vtep *es_vtep, + bool param_change) { bool old_active; bool new_active; @@ -460,7 +1661,7 @@ index 552365959d..40687c558d 100644 old_active = CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE); /* currently we need an active EVI reference to use the VTEP as -@@ -1440,7 +1447,7 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp, +@@ -1445,7 +1450,7 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp, es_vtep->df_alg, es_vtep->df_pref); /* send remote ES to zebra */ @@ -469,27 +1670,23 @@ index 552365959d..40687c558d 100644 /* The NHG is updated first for efficient failover handling. * Note the NHG can be de-activated while there are bgp -@@ -1452,13 +1459,14 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp, +@@ -1457,13 +1462,14 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp, /* queue up the es for background consistency checks */ bgp_evpn_es_cons_checks_pend_add(es_vtep->es); } -+ + return ret; } --static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp, -- struct bgp_evpn_es *es, -- struct in_addr vtep_ip, -- bool esr, uint8_t df_alg, + static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp, + struct bgp_evpn_es *es, + struct in_addr vtep_ip, + bool esr, uint8_t df_alg, - uint16_t df_pref) -+static struct bgp_evpn_es_vtep * -+bgp_evpn_es_vtep_add(struct bgp *bgp, struct bgp_evpn_es *es, -+ struct in_addr vtep_ip, bool esr, uint8_t df_alg, -+ uint16_t df_pref, int *zret) ++ uint16_t df_pref, int *zret) { struct bgp_evpn_es_vtep *es_vtep; bool param_change = false; -@@ -1485,15 +1493,17 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp, +@@ -1490,15 +1496,16 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp, ++es_vtep->evi_cnt; } @@ -500,33 +1697,27 @@ index 552365959d..40687c558d 100644 } -static void bgp_evpn_es_vtep_do_del(struct bgp *bgp, -- struct bgp_evpn_es_vtep *es_vtep, bool esr) -+static enum zclient_send_status -+bgp_evpn_es_vtep_do_del(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep, -+ bool esr) ++static enum zclient_send_status bgp_evpn_es_vtep_do_del(struct bgp *bgp, + struct bgp_evpn_es_vtep *es_vtep, bool esr) { bool param_change = false; + enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS; if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) zlog_debug("es %s vtep %pI4 del %s", es_vtep->es->esi_str, -@@ -1510,18 +1520,25 @@ static void bgp_evpn_es_vtep_do_del(struct bgp *bgp, +@@ -1515,18 +1522,21 @@ static void bgp_evpn_es_vtep_do_del(struct bgp *bgp, --es_vtep->evi_cnt; } - bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep, param_change); + ret = bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep, param_change); bgp_evpn_es_vtep_free(es_vtep); -+ + return ret; } -static void bgp_evpn_es_vtep_del(struct bgp *bgp, -- struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr) +static enum zclient_send_status bgp_evpn_es_vtep_del(struct bgp *bgp, -+ struct bgp_evpn_es *es, -+ struct in_addr vtep_ip, -+ bool esr) + struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr) { struct bgp_evpn_es_vtep *es_vtep; + enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS; @@ -535,20 +1726,17 @@ index 552365959d..40687c558d 100644 if (es_vtep) - bgp_evpn_es_vtep_do_del(bgp, es_vtep, esr); + ret = bgp_evpn_es_vtep_do_del(bgp, es_vtep, esr); -+ + return ret; } /********************** ES MAC-IP paths ************************************* -@@ -3382,12 +3399,14 @@ static struct bgp_evpn_es_evi_vtep *bgp_evpn_es_evi_vtep_find( +@@ -3399,12 +3409,13 @@ static struct bgp_evpn_es_evi_vtep *bgp_evpn_es_evi_vtep_find( /* A VTEP can be added as "active" attach to an ES if EAD-per-ES and * EAD-per-EVI routes are rxed from it. */ -static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp, -- struct bgp_evpn_es_evi_vtep *evi_vtep) -+static enum zclient_send_status -+bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp, -+ struct bgp_evpn_es_evi_vtep *evi_vtep) ++static enum zclient_send_status bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp, + struct bgp_evpn_es_evi_vtep *evi_vtep) { bool old_active; bool new_active; @@ -557,7 +1745,7 @@ index 552365959d..40687c558d 100644 old_active = CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE); -@@ -3408,7 +3427,7 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp, +@@ -3425,7 +3436,7 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp, new_active = CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE); if (old_active == new_active) @@ -566,42 +1754,31 @@ index 552365959d..40687c558d 100644 if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) zlog_debug("es %s evi %u vtep %pI4 %s", -@@ -3417,24 +3436,26 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp, - new_active ? "active" : "inactive"); - - /* add VTEP to parent es */ -- if (new_active) -+ if (new_active) { +@@ -3437,19 +3448,20 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp, + if (new_active) evi_vtep->es_vtep = bgp_evpn_es_vtep_add( bgp, evi_vtep->es_evi->es, evi_vtep->vtep_ip, - false /*esr*/, 0, 0); -- else { + false /*esr*/, 0, 0, &ret); -+ } else { + else { if (evi_vtep->es_vtep) { - bgp_evpn_es_vtep_do_del(bgp, evi_vtep->es_vtep, -- false /*esr*/); + ret = bgp_evpn_es_vtep_do_del(bgp, evi_vtep->es_vtep, -+ false /*esr*/); + false /*esr*/); evi_vtep->es_vtep = NULL; } } /* queue up the parent es for background consistency checks */ bgp_evpn_es_cons_checks_pend_add(evi_vtep->es_evi->es); -+ + return ret; } -static void bgp_evpn_es_evi_vtep_add(struct bgp *bgp, -- struct bgp_evpn_es_evi *es_evi, struct in_addr vtep_ip, -- bool ead_es) -+static enum zclient_send_status -+bgp_evpn_es_evi_vtep_add(struct bgp *bgp, struct bgp_evpn_es_evi *es_evi, -+ struct in_addr vtep_ip, bool ead_es) ++static enum zclient_send_status bgp_evpn_es_evi_vtep_add(struct bgp *bgp, + struct bgp_evpn_es_evi *es_evi, struct in_addr vtep_ip, + bool ead_es) { - struct bgp_evpn_es_evi_vtep *evi_vtep; - -@@ -3454,18 +3475,19 @@ static void bgp_evpn_es_evi_vtep_add(struct bgp *bgp, +@@ -3475,18 +3487,19 @@ static void bgp_evpn_es_evi_vtep_add(struct bgp *bgp, else SET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_EAD_PER_EVI); @@ -610,11 +1787,9 @@ index 552365959d..40687c558d 100644 } -static void bgp_evpn_es_evi_vtep_del(struct bgp *bgp, -- struct bgp_evpn_es_evi *es_evi, struct in_addr vtep_ip, -- bool ead_es) -+static enum zclient_send_status -+bgp_evpn_es_evi_vtep_del(struct bgp *bgp, struct bgp_evpn_es_evi *es_evi, -+ struct in_addr vtep_ip, bool ead_es) ++static enum zclient_send_status bgp_evpn_es_evi_vtep_del(struct bgp *bgp, + struct bgp_evpn_es_evi *es_evi, struct in_addr vtep_ip, + bool ead_es) { struct bgp_evpn_es_evi_vtep *evi_vtep; + enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS; @@ -626,30 +1801,27 @@ index 552365959d..40687c558d 100644 if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) zlog_debug("del es %s evi %u vtep %pI4 %s", -@@ -3478,8 +3500,10 @@ static void bgp_evpn_es_evi_vtep_del(struct bgp *bgp, +@@ -3503,8 +3516,9 @@ static void bgp_evpn_es_evi_vtep_del(struct bgp *bgp, else UNSET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_EAD_PER_EVI); - bgp_evpn_es_evi_vtep_re_eval_active(bgp, evi_vtep); + ret = bgp_evpn_es_evi_vtep_re_eval_active(bgp, evi_vtep); bgp_evpn_es_evi_vtep_free(evi_vtep); -+ + return ret; } /* compare ES-IDs for the ES-EVI RB tree maintained per-VNI */ -@@ -3755,18 +3779,20 @@ int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni) +@@ -3780,7 +3794,7 @@ int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni) /* Add remote ES-EVI entry. This is actually the remote VTEP add and the * ES-EVI is implicity created on first VTEP's reference. */ -int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn, -- const struct prefix_evpn *p) -+enum zclient_send_status bgp_evpn_remote_es_evi_add(struct bgp *bgp, -+ struct bgpevpn *vpn, -+ const struct prefix_evpn *p) ++enum zclient_send_status bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn, + const struct prefix_evpn *p) { char buf[ESI_STR_LEN]; - struct bgp_evpn_es *es; +@@ -3788,10 +3802,11 @@ int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn, struct bgp_evpn_es_evi *es_evi; bool ead_es; const esi_t *esi = &p->prefix.ead_addr.esi; @@ -662,14 +1834,13 @@ index 552365959d..40687c558d 100644 if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) zlog_debug("add remote %s es %s evi %u vtep %pI4", -@@ -3783,27 +3809,29 @@ int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn, +@@ -3808,27 +3823,28 @@ int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn, es_evi = bgp_evpn_es_evi_new(es, vpn); ead_es = !!p->prefix.ead_addr.eth_tag; - bgp_evpn_es_evi_vtep_add(bgp, es_evi, p->prefix.ead_addr.ip.ipaddr_v4, -- ead_es); -+ ret = bgp_evpn_es_evi_vtep_add(bgp, es_evi, -+ p->prefix.ead_addr.ip.ipaddr_v4, ead_es); ++ ret = bgp_evpn_es_evi_vtep_add(bgp, es_evi, p->prefix.ead_addr.ip.ipaddr_v4, + ead_es); bgp_evpn_es_evi_remote_info_re_eval(es_evi); - return 0; @@ -680,10 +1851,8 @@ index 552365959d..40687c558d 100644 * parent es-evi freed up implicitly in last VTEP's deref. */ -int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn, -- const struct prefix_evpn *p) -+enum zclient_send_status bgp_evpn_remote_es_evi_del(struct bgp *bgp, -+ struct bgpevpn *vpn, -+ const struct prefix_evpn *p) ++enum zclient_send_status bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn, + const struct prefix_evpn *p) { char buf[ESI_STR_LEN]; struct bgp_evpn_es *es; @@ -698,7 +1867,7 @@ index 552365959d..40687c558d 100644 if (BGP_DEBUG(evpn_mh, EVPN_MH_ES)) zlog_debug( -@@ -3822,7 +3850,7 @@ int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn, +@@ -3847,7 +3863,7 @@ int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn, esi_to_str(&p->prefix.ead_addr.esi, buf, sizeof(buf)), vpn->vni, &p->prefix.ead_addr.ip.ipaddr_v4); @@ -707,7 +1876,7 @@ index 552365959d..40687c558d 100644 } es_evi = bgp_evpn_es_evi_find(es, vpn); if (!es_evi) { -@@ -3835,14 +3863,15 @@ int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn, +@@ -3860,14 +3876,14 @@ int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn, sizeof(buf)), vpn->vni, &p->prefix.ead_addr.ip.ipaddr_v4); @@ -717,21 +1886,19 @@ index 552365959d..40687c558d 100644 ead_es = !!p->prefix.ead_addr.eth_tag; - bgp_evpn_es_evi_vtep_del(bgp, es_evi, p->prefix.ead_addr.ip.ipaddr_v4, -- ead_es); -+ ret = bgp_evpn_es_evi_vtep_del(bgp, es_evi, -+ p->prefix.ead_addr.ip.ipaddr_v4, ead_es); ++ ret = bgp_evpn_es_evi_vtep_del(bgp, es_evi, p->prefix.ead_addr.ip.ipaddr_v4, + ead_es); bgp_evpn_es_evi_remote_info_re_eval(es_evi); - return 0; -+ + return ret; } /* If a VNI is being deleted we need to force del all remote VTEPs */ diff --git a/bgpd/bgp_evpn_mh.h b/bgpd/bgp_evpn_mh.h -index 11030e323f..d6e77e982f 100644 +index cebabb9fd..5d393c37a 100644 --- a/bgpd/bgp_evpn_mh.h +++ b/bgpd/bgp_evpn_mh.h -@@ -434,10 +434,12 @@ extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, +@@ -418,10 +418,12 @@ extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi, extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi); extern int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni); extern int bgp_evpn_local_es_evi_del(struct bgp *bgp, esi_t *esi, vni_t vni); @@ -749,99 +1916,89 @@ index 11030e323f..d6e77e982f 100644 extern void bgp_evpn_mh_finish(void); void bgp_evpn_vni_es_init(struct bgpevpn *vpn); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index c29442d96c..679abba463 100644 +index e45d4b1ff..3dff073a3 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c -@@ -3213,9 +3213,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, - && (new_select->sub_type == BGP_ROUTE_NORMAL - || new_select->sub_type +@@ -3420,7 +3420,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, == BGP_ROUTE_IMPORTED)) -- - bgp_zebra_route_install( -- dest, old_select, bgp, true); -+ dest, old_select, bgp, true, -+ NULL, false); + + bgp_zebra_route_install(dest, old_select, +- bgp, true); ++ bgp, true, NULL, false); } } -@@ -3313,9 +3313,10 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3529,9 +3529,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, + */ if (old_select && is_route_parent_evpn(old_select)) - bgp_zebra_route_install(dest, old_select, bgp, -- false); -+ false, NULL, false); +- bgp_zebra_route_install(dest, old_select, bgp, false); ++ bgp_zebra_route_install(dest, old_select, bgp, false, NULL, false); - bgp_zebra_route_install(dest, new_select, bgp, true); -+ bgp_zebra_route_install(dest, new_select, bgp, true, -+ NULL, false); ++ bgp_zebra_route_install(dest, new_select, bgp, true, NULL, false); } else { /* Withdraw the route from the kernel. */ if (old_select && old_select->type == ZEBRA_ROUTE_BGP -@@ -3324,7 +3325,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3539,7 +3539,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, + || old_select->sub_type == BGP_ROUTE_AGGREGATE || old_select->sub_type == BGP_ROUTE_IMPORTED)) - bgp_zebra_route_install(dest, old_select, bgp, -- false); -+ false, NULL, false); +- bgp_zebra_route_install(dest, old_select, bgp, false); ++ bgp_zebra_route_install(dest, old_select, bgp, false, NULL, false); } } -@@ -4203,7 +4204,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, +@@ -4444,7 +4444,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) { if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) /* remove from RIB previous entry */ - bgp_zebra_route_install(dest, pi, bgp, false); -+ bgp_zebra_route_install(dest, pi, bgp, false, NULL, -+ false); ++ bgp_zebra_route_install(dest, pi, bgp, false, NULL, false); } if (peer->sort == BGP_PEER_EBGP) { diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h -index 45d61f8dfd..9eb681ea3f 100644 +index 67431ea4f..1550d00ad 100644 --- a/bgpd/bgp_table.h +++ b/bgpd/bgp_table.h -@@ -103,6 +103,8 @@ struct bgp_node { +@@ -75,10 +75,10 @@ struct bgp_dest { + struct bgp_dest *pdest; + STAILQ_ENTRY(bgp_dest) pq; +- struct bgp_path_info *za_bgp_pi; +- struct zebra_announce_item zai; - struct bgp_path_info *za_bgp_pi; +- ++ struct bgp_path_info *za_bgp_pi; + struct bgpevpn *za_vpn; + bool za_is_sync; - uint64_t version; + mpls_label_t local_label; diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c -index 1162941ef1..b81acaf8ec 100644 +index 064f23350..cab758fca 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c -@@ -1713,12 +1713,11 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi) - for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) - for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) - if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) && -- -- (pi->type == ZEBRA_ROUTE_BGP -- && (pi->sub_type == BGP_ROUTE_NORMAL -- || pi->sub_type == BGP_ROUTE_IMPORTED))) -- +@@ -1674,7 +1674,7 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi) + && (pi->sub_type == BGP_ROUTE_NORMAL + || pi->sub_type == BGP_ROUTE_IMPORTED))) + - bgp_zebra_route_install(dest, pi, bgp, true); -+ (pi->type == ZEBRA_ROUTE_BGP && -+ (pi->sub_type == BGP_ROUTE_NORMAL || -+ pi->sub_type == BGP_ROUTE_IMPORTED))) -+ bgp_zebra_route_install(dest, pi, bgp, true, -+ NULL, false); ++ bgp_zebra_route_install(dest, pi, bgp, true, NULL, false); } /* Announce routes of any bgp subtype of a table to zebra */ -@@ -1740,7 +1739,8 @@ void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, +@@ -1696,7 +1696,7 @@ void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi, for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) && pi->type == ZEBRA_ROUTE_BGP) - bgp_zebra_route_install(dest, pi, bgp, true); -+ bgp_zebra_route_install(dest, pi, bgp, true, -+ NULL, false); ++ bgp_zebra_route_install(dest, pi, bgp, true, NULL, false); } - enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest, -@@ -1793,6 +1793,7 @@ enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest, + +@@ -1749,6 +1749,7 @@ enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest, #define ZEBRA_ANNOUNCEMENTS_LIMIT 1000 static void bgp_handle_route_announcements_to_zebra(struct thread *e) { @@ -849,7 +2006,7 @@ index 1162941ef1..b81acaf8ec 100644 uint32_t count = 0; struct bgp_dest *dest = NULL; struct bgp_table *table = NULL; -@@ -1808,6 +1809,9 @@ static void bgp_handle_route_announcements_to_zebra(struct thread *e) +@@ -1764,6 +1765,9 @@ static void bgp_handle_route_announcements_to_zebra(struct thread *e) table = bgp_dest_table(dest); install = CHECK_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_INSTALL); @@ -859,7 +2016,7 @@ index 1162941ef1..b81acaf8ec 100644 if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug( -@@ -1816,17 +1820,33 @@ static void bgp_handle_route_announcements_to_zebra(struct thread *e) +@@ -1772,17 +1776,32 @@ static void bgp_handle_route_announcements_to_zebra(struct thread *e) table->bgp->name_pretty, dest, dest->flags); if (install) { @@ -887,7 +2044,6 @@ index 1162941ef1..b81acaf8ec 100644 + else + status = bgp_zebra_withdraw_actual( + dest, dest->za_bgp_pi, table->bgp); -+ UNSET_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_DELETE); } @@ -897,13 +2053,12 @@ index 1162941ef1..b81acaf8ec 100644 bgp_dest_unlock_node(dest); if (status == ZCLIENT_SEND_BUFFERED) -@@ -1880,8 +1900,16 @@ static void bgp_zebra_buffer_write_ready(void) +@@ -1836,8 +1855,14 @@ static void bgp_zebra_buffer_write_ready(void) * withdrawn. */ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, - struct bgp *bgp, bool install) -+ struct bgp *bgp, bool install, struct bgpevpn *vpn, -+ bool is_sync) ++ struct bgp *bgp, bool install, struct bgpevpn *vpn, bool is_sync) { + bool is_evpn = false; + struct bgp_table *table = NULL; @@ -911,11 +2066,10 @@ index 1162941ef1..b81acaf8ec 100644 + table = bgp_dest_table(dest); + if (table && table->afi == AFI_L2VPN && table->safi == SAFI_EVPN) + is_evpn = true; -+ /* * BGP is installing this route and bgp has been configured * to suppress announcements until the route has been installed -@@ -1891,7 +1919,7 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, +@@ -1847,7 +1872,7 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, if (BGP_SUPPRESS_FIB_ENABLED(bgp)) SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING); @@ -924,7 +2078,7 @@ index 1162941ef1..b81acaf8ec 100644 return; } else { UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING); -@@ -1901,7 +1929,7 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, +@@ -1857,7 +1882,7 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, * Don't try to install if we're not connected to Zebra or Zebra doesn't * know of this instance. */ @@ -933,7 +2087,7 @@ index 1162941ef1..b81acaf8ec 100644 return; if (!CHECK_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_INSTALL) && -@@ -1922,7 +1950,7 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, +@@ -1878,7 +1903,7 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, dest->za_bgp_pi = info; } else if (CHECK_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_DELETE)) { assert(dest->za_bgp_pi); @@ -942,7 +2096,7 @@ index 1162941ef1..b81acaf8ec 100644 bgp_zebra_withdraw_actual(dest, dest->za_bgp_pi, bgp); bgp_path_info_unlock(dest->za_bgp_pi); -@@ -1930,6 +1958,11 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, +@@ -1886,6 +1911,11 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, dest->za_bgp_pi = info; } @@ -954,42 +2108,40 @@ index 1162941ef1..b81acaf8ec 100644 if (install) { UNSET_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_DELETE); SET_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_INSTALL); -@@ -1960,7 +1993,8 @@ void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t sa +@@ -1916,7 +1946,7 @@ void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t sa for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) && (pi->type == ZEBRA_ROUTE_BGP)) - bgp_zebra_route_install(dest, pi, bgp, false); -+ bgp_zebra_route_install(dest, pi, bgp, false, -+ NULL, false); ++ bgp_zebra_route_install(dest, pi, bgp, false, NULL, false); } } } diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h -index 45fcf7f514..5186b7454e 100644 +index 83197c28e..92971b51f 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h -@@ -45,7 +45,8 @@ extern int bgp_zebra_get_table_range(uint32_t chunk_size, +@@ -30,7 +30,7 @@ extern int bgp_zebra_get_table_range(struct zclient *zc, uint32_t chunk_size, extern int bgp_if_update_all(void); extern void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *path, struct bgp *bgp, - bool install); -+ bool install, struct bgpevpn *vpn, -+ bool is_sync); ++ bool install, struct bgpevpn *vpn, bool is_sync); + extern void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi); - - /* Announce routes of any bgp subtype of a table to zebra */ + extern enum zclient_send_status diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h -index bdf31f5161..dc660fb8f0 100644 +index a088a2e11..214a2f9b0 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h -@@ -512,6 +512,7 @@ struct bgp { - #define BGP_FLAG_HARD_ADMIN_RESET (1ULL << 31) - /* Evaluate the AIGP attribute during the best path selection process */ - #define BGP_FLAG_COMPARE_AIGP (1ULL << 32) +@@ -529,6 +529,7 @@ struct bgp { + #define BGP_FLAG_LU_IPV6_EXPLICIT_NULL (1ULL << 34) + #define BGP_FLAG_SOFT_VERSION_CAPABILITY (1ULL << 35) + #define BGP_FLAG_ENFORCE_FIRST_AS (1ULL << 36) +#define BGP_FLAG_VNI_DOWN (1ULL << 38) /* BGP default address-families. * New peers inherit enabled afi/safis from bgp instance. -- -2.17.1 +2.39.4 diff --git a/src/sonic-frr/patch/0037-bgpd-Increase-install-uninstall-speed-of-evpn-vpn-vn.patch b/src/sonic-frr/patch/0037-bgpd-Increase-install-uninstall-speed-of-evpn-vpn-vn.patch index a360a3101599..ab8ff8e0327f 100644 --- a/src/sonic-frr/patch/0037-bgpd-Increase-install-uninstall-speed-of-evpn-vpn-vn.patch +++ b/src/sonic-frr/patch/0037-bgpd-Increase-install-uninstall-speed-of-evpn-vpn-vn.patch @@ -1,8 +1,10 @@ -From 7166c2222cb82885510c3e8c7906c1d7de950f9b Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Thu, 11 Apr 2024 13:28:30 -0400 -Subject: [PATCH 09/11] bgpd: Increase install/uninstall speed of evpn vpn - vni's +From 77687c6866cdbc630cdc8419fd369e7e6f02f45b Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Tue, 17 Sep 2024 00:41:33 -0700 +Subject: [PATCH] From 7166c2222cb82885510c3e8c7906c1d7de950f9b Mon Sep 17 + 00:00:00 2001 From: Donald Sharp Date: Thu, 11 Apr 2024 + 13:28:30 -0400 Subject: [PATCH 09/11] bgpd: Increase install/uninstall speed + of evpn vpn vni's BGP receives notification from zebra about an vpn that needs to be installed into the evpn tables. Unfortunately @@ -17,23 +19,23 @@ scenario. Signed-off-by: Rajasekar Raja Signed-off-by: Donald Sharp +--- + bgpd/bgp_evpn.c | 54 ++++++++++++++----------------------------------- + 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c -index 622fd6afd2..eb5aa9f077 100644 +index 79e16d8f9..8b4968e6d 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c -@@ -3752,9 +3752,7 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) - * particular VNI. +@@ -3926,7 +3926,6 @@ int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install) */ - static int install_uninstall_routes_for_vni(struct bgp *bgp, -- struct bgpevpn *vpn, + int install_uninstall_routes_for_vni(struct bgp *bgp, + struct bgpevpn *vpn, - bgp_evpn_route_type rtype, -- int install) -+ struct bgpevpn *vpn, int install) + int install) { afi_t afi; - safi_t safi; -@@ -3785,7 +3783,9 @@ static int install_uninstall_routes_for_vni(struct bgp *bgp, +@@ -3958,7 +3957,9 @@ int install_uninstall_routes_for_vni(struct bgp *bgp, (const struct prefix_evpn *)bgp_dest_get_prefix( dest); @@ -44,27 +46,25 @@ index 622fd6afd2..eb5aa9f077 100644 continue; for (pi = bgp_dest_get_bgp_path_info(dest); pi; -@@ -3812,7 +3812,8 @@ static int install_uninstall_routes_for_vni(struct bgp *bgp, - bgp->vrf_id, - install ? "install" - : "uninstall", -- rtype == BGP_EVPN_MAC_IP_ROUTE +@@ -3991,7 +3992,8 @@ int install_uninstall_routes_for_vni(struct bgp *bgp, + bgp->vrf_id, + install ? "install" + : "uninstall", +- rtype == BGP_EVPN_MAC_IP_ROUTE + evp->prefix.route_type == + BGP_EVPN_MAC_IP_ROUTE - ? "MACIP" - : "IMET", - vpn->vni); -@@ -3845,23 +3846,11 @@ static int install_routes_for_vrf(struct bgp *bgp_vrf) + ? "MACIP" + : "IMET", + vpn->vni); +@@ -4023,23 +4025,11 @@ int install_routes_for_vrf(struct bgp *bgp_vrf) */ - static int install_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + int install_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) { - int ret; - - /* Install type-3 routes followed by type-2 routes - the ones applicable -+ /* -+ * Install type-3 routes followed by type-2 routes - the ones applicable - * for this VNI. - */ +- * for this VNI. +- */ - ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_IMET_ROUTE, - 1); - if (ret) @@ -77,23 +77,24 @@ index 622fd6afd2..eb5aa9f077 100644 - - return install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_MAC_IP_ROUTE, - 1); ++ /* ++ * Install type-3 routes followed by type-2 routes - the ones applicable ++ * for this VNI. ++ */ + return install_uninstall_routes_for_vni(bgp, vpn, 1); } /* uninstall routes from l3vni vrf. */ -@@ -3877,25 +3866,11 @@ static int uninstall_routes_for_vrf(struct bgp *bgp_vrf) +@@ -4055,25 +4045,11 @@ int uninstall_routes_for_vrf(struct bgp *bgp_vrf) */ - static int uninstall_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) + int uninstall_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn) { - int ret; - - /* Uninstall type-2 routes followed by type-3 routes - the ones - * applicable - * for this VNI. -+ /* -+ * Uninstall type-2 routes followed by type-3 routes - the ones -+ * applicable for this VNI. - */ +- */ - ret = install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_MAC_IP_ROUTE, - 0); - if (ret) @@ -107,10 +108,14 @@ index 622fd6afd2..eb5aa9f077 100644 - - return install_uninstall_routes_for_vni(bgp, vpn, BGP_EVPN_IMET_ROUTE, - 0); ++ /* ++ * Uninstall type-2 routes followed by type-3 routes - the ones ++ * applicable for this VNI. ++ */ + return install_uninstall_routes_for_vni(bgp, vpn, 0); } /* -- -2.17.1 +2.39.4 diff --git a/src/sonic-frr/patch/0040-bgpd-backpressure-Fix-to-withdraw-evpn-type-5-routes.patch b/src/sonic-frr/patch/0040-bgpd-backpressure-Fix-to-withdraw-evpn-type-5-routes.patch index b74d86881ae5..09f19fa990ee 100644 --- a/src/sonic-frr/patch/0040-bgpd-backpressure-Fix-to-withdraw-evpn-type-5-routes.patch +++ b/src/sonic-frr/patch/0040-bgpd-backpressure-Fix-to-withdraw-evpn-type-5-routes.patch @@ -1,8 +1,10 @@ -From f3ec35b461a06f1278383d2347dfbc611b6a91a6 Mon Sep 17 00:00:00 2001 -From: Rajasekar Raja -Date: Fri, 17 May 2024 12:36:31 -0700 -Subject: [PATCH] bgpd: backpressure - Fix to withdraw evpn type-5 routes - immediately +From b6151be854f00f6eb5823e9408c65f00bbdd949f Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Tue, 17 Sep 2024 02:45:34 -0700 +Subject: [PATCH] From f3ec35b461a06f1278383d2347dfbc611b6a91a6 Mon Sep 17 + 00:00:00 2001 From: Rajasekar Raja Date: Fri, 17 May + 2024 12:36:31 -0700 Subject: [PATCH] bgpd: backpressure - Fix to withdraw + evpn type-5 routes immediately As part of backpressure changes, there is a bug where immediate withdraw is to be sent for evpn imported type-5 prefix to clear the nh neigh and @@ -15,40 +17,44 @@ Ticket: #3905571 Signed-off-by: Donald Sharp Signed-off-by: Rajasekar Raja +--- + bgpd/bgp_route.c | 2 +- + bgpd/bgp_zebra.c | 10 +++------- + 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index 679abba463..e28069767f 100644 +index 3dff073a3..26089e326 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c -@@ -3312,8 +3312,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3529,7 +3529,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, */ if (old_select && is_route_parent_evpn(old_select)) -- bgp_zebra_route_install(dest, old_select, bgp, -- false, NULL, false); +- bgp_zebra_route_install(dest, old_select, bgp, false, NULL, false); + bgp_zebra_withdraw_actual(dest, old_select, bgp); - bgp_zebra_route_install(dest, new_select, bgp, true, - NULL, false); + bgp_zebra_route_install(dest, new_select, bgp, true, NULL, false); + } else { diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c -index 524551b1e0..5d5525156b 100644 +index f0fe0ec5c..c0733dfe3 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c -@@ -1889,11 +1889,9 @@ static void bgp_zebra_buffer_write_ready(void) +@@ -1844,11 +1844,10 @@ static void bgp_zebra_buffer_write_ready(void) * save new pi, mark as going to be * withdrawan, remove install flag * - * Withdrawal Install Special case, send withdrawal immediately - * Leave dest on list, release old pi, ++ * + * Withdrawal Install Leave dest on list, release old pi, * save new pi, mark as going to be - * installed. -+ * installed. ++ * installed * Withdrawal Withdrawal Leave dest on list, release old pi, * save new pi, mark as going to be * withdrawn. -@@ -1949,9 +1947,6 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, +@@ -1902,9 +1901,6 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info, dest->za_bgp_pi = info; } else if (CHECK_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_DELETE)) { assert(dest->za_bgp_pi); @@ -59,5 +65,5 @@ index 524551b1e0..5d5525156b 100644 bgp_path_info_lock(info); dest->za_bgp_pi = info; -- -2.43.2 +2.39.4 diff --git a/src/sonic-frr/patch/0042-zebra-Use-built-in-data-structure-counter.patch b/src/sonic-frr/patch/0042-zebra-Use-built-in-data-structure-counter.patch index 3401dae27158..d5e9969bc726 100644 --- a/src/sonic-frr/patch/0042-zebra-Use-built-in-data-structure-counter.patch +++ b/src/sonic-frr/patch/0042-zebra-Use-built-in-data-structure-counter.patch @@ -1,7 +1,10 @@ -From 529cdfa09065c6c77aff4a96a52f0d3bcb385b6f Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Thu, 13 Jun 2024 15:30:00 -0400 -Subject: [PATCH 1/5] zebra: Use built in data structure counter +From 1d441b6b3e45bb2000ec4d29fada07857c7305b4 Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Tue, 17 Sep 2024 03:05:40 -0700 +Subject: [PATCH] From 529cdfa09065c6c77aff4a96a52f0d3bcb385b6f Mon Sep 17 + 00:00:00 2001 From: Donald Sharp Date: Thu, 13 Jun 2024 + 15:30:00 -0400 Subject: [PATCH 1/5] zebra: Use built in data structure + counter Instead of keeping a counter that is independent of the queue's data structure. Just use the queue's @@ -10,12 +13,17 @@ keeping it wrapped inside the mutex for adding/deleting to the queue. Signed-off-by: Donald Sharp +--- + zebra/dplane_fpm_nl.c | 40 ++++++++++++++++++---------------------- + zebra/zebra_dplane.c | 5 +++++ + zebra/zebra_dplane.h | 2 ++ + 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c -index caa2f988e2..bc9815bb10 100644 +index b2fee4ff7..f45003cd2 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c -@@ -135,8 +135,6 @@ struct fpm_nl_ctx { +@@ -133,8 +133,6 @@ struct fpm_nl_ctx { /* Amount of data plane context processed. */ _Atomic uint32_t dplane_contexts; @@ -24,7 +32,7 @@ index caa2f988e2..bc9815bb10 100644 /* Peak amount of data plane contexts enqueued. */ _Atomic uint32_t ctxqueue_len_peak; -@@ -311,6 +309,12 @@ DEFUN(fpm_show_counters, fpm_show_counters_cmd, +@@ -328,6 +326,12 @@ DEFUN(fpm_show_counters, fpm_show_counters_cmd, FPM_STR "FPM statistic counters\n") { @@ -37,7 +45,7 @@ index caa2f988e2..bc9815bb10 100644 vty_out(vty, "%30s\n%30s\n", "FPM counters", "============"); #define SHOW_COUNTER(label, counter) \ -@@ -324,8 +328,7 @@ DEFUN(fpm_show_counters, fpm_show_counters_cmd, +@@ -341,8 +345,7 @@ DEFUN(fpm_show_counters, fpm_show_counters_cmd, SHOW_COUNTER("Connection errors", gfnc->counters.connection_errors); SHOW_COUNTER("Data plane items processed", gfnc->counters.dplane_contexts); @@ -47,7 +55,7 @@ index caa2f988e2..bc9815bb10 100644 SHOW_COUNTER("Data plane items queue peak", gfnc->counters.ctxqueue_len_peak); SHOW_COUNTER("Buffer full hits", gfnc->counters.buffer_full); -@@ -344,6 +347,12 @@ DEFUN(fpm_show_counters_json, fpm_show_counters_json_cmd, +@@ -361,6 +364,12 @@ DEFUN(fpm_show_counters_json, fpm_show_counters_json_cmd, "FPM statistic counters\n" JSON_STR) { @@ -60,7 +68,7 @@ index caa2f988e2..bc9815bb10 100644 struct json_object *jo; jo = json_object_new_object(); -@@ -357,8 +366,7 @@ DEFUN(fpm_show_counters_json, fpm_show_counters_json_cmd, +@@ -374,8 +383,7 @@ DEFUN(fpm_show_counters_json, fpm_show_counters_json_cmd, gfnc->counters.connection_errors); json_object_int_add(jo, "data-plane-contexts", gfnc->counters.dplane_contexts); @@ -70,7 +78,7 @@ index caa2f988e2..bc9815bb10 100644 json_object_int_add(jo, "data-plane-contexts-queue-peak", gfnc->counters.ctxqueue_len_peak); json_object_int_add(jo, "buffer-full-hits", gfnc->counters.buffer_full); -@@ -1380,8 +1388,6 @@ static void fpm_process_queue(struct thread *t) +@@ -1427,8 +1435,6 @@ static void fpm_process_queue(struct event *t) /* Account the processed entries. */ processed_contexts++; @@ -79,7 +87,7 @@ index caa2f988e2..bc9815bb10 100644 dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_SUCCESS); dplane_provider_enqueue_out_ctx(fnc->prov, ctx); -@@ -1550,7 +1556,7 @@ static int fpm_nl_process(struct zebra_dplane_provider *prov) +@@ -1602,7 +1608,7 @@ static int fpm_nl_process(struct zebra_dplane_provider *prov) struct zebra_dplane_ctx *ctx; struct fpm_nl_ctx *fnc; int counter, limit; @@ -88,7 +96,7 @@ index caa2f988e2..bc9815bb10 100644 fnc = dplane_provider_get_data(prov); limit = dplane_provider_get_work_limit(prov); -@@ -1564,20 +1570,12 @@ static int fpm_nl_process(struct zebra_dplane_provider *prov) +@@ -1616,20 +1622,12 @@ static int fpm_nl_process(struct zebra_dplane_provider *prov) * anyway. */ if (fnc->socket != -1 && fnc->connecting == false) { @@ -111,7 +119,7 @@ index caa2f988e2..bc9815bb10 100644 if (peak_queue < cur_queue) peak_queue = cur_queue; continue; -@@ -1594,9 +1592,7 @@ static int fpm_nl_process(struct zebra_dplane_provider *prov) +@@ -1646,9 +1644,7 @@ static int fpm_nl_process(struct zebra_dplane_provider *prov) atomic_store_explicit(&fnc->counters.ctxqueue_len_peak, peak_queue, memory_order_relaxed); @@ -119,14 +127,14 @@ index caa2f988e2..bc9815bb10 100644 - memory_order_relaxed) - > 0) + if (cur_queue > 0) - thread_add_timer(fnc->fthread->master, fpm_process_queue, - fnc, 0, &fnc->t_dequeue); + event_add_event(fnc->fthread->master, fpm_process_queue, fnc, 0, + &fnc->t_dequeue); diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c -index 59b8d6cc63..c252a370b8 100644 +index 70ce555b1..a53bf8b25 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c -@@ -969,6 +969,11 @@ struct zebra_dplane_ctx *dplane_ctx_dequeue(struct dplane_ctx_list_head *q) +@@ -956,6 +956,11 @@ struct zebra_dplane_ctx *dplane_ctx_dequeue(struct dplane_ctx_list_head *q) return ctx; } @@ -139,10 +147,10 @@ index 59b8d6cc63..c252a370b8 100644 * Accessors for information from the context object */ diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h -index 9f9496c8f4..c29e05bbc9 100644 +index 2f7d21850..51c1bff5d 100644 --- a/zebra/zebra_dplane.h +++ b/zebra/zebra_dplane.h -@@ -324,6 +324,8 @@ struct zebra_dplane_ctx *dplane_ctx_get_head(struct dplane_ctx_list_head *q); +@@ -316,6 +316,8 @@ struct zebra_dplane_ctx *dplane_ctx_get_head(struct dplane_ctx_list_head *q); /* Init a list of contexts */ void dplane_ctx_q_init(struct dplane_ctx_list_head *q); @@ -152,5 +160,5 @@ index 9f9496c8f4..c29e05bbc9 100644 * Accessors for information from the context object */ -- -2.43.2 +2.39.4 diff --git a/src/sonic-frr/patch/0046-zebra-Modify-show-zebra-dplane-providers-to-give-mor.patch b/src/sonic-frr/patch/0046-zebra-Modify-show-zebra-dplane-providers-to-give-mor.patch index e865b861d192..5ce76ade3436 100644 --- a/src/sonic-frr/patch/0046-zebra-Modify-show-zebra-dplane-providers-to-give-mor.patch +++ b/src/sonic-frr/patch/0046-zebra-Modify-show-zebra-dplane-providers-to-give-mor.patch @@ -1,8 +1,9 @@ -From d695dfb88418834f0054255dd4385b293efb5a17 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Mon, 17 Jun 2024 10:42:41 -0400 -Subject: [PATCH 5/5] zebra: Modify show `zebra dplane providers` to give more - data +From 08d8e53948d91bdaa98c8179616503908323544c Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Tue, 17 Sep 2024 03:24:51 -0700 +Subject: [PATCH] From d695dfb88418834f0054255dd4385b293efb5a17 Mon Sep 17 + 00:00:00 2001 From: Donald Sharp Date: Mon, 17 Jun 2024 + 10:42:41 -0400 Subject: [PATCH 5/5] zebra: Modify show to give more data The show zebra dplane provider command was ommitting the input and output queues to the dplane itself. @@ -18,13 +19,18 @@ dataplane Outgoing Queue to Zebra: 43 r1# Signed-off-by: Donald Sharp +--- + zebra/rib.h | 1 + + zebra/zebra_dplane.c | 18 +++++++++++++----- + zebra/zebra_rib.c | 11 +++++++++++ + 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/zebra/rib.h b/zebra/rib.h -index 2e62148ea0..b78cd218f6 100644 +index a721f4bac..15f877b66 100644 --- a/zebra/rib.h +++ b/zebra/rib.h -@@ -630,6 +630,7 @@ static inline struct nexthop_group *rib_get_fib_backup_nhg( - } +@@ -628,6 +628,7 @@ extern int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto, + uint8_t instance); extern void zebra_vty_init(void); +extern uint32_t zebra_rib_dplane_results_count(void); @@ -32,10 +38,10 @@ index 2e62148ea0..b78cd218f6 100644 extern pid_t pid; diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c -index f0e1ff6f27..21c73a3796 100644 +index e077c28d1..efa795331 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c -@@ -5998,12 +5998,14 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed) +@@ -6089,12 +6089,14 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed) struct zebra_dplane_provider *prov; uint64_t in, in_q, in_max, out, out_q, out_max; @@ -52,7 +58,7 @@ index f0e1ff6f27..21c73a3796 100644 /* Show counters, useful info from each registered provider */ while (prov) { dplane_provider_lock(prov); -@@ -6022,13 +6024,19 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed) +@@ -6113,13 +6115,19 @@ int dplane_show_provs_helper(struct vty *vty, bool detailed) out_max = atomic_load_explicit(&prov->dp_out_max, memory_order_relaxed); @@ -76,10 +82,10 @@ index f0e1ff6f27..21c73a3796 100644 } diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index 1ff3d98545..ae051d37eb 100644 +index 5b95d8668..430878daf 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c -@@ -4874,6 +4874,17 @@ static int rib_dplane_results(struct dplane_ctx_list_head *ctxlist) +@@ -5001,6 +5001,17 @@ static int rib_dplane_results(struct dplane_ctx_list_head *ctxlist) return 0; } @@ -98,5 +104,5 @@ index 1ff3d98545..ae051d37eb 100644 * Ensure there are no empty slots in the route_info array. * Every route type in zebra should be present there. -- -2.43.2 +2.39.4 diff --git a/src/sonic-frr/patch/0048-bgpd-backpressure-fix-to-properly-remove-dest-for-bg.patch b/src/sonic-frr/patch/0048-bgpd-backpressure-fix-to-properly-remove-dest-for-bg.patch index 1731b6d21f31..ab1acfa76e2e 100644 --- a/src/sonic-frr/patch/0048-bgpd-backpressure-fix-to-properly-remove-dest-for-bg.patch +++ b/src/sonic-frr/patch/0048-bgpd-backpressure-fix-to-properly-remove-dest-for-bg.patch @@ -1,8 +1,10 @@ -From 05d2c5b3ba6f83cd42a4dd5f9e40959fc438b0a6 Mon Sep 17 00:00:00 2001 -From: Rajasekar Raja -Date: Wed, 10 Jul 2024 16:46:29 -0700 -Subject: [PATCH 1/2] bgpd: backpressure - fix to properly remove dest for bgp - under deletion +From 9139ebe729804de71b13510d61bd0e273f6f2918 Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Tue, 17 Sep 2024 03:45:43 -0700 +Subject: [PATCH] From 05d2c5b3ba6f83cd42a4dd5f9e40959fc438b0a6 Mon Sep 17 + 00:00:00 2001 From: Rajasekar Raja Date: Wed, 10 Jul + 2024 16:46:29 -0700 Subject: [PATCH 1/2] bgpd: backpressure - fix to properly + remove dest for bgp under deletion In case of imported routes (L3vni/vrf leaks), when a bgp instance is being deleted, the peer->bgp comparision with the incoming bgp to remove @@ -20,12 +22,16 @@ Ticket :#3980988 Signed-off-by: Chirag Shah Signed-off-by: Rajasekar Raja +--- + bgpd/bgp_evpn.c | 12 ++++++------ + bgpd/bgpd.c | 20 +++++++++++++------- + 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c -index 2243ffdc77..b1f8f19594 100644 +index 5e62854ed..c517a67f5 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c -@@ -6074,16 +6074,16 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, +@@ -6301,16 +6301,16 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni, void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn) { struct bgp_dest *dest = NULL; @@ -46,13 +52,13 @@ index 2243ffdc77..b1f8f19594 100644 + zebra_announce_del(&bm->zebra_announce_head, dest); + } } - bgp_evpn_remote_ip_hash_destroy(vpn); + bgp_evpn_vni_es_cleanup(vpn); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 492566f8c8..e16a58b443 100644 +index 4348a60c5..24577768f 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c -@@ -3689,19 +3689,25 @@ int bgp_delete(struct bgp *bgp) +@@ -3868,19 +3868,25 @@ int bgp_delete(struct bgp *bgp) safi_t safi; int i; struct bgp_dest *dest = NULL; @@ -86,5 +92,5 @@ index 492566f8c8..e16a58b443 100644 bgp_soft_reconfig_table_task_cancel(bgp, NULL, NULL); -- -2.43.2 +2.39.4 diff --git a/src/sonic-frr/patch/0050-bgpd-backpressure-Avoid-use-after-free.patch b/src/sonic-frr/patch/0050-bgpd-backpressure-Avoid-use-after-free.patch index 878d60eb5e37..5c4f4b7d9a0a 100644 --- a/src/sonic-frr/patch/0050-bgpd-backpressure-Avoid-use-after-free.patch +++ b/src/sonic-frr/patch/0050-bgpd-backpressure-Avoid-use-after-free.patch @@ -1,7 +1,10 @@ -From df1d28fcc12d4f5541c9335115887d31e6197b80 Mon Sep 17 00:00:00 2001 -From: Rajasekar Raja -Date: Mon, 22 Jul 2024 10:13:19 -0700 -Subject: [PATCH] bgpd: backpressure - Avoid use after free +From b1e6d39d38f42c21870fa4f027e4e63f4ddf898e Mon Sep 17 00:00:00 2001 +From: sudhanshukumar22 +Date: Tue, 17 Sep 2024 04:13:38 -0700 +Subject: [PATCH] From df1d28fcc12d4f5541c9335115887d31e6197b80 Mon Sep 17 + 00:00:00 2001 From: Rajasekar Raja Date: Mon, 22 Jul + 2024 10:13:19 -0700 Subject: [PATCH] bgpd: backpressure - Avoid use after + free Coverity complains there is a use after free (1598495 and 1598496) At this point, most likely dest->refcount cannot go 1 and free up @@ -12,12 +15,16 @@ Fixing this with a simple order change (no harm fix). Ticket :#4001204 Signed-off-by: Rajasekar Raja +--- + bgpd/bgp_evpn.c | 2 +- + bgpd/bgpd.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c -index b1f8f19594..bb3cd62950 100644 +index c517a67f5..63e2e1c05 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c -@@ -6080,9 +6080,9 @@ void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn) +@@ -6307,9 +6307,9 @@ void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn) dest = dest_next) { dest_next = zebra_announce_next(&bm->zebra_announce_head, dest); if (dest->za_vpn == vpn) { @@ -27,12 +34,12 @@ index b1f8f19594..bb3cd62950 100644 - zebra_announce_del(&bm->zebra_announce_head, dest); } } - + bgp_evpn_remote_ip_hash_destroy(vpn); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 2e1c5e555b..342982069b 100644 +index 8132d0515..8ebfde10c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c -@@ -3706,9 +3706,9 @@ int bgp_delete(struct bgp *bgp) +@@ -3885,9 +3885,9 @@ int bgp_delete(struct bgp *bgp) dest_next = zebra_announce_next(&bm->zebra_announce_head, dest); dest_table = bgp_dest_table(dest); if (dest_table->bgp == bgp) { @@ -44,5 +51,5 @@ index 2e1c5e555b..342982069b 100644 } -- -2.43.2 +2.39.4 diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 1606b67065e4..76f6da09b6a2 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -6,30 +6,12 @@ 0006-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch 0007-ignore-route-from-default-table.patch 0008-Use-vrf_id-for-vrf-not-tabled_id.patch -0009-bgpd-Ensure-suppress-fib-pending-works-with-network-.patch 0010-bgpd-Change-log-level-for-graceful-restart-events.patch -0011-zebra-Static-routes-async-notification-do-not-need-t.patch -0012-zebra-Rename-vrf_lookup_by_tableid-to-zebra_vrf_look.patch -0013-zebra-Move-protodown_r_bit-to-a-better-spot.patch -0014-zebra-Remove-unused-dplane_intf_delete.patch -0015-zebra-Remove-unused-add-variable.patch -0016-zebra-Remove-duplicate-function-for-netlink-interfac.patch -0017-zebra-Add-code-to-get-set-interface-to-pass-up-from-.patch -0018-zebra-Use-zebra-dplane-for-RTM-link-and-addr.patch -0019-zebra-remove-duplicated-nexthops-when-sending-fpm-msg.patch -0020-zebra-Fix-non-notification-of-better-admin-won.patch 0021-Disable-ipv6-src-address-test-in-pceplib.patch 0022-cross-compile-changes.patch -0023-zebra-The-dplane_fpm_nl-return-path-leaks-memory.patch -0024-lib-use-snmp-s-large-fd-sets-for-agentx.patch 0025-bgp-community-memory-leak-fix.patch -0026-bgp-fib-suppress-announce-fix.patch -0027-lib-Do-not-convert-EVPN-prefixes-into-IPv4-IPv6-if-n.patch 0028-zebra-fix-parse-attr-problems-for-encap.patch -0029-zebra-nhg-fix-on-intf-up.patch 0030-zebra-backpressure-Zebra-push-back-on-Buffer-Stream-.patch -0031-bgpd-backpressure-Add-a-typesafe-list-for-Zebra-Anno.patch -0032-bgpd-fix-flushing-ipv6-flowspec-entries-when-peering.patch 0033-bgpd-backpressure-cleanup-bgp_zebra_XX-func-args.patch 0034-gpd-backpressure-Handle-BGP-Zebra-Install-evt-Creat.patch 0035-bgpd-backpressure-Handle-BGP-Zebra-EPVN-Install-evt-.patch @@ -50,4 +32,3 @@ 0050-bgpd-backpressure-Avoid-use-after-free.patch 0051-bgpd-backpressure-fix-ret-value-evpn_route_select_in.patch 0052-bgpd-backpressure-log-error-for-evpn-when-route-inst.patch -0053-bgpd-Set-md5-TCP-socket-option-for-outgoing-connections-on-listener.patch