From 69688a4a8ccdc3dae2872ffe9537bda891350abe Mon Sep 17 00:00:00 2001 From: dgsudharsan Date: Fri, 21 Jul 2023 23:10:26 +0000 Subject: [PATCH] FRR 8.5.1 integration changes --- .gitmodules | 2 +- rules/frr.mk | 6 +- src/sonic-frr/frr | 2 +- ...01-Add-support-of-bgp-tcp-DSCP-value.patch | 141 -- ...erity-of-Vty-connected-from-message.patch} | 17 +- ...EXT_HOP-to-be-0.0.0.0-due-to-allevia.patch | 25 + ...exthops-compare-vrf-only-if-ip-type.patch} | 19 +- ...EXT_HOP-to-be-0.0.0.0-due-to-allevia.patch | 27 - ...r-log-outchannel-to-var-log-frr.log.patch} | 27 +- ... 0005-Add-support-of-bgp-l3vni-evpn.patch} | 52 +- ...et-for-bgp-ipv6-link-local-neighbors.patch | 28 + ...007-ignore-route-from-default-table.patch} | 21 +- ...et-for-bgp-ipv6-link-local-neighbors.patch | 29 - ...08-Use-vrf_id-for-vrf-not-tabled_id.patch} | 20 +- ...ess-fib-pending-works-with-network-.patch} | 45 +- ...og-level-for-graceful-restart-events.patch | 116 + ...the-netlink-DUMP-command-is-interrup.patch | 45 - ...pability-is-always-turned-on-for-int.patch | 36 - ...tes-async-notification-do-not-need-t.patch | 99 + ...e-cannot-accidently-write-into-stack.patch | 108 - ..._lookup_by_tableid-to-zebra_vrf_look.patch | 147 ++ ...ove-protodown_r_bit-to-a-better-spot.patch | 181 ++ ...m-nl-to-allow-for-fast-configuration.patch | 62 - ...rk-XXX-to-work-with-bgp-suppress-fib.patch | 190 -- ...bra-Remove-unused-dplane_intf_delete.patch | 48 + ...015-zebra-Remove-unused-add-variable.patch | 53 + ...rn-statements-do-not-use-paranthesis.patch | 27 - ...er.asic_notification_nexthop_control.patch | 205 -- ...licate-function-for-netlink-interfac.patch | 301 +++ ...o-get-set-interface-to-pass-up-from-.patch | 809 +++++++ ...-fpm_read-to-reduce-code-duplication.patch | 56 - ...8-zebra-Add-dplane_ctx_get-set_flags.patch | 78 - ...e-zebra-dplane-for-RTM-link-and-addr.patch | 2154 +++++++++++++++++ ...plane_ctx_route_init-to-init-route-w.patch | 74 + ...ebra-Rearrange-dplane_ctx_route_init.patch | 135 -- ...a-Add-ctx-to-netlink-message-parsing.patch | 155 -- ...when-dplane_fpm_nl-fails-to-process-.patch | 50 + ...rom-the-dplane_fpm_nl-a-route-update.patch | 289 --- ...ra-Fix-code-because-missing-backport.patch | 100 - ...cide-a-netlink-message-is-not-needed.patch | 31 - ...esolved-entry-up-to-concerned-protoc.patch | 49 - ...capability-and-bgp_open_option_parse.patch | 130 - ...ssage-stream-has-enough-data-to-read.patch | 47 - ...og-level-for-graceful-restart-events.patch | 122 - ...tes-async-notification-do-not-need-t.patch | 46 - ...ble-ipv6-src-address-test-in-pceplib.patch | 14 +- .../patch/cross-compile-changes.patch | 77 +- src/sonic-frr/patch/series | 49 +- 48 files changed, 4243 insertions(+), 2301 deletions(-) delete mode 100644 src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch rename src/sonic-frr/patch/{0002-Reduce-severity-of-Vty-connected-from-message.patch => 0001-Reduce-severity-of-Vty-connected-from-message.patch} (52%) create mode 100644 src/sonic-frr/patch/0002-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch rename src/sonic-frr/patch/{0005-nexthops-compare-vrf-only-if-ip-type.patch => 0003-nexthops-compare-vrf-only-if-ip-type.patch} (75%) delete mode 100644 src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch rename src/sonic-frr/patch/{0006-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch => 0004-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch} (60%) rename src/sonic-frr/patch/{0007-Add-support-of-bgp-l3vni-evpn.patch => 0005-Add-support-of-bgp-l3vni-evpn.patch} (78%) create mode 100644 src/sonic-frr/patch/0006-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch rename src/sonic-frr/patch/{0009-ignore-route-from-default-table.patch => 0007-ignore-route-from-default-table.patch} (68%) delete mode 100644 src/sonic-frr/patch/0008-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch rename src/sonic-frr/patch/{0023-Use-vrf_id-for-vrf-not-tabled_id.patch => 0008-Use-vrf_id-for-vrf-not-tabled_id.patch} (84%) rename src/sonic-frr/patch/{0026-bgpd-Ensure-suppress-fib-pending-works-with-network-.patch => 0009-bgpd-Ensure-suppress-fib-pending-works-with-network-.patch} (80%) create mode 100644 src/sonic-frr/patch/0010-bgpd-Change-log-level-for-graceful-restart-events.patch delete mode 100644 src/sonic-frr/patch/0010-zebra-Note-when-the-netlink-DUMP-command-is-interrup.patch delete mode 100644 src/sonic-frr/patch/0011-bgpd-enhanced-capability-is-always-turned-on-for-int.patch create mode 100644 src/sonic-frr/patch/0011-zebra-Static-routes-async-notification-do-not-need-t.patch delete mode 100644 src/sonic-frr/patch/0012-Ensure-ospf_apiclient_lsa_originate-cannot-accidently-write-into-stack.patch create mode 100644 src/sonic-frr/patch/0012-zebra-Rename-vrf_lookup_by_tableid-to-zebra_vrf_look.patch create mode 100644 src/sonic-frr/patch/0013-zebra-Move-protodown_r_bit-to-a-better-spot.patch delete mode 100644 src/sonic-frr/patch/0013-zebra-fix-dplane-fpm-nl-to-allow-for-fast-configuration.patch delete mode 100644 src/sonic-frr/patch/0014-bgpd-Allow-network-XXX-to-work-with-bgp-suppress-fib.patch create mode 100644 src/sonic-frr/patch/0014-zebra-Remove-unused-dplane_intf_delete.patch create mode 100644 src/sonic-frr/patch/0015-zebra-Remove-unused-add-variable.patch delete mode 100755 src/sonic-frr/patch/0015-zebra-Return-statements-do-not-use-paranthesis.patch delete mode 100755 src/sonic-frr/patch/0016-zebra-Add-zrouter.asic_notification_nexthop_control.patch create mode 100644 src/sonic-frr/patch/0016-zebra-Remove-duplicate-function-for-netlink-interfac.patch create mode 100644 src/sonic-frr/patch/0017-zebra-Add-code-to-get-set-interface-to-pass-up-from-.patch delete mode 100755 src/sonic-frr/patch/0017-zebra-Re-arrange-fpm_read-to-reduce-code-duplication.patch delete mode 100755 src/sonic-frr/patch/0018-zebra-Add-dplane_ctx_get-set_flags.patch create mode 100644 src/sonic-frr/patch/0018-zebra-Use-zebra-dplane-for-RTM-link-and-addr.patch create mode 100644 src/sonic-frr/patch/0019-zebra-Abstract-dplane_ctx_route_init-to-init-route-w.patch delete mode 100755 src/sonic-frr/patch/0019-zebra-Rearrange-dplane_ctx_route_init.patch delete mode 100755 src/sonic-frr/patch/0020-zebra-Add-ctx-to-netlink-message-parsing.patch create mode 100644 src/sonic-frr/patch/0020-zebra-Fix-crash-when-dplane_fpm_nl-fails-to-process-.patch delete mode 100755 src/sonic-frr/patch/0021-zebra-Read-from-the-dplane_fpm_nl-a-route-update.patch delete mode 100755 src/sonic-frr/patch/0022-zebra-Fix-code-because-missing-backport.patch delete mode 100644 src/sonic-frr/patch/0024-zebra-continue-fpm-read-when-we-decide-a-netlink-message-is-not-needed.patch delete mode 100644 src/sonic-frr/patch/0025-zebra-Send-nht-resolved-entry-up-to-concerned-protoc.patch delete mode 100644 src/sonic-frr/patch/0027-bgpd-Ensure-FRR-has-enough-data-to-read-in-peek_for_as4_capability-and-bgp_open_option_parse.patch delete mode 100644 src/sonic-frr/patch/0028-bgpd-Ensure-that-bgp-open-message-stream-has-enough-data-to-read.patch delete mode 100644 src/sonic-frr/patch/0029-bgpd-Change-log-level-for-graceful-restart-events.patch delete mode 100644 src/sonic-frr/patch/0030-zebra-Static-routes-async-notification-do-not-need-t.patch diff --git a/.gitmodules b/.gitmodules index 56fcd2eb0865..b91c3e8aaa67 100644 --- a/.gitmodules +++ b/.gitmodules @@ -46,7 +46,7 @@ [submodule "src/sonic-frr/frr"] path = src/sonic-frr/frr url = https://github.com/sonic-net/sonic-frr.git - branch = frr/8.2 + branch = frr/8.5 [submodule "platform/p4/p4-hlir/p4-hlir-v1.1"] path = platform/p4/p4-hlir/p4-hlir-v1.1 url = https://github.com/p4lang/p4-hlir.git diff --git a/rules/frr.mk b/rules/frr.mk index 7bc5cc8024f0..b062016fbc09 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,9 +1,9 @@ # FRRouting (frr) package -FRR_VERSION = 8.2.2 +FRR_VERSION = 8.5.1 FRR_SUBVERSION = 0 -FRR_BRANCH = frr/8.2 -FRR_TAG = frr-8.2.2 +FRR_BRANCH = frr/8.5 +FRR_TAG = frr-8.5.1 export FRR_VERSION FRR_SUBVERSION FRR_BRANCH FRR_TAG diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index 79188bf710e9..7a2b85ae52b3 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit 79188bf710e92acf42fb5b9b0a2e9593a5ee9b05 +Subproject commit 7a2b85ae52b354248fa9da04100efba0ec6c70c9 diff --git a/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch b/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch deleted file mode 100644 index ba5668394385..000000000000 --- a/src/sonic-frr/patch/0001-Add-support-of-bgp-tcp-DSCP-value.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 4ab192df23362e64d1a11441fae82329388f103e Mon Sep 17 00:00:00 2001 -From: Pavel Shirshov -Date: Mon, 16 Nov 2020 18:00:12 -0800 -Subject: [PATCH 1/8] Add support of bgp tcp DSCP value - ---- - bgpd/bgp_network.c | 11 ++++------- - bgpd/bgp_vty.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ - bgpd/bgpd.c | 1 + - bgpd/bgpd.h | 3 +++ - 4 files changed, 52 insertions(+), 7 deletions(-) - -diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c -index 3fb7619ed..70c771683 100644 ---- a/bgpd/bgp_network.c -+++ b/bgpd/bgp_network.c -@@ -743,11 +743,9 @@ int bgp_connect(struct peer *peer) - #ifdef IPTOS_PREC_INTERNETCONTROL - frr_with_privs(&bgpd_privs) { - if (sockunion_family(&peer->su) == AF_INET) -- setsockopt_ipv4_tos(peer->fd, -- IPTOS_PREC_INTERNETCONTROL); -+ setsockopt_ipv4_tos(peer->fd, peer->bgp->tcp_dscp); - else if (sockunion_family(&peer->su) == AF_INET6) -- setsockopt_ipv6_tclass(peer->fd, -- IPTOS_PREC_INTERNETCONTROL); -+ setsockopt_ipv6_tclass(peer->fd, peer->bgp->tcp_dscp); - } - #endif - -@@ -824,10 +822,9 @@ static int bgp_listener(int sock, struct sockaddr *sa, socklen_t salen, - - #ifdef IPTOS_PREC_INTERNETCONTROL - if (sa->sa_family == AF_INET) -- setsockopt_ipv4_tos(sock, IPTOS_PREC_INTERNETCONTROL); -+ setsockopt_ipv4_tos(sock, bgp->tcp_dscp); - else if (sa->sa_family == AF_INET6) -- setsockopt_ipv6_tclass(sock, -- IPTOS_PREC_INTERNETCONTROL); -+ setsockopt_ipv6_tclass(sock, bgp->tcp_dscp); - #endif - - sockopt_v6only(sa->sa_family, sock); -diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c -index 4df2abef8..950d1d25c 100644 ---- a/bgpd/bgp_vty.c -+++ b/bgpd/bgp_vty.c -@@ -1558,6 +1558,42 @@ DEFUN (no_router_bgp, - return CMD_SUCCESS; - } - -+/* bgp session-dscp */ -+ -+DEFUN (bgp_session_dscp, -+ bgp_session_dscp_cmd, -+ "bgp session-dscp DSCP", -+ BGP_STR -+ "Override default (C0) bgp TCP session DSCP value\n" -+ "Manually configured dscp parameter\n") -+{ -+ struct bgp *bgp = VTY_GET_CONTEXT(bgp); -+ -+ uint8_t value = (uint8_t)strtol(argv[2]->arg, NULL, 16); -+ if ((value == 0 && errno == EINVAL) || (value > 0x3f)) -+ { -+ vty_out (vty, "%% Malformed bgp session-dscp parameter\n"); -+ return CMD_WARNING_CONFIG_FAILED; -+ } -+ -+ bgp->tcp_dscp = value << 2; -+ -+ return CMD_SUCCESS; -+} -+ -+DEFUN (no_bgp_session_dscp, -+ no_bgp_session_dscp_cmd, -+ "no bgp session-dscp", -+ NO_STR -+ BGP_STR -+ "Override default (C0) bgp tcp session ip dscp value\n") -+{ -+ struct bgp *bgp = VTY_GET_CONTEXT(bgp); -+ -+ bgp->tcp_dscp = IPTOS_PREC_INTERNETCONTROL; -+ -+ return CMD_SUCCESS; -+} - - /* BGP router-id. */ - -@@ -17053,6 +17089,10 @@ int bgp_config_write(struct vty *vty) - if (CHECK_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER)) - vty_out(vty, " no bgp fast-external-failover\n"); - -+ /* BGP session DSCP value */ -+ if (bgp->tcp_dscp != IPTOS_PREC_INTERNETCONTROL) -+ vty_out(vty, " bgp session-dscp %02X\n", bgp->tcp_dscp >> 2); -+ - /* BGP router ID. */ - if (bgp->router_id_static.s_addr != INADDR_ANY) - vty_out(vty, " bgp router-id %pI4\n", -@@ -17662,6 +17702,10 @@ void bgp_vty_init(void) - /* "no router bgp" commands. */ - install_element(CONFIG_NODE, &no_router_bgp_cmd); - -+ /* "bgp session-dscp command */ -+ install_element (BGP_NODE, &bgp_session_dscp_cmd); -+ install_element (BGP_NODE, &no_bgp_session_dscp_cmd); -+ - /* "bgp router-id" commands. */ - install_element(BGP_NODE, &bgp_router_id_cmd); - install_element(BGP_NODE, &no_bgp_router_id_cmd); -diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 7e528b219..005523544 100644 ---- a/bgpd/bgpd.c -+++ b/bgpd/bgpd.c -@@ -3229,6 +3229,7 @@ static struct bgp *bgp_create(as_t *as, const char *name, - bgp->evpn_info = XCALLOC(MTYPE_BGP_EVPN_INFO, - sizeof(struct bgp_evpn_info)); - -+ bgp->tcp_dscp = IPTOS_PREC_INTERNETCONTROL; - bgp_evpn_init(bgp); - bgp_evpn_vrf_es_init(bgp); - bgp_pbr_init(bgp); -diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h -index 8b93c450e..e780d8a03 100644 ---- a/bgpd/bgpd.h -+++ b/bgpd/bgpd.h -@@ -743,6 +743,9 @@ struct bgp { - /* Weighted ECMP related config. */ - enum bgp_link_bw_handling lb_handling; - -+ /* dscp value for tcp sessions */ -+ uint8_t tcp_dscp; -+ - /* Process Queue for handling routes */ - struct work_queue *process_queue; - --- -2.12.2 - diff --git a/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch b/src/sonic-frr/patch/0001-Reduce-severity-of-Vty-connected-from-message.patch similarity index 52% rename from src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch rename to src/sonic-frr/patch/0001-Reduce-severity-of-Vty-connected-from-message.patch index 764d38463289..3aafe4c93d03 100644 --- a/src/sonic-frr/patch/0002-Reduce-severity-of-Vty-connected-from-message.patch +++ b/src/sonic-frr/patch/0001-Reduce-severity-of-Vty-connected-from-message.patch @@ -1,17 +1,16 @@ -From 15274a197e4d3b7ac0f11ca63a5274f1168739f5 Mon Sep 17 00:00:00 2001 +From 69370e52e94c66e06052a7859dd059dfa34fd61e Mon Sep 17 00:00:00 2001 From: Pavel Shirshov Date: Mon, 16 Nov 2020 18:11:47 -0800 -Subject: [PATCH 2/8] Reduce severity of 'Vty connected from' message +Subject: [PATCH] From 15274a197e4d3b7ac0f11ca63a5274f1168739f5 Mon Sep 17 + 00:00:00 2001 Subject: [PATCH 2/8] Reduce severity of 'Vty connected from' + message ---- - lib/vty.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/vty.c b/lib/vty.c -index 8eaf13619..7edeb5538 100644 +index ab98ac14e..c32fc13ba 100644 --- a/lib/vty.c +++ b/lib/vty.c -@@ -1814,7 +1814,7 @@ static int vty_accept(struct thread *thread) +@@ -1843,7 +1843,7 @@ static void vty_accept(struct thread *thread) zlog_info("can't set sockopt to vty_sock : %s", safe_strerror(errno)); @@ -19,7 +18,7 @@ index 8eaf13619..7edeb5538 100644 + zlog_debug("Vty connection from %pSU", &su); vty_create(vty_sock, &su); - + } -- -2.12.2 +2.17.1 diff --git a/src/sonic-frr/patch/0002-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch b/src/sonic-frr/patch/0002-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch new file mode 100644 index 000000000000..f80a3d5d5e4e --- /dev/null +++ b/src/sonic-frr/patch/0002-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch @@ -0,0 +1,25 @@ +From 44ed2b0d2a2ca6029238118603264e02e2e965f4 Mon Sep 17 00:00:00 2001 +From: Pavel Shirshov +Date: Mon, 16 Nov 2020 18:33:46 -0800 +Subject: [PATCH] From afff474c79e0c177e090d1b45d68c9f816a52e3e Mon Sep 17 + 00:00:00 2001 Subject: [PATCH 4/8] Allow BGP attr NEXT_HOP to be 0.0.0.0 due + to alleviate + + +diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c +index f4dff0d80..f00c54c40 100644 +--- a/bgpd/bgp_route.c ++++ b/bgpd/bgp_route.c +@@ -3835,8 +3835,7 @@ bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, + + /* If NEXT_HOP is present, validate it. */ + if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) { +- if (attr->nexthop.s_addr == INADDR_ANY || +- !ipv4_unicast_valid(&attr->nexthop) || ++ if (!ipv4_unicast_valid(&attr->nexthop) || + bgp_nexthop_self(bgp, afi, type, stype, attr, dest)) + return true; + } +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch b/src/sonic-frr/patch/0003-nexthops-compare-vrf-only-if-ip-type.patch similarity index 75% rename from src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch rename to src/sonic-frr/patch/0003-nexthops-compare-vrf-only-if-ip-type.patch index 2db1105622eb..1d5b89a30f72 100644 --- a/src/sonic-frr/patch/0005-nexthops-compare-vrf-only-if-ip-type.patch +++ b/src/sonic-frr/patch/0003-nexthops-compare-vrf-only-if-ip-type.patch @@ -1,15 +1,12 @@ -From 786087468520db44c55e3566f77438b41f52763f Mon Sep 17 00:00:00 2001 +From 2b778b1984c5f88500625a0e96a5ba1d1fe0316c Mon Sep 17 00:00:00 2001 From: Pavel Shirshov Date: Mon, 16 Nov 2020 18:35:01 -0800 -Subject: [PATCH 5/8] nexthops compare vrf only if ip type +Subject: [PATCH] From 786087468520db44c55e3566f77438b41f52763f Mon Sep 17 + 00:00:00 2001 Subject: [PATCH 5/8] nexthops compare vrf only if ip type ---- - lib/nexthop.c | 12 ++++++------ - lib/zclient.c | 12 ++++++------ - 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c -index e17eeb830..a1ce22e3b 100644 +index 248acd270..7ebc4fefb 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -140,12 +140,6 @@ static int _nexthop_cmp_no_labels(const struct nexthop *next1, @@ -39,10 +36,10 @@ index e17eeb830..a1ce22e3b 100644 if (ret != 0) return ret; diff --git a/lib/zclient.c b/lib/zclient.c -index 445837017..c104623b7 100644 +index 07c7e5aea..0082b2148 100644 --- a/lib/zclient.c +++ b/lib/zclient.c -@@ -864,12 +864,6 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, +@@ -869,12 +869,6 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, { int ret = 0; @@ -55,7 +52,7 @@ index 445837017..c104623b7 100644 if (next1->type < next2->type) return -1; -@@ -885,6 +879,12 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, +@@ -890,6 +884,12 @@ static int zapi_nexthop_cmp_no_labels(const struct zapi_nexthop *next1, switch (next1->type) { case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV6: @@ -69,5 +66,5 @@ index 445837017..c104623b7 100644 &next2->gate); if (ret != 0) -- -2.12.2 +2.17.1 diff --git a/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch b/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch deleted file mode 100644 index 9d2f08efb191..000000000000 --- a/src/sonic-frr/patch/0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch +++ /dev/null @@ -1,27 +0,0 @@ -From afff474c79e0c177e090d1b45d68c9f816a52e3e Mon Sep 17 00:00:00 2001 -From: Pavel Shirshov -Date: Mon, 16 Nov 2020 18:33:46 -0800 -Subject: [PATCH 4/8] Allow BGP attr NEXT_HOP to be 0.0.0.0 due to - alleviate - ---- - bgpd/bgp_route.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index b297ca006..d4b5066c6 100644 ---- a/bgpd/bgp_route.c -+++ b/bgpd/bgp_route.c -@@ -3625,8 +3625,7 @@ bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi, - - /* If NEXT_HOP is present, validate it. */ - if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) { -- if (attr->nexthop.s_addr == INADDR_ANY -- || IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr)) -+ if (IPV4_CLASS_DE(ntohl(attr->nexthop.s_addr)) - || bgp_nexthop_self(bgp, afi, type, stype, attr, dest)) - return true; - } --- -2.12.2 - diff --git a/src/sonic-frr/patch/0006-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch b/src/sonic-frr/patch/0004-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch similarity index 60% rename from src/sonic-frr/patch/0006-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch rename to src/sonic-frr/patch/0004-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch index 6d3db6d518e9..6936e36100a0 100644 --- a/src/sonic-frr/patch/0006-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch +++ b/src/sonic-frr/patch/0004-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch @@ -1,27 +1,25 @@ -From 0417036a3aece862c95111d4646ca7508a028165 Mon Sep 17 00:00:00 2001 +From ece5d83bebfe2345edf8e18f5af713bd99cc3739 Mon Sep 17 00:00:00 2001 From: Ying Xie Date: Wed, 25 Nov 2020 22:28:43 +0000 -Subject: [PATCH] [PATCH 6/8] [frr] remove frr log outchannel to /var/log/frr.log -SONiC runs frr inside a docker and the logs are sent to base image -via rsyslog and recorded already. There is no need to keep the -frr.log inside the docker. It will grow and take all harddrive -space eventually. +Subject: [PATCH] From 0417036a3aece862c95111d4646ca7508a028165 Mon Sep 17 + 00:00:00 2001 Subject: [PATCH] [PATCH 6/8] [frr] remove frr log outchannel to + /var/log/frr.log SONiC runs frr inside a docker and the logs are sent to base + image via rsyslog and recorded already. There is no need to keep the frr.log + inside the docker. It will grow and take all harddrive space eventually. ---- - tools/etc/rsyslog.d/45-frr.conf | 19 ------------------- - 1 file changed, 19 deletions(-) diff --git a/tools/etc/rsyslog.d/45-frr.conf b/tools/etc/rsyslog.d/45-frr.conf -index feeeb13f1..fcd23d23a 100644 +index 75b20d76b..9cdd55762 100644 --- a/tools/etc/rsyslog.d/45-frr.conf +++ b/tools/etc/rsyslog.d/45-frr.conf -@@ -2,25 +2,6 @@ +@@ -2,29 +2,6 @@ # to /var/log/frr/frr.log, then drops the message so it does # not also go to /var/log/syslog, so the messages are not duplicated -$outchannel frr_log,/var/log/frr/frr.log -if $programname == 'babeld' or - $programname == 'bgpd' or +- $programname == 'bfdd' or - $programname == 'eigrpd' or - $programname == 'frr' or - $programname == 'isisd' or @@ -31,6 +29,9 @@ index feeeb13f1..fcd23d23a 100644 - $programname == 'ospf6d' or - $programname == 'ospfd' or - $programname == 'pimd' or +- $programname == 'pim6d' or +- $programname == 'pathd' or +- $programname == 'pbrd' or - $programname == 'ripd' or - $programname == 'ripngd' or - $programname == 'vrrpd' or @@ -40,7 +41,7 @@ index feeeb13f1..fcd23d23a 100644 - if $programname == 'babeld' or $programname == 'bgpd' or - $programname == 'eigrpd' or + $programname == 'bfdd' or -- -2.12.2 +2.17.1 diff --git a/src/sonic-frr/patch/0007-Add-support-of-bgp-l3vni-evpn.patch b/src/sonic-frr/patch/0005-Add-support-of-bgp-l3vni-evpn.patch similarity index 78% rename from src/sonic-frr/patch/0007-Add-support-of-bgp-l3vni-evpn.patch rename to src/sonic-frr/patch/0005-Add-support-of-bgp-l3vni-evpn.patch index 5efd29fdcf09..fe2636c2e289 100644 --- a/src/sonic-frr/patch/0007-Add-support-of-bgp-l3vni-evpn.patch +++ b/src/sonic-frr/patch/0005-Add-support-of-bgp-l3vni-evpn.patch @@ -1,22 +1,16 @@ -From 369bbb4d62aa47d5a6d5157ca6ea819c4cb80f15 Mon Sep 17 00:00:00 2001 +From f5f0018266c98ad96cdbe69ae60d501de21e5600 Mon Sep 17 00:00:00 2001 From: Stepan Blyschak Date: Thu, 20 Oct 2022 13:19:31 +0000 -Subject: [PATCH 07/13] Added support of L3VNI EVPN +Subject: [PATCH] From 369bbb4d62aa47d5a6d5157ca6ea819c4cb80f15 Mon Sep 17 + 00:00:00 2001 Subject: [PATCH 07/13] Added support of L3VNI EVPN This is temp patch till Prefix to ARP indirection is add in neighorch Signed-off-by: Kishore Kunal Signed-off-by: Stepan Blyschak ---- - lib/nexthop.c | 1 + - lib/nexthop.h | 7 ++++++- - zebra/rt_netlink.c | 15 ++++++++++++++- - zebra/zapi_msg.c | 4 ++++ - zebra/zebra_dplane.c | 2 +- - 5 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/nexthop.c b/lib/nexthop.c -index a1ce22e3b..10a87f072 100644 +index 7ebc4fefb..2f7bb0e7b 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c @@ -813,6 +813,7 @@ void nexthop_copy_no_recurse(struct nexthop *copy, @@ -28,13 +22,13 @@ index a1ce22e3b..10a87f072 100644 nexthop_add_labels(copy, nexthop->nh_label_type, nexthop->nh_label->num_labels, diff --git a/lib/nexthop.h b/lib/nexthop.h -index 320b46315..77eea3674 100644 +index f1309aa52..7b4bbbafd 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -66,6 +66,11 @@ enum nh_encap_type { /* Backup index value is limited */ #define NEXTHOP_BACKUP_IDX_MAX 255 - + +struct vxlan_nh_encap { + vni_t vni; + struct ethaddr rmac; @@ -43,31 +37,31 @@ index 320b46315..77eea3674 100644 /* Nexthop structure. */ struct nexthop { struct nexthop *next; -@@ -135,7 +140,7 @@ struct nexthop { +@@ -137,7 +142,7 @@ struct nexthop { /* Encapsulation information. */ enum nh_encap_type nh_encap_type; union { - vni_t vni; + struct vxlan_nh_encap encap_data; } nh_encap; - + /* SR-TE color used for matching SR-TE policies */ diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c -index 03c84d6dc..a56a95276 100644 +index 79d79d74b..325199eff 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c -@@ -1869,6 +1869,7 @@ static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen, +@@ -1969,6 +1969,7 @@ static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen, struct nexthop *nh) { struct rtattr *nest; + struct vxlan_nh_encap* encap_data; - + switch (nh->nh_encap_type) { case NET_VXLAN: -@@ -1879,9 +1880,21 @@ static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen, +@@ -1979,9 +1980,21 @@ static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen, if (!nest) return false; - + + encap_data = &nh->nh_encap.encap_data; + if (!nl_attr_put32(n, nlen, 0 /* VXLAN_VNI */, @@ -88,10 +82,10 @@ index 03c84d6dc..a56a95276 100644 break; } diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c -index 5cf7d815d..529cbb44b 100644 +index c0945eae2..157c33ced 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c -@@ -1577,6 +1577,8 @@ static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh, +@@ -1605,6 +1605,8 @@ static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh, vtep_ip.ipa_type = IPADDR_V4; memcpy(&(vtep_ip.ipaddr_v4), &(api_nh->gate.ipv4), sizeof(struct in_addr)); @@ -99,8 +93,8 @@ index 5cf7d815d..529cbb44b 100644 + &api_nh->rmac, ETH_ALEN); zebra_rib_queue_evpn_route_add( api_nh->vrf_id, &api_nh->rmac, &vtep_ip, p); - } -@@ -1610,6 +1612,8 @@ static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh, + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN); +@@ -1639,6 +1641,8 @@ static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh, vtep_ip.ipa_type = IPADDR_V6; memcpy(&vtep_ip.ipaddr_v6, &(api_nh->gate.ipv6), sizeof(struct in6_addr)); @@ -108,12 +102,12 @@ index 5cf7d815d..529cbb44b 100644 + &api_nh->rmac, ETH_ALEN); zebra_rib_queue_evpn_route_add( api_nh->vrf_id, &api_nh->rmac, &vtep_ip, p); - } + SET_FLAG(nexthop->flags, NEXTHOP_FLAG_EVPN); diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c -index 656ebcf3b..bd59df189 100644 +index f6f436f39..c8511bd28 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c -@@ -2420,7 +2420,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, +@@ -2917,7 +2917,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, zl3vni = zl3vni_from_vrf(nexthop->vrf_id); if (zl3vni && is_l3vni_oper_up(zl3vni)) { nexthop->nh_encap_type = NET_VXLAN; @@ -121,7 +115,7 @@ index 656ebcf3b..bd59df189 100644 + nexthop->nh_encap.encap_data.vni = zl3vni->vni; } } - --- -2.30.2 + +-- +2.17.1 diff --git a/src/sonic-frr/patch/0006-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch b/src/sonic-frr/patch/0006-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch new file mode 100644 index 000000000000..575e636593bb --- /dev/null +++ b/src/sonic-frr/patch/0006-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch @@ -0,0 +1,28 @@ +From 4fdb386b2b41278ca10431fe2b386853985aff0f Mon Sep 17 00:00:00 2001 +From: Akhilesh Samineni +Date: Mon, 5 Apr 2021 13:21:40 -0700 +Subject: [PATCH] From 92ab2d74fca06f86c00d886ac249f7f2d89e93fe Mon Sep 17 + 00:00:00 2001 Subject: [PATCH 8/8] Link local scope was not set while binding + socket with local address causing socket errors for bgp ipv6 link local + neighbors. + + +diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c +index 76bb9949d..5acdde08d 100644 +--- a/bgpd/bgp_network.c ++++ b/bgpd/bgp_network.c +@@ -678,6 +678,11 @@ int bgp_update_address(struct interface *ifp, const union sockunion *dst, + return 1; + + prefix2sockunion(sel, addr); ++ ++ if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6.sin6_addr)) { ++ addr->sin6.sin6_scope_id = ifp->ifindex; ++ } ++ + return 0; + } + +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0009-ignore-route-from-default-table.patch b/src/sonic-frr/patch/0007-ignore-route-from-default-table.patch similarity index 68% rename from src/sonic-frr/patch/0009-ignore-route-from-default-table.patch rename to src/sonic-frr/patch/0007-ignore-route-from-default-table.patch index 6af5bfc45783..52167d765287 100644 --- a/src/sonic-frr/patch/0009-ignore-route-from-default-table.patch +++ b/src/sonic-frr/patch/0007-ignore-route-from-default-table.patch @@ -1,21 +1,19 @@ -From ca66350aecf7db3354019480d11754fabae3a97c Mon Sep 17 00:00:00 2001 +From 1a639f2dcd400997345dab424a2adbc091752661 Mon Sep 17 00:00:00 2001 From: Stepan Blyschak Date: Thu, 20 Oct 2022 13:07:18 +0000 -Subject: [PATCH 09/13] ignore route from default table +Subject: [PATCH] From ca66350aecf7db3354019480d11754fabae3a97c Mon Sep 17 + 00:00:00 2001 Subject: [PATCH 09/13] ignore route from default table Signed-off-by: Stepan Blyschak ---- - zebra/dplane_fpm_nl.c | 9 +++++++++ - 1 file changed, 9 insertions(+) diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c -index 3b02128c9..da8504adf 100644 +index 0a9fecc9d..b18a96353 100644 --- a/zebra/dplane_fpm_nl.c +++ b/zebra/dplane_fpm_nl.c -@@ -699,6 +699,15 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx) +@@ -814,6 +814,15 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx) || op == DPLANE_OP_NH_UPDATE)) return 0; - + + /* + * Ignore route from default table, because when mgmt port goes down, + * zebra will remove the default route and causing ASIC to blackhole IO. @@ -26,7 +24,8 @@ index 3b02128c9..da8504adf 100644 + } + nl_buf_len = 0; - + frr_mutex_lock_autounlock(&fnc->obuf_mutex); --- -2.30.2 +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0008-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch b/src/sonic-frr/patch/0008-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch deleted file mode 100644 index c2ff17dab88c..000000000000 --- a/src/sonic-frr/patch/0008-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 92ab2d74fca06f86c00d886ac249f7f2d89e93fe Mon Sep 17 00:00:00 2001 -From: Akhilesh Samineni -Date: Mon, 5 Apr 2021 13:21:40 -0700 -Subject: [PATCH 8/8] Link local scope was not set while binding socket - with local address causing socket errors for bgp ipv6 link local neighbors. - ---- - bgpd/bgp_network.c | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c -index 70c771683..dbc9870a5 100644 ---- a/bgpd/bgp_network.c -+++ b/bgpd/bgp_network.c -@@ -662,6 +662,11 @@ static int bgp_update_address(struct interface *ifp, const union sockunion *dst, - return 1; - - prefix2sockunion(sel, addr); -+ -+ if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6.sin6_addr)) { -+ addr->sin6.sin6_scope_id = ifp->ifindex; -+ } -+ - return 0; - } - --- -2.12.2 - diff --git a/src/sonic-frr/patch/0023-Use-vrf_id-for-vrf-not-tabled_id.patch b/src/sonic-frr/patch/0008-Use-vrf_id-for-vrf-not-tabled_id.patch similarity index 84% rename from src/sonic-frr/patch/0023-Use-vrf_id-for-vrf-not-tabled_id.patch rename to src/sonic-frr/patch/0008-Use-vrf_id-for-vrf-not-tabled_id.patch index b69ce1fbb811..ae8b05f06bd0 100644 --- a/src/sonic-frr/patch/0023-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,18 +1,16 @@ -From 349e3f758860be0077b69919c39764d3486ec44a Mon Sep 17 00:00:00 2001 +From 44f3736ee601e06e43e978fa075402c3da4823bd Mon Sep 17 00:00:00 2001 From: Stepan Blyschak Date: Mon, 16 Jan 2023 11:45:19 +0000 -Subject: [PATCH] use vrf id instead of table id +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 ---- - zebra/rt_netlink.c | 74 ++++++++++++++++++++++++++++++++++++++-------- - 1 file changed, 61 insertions(+), 13 deletions(-) diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c -index 29137a09f..e7b808754 100644 +index 325199eff..587045eac 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c -@@ -388,6 +388,30 @@ vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) +@@ -406,6 +406,30 @@ vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) return VRF_DEFAULT; } @@ -43,7 +41,7 @@ index 29137a09f..e7b808754 100644 /** * @parse_encap_mpls() - Parses encapsulated mpls attributes * @tb: Pointer to rtattr to look for nested items in. -@@ -754,14 +778,26 @@ int netlink_route_change_read_unicast_internal(struct nlmsghdr *h, +@@ -782,14 +806,26 @@ int netlink_route_change_read_unicast_internal(struct nlmsghdr *h, if (rtm->rtm_family == AF_MPLS) return 0; @@ -77,8 +75,8 @@ index 29137a09f..e7b808754 100644 if (vrf_id == VRF_DEFAULT) { if (!is_zebra_valid_kernel_table(table) && !is_zebra_main_routing_table(table)) -@@ -2004,12 +2040,24 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, - #endif +@@ -2102,12 +2138,24 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, + /* Table corresponding to this route. */ table_id = dplane_ctx_get_table(ctx); - if (table_id < 256) @@ -109,5 +107,5 @@ index 29137a09f..e7b808754 100644 if (IS_ZEBRA_DEBUG_KERNEL) -- -2.30.2 +2.17.1 diff --git a/src/sonic-frr/patch/0026-bgpd-Ensure-suppress-fib-pending-works-with-network-.patch b/src/sonic-frr/patch/0009-bgpd-Ensure-suppress-fib-pending-works-with-network-.patch similarity index 80% rename from src/sonic-frr/patch/0026-bgpd-Ensure-suppress-fib-pending-works-with-network-.patch rename to src/sonic-frr/patch/0009-bgpd-Ensure-suppress-fib-pending-works-with-network-.patch index 4805315cee1d..a276f9ba5b49 100644 --- a/src/sonic-frr/patch/0026-bgpd-Ensure-suppress-fib-pending-works-with-network-.patch +++ b/src/sonic-frr/patch/0009-bgpd-Ensure-suppress-fib-pending-works-with-network-.patch @@ -1,8 +1,9 @@ -From 5a1d3c9e24791ebdb7e375a02afe9c5f6146c488 Mon Sep 17 00:00:00 2001 +From c4a198c977168a6bd420197d19c8a4c0f4eacc8a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 22 Mar 2023 11:35:28 -0400 -Subject: [PATCH] bgpd: Ensure suppress-fib-pending works with network - statements +Subject: [PATCH] From 5a1d3c9e24791ebdb7e375a02afe9c5f6146c488 Mon Sep 17 + 00:00:00 2001 Subject: [PATCH] bgpd: Ensure suppress-fib-pending works with + network statements The flag for telling BGP that a route is expected to be installed first before notifying a peer was always being set upon receipt @@ -22,17 +23,12 @@ cover the case when a network statement is added after the route has been learned from a peer. Signed-off-by: Donald Sharp ---- - bgpd/bgp_route.c | 22 ------------------- - bgpd/bgp_zebra.c | 14 ++++++++++++ - .../bgp_suppress_fib/test_bgp_suppress_fib.py | 14 ++++++++++++ - 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c -index d4b5066c6..c01e2fd2c 100644 +index f00c54c40..a7a5c9849 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c -@@ -2994,11 +2994,6 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3203,11 +3203,6 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, if (bgp_fibupd_safi(safi) && !bgp_option_check(BGP_OPT_NO_FIB)) { @@ -44,7 +40,7 @@ index d4b5066c6..c01e2fd2c 100644 if (new_select->type == ZEBRA_ROUTE_BGP && (new_select->sub_type == BGP_ROUTE_NORMAL || new_select->sub_type -@@ -3104,10 +3099,6 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, +@@ -3313,10 +3308,6 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, || new_select->sub_type == BGP_ROUTE_AGGREGATE || new_select->sub_type == BGP_ROUTE_IMPORTED)) { @@ -55,10 +51,10 @@ index d4b5066c6..c01e2fd2c 100644 /* if this is an evpn imported type-5 prefix, * we need to withdraw the route first to clear * the nh neigh and the RMAC entry. -@@ -3953,19 +3944,6 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, +@@ -4261,18 +4252,6 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, + bgp_attr_flush(&new_attr); goto filtered; } - - /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following - * condition : - * Suppress fib is enabled @@ -71,17 +67,16 @@ index d4b5066c6..c01e2fd2c 100644 - && (!bgp_option_check(BGP_OPT_NO_FIB)) - && (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED))) - SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING); -- - /* If maximum prefix count is configured and current prefix - * count exeed it. - */ + + /* If neighbor soo is configured, tag all incoming routes with + * this SoO tag and then filter out advertisements in diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c -index 21912d143..71816813a 100644 +index 95e80ba1b..efcf49785 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c -@@ -1269,6 +1269,14 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, - uint32_t nhg_id = 0; - bool is_add; +@@ -1322,6 +1322,14 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, + uint32_t bos = 0; + uint32_t exp = 0; + /* + * BGP is installing this route and bgp has been configured @@ -94,7 +89,7 @@ index 21912d143..71816813a 100644 /* Don't try to install if we're not connected to Zebra or Zebra doesn't * know of this instance. */ -@@ -1681,6 +1689,12 @@ void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info, +@@ -1758,6 +1766,12 @@ void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info, struct zapi_route api; struct peer *peer; @@ -108,10 +103,10 @@ index 21912d143..71816813a 100644 * know of this instance. */ diff --git a/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py b/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py -index 96a294cae..f812079c7 100644 +index 6d2b65a61..7bcb28166 100644 --- a/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py +++ b/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py -@@ -229,6 +229,20 @@ def test_bgp_allow_as_in(): +@@ -230,6 +230,20 @@ def test_bgp_allow_as_in(): assertmsg = '"r2" 192.168.1.1/32 route should be gone' assert result is None, assertmsg @@ -133,5 +128,5 @@ index 96a294cae..f812079c7 100644 if __name__ == "__main__": args = ["-s"] + sys.argv[1:] -- -2.20.1 +2.17.1 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 new file mode 100644 index 000000000000..54fcc1575a75 --- /dev/null +++ b/src/sonic-frr/patch/0010-bgpd-Change-log-level-for-graceful-restart-events.patch @@ -0,0 +1,116 @@ +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 +--- 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); + +- 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); + } + + FOREACH_AFI_SAFI (afi, safi) { +@@ -842,8 +842,8 @@ static void bgp_graceful_stale_timer_expire(struct thread *thread) + + peer = THREAD_ARG(thread); + +- if (bgp_debug_neighbor_events(peer)) +- zlog_debug("%pBP graceful restart stalepath timer expired", ++ if (peer) ++ zlog_info("%pBP graceful restart stalepath timer expired", + peer); + + /* NSF delete stale route */ +@@ -1412,20 +1412,17 @@ enum bgp_fsm_state_progress bgp_stop(struct peer *peer) + /* graceful restart */ + if (peer->t_gr_stale) { + THREAD_OFF(peer->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); + } + if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) { +- if (bgp_debug_neighbor_events(peer)) { +- zlog_debug( +- "%pBP graceful restart timer started for %d sec", +- peer, peer->v_gr_restart); +- zlog_debug( +- "%pBP graceful restart stalepath timer started for %d sec", +- peer, peer->bgp->stalepath_time); +- } ++ zlog_info( ++ "%pBP graceful restart timer started for %d sec", ++ peer, peer->v_gr_restart); ++ zlog_info( ++ "%pBP graceful restart stalepath timer started for %d sec", ++ peer, peer->bgp->stalepath_time); + BGP_TIMER_ON(peer->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) + UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE); + if (peer->t_gr_stale) { + THREAD_OFF(peer->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); + } + } + + if (peer->t_gr_restart) { + THREAD_OFF(peer->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); + } + + /* Reset uptime, turn on keepalives, send current table. */ +diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c +index 8b3a1e3dd..2f3b837a5 100644 +--- a/bgpd/bgpd.c ++++ b/bgpd/bgpd.c +@@ -2453,15 +2453,13 @@ void peer_nsf_stop(struct peer *peer) + + if (peer->t_gr_restart) { + THREAD_OFF(peer->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 (bgp_debug_neighbor_events(peer)) +- zlog_debug( +- "%pBP graceful restart stalepath timer stopped", +- peer); ++ zlog_info( ++ "%pBP graceful restart stalepath timer stopped", ++ peer); + } + bgp_clear_route_all(peer); + } +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0010-zebra-Note-when-the-netlink-DUMP-command-is-interrup.patch b/src/sonic-frr/patch/0010-zebra-Note-when-the-netlink-DUMP-command-is-interrup.patch deleted file mode 100644 index 3da1ab318d1c..000000000000 --- a/src/sonic-frr/patch/0010-zebra-Note-when-the-netlink-DUMP-command-is-interrup.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 8f10590a85669f300d2706d5ef1e560cdbaaf0f8 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Fri, 25 Mar 2022 19:08:14 -0400 -Subject: [PATCH 10/10] zebra: Note when the netlink DUMP command is - interrupted - -There exists code paths in the linux kernel where a dump command -will be interrupted( I am not sure I understand what this really -means ) and the data sent back from the kernel is wrong or incomplete. - -At this point in time I am not 100% certain what should be done, but -let's start noticing that this has happened so we can formulate a plan -or allow the end operator to know bad stuff is a foot at the circle K. - -Signed-off-by: Donald Sharp ---- - zebra/kernel_netlink.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c -index ccafc8f0c..9dc597fad 100644 ---- a/zebra/kernel_netlink.c -+++ b/zebra/kernel_netlink.c -@@ -972,6 +972,18 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), - return err; - } - -+ /* -+ * What is the right thing to do? The kernel -+ * is telling us that the dump request was interrupted -+ * and we more than likely are out of luck and have -+ * missed data from the kernel. At this point in time -+ * lets just note that this is happening. -+ */ -+ if (h->nlmsg_flags & NLM_F_DUMP_INTR) -+ flog_err( -+ EC_ZEBRA_NETLINK_BAD_SEQUENCE, -+ "netlink recvmsg: The Dump request was interrupted"); -+ - /* OK we got netlink message. */ - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug( --- -2.17.1 - diff --git a/src/sonic-frr/patch/0011-bgpd-enhanced-capability-is-always-turned-on-for-int.patch b/src/sonic-frr/patch/0011-bgpd-enhanced-capability-is-always-turned-on-for-int.patch deleted file mode 100644 index cefa7c31449f..000000000000 --- a/src/sonic-frr/patch/0011-bgpd-enhanced-capability-is-always-turned-on-for-int.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 4db4fc1bf0599f79067bfd62aa435be8e161d81e Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Tue, 3 May 2022 12:51:21 -0400 -Subject: [PATCH] bgpd: enhanced capability is always turned on for interface - based peers - -FRR is displaying that the peer enhanced capability command is not -turned on when the interface is part of a peer group. Saving the -config and then reloading actually turns it off. - -Fix the code so that FRR does not display the enhanced capability -for interface based peers. - -Fixes: #11108 -Signed-off-by: Donald Sharp ---- - bgpd/bgp_vty.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c -index 4df2abef8..6fcce239b 100644 ---- a/bgpd/bgp_vty.c -+++ b/bgpd/bgp_vty.c -@@ -16586,7 +16586,8 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp, - - /* capability extended-nexthop */ - if (peergroup_flag_check(peer, PEER_FLAG_CAPABILITY_ENHE)) { -- if (CHECK_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE)) -+ if (CHECK_FLAG(peer->flags_invert, PEER_FLAG_CAPABILITY_ENHE) && -+ !peer->conf_if) - vty_out(vty, - " no neighbor %s capability extended-nexthop\n", - addr); --- -2.17.1 - diff --git a/src/sonic-frr/patch/0011-zebra-Static-routes-async-notification-do-not-need-t.patch b/src/sonic-frr/patch/0011-zebra-Static-routes-async-notification-do-not-need-t.patch new file mode 100644 index 000000000000..6b633badf97b --- /dev/null +++ b/src/sonic-frr/patch/0011-zebra-Static-routes-async-notification-do-not-need-t.patch @@ -0,0 +1,99 @@ +From 56d349ef47ba24bcf838488b1e40474755655259 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Thu, 29 Jun 2023 09:35:00 -0400 +Subject: [PATCH] zebra: Static routes async notification do not need this test + +When using asic_offload with an asynchronous notification the +rib_route_match_ctx function is testing for distance and tag +being correct against the re. + +Normal route notification for static routes is this(well really all routes): +a) zebra dplane generates a ctx to send to the dplane for route install +b) dplane installs it in the kernel +c) if the dplane_fpm_nl.c module is being used it installs it. +d) The context's success code is set to it worked and passes the context +back up to zebra for processing. +e) Zebra master receives this and checks the distance and tag are correct +for static routes and accepts the route and marks it installed. + +If the operator is using a wait for install mechansim where the dplane +is asynchronously sending the result back up at a future time *and* +it is using the dplane_fpm_nl.c code where it uses the rt_netlink.c +route parsing code, then there is no way to set distance as that we +do not pass distance to the kernel. + +As such static routes were never being properly handled since the re and +context would not match and the route would still be marked as queued. + +Modify the code such that the asynchronous path notification for static +routes ignores the distance and tag's as that there is no way to test +for this data from that path at this point in time. + +Signed-off-by: Donald Sharp + +diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c +index fd6df441c6..039c44cc09 100644 +--- a/zebra/zebra_rib.c ++++ b/zebra/zebra_rib.c +@@ -1465,7 +1465,7 @@ static void zebra_rib_evaluate_mpls(struct route_node *rn) + */ + static bool rib_route_match_ctx(const struct route_entry *re, + const struct zebra_dplane_ctx *ctx, +- bool is_update) ++ bool is_update, bool async) + { + bool result = false; + +@@ -1481,13 +1481,12 @@ static bool rib_route_match_ctx(const struct route_entry *re, + /* We use an extra test for statics, and another for + * kernel routes. + */ +- if (re->type == ZEBRA_ROUTE_STATIC && ++ if (re->type == ZEBRA_ROUTE_STATIC && !async && + (re->distance != dplane_ctx_get_old_distance(ctx) || + re->tag != dplane_ctx_get_old_tag(ctx))) { + result = false; + } else if (re->type == ZEBRA_ROUTE_KERNEL && +- re->metric != +- dplane_ctx_get_old_metric(ctx)) { ++ re->metric != dplane_ctx_get_old_metric(ctx)) { + result = false; + } + } +@@ -1509,7 +1508,7 @@ static bool rib_route_match_ctx(const struct route_entry *re, + /* We use an extra test for statics, and another for + * kernel routes. + */ +- if (re->type == ZEBRA_ROUTE_STATIC && ++ if (re->type == ZEBRA_ROUTE_STATIC && !async && + (re->distance != dplane_ctx_get_distance(ctx) || + re->tag != dplane_ctx_get_tag(ctx))) { + result = false; +@@ -1973,13 +1972,13 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx) + RNODE_FOREACH_RE(rn, rib) { + + if (re == NULL) { +- if (rib_route_match_ctx(rib, ctx, false)) ++ if (rib_route_match_ctx(rib, ctx, false, false)) + re = rib; + } + + /* Check for old route match */ + if (is_update && (old_re == NULL)) { +- if (rib_route_match_ctx(rib, ctx, true /*is_update*/)) ++ if (rib_route_match_ctx(rib, ctx, true, false)) + old_re = rib; + } + +@@ -2247,7 +2246,7 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) + * info. + */ + RNODE_FOREACH_RE(rn, re) { +- if (rib_route_match_ctx(re, ctx, false /*!update*/)) ++ if (rib_route_match_ctx(re, ctx, false, true)) + break; + } + +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0012-Ensure-ospf_apiclient_lsa_originate-cannot-accidently-write-into-stack.patch b/src/sonic-frr/patch/0012-Ensure-ospf_apiclient_lsa_originate-cannot-accidently-write-into-stack.patch deleted file mode 100644 index d46f13a3caf1..000000000000 --- a/src/sonic-frr/patch/0012-Ensure-ospf_apiclient_lsa_originate-cannot-accidently-write-into-stack.patch +++ /dev/null @@ -1,108 +0,0 @@ -From d8d77d3733bc299ed5dd7b44c4d464ba2bfed288 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Wed, 20 Jul 2022 16:43:17 -0400 -Subject: [PATCH 1/3] ospfclient: Ensure ospf_apiclient_lsa_originate cannot - accidently write into stack - -Even though OSPF_MAX_LSA_SIZE is quite large and holds the upper bound -on what can be written into a lsa, let's add a small check to ensure -it is not possible to do a bad thing. - -This wins one of the long standing bug awards. 2003! - -Fixes: #11602 -Signed-off-by: Donald Sharp ---- - ospfclient/ospf_apiclient.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/ospfclient/ospf_apiclient.c b/ospfclient/ospf_apiclient.c -index 29f1c0807db..51c8a5b8c06 100644 ---- a/ospfclient/ospf_apiclient.c -+++ b/ospfclient/ospf_apiclient.c -@@ -447,6 +447,12 @@ int ospf_apiclient_lsa_originate(struct ospf_apiclient *oclient, - return OSPF_API_ILLEGALLSATYPE; - } - -+ if ((size_t)opaquelen > sizeof(buf) - sizeof(struct lsa_header)) { -+ fprintf(stderr, "opaquelen(%d) is larger than buf size %zu\n", -+ opaquelen, sizeof(buf)); -+ return OSPF_API_NOMEMORY; -+ } -+ - /* Make a new LSA from parameters */ - lsah = (struct lsa_header *)buf; - lsah->ls_age = 0; - -From 519929cdd47ac4d9f7f33e13922e1a063f69bb24 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Wed, 20 Jul 2022 16:49:09 -0400 -Subject: [PATCH 2/3] isisd: Ensure rcap is freed in error case - -unpack_tlv_router_cap allocates memory that in the error -case is not being freed. - -Signed-off-by: Donald Sharp ---- - isisd/isis_tlvs.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c -index f1aae7caf10..dad271225b3 100644 ---- a/isisd/isis_tlvs.c -+++ b/isisd/isis_tlvs.c -@@ -2966,9 +2966,9 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap, - } - - static int unpack_tlv_router_cap(enum isis_tlv_context context, -- uint8_t tlv_type, uint8_t tlv_len, -- struct stream *s, struct sbuf *log, -- void *dest, int indent) -+ uint8_t tlv_type, uint8_t tlv_len, -+ struct stream *s, struct sbuf *log, void *dest, -+ int indent) - { - struct isis_tlvs *tlvs = dest; - struct isis_router_cap *rcap; -@@ -3013,7 +3013,7 @@ static int unpack_tlv_router_cap(enum isis_tlv_context context, - log, indent, - "WARNING: Router Capability subTLV length too large compared to expected size\n"); - stream_forward_getp(s, STREAM_READABLE(s)); -- -+ XFREE(MTYPE_ISIS_TLV, rcap); - return 0; - } - - -From 3c4821679f2362bcd38fcc7803f28a5210441ddb Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Thu, 21 Jul 2022 08:11:58 -0400 -Subject: [PATCH 3/3] bgpd: Make sure hdr length is at a minimum of what is - expected - -Ensure that if the capability length specified is enough data. - -Signed-off-by: Donald Sharp ---- - bgpd/bgp_packet.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c -index 7c92a8d9e83..bcd47e32d45 100644 ---- a/bgpd/bgp_packet.c -+++ b/bgpd/bgp_packet.c -@@ -2440,6 +2440,14 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt, - "%s CAPABILITY has action: %d, code: %u, length %u", - peer->host, action, hdr->code, hdr->length); - -+ if (hdr->length < sizeof(struct capability_mp_data)) { -+ zlog_info( -+ "%s Capability structure is not properly filled out, expected at least %zu bytes but header length specified is %d", -+ peer->host, sizeof(struct capability_mp_data), -+ hdr->length); -+ return BGP_Stop; -+ } -+ - /* Capability length check. */ - if ((pnt + hdr->length + 3) > end) { - zlog_info("%s Capability length error", peer->host); diff --git a/src/sonic-frr/patch/0012-zebra-Rename-vrf_lookup_by_tableid-to-zebra_vrf_look.patch b/src/sonic-frr/patch/0012-zebra-Rename-vrf_lookup_by_tableid-to-zebra_vrf_look.patch new file mode 100644 index 000000000000..ca6517fbf655 --- /dev/null +++ b/src/sonic-frr/patch/0012-zebra-Rename-vrf_lookup_by_tableid-to-zebra_vrf_look.patch @@ -0,0 +1,147 @@ +From 2b9c7592a9857ddccc77b9d3f178e0c5bd5f19ed Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Wed, 26 Apr 2023 23:25:27 -0400 +Subject: [PATCH] zebra: Rename vrf_lookup_by_tableid to zebra_vrf_lookup.. + +Rename the vrf_lookup_by_id function to zebra_vrf_lookup_by_id +and move to zebra_vrf.c where it nominally belongs, as that +we need zebra specific data to find this vrf_id and as such +it does not belong in vrf.c + +Signed-off-by: Donald Sharp + +diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c +index 81347b550a..4599121261 100644 +--- a/zebra/if_netlink.c ++++ b/zebra/if_netlink.c +@@ -342,7 +342,8 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, + if (!vrf_lookup_by_id((vrf_id_t)ifi->ifi_index)) { + vrf_id_t exist_id; + +- exist_id = vrf_lookup_by_table(nl_table_id, ns_id); ++ exist_id = ++ zebra_vrf_lookup_by_table(nl_table_id, ns_id); + if (exist_id != VRF_DEFAULT) { + vrf = vrf_lookup_by_id(exist_id); + +diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c +index 587045eac2..6b9b047858 100644 +--- a/zebra/rt_netlink.c ++++ b/zebra/rt_netlink.c +@@ -379,33 +379,6 @@ static inline int proto2zebra(int proto, int family, bool is_nexthop) + return proto; + } + +-/* +-Pending: create an efficient table_id (in a tree/hash) based lookup) +- */ +-vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) +-{ +- struct vrf *vrf; +- struct zebra_vrf *zvrf; +- +- RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { +- zvrf = vrf->info; +- if (zvrf == NULL) +- continue; +- /* case vrf with netns : match the netnsid */ +- if (vrf_is_backend_netns()) { +- if (ns_id == zvrf_id(zvrf)) +- return zvrf_id(zvrf); +- } else { +- /* VRF is VRF_BACKEND_VRF_LITE */ +- if (zvrf->table_id != table_id) +- continue; +- return zvrf_id(zvrf); +- } +- } +- +- return VRF_DEFAULT; +-} +- + static uint32_t table_lookup_by_vrf(vrf_id_t vrf_id, ns_id_t ns_id) + { + struct vrf *vrf; +@@ -814,7 +787,7 @@ int netlink_route_change_read_unicast_internal(struct nlmsghdr *h, + 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]) +@@ -1114,7 +1087,7 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h, + else + table = rtm->rtm_table; + +- vrf = vrf_lookup_by_table(table, ns_id); ++ vrf = zebra_vrf_lookup_by_table(table, ns_id); + + if (tb[RTA_IIF]) + iif = *(int *)RTA_DATA(tb[RTA_IIF]); +diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h +index 8506367ae4..364aac0f6b 100644 +--- a/zebra/rt_netlink.h ++++ b/zebra/rt_netlink.h +@@ -102,7 +102,6 @@ extern int netlink_macfdb_read_specific_mac(struct zebra_ns *zns, + uint16_t vid); + extern int netlink_neigh_read_specific_ip(const struct ipaddr *ip, + struct interface *vlan_if); +-extern vrf_id_t vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id); + + struct nl_batch; + extern enum netlink_msg_status +diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c +index be5e91495f..c59cb7c0a7 100644 +--- a/zebra/zebra_vrf.c ++++ b/zebra/zebra_vrf.c +@@ -389,6 +389,33 @@ struct zebra_vrf *zebra_vrf_alloc(struct vrf *vrf) + return zvrf; + } + ++/* ++Pending: create an efficient table_id (in a tree/hash) based lookup) ++ */ ++vrf_id_t zebra_vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) ++{ ++ struct vrf *vrf; ++ struct zebra_vrf *zvrf; ++ ++ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { ++ zvrf = vrf->info; ++ if (zvrf == NULL) ++ continue; ++ /* case vrf with netns : match the netnsid */ ++ if (vrf_is_backend_netns()) { ++ if (ns_id == zvrf_id(zvrf)) ++ return zvrf_id(zvrf); ++ } else { ++ /* VRF is VRF_BACKEND_VRF_LITE */ ++ if (zvrf->table_id != table_id) ++ continue; ++ return zvrf_id(zvrf); ++ } ++ } ++ ++ return VRF_DEFAULT; ++} ++ + /* Lookup VRF by identifier. */ + struct zebra_vrf *zebra_vrf_lookup_by_id(vrf_id_t vrf_id) + { +diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h +index 02e3c197c9..937e7fb144 100644 +--- a/zebra/zebra_vrf.h ++++ b/zebra/zebra_vrf.h +@@ -252,6 +252,7 @@ extern struct route_table *zebra_vrf_get_table_with_table_id(afi_t afi, + extern void zebra_vrf_update_all(struct zserv *client); + extern struct zebra_vrf *zebra_vrf_lookup_by_id(vrf_id_t vrf_id); + extern struct zebra_vrf *zebra_vrf_lookup_by_name(const char *); ++extern vrf_id_t zebra_vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id); + extern struct zebra_vrf *zebra_vrf_alloc(struct vrf *vrf); + extern struct route_table *zebra_vrf_table(afi_t, safi_t, vrf_id_t); + +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0013-zebra-Move-protodown_r_bit-to-a-better-spot.patch b/src/sonic-frr/patch/0013-zebra-Move-protodown_r_bit-to-a-better-spot.patch new file mode 100644 index 000000000000..cd88419fcbd6 --- /dev/null +++ b/src/sonic-frr/patch/0013-zebra-Move-protodown_r_bit-to-a-better-spot.patch @@ -0,0 +1,181 @@ +From c43808ca6daa59d533e14790ffc7f2e11b508924 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Thu, 27 Apr 2023 07:37:58 -0400 +Subject: [PATCH] zebra: Move protodown_r_bit to a better spot + +Since we are moving some code handling out of the dataplane +and into zebra proper, lets move the protodown r bit as well. + +Signed-off-by: Donald Sharp + +diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c +index 4599121261..95889e22fd 100644 +--- a/zebra/if_netlink.c ++++ b/zebra/if_netlink.c +@@ -78,7 +78,6 @@ + #include "zebra/zebra_trace.h" + + extern struct zebra_privs_t zserv_privs; +-uint8_t frr_protodown_r_bit = FRR_PROTODOWN_REASON_DEFAULT_BIT; + + /* Note: on netlink systems, there should be a 1-to-1 mapping between interface + names and ifindex values. */ +@@ -819,9 +818,7 @@ static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id, + + static bool is_if_protodown_reason_only_frr(uint32_t rc_bitfield) + { +- /* This shouldn't be possible */ +- assert(frr_protodown_r_bit < 32); +- return (rc_bitfield == (((uint32_t)1) << frr_protodown_r_bit)); ++ return (rc_bitfield == (((uint32_t)1) << if_netlink_get_frr_protodown_r_bit())); + } + + /* +@@ -2247,9 +2244,10 @@ ssize_t netlink_intf_msg_encode(uint16_t cmd, + return -1; + + nl_attr_put32(&req->n, buflen, IFLA_PROTO_DOWN_REASON_MASK, +- (1 << frr_protodown_r_bit)); ++ (1 << if_netlink_get_frr_protodown_r_bit())); + nl_attr_put32(&req->n, buflen, IFLA_PROTO_DOWN_REASON_VALUE, +- ((int)pd_reason_val) << frr_protodown_r_bit); ++ ((int)pd_reason_val) ++ << if_netlink_get_frr_protodown_r_bit()); + + nl_attr_nest_end(&req->n, nest_protodown_reason); + +@@ -2274,37 +2272,6 @@ void interface_list(struct zebra_ns *zns) + interface_addr_lookup_netlink(zns); + } + +-void if_netlink_set_frr_protodown_r_bit(uint8_t bit) +-{ +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "Protodown reason bit index changed: bit-index %u -> bit-index %u", +- frr_protodown_r_bit, bit); +- +- frr_protodown_r_bit = bit; +-} +- +-void if_netlink_unset_frr_protodown_r_bit(void) +-{ +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "Protodown reason bit index changed: bit-index %u -> bit-index %u", +- frr_protodown_r_bit, FRR_PROTODOWN_REASON_DEFAULT_BIT); +- +- frr_protodown_r_bit = FRR_PROTODOWN_REASON_DEFAULT_BIT; +-} +- +- +-bool if_netlink_frr_protodown_r_bit_is_set(void) +-{ +- return (frr_protodown_r_bit != FRR_PROTODOWN_REASON_DEFAULT_BIT); +-} +- +-uint8_t if_netlink_get_frr_protodown_r_bit(void) +-{ +- return frr_protodown_r_bit; +-} +- + /** + * netlink_request_tunneldump() - Request all tunnels from the linux kernel + * +diff --git a/zebra/if_netlink.h b/zebra/if_netlink.h +index 21ae1713be..f5a170a609 100644 +--- a/zebra/if_netlink.h ++++ b/zebra/if_netlink.h +@@ -54,17 +54,6 @@ extern int netlink_tunneldump_read(struct zebra_ns *zns); + extern enum netlink_msg_status + netlink_put_intf_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx); + +-#define FRR_PROTODOWN_REASON_DEFAULT_BIT 7 +-/* Protodown bit setter/getter +- * +- * Allow users to change the bit if it conflicts with another +- * on their system. +- */ +-extern void if_netlink_set_frr_protodown_r_bit(uint8_t bit); +-extern void if_netlink_unset_frr_protodown_r_bit(void); +-extern bool if_netlink_frr_protodown_r_bit_is_set(void); +-extern uint8_t if_netlink_get_frr_protodown_r_bit(void); +- + #ifdef __cplusplus + } + #endif +diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c +index a9a7b66ce7..12689804ea 100644 +--- a/zebra/zebra_router.c ++++ b/zebra/zebra_router.c +@@ -280,6 +280,8 @@ void zebra_router_init(bool asic_offload, bool notify_on_ack) + { + zrouter.sequence_num = 0; + ++ zrouter.protodown_r_bit = FRR_PROTODOWN_REASON_DEFAULT_BIT; ++ + zrouter.allow_delete = false; + + zrouter.packets_to_process = ZEBRA_ZAPI_PACKETS_TO_PROCESS; +diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h +index e0ef86f082..61bde4ac2a 100644 +--- a/zebra/zebra_router.h ++++ b/zebra/zebra_router.h +@@ -244,6 +244,8 @@ struct zebra_router { + + /* Should we allow non FRR processes to delete our routes */ + bool allow_delete; ++ ++ uint8_t protodown_r_bit; + }; + + #define GRACEFUL_RESTART_TIME 60 +@@ -302,6 +304,32 @@ static inline bool zebra_router_in_shutdown(void) + return atomic_load_explicit(&zrouter.in_shutdown, memory_order_relaxed); + } + ++#define FRR_PROTODOWN_REASON_DEFAULT_BIT 7 ++/* Protodown bit setter/getter ++ * ++ * Allow users to change the bit if it conflicts with another ++ * on their system. ++ */ ++static inline void if_netlink_set_frr_protodown_r_bit(uint8_t bit) ++{ ++ zrouter.protodown_r_bit = bit; ++} ++ ++static inline void if_netlink_unset_frr_protodown_r_bit(void) ++{ ++ zrouter.protodown_r_bit = FRR_PROTODOWN_REASON_DEFAULT_BIT; ++} ++ ++static inline bool if_netlink_frr_protodown_r_bit_is_set(void) ++{ ++ return (zrouter.protodown_r_bit != FRR_PROTODOWN_REASON_DEFAULT_BIT); ++} ++ ++static inline uint8_t if_netlink_get_frr_protodown_r_bit(void) ++{ ++ return zrouter.protodown_r_bit; ++} ++ + /* zebra_northbound.c */ + extern const struct frr_yang_module_info frr_zebra_info; + +diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c +index c59cb7c0a7..9c5b38b96b 100644 +--- a/zebra/zebra_vrf.c ++++ b/zebra/zebra_vrf.c +@@ -390,7 +390,7 @@ struct zebra_vrf *zebra_vrf_alloc(struct vrf *vrf) + } + + /* +-Pending: create an efficient table_id (in a tree/hash) based lookup) ++ * Pending: create an efficient table_id (in a tree/hash) based lookup) + */ + vrf_id_t zebra_vrf_lookup_by_table(uint32_t table_id, ns_id_t ns_id) + { +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0013-zebra-fix-dplane-fpm-nl-to-allow-for-fast-configuration.patch b/src/sonic-frr/patch/0013-zebra-fix-dplane-fpm-nl-to-allow-for-fast-configuration.patch deleted file mode 100644 index 9a412d24ee86..000000000000 --- a/src/sonic-frr/patch/0013-zebra-fix-dplane-fpm-nl-to-allow-for-fast-configuration.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 551fa8c3549e24020dfce33d06ade4a14f72abfe Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Mon, 14 Nov 2022 08:28:45 -0500 -Subject: [PATCH] zebra: Fix dplane_fpm_nl to allow for fast configuration - -If you have this order in your configuration file: - -no fpm use-next-hop-groups -fpm address 127.0.0.1 - -the dplane code was using the same event thread t_event and the second -add event in the code was going, you already have an event scheduled -and as such the second event does not overwrite it. Leaving -no code to actually start the whole processing. There are probably -other cli iterations that will cause this fun as well, but I'm -not going to spend the time sussing them out at the moment. - -Fixes: #12314 -Signed-off-by: Donald Sharp ---- - zebra/dplane_fpm_nl.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c -index 7383c982baa..c5e1c113cb0 100644 ---- a/zebra/dplane_fpm_nl.c -+++ b/zebra/dplane_fpm_nl.c -@@ -98,6 +98,7 @@ struct fpm_nl_ctx { - struct thread *t_read; - struct thread *t_write; - struct thread *t_event; -+ struct thread *t_nhg; - struct thread *t_dequeue; - - /* zebra events. */ -@@ -271,7 +272,7 @@ DEFUN(fpm_use_nhg, fpm_use_nhg_cmd, - return CMD_SUCCESS; - - thread_add_event(gfnc->fthread->master, fpm_process_event, gfnc, -- FNE_TOGGLE_NHG, &gfnc->t_event); -+ FNE_TOGGLE_NHG, &gfnc->t_nhg); - - return CMD_SUCCESS; - } -@@ -287,7 +288,7 @@ DEFUN(no_fpm_use_nhg, no_fpm_use_nhg_cmd, - return CMD_SUCCESS; - - thread_add_event(gfnc->fthread->master, fpm_process_event, gfnc, -- FNE_TOGGLE_NHG, &gfnc->t_event); -+ FNE_TOGGLE_NHG, &gfnc->t_nhg); - - return CMD_SUCCESS; - } -@@ -1367,6 +1368,8 @@ static int fpm_nl_finish_early(struct fpm_nl_ctx *fnc) - THREAD_OFF(fnc->t_ribwalk); - THREAD_OFF(fnc->t_rmacreset); - THREAD_OFF(fnc->t_rmacwalk); -+ THREAD_OFF(fnc->t_event); -+ THREAD_OFF(fnc->t_nhg); - thread_cancel_async(fnc->fthread->master, &fnc->t_read, NULL); - thread_cancel_async(fnc->fthread->master, &fnc->t_write, NULL); - thread_cancel_async(fnc->fthread->master, &fnc->t_connect, NULL); diff --git a/src/sonic-frr/patch/0014-bgpd-Allow-network-XXX-to-work-with-bgp-suppress-fib.patch b/src/sonic-frr/patch/0014-bgpd-Allow-network-XXX-to-work-with-bgp-suppress-fib.patch deleted file mode 100644 index 60f1aa4cd357..000000000000 --- a/src/sonic-frr/patch/0014-bgpd-Allow-network-XXX-to-work-with-bgp-suppress-fib.patch +++ /dev/null @@ -1,190 +0,0 @@ -From 2ce65073a1c2c1a225488287eb886a76149db0a4 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Wed, 12 Oct 2022 14:53:21 -0400 -Subject: [PATCH 04/11] bgpd: Allow `network XXX` to work with bgp - suppress-fib-pending - -When bgp is using `bgp suppress-fib-pending` and the end -operator is using network statements, bgp was not sending -the network'ed prefix'es to it's peers. Fix this. - -Also update the test cases for bgp_suppress_fib to test -this new corner case( I am sure that there are going to -be others that will need to be added ). - -Fixes: #12112 -Signed-off-by: Donald Sharp -(cherry picked from commit 4801fc4670020406fc609dedabc7482d88e3b656) ---- - bgpd/bgp_route.h | 20 ++++++++++++++-- - .../bgp_suppress_fib/r1/bgp_ipv4_allowas.json | 2 +- - .../bgp_suppress_fib/r2/bgp_ipv4_allowas.json | 2 +- - tests/topotests/bgp_suppress_fib/r2/bgpd.conf | 2 ++ - .../topotests/bgp_suppress_fib/r2/zebra.conf | 3 +++ - .../bgp_suppress_fib/r3/v4_route3.json | 23 +++++++++++++++++++ - .../bgp_suppress_fib/test_bgp_suppress_fib.py | 14 ++++++++--- - 7 files changed, 59 insertions(+), 7 deletions(-) - create mode 100644 tests/topotests/bgp_suppress_fib/r3/v4_route3.json - -diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h -index a8ec2dc90..003a6cb79 100644 ---- a/bgpd/bgp_route.h -+++ b/bgpd/bgp_route.h -@@ -595,19 +595,35 @@ static inline bool bgp_check_advertise(struct bgp *bgp, struct bgp_dest *dest) - */ - static inline bool bgp_check_withdrawal(struct bgp *bgp, struct bgp_dest *dest) - { -- struct bgp_path_info *pi; -+ struct bgp_path_info *pi, *selected = NULL; - - if (!BGP_SUPPRESS_FIB_ENABLED(bgp)) - return false; - - for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) { -- if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) -+ if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) { -+ selected = pi; - continue; -+ } - - if (pi->sub_type != BGP_ROUTE_NORMAL) - return true; - } - -+ /* -+ * pi is selected and bgp is dealing with a static route -+ * ( ie a network statement of some sort ). FIB installed -+ * is irrelevant -+ * -+ * I am not sure what the above for loop is wanted in this -+ * manner at this point. But I do know that if I have -+ * a static route that is selected and it's the one -+ * being checked for should I withdrawal we do not -+ * want to withdraw the route on installation :) -+ */ -+ if (selected && selected->sub_type == BGP_ROUTE_STATIC) -+ return false; -+ - if (CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)) - return false; - -diff --git a/tests/topotests/bgp_suppress_fib/r1/bgp_ipv4_allowas.json b/tests/topotests/bgp_suppress_fib/r1/bgp_ipv4_allowas.json -index bc4d0f479..1a5ede276 100644 ---- a/tests/topotests/bgp_suppress_fib/r1/bgp_ipv4_allowas.json -+++ b/tests/topotests/bgp_suppress_fib/r1/bgp_ipv4_allowas.json -@@ -32,7 +32,7 @@ - ], - "peer":{ - "peerId":"10.0.0.2", -- "routerId":"10.0.0.9", -+ "routerId":"60.0.0.1", - "type":"external" - } - } -diff --git a/tests/topotests/bgp_suppress_fib/r2/bgp_ipv4_allowas.json b/tests/topotests/bgp_suppress_fib/r2/bgp_ipv4_allowas.json -index 16561ce83..4a35abfd6 100644 ---- a/tests/topotests/bgp_suppress_fib/r2/bgp_ipv4_allowas.json -+++ b/tests/topotests/bgp_suppress_fib/r2/bgp_ipv4_allowas.json -@@ -61,7 +61,7 @@ - ], - "peer":{ - "peerId":"0.0.0.0", -- "routerId":"10.0.0.9" -+ "routerId":"60.0.0.1" - } - } - ] -diff --git a/tests/topotests/bgp_suppress_fib/r2/bgpd.conf b/tests/topotests/bgp_suppress_fib/r2/bgpd.conf -index ebef2012a..010e86aad 100644 ---- a/tests/topotests/bgp_suppress_fib/r2/bgpd.conf -+++ b/tests/topotests/bgp_suppress_fib/r2/bgpd.conf -@@ -7,3 +7,5 @@ router bgp 2 - bgp suppress-fib-pending - neighbor 10.0.0.1 remote-as 1 - neighbor 10.0.0.10 remote-as 3 -+ address-family ipv4 uni -+ network 60.0.0.0/24 -\ No newline at end of file -diff --git a/tests/topotests/bgp_suppress_fib/r2/zebra.conf b/tests/topotests/bgp_suppress_fib/r2/zebra.conf -index 443fffc70..6e8bce045 100644 ---- a/tests/topotests/bgp_suppress_fib/r2/zebra.conf -+++ b/tests/topotests/bgp_suppress_fib/r2/zebra.conf -@@ -1,4 +1,7 @@ - ! -+interface lo -+ ip address 60.0.0.1/24 -+! - interface r2-eth0 - ip address 10.0.0.2/30 - ! -diff --git a/tests/topotests/bgp_suppress_fib/r3/v4_route3.json b/tests/topotests/bgp_suppress_fib/r3/v4_route3.json -new file mode 100644 -index 000000000..ab8c3aa5e ---- /dev/null -+++ b/tests/topotests/bgp_suppress_fib/r3/v4_route3.json -@@ -0,0 +1,23 @@ -+{ -+ "60.0.0.0/24":[ -+ { -+ "prefix":"60.0.0.0/24", -+ "protocol":"bgp", -+ "selected":true, -+ "destSelected":true, -+ "distance":20, -+ "metric":0, -+ "installed":true, -+ "table":254, -+ "nexthops":[ -+ { -+ "fib":true, -+ "ip":"10.0.0.9", -+ "afi":"ipv4", -+ "interfaceName":"r3-eth0", -+ "active":true -+ } -+ ] -+ } -+ ] -+} -diff --git a/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py b/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py -index 2c87d9d7b..96a294cae 100644 ---- a/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py -+++ b/tests/topotests/bgp_suppress_fib/test_bgp_suppress_fib.py -@@ -84,8 +84,6 @@ def test_bgp_route(): - - r3 = tgen.gears["r3"] - -- sleep(5) -- - json_file = "{}/r3/v4_route.json".format(CWD) - expected = json.loads(open(json_file).read()) - -@@ -95,7 +93,7 @@ def test_bgp_route(): - "show ip route 40.0.0.0 json", - expected, - ) -- _, result = topotest.run_and_expect(test_func, None, count=2, wait=0.5) -+ _, result = topotest.run_and_expect(test_func, None, count=20, wait=0.5) - assertmsg = '"r3" JSON output mismatches' - assert result is None, assertmsg - -@@ -112,6 +110,16 @@ def test_bgp_route(): - assertmsg = '"r3" JSON output mismatches' - assert result is None, assertmsg - -+ json_file = "{}/r3/v4_route3.json".format(CWD) -+ expected = json.loads(open(json_file).read()) -+ -+ test_func = partial( -+ topotest.router_json_cmp, -+ r3, -+ "show ip route 10.0.0.3 json", -+ expected, -+ ) -+ _, result = topotest.run_and_expect(test_func, None, count=3, wait=0.5) - - def test_bgp_better_admin_won(): - "A better Admin distance protocol may come along and knock us out" --- -2.30.2 - diff --git a/src/sonic-frr/patch/0014-zebra-Remove-unused-dplane_intf_delete.patch b/src/sonic-frr/patch/0014-zebra-Remove-unused-dplane_intf_delete.patch new file mode 100644 index 000000000000..756e0cf97419 --- /dev/null +++ b/src/sonic-frr/patch/0014-zebra-Remove-unused-dplane_intf_delete.patch @@ -0,0 +1,48 @@ +From 88f7441f56bf61008a52adda97525ffb20f9543d Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Fri, 14 Apr 2023 07:43:19 -0400 +Subject: [PATCH] zebra: Remove unused dplane_intf_delete + +There is no need for this functionality and it is +not used. + +Signed-off-by: Donald Sharp + +diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c +index 4927af5625..a6c08f7371 100644 +--- a/zebra/zebra_dplane.c ++++ b/zebra/zebra_dplane.c +@@ -4648,18 +4648,6 @@ enum zebra_dplane_result dplane_intf_update(const struct interface *ifp) + return ret; + } + +-/* +- * Enqueue a interface delete for the dataplane. +- */ +-enum zebra_dplane_result dplane_intf_delete(const struct interface *ifp) +-{ +- enum zebra_dplane_result ret = ZEBRA_DPLANE_REQUEST_FAILURE; +- +- if (ifp) +- ret = dplane_intf_update_internal(ifp, DPLANE_OP_INTF_DELETE); +- return ret; +-} +- + /* + * Enqueue vxlan/evpn mac add (or update). + */ +diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h +index ae13243a16..9ef0afd3a8 100644 +--- a/zebra/zebra_dplane.h ++++ b/zebra/zebra_dplane.h +@@ -758,7 +758,6 @@ enum zebra_dplane_result dplane_intf_addr_unset(const struct interface *ifp, + */ + enum zebra_dplane_result dplane_intf_add(const struct interface *ifp); + enum zebra_dplane_result dplane_intf_update(const struct interface *ifp); +-enum zebra_dplane_result dplane_intf_delete(const struct interface *ifp); + + /* + * Enqueue tc link changes for the dataplane. +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0015-zebra-Remove-unused-add-variable.patch b/src/sonic-frr/patch/0015-zebra-Remove-unused-add-variable.patch new file mode 100644 index 000000000000..dc263d3d94c0 --- /dev/null +++ b/src/sonic-frr/patch/0015-zebra-Remove-unused-add-variable.patch @@ -0,0 +1,53 @@ +From 4cc6c7af6f7c72ddf18ab562f4e2c2b25e32f1b5 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Sat, 15 Apr 2023 08:04:51 -0400 +Subject: [PATCH] zebra: Remove unused add variable + +Function was not using the add variable. Remove it. + +Signed-off-by: Donald Sharp + +diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c +index 95889e22fd..e54fb09022 100644 +--- a/zebra/if_netlink.c ++++ b/zebra/if_netlink.c +@@ -670,7 +670,7 @@ static void netlink_interface_update_l2info(struct interface *ifp, + struct zebra_l2info_bridge bridge_info; + + netlink_extract_bridge_info(link_data, &bridge_info); +- zebra_l2_bridge_add_update(ifp, &bridge_info, add); ++ zebra_l2_bridge_add_update(ifp, &bridge_info); + } else if (IS_ZEBRA_IF_VLAN(ifp)) { + struct zebra_l2info_vlan vlan_info; + +diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c +index 8a9f3dffe3..07bbc6e3bc 100644 +--- a/zebra/zebra_l2.c ++++ b/zebra/zebra_l2.c +@@ -258,8 +258,7 @@ void zebra_l2if_update_bond(struct interface *ifp, bool add) + * map slaves (if any) to the bridge. + */ + void zebra_l2_bridge_add_update(struct interface *ifp, +- struct zebra_l2info_bridge *bridge_info, +- int add) ++ struct zebra_l2info_bridge *bridge_info) + { + struct zebra_if *zif; + +diff --git a/zebra/zebra_l2.h b/zebra/zebra_l2.h +index 1c3e98158d..8fef008f52 100644 +--- a/zebra/zebra_l2.h ++++ b/zebra/zebra_l2.h +@@ -109,8 +109,7 @@ extern void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave, + extern void + zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave); + extern void zebra_l2_bridge_add_update(struct interface *ifp, +- struct zebra_l2info_bridge *bridge_info, +- int add); ++ struct zebra_l2info_bridge *bridge_info); + extern void zebra_l2_bridge_del(struct interface *ifp); + extern void zebra_l2_vlanif_update(struct interface *ifp, + struct zebra_l2info_vlan *vlan_info); +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0015-zebra-Return-statements-do-not-use-paranthesis.patch b/src/sonic-frr/patch/0015-zebra-Return-statements-do-not-use-paranthesis.patch deleted file mode 100755 index 592af9308c07..000000000000 --- a/src/sonic-frr/patch/0015-zebra-Return-statements-do-not-use-paranthesis.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 07a41dcd82ff41b406d0011554d70ce79da68df5 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Wed, 5 Oct 2022 10:26:07 -0400 -Subject: [PATCH 1/8] zebra: Return statements do not use paranthesis - -Signed-off-by: Donald Sharp ---- - zebra/zebra_rib.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index cf1baf077..472e48925 100644 ---- a/zebra/zebra_rib.c -+++ b/zebra/zebra_rib.c -@@ -1403,8 +1403,7 @@ static bool rib_route_match_ctx(const struct route_entry *re, - } - - done: -- -- return (result); -+ return result; - } - - static void zebra_rib_fixup_system(struct route_node *rn) --- -2.30.2 - diff --git a/src/sonic-frr/patch/0016-zebra-Add-zrouter.asic_notification_nexthop_control.patch b/src/sonic-frr/patch/0016-zebra-Add-zrouter.asic_notification_nexthop_control.patch deleted file mode 100755 index 78e17849cad0..000000000000 --- a/src/sonic-frr/patch/0016-zebra-Add-zrouter.asic_notification_nexthop_control.patch +++ /dev/null @@ -1,205 +0,0 @@ -From 01e267d98c63ee4464f96fead11dda9ee0ad911b Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Wed, 5 Oct 2022 10:04:11 -0400 -Subject: [PATCH 2/8] zebra: Add `zrouter.asic_notification_nexthop_control` - -Volta submitted notification changes for the dplane that had a -special use case for their system. Volta is no more, the code -is not being actively developed and from talking with ex-Volta -employees there is no current plans to even maintain this code. -Wrap the special handling of nexthops that their asic-dataplane -did in a bit of code to isolate it and allow for future removal, -as that I do not actually believe anyone else is using this code. -Add a CPP_NOTICE several years into the future that will tell us -to remove the code. If someone starts using it then they will -have to notice this variable to set it and hopefully they will -see my CPP_NOTICE to come talk to us. If this is being used then -we can just remove this wrapper. - -Signed-off-by: Donald Sharp ---- - zebra/zebra_rib.c | 95 +++++++++++++++++++++++++------------------- - zebra/zebra_router.c | 11 +++++ - zebra/zebra_router.h | 8 ++++ - zebra/zebra_vty.c | 9 +++++ - 4 files changed, 83 insertions(+), 40 deletions(-) - -diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index 472e48925..abd6e07f9 100644 ---- a/zebra/zebra_rib.c -+++ b/zebra/zebra_rib.c -@@ -2215,55 +2215,70 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) - /* Various fib transitions: changed nexthops; from installed to - * not-installed; or not-installed to installed. - */ -- if (start_count > 0 && end_count > 0) { -- if (debug_p) -- zlog_debug( -- "%s(%u:%u):%pRN applied nexthop changes from dplane notification", -- VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), -- dplane_ctx_get_table(ctx), rn); -+ if (zrouter.asic_notification_nexthop_control) { -+ if (start_count > 0 && end_count > 0) { -+ if (debug_p) -+ zlog_debug( -+ "%s(%u:%u):%pRN applied nexthop changes from dplane notification", -+ VRF_LOGNAME(vrf), -+ dplane_ctx_get_vrf(ctx), -+ dplane_ctx_get_table(ctx), rn); - -- /* Changed nexthops - update kernel/others */ -- dplane_route_notif_update(rn, re, -- DPLANE_OP_ROUTE_UPDATE, ctx); -+ /* Changed nexthops - update kernel/others */ -+ dplane_route_notif_update(rn, re, -+ DPLANE_OP_ROUTE_UPDATE, ctx); - -- } else if (start_count == 0 && end_count > 0) { -- if (debug_p) -- zlog_debug( -- "%s(%u:%u):%pRN installed transition from dplane notification", -- VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), -- dplane_ctx_get_table(ctx), rn); -+ } else if (start_count == 0 && end_count > 0) { -+ if (debug_p) -+ zlog_debug( -+ "%s(%u:%u):%pRN installed transition from dplane notification", -+ VRF_LOGNAME(vrf), -+ dplane_ctx_get_vrf(ctx), -+ dplane_ctx_get_table(ctx), rn); - -- /* We expect this to be the selected route, so we want -- * to tell others about this transition. -- */ -- SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); -+ /* We expect this to be the selected route, so we want -+ * to tell others about this transition. -+ */ -+ SET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); - -- /* Changed nexthops - update kernel/others */ -- dplane_route_notif_update(rn, re, DPLANE_OP_ROUTE_UPDATE, ctx); -+ /* Changed nexthops - update kernel/others */ -+ dplane_route_notif_update(rn, re, -+ DPLANE_OP_ROUTE_UPDATE, ctx); - -- /* Redistribute, lsp, and nht update */ -- redistribute_update(rn, re, NULL); -+ /* Redistribute, lsp, and nht update */ -+ redistribute_update(rn, re, NULL); - -- } else if (start_count > 0 && end_count == 0) { -- if (debug_p) -- zlog_debug( -- "%s(%u:%u):%pRN un-installed transition from dplane notification", -- VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx), -- dplane_ctx_get_table(ctx), rn); -+ } else if (start_count > 0 && end_count == 0) { -+ if (debug_p) -+ zlog_debug( -+ "%s(%u:%u):%pRN un-installed transition from dplane notification", -+ VRF_LOGNAME(vrf), -+ dplane_ctx_get_vrf(ctx), -+ dplane_ctx_get_table(ctx), rn); - -- /* Transition from _something_ installed to _nothing_ -- * installed. -- */ -- /* We expect this to be the selected route, so we want -- * to tell others about this transistion. -- */ -- UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); -+ /* Transition from _something_ installed to _nothing_ -+ * installed. -+ */ -+ /* We expect this to be the selected route, so we want -+ * to tell others about this transistion. -+ */ -+ UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED); - -- /* Changed nexthops - update kernel/others */ -- dplane_route_notif_update(rn, re, DPLANE_OP_ROUTE_DELETE, ctx); -+ /* Changed nexthops - update kernel/others */ -+ dplane_route_notif_update(rn, re, -+ DPLANE_OP_ROUTE_DELETE, ctx); - -- /* Redistribute, lsp, and nht update */ -- redistribute_delete(rn, re, NULL); -+ /* Redistribute, lsp, and nht update */ -+ redistribute_delete(rn, re, NULL); -+ } -+ } -+ -+ if (!zebra_router_notify_on_ack()) { -+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED)) -+ zsend_route_notify_owner_ctx(ctx, ZAPI_ROUTE_INSTALLED); -+ if (CHECK_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED)) -+ zsend_route_notify_owner_ctx(ctx, -+ ZAPI_ROUTE_FAIL_INSTALL); - } - - /* Make any changes visible for lsp and nexthop-tracking processing */ -diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c -index 92a3b9424..d47517bbb 100644 ---- a/zebra/zebra_router.c -+++ b/zebra/zebra_router.c -@@ -304,6 +304,17 @@ void zebra_router_init(bool asic_offload, bool notify_on_ack) - zrouter.asic_offloaded = asic_offload; - zrouter.notify_on_ack = notify_on_ack; - -+ /* -+ * If you start using asic_notification_nexthop_control -+ * come talk to the FRR community about what you are doing -+ * We would like to know. -+ */ -+#if CONFDATE > 20251231 -+ CPP_NOTICE( -+ "Remove zrouter.asic_notification_nexthop_control as that it's not being maintained or used"); -+#endif -+ zrouter.asic_notification_nexthop_control = false; -+ - #ifdef HAVE_SCRIPTING - zebra_script_init(); - #endif -diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h -index c0eab9cd6..583bd0038 100644 ---- a/zebra/zebra_router.h -+++ b/zebra/zebra_router.h -@@ -209,6 +209,14 @@ struct zebra_router { - */ - bool asic_offloaded; - bool notify_on_ack; -+ -+ /* -+ * If the asic is notifying us about successful nexthop -+ * allocation/control. Some developers have made their -+ * asic take control of how many nexthops/ecmp they can -+ * have and will report what is successfull or not -+ */ -+ bool asic_notification_nexthop_control; - }; - - #define GRACEFUL_RESTART_TIME 60 -diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c -index 0a3d676a9..a7eb09df0 100644 ---- a/zebra/zebra_vty.c -+++ b/zebra/zebra_vty.c -@@ -3972,6 +3972,15 @@ DEFUN (show_zebra, - if (zrouter.asic_offloaded) - vty_out(vty, "Asic Offload is being used\n"); - -+ /* -+ * Do not display this unless someone is actually using it -+ * -+ * Why this distinction? I think this is effectively dead code -+ * and should not be exposed. Maybe someone proves me wrong. -+ */ -+ if (zrouter.asic_notification_nexthop_control) -+ vty_out(vty, "ASIC offload and nexthop control is being used"); -+ - vty_out(vty, - " Route Route Neighbor LSP LSP\n"); - vty_out(vty, --- -2.30.2 - diff --git a/src/sonic-frr/patch/0016-zebra-Remove-duplicate-function-for-netlink-interfac.patch b/src/sonic-frr/patch/0016-zebra-Remove-duplicate-function-for-netlink-interfac.patch new file mode 100644 index 000000000000..8f13d20f0052 --- /dev/null +++ b/src/sonic-frr/patch/0016-zebra-Remove-duplicate-function-for-netlink-interfac.patch @@ -0,0 +1,301 @@ +From e12ffa6871d33712b03fc2ca28de278913e95bce Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Thu, 13 Apr 2023 16:43:27 -0400 +Subject: [PATCH] zebra: Remove duplicate function for netlink interface + changes + +Turns out FRR has 2 functions one specifically for startup +and one for normal day to day operations. There were only +a couple of minor differences from what I could tell, and +where they were different the after startup functionality should +have been updated too. I cannot figure out why we have 2. + +Non-startup handling of bonds appears to be incorrect +so let's fix that. Additionally the speed was not +properly being set in non-startup situations. + +Signed-off-by: Donald Sharp + +diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c +index e54fb09022..ed5b3c4a66 100644 +--- a/zebra/if_netlink.c ++++ b/zebra/if_netlink.c +@@ -938,178 +938,6 @@ static void if_sweep_protodown(struct zebra_if *zif) + dplane_intf_update(zif->ifp); + } + +-/* +- * Called from interface_lookup_netlink(). This function is only used +- * during bootstrap. +- */ +-static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup) +-{ +- int len; +- struct ifinfomsg *ifi; +- struct rtattr *tb[IFLA_MAX + 1]; +- struct rtattr *linkinfo[IFLA_MAX + 1]; +- struct interface *ifp; +- char *name = NULL; +- char *kind = NULL; +- char *desc = NULL; +- char *slave_kind = NULL; +- struct zebra_ns *zns = NULL; +- vrf_id_t vrf_id = VRF_DEFAULT; +- enum zebra_iftype zif_type = ZEBRA_IF_OTHER; +- enum zebra_slave_iftype zif_slave_type = ZEBRA_IF_SLAVE_NONE; +- ifindex_t bridge_ifindex = IFINDEX_INTERNAL; +- ifindex_t link_ifindex = IFINDEX_INTERNAL; +- ifindex_t bond_ifindex = IFINDEX_INTERNAL; +- struct zebra_if *zif; +- ns_id_t link_nsid = ns_id; +- uint8_t bypass = 0; +- +- frrtrace(3, frr_zebra, netlink_interface, h, ns_id, startup); +- +- zns = zebra_ns_lookup(ns_id); +- ifi = NLMSG_DATA(h); +- +- if (h->nlmsg_type != RTM_NEWLINK) +- return 0; +- +- len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg)); +- if (len < 0) { +- zlog_err( +- "%s: Message received from netlink is of a broken size: %d %zu", +- __func__, h->nlmsg_len, +- (size_t)NLMSG_LENGTH(sizeof(struct ifinfomsg))); +- return -1; +- } +- +- /* We are interested in some AF_BRIDGE notifications. */ +- if (ifi->ifi_family == AF_BRIDGE) +- return netlink_bridge_interface(h, len, ns_id, startup); +- +- /* Looking up interface name. */ +- memset(linkinfo, 0, sizeof(linkinfo)); +- netlink_parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, +- NLA_F_NESTED); +- +- /* check for wireless messages to ignore */ +- if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0)) { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug("%s: ignoring IFLA_WIRELESS message", +- __func__); +- return 0; +- } +- +- if (tb[IFLA_IFNAME] == NULL) +- return -1; +- name = (char *)RTA_DATA(tb[IFLA_IFNAME]); +- +- if (tb[IFLA_IFALIAS]) +- desc = (char *)RTA_DATA(tb[IFLA_IFALIAS]); +- +- if (tb[IFLA_LINKINFO]) { +- netlink_parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, +- tb[IFLA_LINKINFO]); +- +- if (linkinfo[IFLA_INFO_KIND]) +- kind = RTA_DATA(linkinfo[IFLA_INFO_KIND]); +- +- if (linkinfo[IFLA_INFO_SLAVE_KIND]) +- slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]); +- +- if ((slave_kind != NULL) && strcmp(slave_kind, "bond") == 0) +- netlink_determine_zebra_iftype("bond_slave", &zif_type); +- else +- netlink_determine_zebra_iftype(kind, &zif_type); +- } +- +- /* If VRF, create the VRF structure itself. */ +- if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) { +- netlink_vrf_change(h, tb[IFLA_LINKINFO], ns_id, name); +- vrf_id = (vrf_id_t)ifi->ifi_index; +- } +- +- if (tb[IFLA_MASTER]) { +- if (slave_kind && (strcmp(slave_kind, "vrf") == 0) +- && !vrf_is_backend_netns()) { +- zif_slave_type = ZEBRA_IF_SLAVE_VRF; +- vrf_id = *(uint32_t *)RTA_DATA(tb[IFLA_MASTER]); +- } else if (slave_kind && (strcmp(slave_kind, "bridge") == 0)) { +- zif_slave_type = ZEBRA_IF_SLAVE_BRIDGE; +- bridge_ifindex = +- *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]); +- } else if (slave_kind && (strcmp(slave_kind, "bond") == 0)) { +- zif_slave_type = ZEBRA_IF_SLAVE_BOND; +- bond_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]); +- bypass = netlink_parse_lacp_bypass(linkinfo); +- } else +- zif_slave_type = ZEBRA_IF_SLAVE_OTHER; +- } +- if (vrf_is_backend_netns()) +- vrf_id = (vrf_id_t)ns_id; +- +- /* If linking to another interface, note it. */ +- if (tb[IFLA_LINK]) +- link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]); +- +- if (tb[IFLA_LINK_NETNSID]) { +- link_nsid = *(ns_id_t *)RTA_DATA(tb[IFLA_LINK_NETNSID]); +- link_nsid = ns_id_get_absolute(ns_id, link_nsid); +- } +- +- ifp = if_get_by_name(name, vrf_id, NULL); +- set_ifindex(ifp, ifi->ifi_index, zns); /* add it to ns struct */ +- +- ifp->flags = ifi->ifi_flags & 0x0000fffff; +- ifp->mtu6 = ifp->mtu = *(uint32_t *)RTA_DATA(tb[IFLA_MTU]); +- ifp->metric = 0; +- ifp->speed = get_iflink_speed(ifp, NULL); +- ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; +- +- /* Set zebra interface type */ +- zebra_if_set_ziftype(ifp, zif_type, zif_slave_type); +- if (IS_ZEBRA_IF_VRF(ifp)) +- SET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK); +- +- /* +- * Just set the @link/lower-device ifindex. During nldump interfaces are +- * not ordered in any fashion so we may end up getting upper devices +- * before lower devices. We will setup the real linkage once the dump +- * is complete. +- */ +- zif = (struct zebra_if *)ifp->info; +- zif->link_ifindex = link_ifindex; +- +- if (desc) { +- XFREE(MTYPE_ZIF_DESC, zif->desc); +- zif->desc = XSTRDUP(MTYPE_ZIF_DESC, desc); +- } +- +- /* Hardware type and address. */ +- ifp->ll_type = netlink_to_zebra_link_type(ifi->ifi_type); +- +- netlink_interface_update_hw_addr(tb, ifp); +- +- if_add_update(ifp); +- +- /* Extract and save L2 interface information, take additional actions. +- */ +- netlink_interface_update_l2info(ifp, linkinfo[IFLA_INFO_DATA], +- 1, link_nsid); +- if (IS_ZEBRA_IF_BOND(ifp)) +- zebra_l2if_update_bond(ifp, true); +- if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) +- zebra_l2if_update_bridge_slave(ifp, bridge_ifindex, ns_id, +- ZEBRA_BRIDGE_NO_ACTION); +- else if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) +- zebra_l2if_update_bond_slave(ifp, bond_ifindex, !!bypass); +- +- if (tb[IFLA_PROTO_DOWN]) { +- netlink_proc_dplane_if_protodown(zif, tb); +- if_sweep_protodown(zif); +- } +- +- return 0; +-} +- + /* Request for specific interface or address information from the kernel */ + static int netlink_request_intf_addr(struct nlsock *netlink_cmd, int family, + int type, uint32_t filter_mask) +@@ -1165,7 +993,7 @@ int interface_lookup_netlink(struct zebra_ns *zns) + ret = netlink_request_intf_addr(netlink_cmd, AF_PACKET, RTM_GETLINK, 0); + if (ret < 0) + return ret; +- ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0, ++ ret = netlink_parse_info(netlink_link_change, netlink_cmd, &dp_info, 0, + true); + if (ret < 0) + return ret; +@@ -1175,7 +1003,7 @@ int interface_lookup_netlink(struct zebra_ns *zns) + RTEXT_FILTER_BRVLAN); + if (ret < 0) + return ret; +- ret = netlink_parse_info(netlink_interface, netlink_cmd, &dp_info, 0, ++ ret = netlink_parse_info(netlink_link_change, netlink_cmd, &dp_info, 0, + true); + if (ret < 0) + return ret; +@@ -1816,6 +1644,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) + ifindex_t master_infindex = IFINDEX_INTERNAL; + uint8_t bypass = 0; + ++ frrtrace(3, frr_zebra, netlink_interface, h, ns_id, startup); ++ + zns = zebra_ns_lookup(ns_id); + ifi = NLMSG_DATA(h); + +@@ -1884,7 +1714,10 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) + if (linkinfo[IFLA_INFO_SLAVE_KIND]) + slave_kind = RTA_DATA(linkinfo[IFLA_INFO_SLAVE_KIND]); + +- netlink_determine_zebra_iftype(kind, &zif_type); ++ if ((slave_kind != NULL) && strcmp(slave_kind, "bond") == 0) ++ netlink_determine_zebra_iftype("bond_slave", &zif_type); ++ else ++ netlink_determine_zebra_iftype(kind, &zif_type); + } + + /* If linking to another interface, note it. */ +@@ -1961,6 +1794,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) + } + ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]); + ifp->metric = 0; ++ ifp->speed = get_iflink_speed(ifp, NULL); + ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; + + /* Set interface type */ +@@ -1972,6 +1806,16 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) + /* Update link. */ + zebra_if_update_link(ifp, link_ifindex, link_nsid); + ++ /* ++ * Just set the @link/lower-device ifindex. During ++ * nldump interfaces are not ordered in any fashion so ++ * we may end up getting upper devices before lower ++ * devices. We will setup the real linkage once the dump ++ * is complete. ++ */ ++ zif = (struct zebra_if *)ifp->info; ++ zif->link_ifindex = link_ifindex; ++ + ifp->ll_type = + netlink_to_zebra_link_type(ifi->ifi_type); + netlink_interface_update_hw_addr(tb, ifp); +@@ -1984,6 +1828,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) + netlink_interface_update_l2info( + ifp, linkinfo[IFLA_INFO_DATA], + 1, link_nsid); ++ if (IS_ZEBRA_IF_BOND(ifp)) ++ zebra_l2if_update_bond(ifp, true); + if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) + zebra_l2if_update_bridge_slave( + ifp, bridge_ifindex, ns_id, +@@ -1992,10 +1838,12 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) + zebra_l2if_update_bond_slave(ifp, bond_ifindex, + !!bypass); + +- if (tb[IFLA_PROTO_DOWN]) ++ if (tb[IFLA_PROTO_DOWN]) { + netlink_proc_dplane_if_protodown(ifp->info, tb); ++ if (startup) ++ if_sweep_protodown(zif); ++ } + if (IS_ZEBRA_IF_BRIDGE(ifp)) { +- zif = ifp->info; + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug( + "RTM_NEWLINK ADD for %s(%u), vlan-aware %d", +@@ -2329,7 +2177,7 @@ int netlink_tunneldump_read(struct zebra_ns *zns) + if (ret < 0) + return ret; + +- ret = netlink_parse_info(netlink_interface, netlink_cmd, ++ ret = netlink_parse_info(netlink_link_change, netlink_cmd, + &dp_info, 0, true); + + if (ret < 0) +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0017-zebra-Add-code-to-get-set-interface-to-pass-up-from-.patch b/src/sonic-frr/patch/0017-zebra-Add-code-to-get-set-interface-to-pass-up-from-.patch new file mode 100644 index 000000000000..c46c29737a0e --- /dev/null +++ b/src/sonic-frr/patch/0017-zebra-Add-code-to-get-set-interface-to-pass-up-from-.patch @@ -0,0 +1,809 @@ +From 1b576b080613cd545ecd742b6a16146ab781695f Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Thu, 20 Apr 2023 08:51:42 -0400 +Subject: [PATCH] zebra: Add code to get/set interface to pass up from dplane + +1) Add a bunch of get/set functions and associated data +structure in zebra_dplane to allow the setting and retrieval +of interface netlink data up into the master pthread. + +2) Add a bit of code to breakup startup into stages. This is +because FRR currently has a mix of dplane and non dplane interactions +and the code needs to be paused before continuing on. + +Signed-off-by: Donald Sharp + +diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c +index 804eb43a44..0d629fe0b9 100644 +--- a/zebra/dplane_fpm_nl.c ++++ b/zebra/dplane_fpm_nl.c +@@ -955,6 +955,7 @@ static int fpm_nl_enqueue(struct fpm_nl_ctx *fnc, struct zebra_dplane_ctx *ctx) + case DPLANE_OP_TC_FILTER_DELETE: + case DPLANE_OP_TC_FILTER_UPDATE: + case DPLANE_OP_NONE: ++ case DPLANE_OP_STARTUP_STAGE: + break; + + } +diff --git a/zebra/interface.c b/zebra/interface.c +index 84e52d4b43..a05b9690ef 100644 +--- a/zebra/interface.c ++++ b/zebra/interface.c +@@ -1590,6 +1590,7 @@ void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx) + case DPLANE_OP_TC_FILTER_ADD: + case DPLANE_OP_TC_FILTER_DELETE: + case DPLANE_OP_TC_FILTER_UPDATE: ++ case DPLANE_OP_STARTUP_STAGE: + break; /* should never hit here */ + } + } +diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c +index 42afe61469..4cd84cada2 100644 +--- a/zebra/kernel_netlink.c ++++ b/zebra/kernel_netlink.c +@@ -1632,6 +1632,7 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth, + case DPLANE_OP_IPSET_DELETE: + case DPLANE_OP_IPSET_ENTRY_ADD: + case DPLANE_OP_IPSET_ENTRY_DELETE: ++ case DPLANE_OP_STARTUP_STAGE: + return FRR_NETLINK_ERROR; + + case DPLANE_OP_GRE_SET: +diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c +index 684ccc3ed5..f3462b9f22 100644 +--- a/zebra/kernel_socket.c ++++ b/zebra/kernel_socket.c +@@ -1631,6 +1631,7 @@ void kernel_update_multi(struct dplane_ctx_list_head *ctx_list) + case DPLANE_OP_GRE_SET: + case DPLANE_OP_INTF_ADDR_ADD: + case DPLANE_OP_INTF_ADDR_DEL: ++ case DPLANE_OP_STARTUP_STAGE: + zlog_err("Unhandled dplane data for %s", + dplane_op2str(dplane_ctx_get_op(ctx))); + res = ZEBRA_DPLANE_REQUEST_FAILURE; +diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c +index a6c08f7371..0b33a5189c 100644 +--- a/zebra/zebra_dplane.c ++++ b/zebra/zebra_dplane.c +@@ -193,10 +193,43 @@ struct dplane_br_port_info { + */ + struct dplane_intf_info { + ++ enum zebra_iftype zif_type; ++ ifindex_t bond_ifindex; ++ ifindex_t link_ifindex; ++ int32_t mtu; ++ vrf_id_t vrf_id; ++ enum zebra_slave_iftype zif_slave_type; ++ ifindex_t master_ifindex; ++ ifindex_t bridge_ifindex; ++ ns_id_t link_nsid; ++ enum zebra_slave_iftype zslave_type; ++ uint8_t bypass; ++ enum zebra_link_type zltype; ++ bool startup; ++ uint8_t family; ++ struct zebra_vxlan_vni_array *vniarray; ++ struct zebra_dplane_bridge_vlan_info bvinfo; ++ struct zebra_dplane_bridge_vlan_info_array *bvarray; ++ ++ char desc[128]; ++ ++ int32_t hw_addr_len; ++ uint8_t hw_addr[INTERFACE_HWADDR_MAX]; ++ ++ uint32_t table_id; ++ ++ struct zebra_l2info_bridge binfo; ++ struct zebra_l2info_vlan vinfo; ++ struct zebra_l2info_vxlan vxinfo; ++ struct zebra_l2info_gre grinfo; ++ ++ uint32_t rc_bitfield; ++ + uint32_t metric; + uint32_t flags; + + bool protodown; ++ bool protodown_set; + bool pd_reason_val; + + #define DPLANE_INTF_CONNECTED (1 << 0) /* Connected peer, p2p */ +@@ -408,6 +441,7 @@ struct zebra_dplane_ctx { + struct dplane_neigh_table neightable; + struct dplane_gre_ctx gre; + struct dplane_netconf_info netconf; ++ enum zebra_dplane_startup_notifications spot; + } u; + + /* Namespace info, used especially for netlink kernel communication */ +@@ -820,8 +854,14 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) + case DPLANE_OP_NONE: + case DPLANE_OP_IPSET_ADD: + case DPLANE_OP_IPSET_DELETE: ++ break; + case DPLANE_OP_INTF_INSTALL: + case DPLANE_OP_INTF_UPDATE: ++ if (ctx->u.intf.vniarray) ++ XFREE(MTYPE_TMP, ctx->u.intf.vniarray); ++ if (ctx->u.intf.bvarray) ++ XFREE(MTYPE_TMP, ctx->u.intf.bvarray); ++ break; + case DPLANE_OP_INTF_DELETE: + case DPLANE_OP_TC_QDISC_INSTALL: + case DPLANE_OP_TC_QDISC_UNINSTALL: +@@ -845,6 +885,7 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx) + break; + case DPLANE_OP_GRE_SET: + case DPLANE_OP_INTF_NETCONFIG: ++ case DPLANE_OP_STARTUP_STAGE: + break; + } + } +@@ -1168,6 +1209,8 @@ const char *dplane_op2str(enum dplane_op_e op) + case DPLANE_OP_TC_FILTER_UPDATE: + ret = "TC__FILTER_UPDATE"; + break; ++ case DPLANE_OP_STARTUP_STAGE: ++ ret = "STARTUP_STAGE"; + } + + return ret; +@@ -1309,6 +1352,422 @@ const char *dplane_ctx_get_ifname(const struct zebra_dplane_ctx *ctx) + return ctx->zd_ifname; + } + ++void dplane_ctx_set_ifp_bridge_vlan_info_array( ++ struct zebra_dplane_ctx *ctx, ++ struct zebra_dplane_bridge_vlan_info_array *bvarray) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.bvarray = bvarray; ++} ++ ++const struct zebra_dplane_bridge_vlan_info_array * ++dplane_ctx_get_ifp_bridge_vlan_info_array(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.bvarray; ++} ++ ++void dplane_ctx_set_ifp_vxlan_vni_array(struct zebra_dplane_ctx *ctx, ++ struct zebra_vxlan_vni_array *vniarray) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.vniarray = vniarray; ++} ++ ++const struct zebra_vxlan_vni_array * ++dplane_ctx_get_ifp_vxlan_vni_array(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.vniarray; ++} ++ ++void dplane_ctx_set_ifp_bridge_vlan_info( ++ struct zebra_dplane_ctx *ctx, ++ struct zebra_dplane_bridge_vlan_info *bvinfo) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.bvinfo = *bvinfo; ++} ++ ++const struct zebra_dplane_bridge_vlan_info * ++dplane_ctx_get_ifp_bridge_vlan_info(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return &ctx->u.intf.bvinfo; ++} ++ ++void dplane_ctx_set_ifp_family(struct zebra_dplane_ctx *ctx, uint8_t family) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.family = family; ++} ++ ++uint8_t dplane_ctx_get_ifp_family(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.family; ++} ++ ++void dplane_ctx_set_ifp_zltype(struct zebra_dplane_ctx *ctx, ++ enum zebra_link_type zltype) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.zltype = zltype; ++} ++ ++enum zebra_link_type ++dplane_ctx_get_ifp_zltype(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.zltype; ++} ++ ++void dplane_ctx_set_ifp_link_ifindex(struct zebra_dplane_ctx *ctx, ++ ifindex_t link_ifindex) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.link_ifindex = link_ifindex; ++} ++ ++ifindex_t dplane_ctx_get_ifp_link_ifindex(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.link_ifindex; ++} ++ ++void dplane_ctx_set_ifp_desc(struct zebra_dplane_ctx *ctx, const char *desc) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ strlcpy(ctx->u.intf.desc, desc, sizeof(ctx->u.intf.desc)); ++} ++ ++char *dplane_ctx_get_ifp_desc(struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.desc; ++} ++ ++void dplane_ctx_set_ifp_flags(struct zebra_dplane_ctx *ctx, uint64_t flags) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.flags = flags; ++} ++ ++uint64_t dplane_ctx_get_ifp_flags(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.flags; ++} ++ ++void dplane_ctx_set_ifp_bypass(struct zebra_dplane_ctx *ctx, uint8_t bypass) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.bypass = bypass; ++} ++ ++uint8_t dplane_ctx_get_ifp_bypass(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.bypass; ++} ++ ++void dplane_ctx_set_ifp_bridge_ifindex(struct zebra_dplane_ctx *ctx, ++ ifindex_t bridge_ifindex) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.bridge_ifindex = bridge_ifindex; ++} ++ ++ifindex_t dplane_ctx_get_ifp_bridge_ifindex(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.bridge_ifindex; ++} ++ ++void dplane_ctx_set_ifp_zif_slave_type(struct zebra_dplane_ctx *ctx, ++ enum zebra_slave_iftype zslave_type) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.zslave_type = zslave_type; ++} ++ ++enum zebra_slave_iftype ++dplane_ctx_get_ifp_zif_slave_type(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.zslave_type; ++} ++ ++void dplane_ctx_set_ifp_master_ifindex(struct zebra_dplane_ctx *ctx, ++ ifindex_t master_ifindex) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.master_ifindex = master_ifindex; ++} ++ ++ifindex_t dplane_ctx_get_ifp_master_ifindex(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.master_ifindex; ++} ++ ++void dplane_ctx_set_ifp_mtu(struct zebra_dplane_ctx *ctx, uint32_t mtu) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.mtu = mtu; ++} ++ ++uint32_t dplane_ctx_get_ifp_mtu(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.mtu; ++} ++ ++void dplane_ctx_set_ifp_vrf_id(struct zebra_dplane_ctx *ctx, vrf_id_t vrf_id) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.vrf_id = vrf_id; ++} ++ ++vrf_id_t dplane_ctx_get_ifp_vrf_id(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.vrf_id; ++} ++ ++void dplane_ctx_set_ifp_link_nsid(struct zebra_dplane_ctx *ctx, ++ ns_id_t link_nsid) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.link_nsid = link_nsid; ++} ++ ++ns_id_t dplane_ctx_get_ifp_link_nsid(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.link_nsid; ++} ++ ++void dplane_ctx_set_ifp_startup(struct zebra_dplane_ctx *ctx, bool startup) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.startup = startup; ++} ++ ++bool dplane_ctx_get_ifp_startup(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.startup; ++} ++ ++void dplane_ctx_set_ifp_protodown_set(struct zebra_dplane_ctx *ctx, bool set) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.protodown_set = set; ++} ++ ++bool dplane_ctx_get_ifp_protodown_set(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.protodown_set; ++} ++ ++void dplane_ctx_set_ifp_protodown(struct zebra_dplane_ctx *ctx, bool protodown) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.protodown = protodown; ++} ++ ++bool dplane_ctx_get_ifp_protodown(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.protodown; ++} ++ ++ifindex_t dplane_ctx_get_ifp_bond_ifindex(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.bond_ifindex; ++} ++ ++void dplane_ctx_set_ifp_rc_bitfield(struct zebra_dplane_ctx *ctx, ++ uint32_t rc_bitfield) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.rc_bitfield = rc_bitfield; ++} ++ ++uint32_t dplane_ctx_get_ifp_rc_bitfield(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.rc_bitfield; ++} ++ ++void dplane_ctx_set_ifp_gre_info(struct zebra_dplane_ctx *ctx, ++ struct zebra_l2info_gre *grinfo) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.grinfo = *grinfo; ++} ++ ++const struct zebra_l2info_gre * ++dplane_ctx_get_ifp_gre_info(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return &ctx->u.intf.grinfo; ++} ++ ++void dplane_ctx_set_ifp_vxlan_info(struct zebra_dplane_ctx *ctx, ++ struct zebra_l2info_vxlan *vxinfo) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.vxinfo = *vxinfo; ++} ++ ++const struct zebra_l2info_vxlan * ++dplane_ctx_get_ifp_vxlan_info(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return &ctx->u.intf.vxinfo; ++} ++ ++void dplane_ctx_set_ifp_vlan_info(struct zebra_dplane_ctx *ctx, ++ struct zebra_l2info_vlan *vinfo) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.vinfo = *vinfo; ++} ++ ++const struct zebra_l2info_vlan * ++dplane_ctx_get_ifp_vlan_info(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return &ctx->u.intf.vinfo; ++} ++ ++void dplane_ctx_set_ifp_bridge_info(struct zebra_dplane_ctx *ctx, ++ struct zebra_l2info_bridge *binfo) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.binfo = *binfo; ++} ++ ++const struct zebra_l2info_bridge * ++dplane_ctx_get_ifp_bridge_info(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return &ctx->u.intf.binfo; ++} ++ ++void dplane_ctx_set_ifp_table_id(struct zebra_dplane_ctx *ctx, ++ uint32_t table_id) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.table_id = table_id; ++} ++ ++uint32_t dplane_ctx_get_ifp_table_id(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.table_id; ++} ++ ++void dplane_ctx_set_ifp_hw_addr(struct zebra_dplane_ctx *ctx, ++ int32_t hw_addr_len, uint8_t *hw_addr) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.hw_addr_len = hw_addr_len; ++ memcpy(ctx->u.intf.hw_addr, hw_addr, hw_addr_len); ++} ++ ++int32_t dplane_ctx_get_ifp_hw_addr_len(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.hw_addr_len; ++} ++ ++const uint8_t *dplane_ctx_get_ifp_hw_addr(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.hw_addr; ++} ++ ++void dplane_ctx_set_ifp_bond_ifindex(struct zebra_dplane_ctx *ctx, ++ ifindex_t bond_ifindex) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.bond_ifindex = bond_ifindex; ++} ++ ++enum zebra_iftype ++dplane_ctx_get_ifp_zif_type(const struct zebra_dplane_ctx *ctx) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ return ctx->u.intf.zif_type; ++} ++ ++void dplane_ctx_set_ifp_zif_type(struct zebra_dplane_ctx *ctx, ++ enum zebra_iftype zif_type) ++{ ++ DPLANE_CTX_VALID(ctx); ++ ++ ctx->u.intf.zif_type = zif_type; ++} ++ + void dplane_ctx_set_ifname(struct zebra_dplane_ctx *ctx, const char *ifname) + { + DPLANE_CTX_VALID(ctx); +@@ -6102,6 +6561,7 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx) + case DPLANE_OP_TC_FILTER_ADD: + case DPLANE_OP_TC_FILTER_DELETE: + case DPLANE_OP_TC_FILTER_UPDATE: ++ case DPLANE_OP_STARTUP_STAGE: + break; + } + } +@@ -6274,6 +6734,7 @@ static void kernel_dplane_handle_result(struct zebra_dplane_ctx *ctx) + break; + + case DPLANE_OP_NONE: ++ case DPLANE_OP_STARTUP_STAGE: + if (res != ZEBRA_DPLANE_REQUEST_SUCCESS) + atomic_fetch_add_explicit(&zdplane_info.dg_other_errors, + 1, memory_order_relaxed); +@@ -6966,6 +7427,25 @@ void zebra_dplane_start(void) + frr_pthread_run(zdplane_info.dg_pthread, NULL); + } + ++enum zebra_dplane_startup_notifications ++dplane_ctx_get_startup_spot(struct zebra_dplane_ctx *ctx) ++{ ++ return ctx->u.spot; ++} ++ ++void zebra_dplane_startup_stage(struct zebra_ns *zns, ++ enum zebra_dplane_startup_notifications spot) ++{ ++ struct zebra_dplane_ctx *ctx = dplane_ctx_alloc(); ++ ++ ctx->zd_op = DPLANE_OP_STARTUP_STAGE; ++ ctx->zd_status = ZEBRA_DPLANE_REQUEST_QUEUED; ++ ++ ctx->u.spot = spot; ++ dplane_ctx_set_ns_id(ctx, zns->ns_id); ++ ++ dplane_provider_enqueue_to_zebra(ctx); ++} + /* + * Initialize the dataplane module at startup; called by zebra rib_init() + */ +diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h +index 9ef0afd3a8..c10482ed96 100644 +--- a/zebra/zebra_dplane.h ++++ b/zebra/zebra_dplane.h +@@ -100,6 +100,11 @@ enum zebra_dplane_result { + ZEBRA_DPLANE_REQUEST_FAILURE, + }; + ++enum zebra_dplane_startup_notifications { ++ ZEBRA_DPLANE_INTERFACES_READ, ++ ZEBRA_DPLANE_TUNNELS_READ, ++ ZEBRA_DPLANE_ADDRESSES_READ, ++}; + /* + * API between the zebra dataplane system and the main zebra processing + * context. +@@ -201,7 +206,10 @@ enum dplane_op_e { + DPLANE_OP_TC_CLASS_UPDATE, + DPLANE_OP_TC_FILTER_ADD, + DPLANE_OP_TC_FILTER_DELETE, +- DPLANE_OP_TC_FILTER_UPDATE ++ DPLANE_OP_TC_FILTER_UPDATE, ++ ++ /* Startup Control */ ++ DPLANE_OP_STARTUP_STAGE, + }; + + /* +@@ -336,6 +344,105 @@ const char *dplane_ctx_get_ifname(const struct zebra_dplane_ctx *ctx); + void dplane_ctx_set_ifname(struct zebra_dplane_ctx *ctx, const char *ifname); + ifindex_t dplane_ctx_get_ifindex(const struct zebra_dplane_ctx *ctx); + void dplane_ctx_set_ifindex(struct zebra_dplane_ctx *ctx, ifindex_t ifindex); ++void dplane_ctx_set_ifp_bond_ifindex(struct zebra_dplane_ctx *ctx, ++ ifindex_t ifindex); ++ifindex_t dplane_ctx_get_ifp_bond_ifindex(const struct zebra_dplane_ctx *ctx); ++enum zebra_iftype ++dplane_ctx_get_ifp_zif_type(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_zif_type(struct zebra_dplane_ctx *ctx, ++ enum zebra_iftype zif_type); ++void dplane_ctx_set_ifp_table_id(struct zebra_dplane_ctx *ctx, ++ uint32_t table_id); ++uint32_t dplane_ctx_get_ifp_table_id(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_hw_addr(struct zebra_dplane_ctx *ctx, ++ int32_t hw_addr_len, uint8_t *hw_addr); ++int32_t dplane_ctx_get_ifp_hw_addr_len(const struct zebra_dplane_ctx *ctx); ++const uint8_t *dplane_ctx_get_ifp_hw_addr(const struct zebra_dplane_ctx *ctx); ++struct zebra_l2info_bridge; ++void dplane_ctx_set_ifp_bridge_info(struct zebra_dplane_ctx *ctx, ++ struct zebra_l2info_bridge *binfo); ++const struct zebra_l2info_bridge * ++dplane_ctx_get_ifp_bridge_info(const struct zebra_dplane_ctx *ctx); ++struct zebra_l2info_vlan; ++void dplane_ctx_set_ifp_vlan_info(struct zebra_dplane_ctx *ctx, ++ struct zebra_l2info_vlan *vinfo); ++const struct zebra_l2info_vlan * ++dplane_ctx_get_ifp_vlan_info(const struct zebra_dplane_ctx *ctx); ++struct zebra_l2info_vxlan; ++void dplane_ctx_set_ifp_vxlan_info(struct zebra_dplane_ctx *ctx, ++ struct zebra_l2info_vxlan *vxinfo); ++const struct zebra_l2info_vxlan * ++dplane_ctx_get_ifp_vxlan_info(const struct zebra_dplane_ctx *ctx); ++struct zebra_l2info_gre; ++void dplane_ctx_set_ifp_gre_info(struct zebra_dplane_ctx *ctx, ++ struct zebra_l2info_gre *greinfo); ++const struct zebra_l2info_gre * ++dplane_ctx_get_ifp_gre_info(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_zltype(struct zebra_dplane_ctx *ctx, ++ enum zebra_link_type zlt); ++enum zebra_link_type ++dplane_ctx_get_ifp_zltype(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_link_nsid(struct zebra_dplane_ctx *ctx, ns_id_t ns_id); ++ns_id_t dplane_ctx_get_ifp_link_nsid(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_desc(struct zebra_dplane_ctx *ctx, const char *desc); ++char *dplane_ctx_get_ifp_desc(struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_mtu(struct zebra_dplane_ctx *ctx, uint32_t mtu); ++uint32_t dplane_ctx_get_ifp_mtu(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_vrf_id(struct zebra_dplane_ctx *ctx, vrf_id_t vrf_id); ++vrf_id_t dplane_ctx_get_ifp_vrf_id(const struct zebra_dplane_ctx *ctx); ++enum zebra_slave_iftype; ++void dplane_ctx_set_ifp_zif_slave_type(struct zebra_dplane_ctx *ctx, ++ enum zebra_slave_iftype zslave_type); ++enum zebra_slave_iftype ++dplane_ctx_get_ifp_zif_slave_type(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_master_ifindex(struct zebra_dplane_ctx *ctx, ++ ifindex_t master_ifindex); ++ifindex_t dplane_ctx_get_ifp_master_ifindex(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_bridge_ifindex(struct zebra_dplane_ctx *ctx, ++ ifindex_t bridge_ifindex); ++ifindex_t dplane_ctx_get_ifp_bridge_ifindex(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_bypass(struct zebra_dplane_ctx *ctx, uint8_t bypass); ++uint8_t dplane_ctx_get_ifp_bypass(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_flags(struct zebra_dplane_ctx *ctx, uint64_t flags); ++uint64_t dplane_ctx_get_ifp_flags(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_protodown(struct zebra_dplane_ctx *ctx, bool protodown); ++bool dplane_ctx_get_ifp_protodown(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_startup(struct zebra_dplane_ctx *ctx, bool startup); ++bool dplane_ctx_get_ifp_startup(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_protodown_set(struct zebra_dplane_ctx *ctx, bool set); ++bool dplane_ctx_get_ifp_protodown_set(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_rc_bitfield(struct zebra_dplane_ctx *ctx, ++ uint32_t rc_bitfield); ++uint32_t dplane_ctx_get_ifp_rc_bitfield(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_link_ifindex(struct zebra_dplane_ctx *ctx, ++ ifindex_t link_ifindex); ++ifindex_t dplane_ctx_get_ifp_link_ifindex(const struct zebra_dplane_ctx *ctx); ++void dplane_ctx_set_ifp_family(struct zebra_dplane_ctx *ctx, uint8_t family); ++uint8_t dplane_ctx_get_ifp_family(const struct zebra_dplane_ctx *ctx); ++struct zebra_vxlan_vni_array; ++void dplane_ctx_set_ifp_vxlan_vni_array(struct zebra_dplane_ctx *ctx, ++ struct zebra_vxlan_vni_array *vniarray); ++const struct zebra_vxlan_vni_array * ++dplane_ctx_get_ifp_vxlan_vni_array(const struct zebra_dplane_ctx *ctx); ++struct zebra_dplane_bridge_vlan_info { ++ uint16_t flags; ++ uint16_t vid; ++}; ++void dplane_ctx_set_ifp_bridge_vlan_info( ++ struct zebra_dplane_ctx *ctx, ++ struct zebra_dplane_bridge_vlan_info *bvinfo); ++const struct zebra_dplane_bridge_vlan_info * ++dplane_ctx_get_ifp_bridge_vlan_info(const struct zebra_dplane_ctx *ctx); ++ ++struct zebra_dplane_bridge_vlan_info_array { ++ int count; ++ struct zebra_dplane_bridge_vlan_info array[0]; ++}; ++void dplane_ctx_set_ifp_bridge_vlan_info_array( ++ struct zebra_dplane_ctx *ctx, ++ struct zebra_dplane_bridge_vlan_info_array *bvarray); ++const struct zebra_dplane_bridge_vlan_info_array * ++dplane_ctx_get_ifp_bridge_vlan_info_array(const struct zebra_dplane_ctx *ctx); + + /* Retrieve last/current provider id */ + uint32_t dplane_ctx_get_provider(const struct zebra_dplane_ctx *ctx); +@@ -1083,6 +1190,9 @@ void zebra_dplane_pre_finish(void); + void zebra_dplane_finish(void); + void zebra_dplane_shutdown(void); + ++void zebra_dplane_startup_stage(struct zebra_ns *zns, ++ enum zebra_dplane_startup_notifications spot); ++ + /* + * decision point for sending a routing update through the old + * straight to zebra master pthread or through the dplane to +@@ -1093,6 +1203,9 @@ void dplane_rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, + struct nexthop_group *ng, int startup, + struct zebra_dplane_ctx *ctx); + ++enum zebra_dplane_startup_notifications ++dplane_ctx_get_startup_spot(struct zebra_dplane_ctx *ctx); ++ + #ifdef __cplusplus + } + #endif +diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c +index 758fed7280..8f686eb5f8 100644 +--- a/zebra/zebra_nhg.c ++++ b/zebra/zebra_nhg.c +@@ -3177,6 +3177,7 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx) + case DPLANE_OP_TC_FILTER_ADD: + case DPLANE_OP_TC_FILTER_DELETE: + case DPLANE_OP_TC_FILTER_UPDATE: ++ case DPLANE_OP_STARTUP_STAGE: + break; + } + } +diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c +index 5e50d720a6..201fc761ae 100644 +--- a/zebra/zebra_rib.c ++++ b/zebra/zebra_rib.c +@@ -4770,6 +4770,7 @@ static void rib_process_dplane_results(struct thread *thread) + case DPLANE_OP_NEIGH_TABLE_UPDATE: + case DPLANE_OP_GRE_SET: + case DPLANE_OP_NONE: ++ case DPLANE_OP_STARTUP_STAGE: + break; + + } /* Dispatch by op code */ +diff --git a/zebra/zebra_script.c b/zebra/zebra_script.c +index 5c67ad4f16..22c1824b5a 100644 +--- a/zebra/zebra_script.c ++++ b/zebra/zebra_script.c +@@ -428,6 +428,7 @@ void lua_pushzebra_dplane_ctx(lua_State *L, const struct zebra_dplane_ctx *ctx) + /* Not currently handled */ + case DPLANE_OP_INTF_NETCONFIG: /*NYI*/ + case DPLANE_OP_NONE: ++ case DPLANE_OP_STARTUP_STAGE: + break; + } /* Dispatch by op code */ + } +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0017-zebra-Re-arrange-fpm_read-to-reduce-code-duplication.patch b/src/sonic-frr/patch/0017-zebra-Re-arrange-fpm_read-to-reduce-code-duplication.patch deleted file mode 100755 index 4c392f511118..000000000000 --- a/src/sonic-frr/patch/0017-zebra-Re-arrange-fpm_read-to-reduce-code-duplication.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 88ba9ad950d461847a159b0f4899375ecd23d4b9 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Wed, 5 Oct 2022 11:28:43 -0400 -Subject: [PATCH 3/8] zebra: Re-arrange fpm_read to reduce code duplication - -Signed-off-by: Donald Sharp ---- - zebra/dplane_fpm_nl.c | 19 +++++++++---------- - 1 file changed, 9 insertions(+), 10 deletions(-) - -diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c -index 3b02128c9..8d41f3b07 100644 ---- a/zebra/dplane_fpm_nl.c -+++ b/zebra/dplane_fpm_nl.c -@@ -466,13 +466,6 @@ static int fpm_read(struct thread *t) - /* Let's ignore the input at the moment. */ - rv = stream_read_try(fnc->ibuf, fnc->socket, - STREAM_WRITEABLE(fnc->ibuf)); -- /* We've got an interruption. */ -- if (rv == -2) { -- /* Schedule next read. */ -- thread_add_read(fnc->fthread->master, fpm_read, fnc, -- fnc->socket, &fnc->t_read); -- return 0; -- } - if (rv == 0) { - atomic_fetch_add_explicit(&fnc->counters.connection_closes, 1, - memory_order_relaxed); -@@ -491,15 +484,21 @@ static int fpm_read(struct thread *t) - FPM_RECONNECT(fnc); - return 0; - } -+ -+ /* Schedule the next read */ -+ thread_add_read(fnc->fthread->master, fpm_read, fnc, fnc->socket, -+ &fnc->t_read); -+ -+ /* We've got an interruption. */ -+ if (rv == -2) -+ return 0; -+ - stream_reset(fnc->ibuf); - - /* Account all bytes read. */ - atomic_fetch_add_explicit(&fnc->counters.bytes_read, rv, - memory_order_relaxed); - -- thread_add_read(fnc->fthread->master, fpm_read, fnc, fnc->socket, -- &fnc->t_read); -- - return 0; - } - --- -2.30.2 - diff --git a/src/sonic-frr/patch/0018-zebra-Add-dplane_ctx_get-set_flags.patch b/src/sonic-frr/patch/0018-zebra-Add-dplane_ctx_get-set_flags.patch deleted file mode 100755 index a75623cc5b8c..000000000000 --- a/src/sonic-frr/patch/0018-zebra-Add-dplane_ctx_get-set_flags.patch +++ /dev/null @@ -1,78 +0,0 @@ -From 77d430e04359417d6fca8226e256ee2845fbbc58 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Mon, 3 Oct 2022 15:28:48 -0400 -Subject: [PATCH 4/8] zebra: Add dplane_ctx_get|set_flags - -Zebra needs the ability to pass this data around. -Add it to the dplanes ability to pass. - -Signed-off-by: Donald Sharp - -zebra: Add a dplane_ctx_set_flags - -The dplane_ctx_set_flags call is missing, we will need it. Add it. - -Signed-off-by: Donald Sharp ---- - zebra/zebra_dplane.c | 17 +++++++++++++++++ - zebra/zebra_dplane.h | 2 ++ - 2 files changed, 19 insertions(+) - -diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c -index 656ebcf3b..5d94e1a0b 100644 ---- a/zebra/zebra_dplane.c -+++ b/zebra/zebra_dplane.c -@@ -132,6 +132,8 @@ struct dplane_route_info { - uint32_t zd_mtu; - uint32_t zd_nexthop_mtu; - -+ uint32_t zd_flags; -+ - /* Nexthop hash entry info */ - struct dplane_nexthop_info nhe; - -@@ -1323,6 +1325,20 @@ uint16_t dplane_ctx_get_old_instance(const struct zebra_dplane_ctx *ctx) - return ctx->u.rinfo.zd_old_instance; - } - -+uint32_t dplane_ctx_get_flags(const struct zebra_dplane_ctx *ctx) -+{ -+ DPLANE_CTX_VALID(ctx); -+ -+ return ctx->u.rinfo.zd_flags; -+} -+ -+void dplane_ctx_set_flags(struct zebra_dplane_ctx *ctx, uint32_t flags) -+{ -+ DPLANE_CTX_VALID(ctx); -+ -+ ctx->u.rinfo.zd_flags = flags; -+} -+ - uint32_t dplane_ctx_get_metric(const struct zebra_dplane_ctx *ctx) - { - DPLANE_CTX_VALID(ctx); -@@ -2358,6 +2374,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, - - ctx->zd_table_id = re->table; - -+ ctx->u.rinfo.zd_flags = re->flags; - ctx->u.rinfo.zd_metric = re->metric; - ctx->u.rinfo.zd_old_metric = re->metric; - ctx->zd_vrf_id = re->vrf_id; -diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h -index 1d5518138..3210137c0 100644 ---- a/zebra/zebra_dplane.h -+++ b/zebra/zebra_dplane.h -@@ -343,6 +343,8 @@ route_tag_t dplane_ctx_get_old_tag(const struct zebra_dplane_ctx *ctx); - uint16_t dplane_ctx_get_instance(const struct zebra_dplane_ctx *ctx); - void dplane_ctx_set_instance(struct zebra_dplane_ctx *ctx, uint16_t instance); - uint16_t dplane_ctx_get_old_instance(const struct zebra_dplane_ctx *ctx); -+uint32_t dplane_ctx_get_flags(const struct zebra_dplane_ctx *ctx); -+void dplane_ctx_set_flags(struct zebra_dplane_ctx *ctx, uint32_t flags); - uint32_t dplane_ctx_get_metric(const struct zebra_dplane_ctx *ctx); - uint32_t dplane_ctx_get_old_metric(const struct zebra_dplane_ctx *ctx); - uint32_t dplane_ctx_get_mtu(const struct zebra_dplane_ctx *ctx); --- -2.30.2 - diff --git a/src/sonic-frr/patch/0018-zebra-Use-zebra-dplane-for-RTM-link-and-addr.patch b/src/sonic-frr/patch/0018-zebra-Use-zebra-dplane-for-RTM-link-and-addr.patch new file mode 100644 index 000000000000..98f3b224a75e --- /dev/null +++ b/src/sonic-frr/patch/0018-zebra-Use-zebra-dplane-for-RTM-link-and-addr.patch @@ -0,0 +1,2154 @@ +From 2c33b9ab847a53d8006687e89c0cbd589fe7071f Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Wed, 26 Apr 2023 23:02:09 -0400 +Subject: [PATCH] zebra: Use zebra dplane for RTM link and addr + +a) Move the reads of link and address information +into the dplane +b) Move the startup read of data into the dplane +as well. +c) Break up startup reading of the linux kernel data +into multiple phases. As that we have implied ordering +of data that must be read first and if the dplane has +taken over some data reading then we must delay initial +read-in of other data. + +Fixes: #13288 +Signed-off-by: Donald Sharp + +diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c +index ed5b3c4a66..7613f5fcc4 100644 +--- a/zebra/if_netlink.c ++++ b/zebra/if_netlink.c +@@ -79,64 +79,21 @@ + + extern struct zebra_privs_t zserv_privs; + +-/* Note: on netlink systems, there should be a 1-to-1 mapping between interface +- names and ifindex values. */ +-static void set_ifindex(struct interface *ifp, ifindex_t ifi_index, +- struct zebra_ns *zns) +-{ +- struct interface *oifp; +- +- if (((oifp = if_lookup_by_index_per_ns(zns, ifi_index)) != NULL) +- && (oifp != ifp)) { +- if (ifi_index == IFINDEX_INTERNAL) +- flog_err( +- EC_LIB_INTERFACE, +- "Netlink is setting interface %s ifindex to reserved internal value %u", +- ifp->name, ifi_index); +- else { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "interface index %d was renamed from %s to %s", +- ifi_index, oifp->name, ifp->name); +- if (if_is_up(oifp)) +- flog_err( +- EC_LIB_INTERFACE, +- "interface rename detected on up interface: index %d was renamed from %s to %s, results are uncertain!", +- ifi_index, oifp->name, ifp->name); +- if_delete_update(&oifp); +- } +- } +- if_set_index(ifp, ifi_index); +-} +- + /* Utility function to parse hardware link-layer address and update ifp */ + static void netlink_interface_update_hw_addr(struct rtattr **tb, +- struct interface *ifp) ++ struct zebra_dplane_ctx *ctx) + { +- int i; +- + if (tb[IFLA_ADDRESS]) { + int hw_addr_len; + + hw_addr_len = RTA_PAYLOAD(tb[IFLA_ADDRESS]); + + if (hw_addr_len > INTERFACE_HWADDR_MAX) +- zlog_debug("Hardware address is too large: %d", +- hw_addr_len); +- else { +- ifp->hw_addr_len = hw_addr_len; +- memcpy(ifp->hw_addr, RTA_DATA(tb[IFLA_ADDRESS]), +- hw_addr_len); +- +- for (i = 0; i < hw_addr_len; i++) +- if (ifp->hw_addr[i] != 0) +- break; +- +- if (i == hw_addr_len) +- ifp->hw_addr_len = 0; +- else +- ifp->hw_addr_len = hw_addr_len; +- } ++ zlog_warn("Hardware address is too large: %d", ++ hw_addr_len); ++ else ++ dplane_ctx_set_ifp_hw_addr(ctx, hw_addr_len, ++ RTA_DATA(tb[IFLA_ADDRESS])); + } + } + +@@ -251,26 +208,6 @@ static enum zebra_link_type netlink_to_zebra_link_type(unsigned int hwt) + } + } + +-static inline void zebra_if_set_ziftype(struct interface *ifp, +- enum zebra_iftype zif_type, +- enum zebra_slave_iftype zif_slave_type) +-{ +- struct zebra_if *zif; +- +- zif = (struct zebra_if *)ifp->info; +- zif->zif_slave_type = zif_slave_type; +- +- if (zif->zif_type != zif_type) { +- zif->zif_type = zif_type; +- /* If the if_type has been set to bond initialize ES info +- * against it. XXX - note that we don't handle the case where +- * a zif changes from bond to non-bond; it is really +- * an unexpected/error condition. +- */ +- zebra_evpn_if_init(zif); +- } +-} +- + static void netlink_determine_zebra_iftype(const char *kind, + enum zebra_iftype *zif_type) + { +@@ -300,16 +237,11 @@ static void netlink_determine_zebra_iftype(const char *kind, + } + + static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, +- uint32_t ns_id, const char *name) ++ uint32_t ns_id, const char *name, ++ struct zebra_dplane_ctx *ctx) + { +- struct ifinfomsg *ifi; + struct rtattr *linkinfo[IFLA_INFO_MAX + 1]; + struct rtattr *attr[IFLA_VRF_MAX + 1]; +- struct vrf *vrf = NULL; +- struct zebra_vrf *zvrf; +- uint32_t nl_table_id; +- +- ifi = NLMSG_DATA(h); + + netlink_parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb); + +@@ -331,75 +263,8 @@ static void netlink_vrf_change(struct nlmsghdr *h, struct rtattr *tb, + return; + } + +- nl_table_id = *(uint32_t *)RTA_DATA(attr[IFLA_VRF_TABLE]); +- +- if (h->nlmsg_type == RTM_NEWLINK) { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug("RTM_NEWLINK for VRF %s(%u) table %u", name, +- ifi->ifi_index, nl_table_id); +- +- if (!vrf_lookup_by_id((vrf_id_t)ifi->ifi_index)) { +- vrf_id_t exist_id; +- +- exist_id = +- zebra_vrf_lookup_by_table(nl_table_id, ns_id); +- if (exist_id != VRF_DEFAULT) { +- vrf = vrf_lookup_by_id(exist_id); +- +- flog_err( +- EC_ZEBRA_VRF_MISCONFIGURED, +- "VRF %s id %u table id overlaps existing vrf %s, misconfiguration exiting", +- name, ifi->ifi_index, vrf->name); +- exit(-1); +- } +- } +- +- vrf = vrf_update((vrf_id_t)ifi->ifi_index, name); +- if (!vrf) { +- flog_err(EC_LIB_INTERFACE, "VRF %s id %u not created", +- name, ifi->ifi_index); +- return; +- } +- +- /* +- * This is the only place that we get the actual kernel table_id +- * being used. We need it to set the table_id of the routes +- * we are passing to the kernel.... And to throw some totally +- * awesome parties. that too. +- * +- * At this point we *must* have a zvrf because the vrf_create +- * callback creates one. We *must* set the table id +- * before the vrf_enable because of( at the very least ) +- * static routes being delayed for installation until +- * during the vrf_enable callbacks. +- */ +- zvrf = (struct zebra_vrf *)vrf->info; +- zvrf->table_id = nl_table_id; +- +- /* Enable the created VRF. */ +- if (!vrf_enable(vrf)) { +- flog_err(EC_LIB_INTERFACE, +- "Failed to enable VRF %s id %u", name, +- ifi->ifi_index); +- return; +- } +- +- } else // h->nlmsg_type == RTM_DELLINK +- { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug("RTM_DELLINK for VRF %s(%u)", name, +- ifi->ifi_index); +- +- vrf = vrf_lookup_by_id((vrf_id_t)ifi->ifi_index); +- +- if (!vrf) { +- flog_warn(EC_ZEBRA_VRF_NOT_FOUND, "%s: vrf not found", +- __func__); +- return; +- } +- +- vrf_delete(vrf); +- } ++ dplane_ctx_set_ifp_table_id( ++ ctx, *(uint32_t *)RTA_DATA(attr[IFLA_VRF_TABLE])); + } + + static uint32_t get_iflink_speed(struct interface *interface, int *error) +@@ -659,58 +524,120 @@ static int netlink_extract_vxlan_info(struct rtattr *link_data, + * bridge interface is added or updated, take further actions to map + * its members. Likewise, for VxLAN interface. + */ +-static void netlink_interface_update_l2info(struct interface *ifp, ++static void netlink_interface_update_l2info(struct zebra_dplane_ctx *ctx, ++ enum zebra_iftype zif_type, + struct rtattr *link_data, int add, + ns_id_t link_nsid) + { ++ struct zebra_l2info_bridge bridge_info; ++ struct zebra_l2info_vlan vlan_info; ++ struct zebra_l2info_vxlan vxlan_info; ++ struct zebra_l2info_gre gre_info; ++ + if (!link_data) + return; + +- if (IS_ZEBRA_IF_BRIDGE(ifp)) { +- struct zebra_l2info_bridge bridge_info; +- ++ switch (zif_type) { ++ case ZEBRA_IF_BRIDGE: + netlink_extract_bridge_info(link_data, &bridge_info); +- zebra_l2_bridge_add_update(ifp, &bridge_info); +- } else if (IS_ZEBRA_IF_VLAN(ifp)) { +- struct zebra_l2info_vlan vlan_info; +- ++ dplane_ctx_set_ifp_bridge_info(ctx, &bridge_info); ++ break; ++ case ZEBRA_IF_VLAN: + netlink_extract_vlan_info(link_data, &vlan_info); +- zebra_l2_vlanif_update(ifp, &vlan_info); +- zebra_evpn_acc_bd_svi_set(ifp->info, NULL, +- !!if_is_operative(ifp)); +- } else if (IS_ZEBRA_IF_VXLAN(ifp)) { +- struct zebra_l2info_vxlan vxlan_info; +- ++ dplane_ctx_set_ifp_vlan_info(ctx, &vlan_info); ++ break; ++ case ZEBRA_IF_VXLAN: + netlink_extract_vxlan_info(link_data, &vxlan_info); + vxlan_info.link_nsid = link_nsid; +- zebra_l2_vxlanif_add_update(ifp, &vxlan_info, add); +- if (link_nsid != NS_UNKNOWN && +- vxlan_info.ifindex_link) +- zebra_if_update_link(ifp, vxlan_info.ifindex_link, +- link_nsid); +- } else if (IS_ZEBRA_IF_GRE(ifp)) { +- struct zebra_l2info_gre gre_info; +- ++ dplane_ctx_set_ifp_vxlan_info(ctx, &vxlan_info); ++ break; ++ case ZEBRA_IF_GRE: + netlink_extract_gre_info(link_data, &gre_info); + gre_info.link_nsid = link_nsid; +- zebra_l2_greif_add_update(ifp, &gre_info, add); +- if (link_nsid != NS_UNKNOWN && +- gre_info.ifindex_link) +- zebra_if_update_link(ifp, gre_info.ifindex_link, +- link_nsid); ++ dplane_ctx_set_ifp_gre_info(ctx, &gre_info); ++ break; ++ case ZEBRA_IF_OTHER: ++ case ZEBRA_IF_VRF: ++ case ZEBRA_IF_MACVLAN: ++ case ZEBRA_IF_VETH: ++ case ZEBRA_IF_BOND: ++ case ZEBRA_IF_BOND_SLAVE: ++ break; + } + } + +-static int netlink_bridge_vxlan_update(struct interface *ifp, +- struct rtattr *af_spec) ++#if 0 ++static int ++netlink_bridge_vxlan_vlan_vni_map_update(struct zebra_dplane_ctx *ctx, ++ struct rtattr *af_spec) ++{ ++ int rem; ++ uint16_t flags; ++ struct rtattr *i; ++ struct zebra_vxlan_vni_array *vniarray = NULL; ++ struct zebra_vxlan_vni vni_end; ++ struct zebra_vxlan_vni vni_start; ++ struct rtattr *aftb[IFLA_BRIDGE_VLAN_TUNNEL_MAX + 1]; ++ int32_t count = 0; ++ ++ memset(&vni_start, 0, sizeof(vni_start)); ++ memset(&vni_end, 0, sizeof(vni_end)); ++ ++ for (i = RTA_DATA(af_spec), rem = RTA_PAYLOAD(af_spec); RTA_OK(i, rem); ++ i = RTA_NEXT(i, rem)) { ++ ++ if (i->rta_type != IFLA_BRIDGE_VLAN_TUNNEL_INFO) ++ continue; ++ ++ memset(aftb, 0, sizeof(aftb)); ++ netlink_parse_rtattr_nested(aftb, IFLA_BRIDGE_VLAN_TUNNEL_MAX, ++ i); ++ if (!aftb[IFLA_BRIDGE_VLAN_TUNNEL_ID] || ++ !aftb[IFLA_BRIDGE_VLAN_TUNNEL_VID]) ++ /* vlan-vni info missing */ ++ return 0; ++ ++ count++; ++ flags = 0; ++ vniarray = XREALLOC( ++ MTYPE_TMP, vniarray, ++ sizeof(struct zebra_vxlan_vni_array) + ++ count * sizeof(struct zebra_vxlan_vni)); ++ ++ memset(&vniarray->vnis[count - 1], 0, ++ sizeof(struct zebra_vxlan_vni)); ++ ++ vniarray->vnis[count - 1].vni = ++ *(vni_t *)RTA_DATA(aftb[IFLA_BRIDGE_VLAN_TUNNEL_ID]); ++ vniarray->vnis[count - 1].access_vlan = *(vlanid_t *)RTA_DATA( ++ aftb[IFLA_BRIDGE_VLAN_TUNNEL_VID]); ++ ++ if (aftb[IFLA_BRIDGE_VLAN_TUNNEL_FLAGS]) ++ flags = *(uint16_t *)RTA_DATA( ++ aftb[IFLA_BRIDGE_VLAN_TUNNEL_FLAGS]); ++ ++ vniarray->vnis[count - 1].flags = flags; ++ } ++ ++ if (count) { ++ vniarray->count = count; ++ dplane_ctx_set_ifp_vxlan_vni_array(ctx, vniarray); ++ } ++ return 0; ++} ++#endif ++static int netlink_bridge_vxlan_update(struct zebra_dplane_ctx *ctx, ++ struct rtattr *af_spec) + { + struct rtattr *aftb[IFLA_BRIDGE_MAX + 1]; + struct bridge_vlan_info *vinfo; +- vlanid_t access_vlan; ++ struct zebra_dplane_bridge_vlan_info bvinfo; + + if (!af_spec) + return 0; + ++ //netlink_bridge_vxlan_vlan_vni_map_update(ctx, af_spec); ++ + /* There is a 1-to-1 mapping of VLAN to VxLAN - hence + * only 1 access VLAN is accepted. + */ +@@ -719,119 +646,73 @@ static int netlink_bridge_vxlan_update(struct interface *ifp, + return 0; + + vinfo = RTA_DATA(aftb[IFLA_BRIDGE_VLAN_INFO]); +- if (!(vinfo->flags & BRIDGE_VLAN_INFO_PVID)) +- return 0; ++ bvinfo.flags = vinfo->flags; ++ bvinfo.vid = vinfo->vid; + +- access_vlan = (vlanid_t)vinfo->vid; +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug("Access VLAN %u for VxLAN IF %s(%u)", access_vlan, +- ifp->name, ifp->ifindex); +- zebra_l2_vxlanif_update_access_vlan(ifp, access_vlan); ++ dplane_ctx_set_ifp_bridge_vlan_info(ctx, &bvinfo); + return 0; + } + +-static void netlink_bridge_vlan_update(struct interface *ifp, +- struct rtattr *af_spec) ++static void netlink_bridge_vlan_update(struct zebra_dplane_ctx *ctx, ++ struct rtattr *af_spec) + { + struct rtattr *i; + int rem; +- uint16_t vid_range_start = 0; +- struct zebra_if *zif; +- bitfield_t old_vlan_bitmap; + struct bridge_vlan_info *vinfo; +- +- zif = (struct zebra_if *)ifp->info; +- +- /* cache the old bitmap addrs */ +- old_vlan_bitmap = zif->vlan_bitmap; +- /* create a new bitmap space for re-eval */ +- bf_init(zif->vlan_bitmap, IF_VLAN_BITMAP_MAX); ++ struct zebra_dplane_bridge_vlan_info_array *bvarray = NULL; ++ int32_t count = 0; + + if (af_spec) { + for (i = RTA_DATA(af_spec), rem = RTA_PAYLOAD(af_spec); + RTA_OK(i, rem); i = RTA_NEXT(i, rem)) { +- + if (i->rta_type != IFLA_BRIDGE_VLAN_INFO) + continue; + +- vinfo = RTA_DATA(i); +- +- if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) { +- vid_range_start = vinfo->vid; +- continue; +- } ++ count++; ++ bvarray = XREALLOC( ++ MTYPE_TMP, bvarray, ++ sizeof(struct ++ zebra_dplane_bridge_vlan_info_array) + ++ count * sizeof(struct ++ zebra_dplane_bridge_vlan_info)); + +- if (!(vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END)) +- vid_range_start = vinfo->vid; +- +- zebra_vlan_bitmap_compute(ifp, vid_range_start, +- vinfo->vid); ++ vinfo = RTA_DATA(i); ++ bvarray->array[count - 1].flags = vinfo->flags; ++ bvarray->array[count - 1].vid = vinfo->vid; + } + } + +- zebra_vlan_mbr_re_eval(ifp, old_vlan_bitmap); +- +- bf_free(old_vlan_bitmap); ++ if (count) { ++ bvarray->count = count; ++ dplane_ctx_set_ifp_bridge_vlan_info_array(ctx, bvarray); ++ } + } + +-static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id, +- int startup) ++static int netlink_bridge_interface(struct zebra_dplane_ctx *ctx, ++ struct rtattr *af_spec, int startup) + { +- char *name = NULL; +- struct ifinfomsg *ifi; +- struct rtattr *tb[IFLA_MAX + 1]; +- struct interface *ifp; +- struct zebra_if *zif; +- struct rtattr *af_spec; + +- /* Fetch name and ifindex */ +- ifi = NLMSG_DATA(h); +- netlink_parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len); +- +- if (tb[IFLA_IFNAME] == NULL) +- return -1; +- name = (char *)RTA_DATA(tb[IFLA_IFNAME]); +- +- /* The interface should already be known, if not discard. */ +- ifp = if_lookup_by_index_per_ns(zebra_ns_lookup(ns_id), ifi->ifi_index); +- if (!ifp) { +- zlog_debug("Cannot find bridge IF %s(%u)", name, +- ifi->ifi_index); +- return 0; +- } +- +- /* We are only interested in the access VLAN i.e., AF_SPEC */ +- af_spec = tb[IFLA_AF_SPEC]; +- +- if (IS_ZEBRA_IF_VXLAN(ifp)) +- return netlink_bridge_vxlan_update(ifp, af_spec); ++ netlink_bridge_vxlan_update(ctx, af_spec); + + /* build vlan bitmap associated with this interface if that + * device type is interested in the vlans + */ +- zif = (struct zebra_if *)ifp->info; +- if (bf_is_inited(zif->vlan_bitmap)) +- netlink_bridge_vlan_update(ifp, af_spec); ++ netlink_bridge_vlan_update(ctx, af_spec); + ++ dplane_provider_enqueue_to_zebra(ctx); + return 0; + } + +-static bool is_if_protodown_reason_only_frr(uint32_t rc_bitfield) +-{ +- return (rc_bitfield == (((uint32_t)1) << if_netlink_get_frr_protodown_r_bit())); +-} +- + /* + * Process interface protodown dplane update. + * + * If the interface is an es bond member then it must follow EVPN's + * protodown setting. + */ +-static void netlink_proc_dplane_if_protodown(struct zebra_if *zif, ++static void netlink_proc_dplane_if_protodown(struct zebra_dplane_ctx *ctx, + struct rtattr **tb) + { + bool protodown; +- bool old_protodown; + uint32_t rc_bitfield = 0; + struct rtattr *pd_reason_info[IFLA_MAX + 1]; + +@@ -846,59 +727,9 @@ static void netlink_proc_dplane_if_protodown(struct zebra_if *zif, + pd_reason_info[IFLA_PROTO_DOWN_REASON_VALUE]); + } + +- /* +- * Set our reason code to note it wasn't us. +- * If the reason we got from the kernel is ONLY frr though, don't +- * set it. +- */ +- COND_FLAG(zif->protodown_rc, ZEBRA_PROTODOWN_EXTERNAL, +- protodown && rc_bitfield && +- !is_if_protodown_reason_only_frr(rc_bitfield)); +- +- +- old_protodown = !!ZEBRA_IF_IS_PROTODOWN(zif); +- if (protodown == old_protodown) +- return; +- +- if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug("interface %s dplane change, protdown %s", +- zif->ifp->name, protodown ? "on" : "off"); +- +- /* Set protodown, respectively */ +- COND_FLAG(zif->flags, ZIF_FLAG_PROTODOWN, protodown); +- +- if (zebra_evpn_is_es_bond_member(zif->ifp)) { +- /* Check it's not already being sent to the dplane first */ +- if (protodown && +- CHECK_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN)) { +- if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "bond mbr %s protodown on recv'd but already sent protodown on to the dplane", +- zif->ifp->name); +- return; +- } +- +- if (!protodown && +- CHECK_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN)) { +- if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "bond mbr %s protodown off recv'd but already sent protodown off to the dplane", +- zif->ifp->name); +- return; +- } +- +- if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "bond mbr %s reinstate protodown %s in the dplane", +- zif->ifp->name, old_protodown ? "on" : "off"); +- +- if (old_protodown) +- SET_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN); +- else +- SET_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN); +- +- dplane_intf_update(zif->ifp); +- } ++ dplane_ctx_set_ifp_rc_bitfield(ctx, rc_bitfield); ++ dplane_ctx_set_ifp_protodown(ctx, protodown); ++ dplane_ctx_set_ifp_protodown_set(ctx, true); + } + + static uint8_t netlink_parse_lacp_bypass(struct rtattr **linkinfo) +@@ -915,29 +746,6 @@ static uint8_t netlink_parse_lacp_bypass(struct rtattr **linkinfo) + return bypass; + } + +-/* +- * Only called at startup to cleanup leftover protodown reasons we may +- * have not cleaned up. We leave protodown set though. +- */ +-static void if_sweep_protodown(struct zebra_if *zif) +-{ +- bool protodown; +- +- protodown = !!ZEBRA_IF_IS_PROTODOWN(zif); +- +- if (!protodown) +- return; +- +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug("interface %s sweeping protodown %s reason 0x%x", +- zif->ifp->name, protodown ? "on" : "off", +- zif->protodown_rc); +- +- /* Only clear our reason codes, leave external if it was set */ +- UNSET_FLAG(zif->protodown_rc, ZEBRA_PROTODOWN_ALL); +- dplane_intf_update(zif->ifp); +-} +- + /* Request for specific interface or address information from the kernel */ + static int netlink_request_intf_addr(struct nlsock *netlink_cmd, int family, + int type, uint32_t filter_mask) +@@ -984,7 +792,7 @@ int interface_lookup_netlink(struct zebra_ns *zns) + { + int ret; + struct zebra_dplane_info dp_info; +- struct nlsock *netlink_cmd = &zns->netlink_cmd; ++ struct nlsock *netlink_cmd = &zns->netlink_dplane_out; + + /* Capture key info from ns struct */ + zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/); +@@ -1008,6 +816,13 @@ int interface_lookup_netlink(struct zebra_ns *zns) + if (ret < 0) + return ret; + ++ return ret; ++} ++ ++void interface_list_tunneldump(struct zebra_ns *zns) ++{ ++ int ret; ++ + /* + * So netlink_tunneldump_read will initiate a request + * per tunnel to get data. If we are on a kernel that +@@ -1020,13 +835,12 @@ int interface_lookup_netlink(struct zebra_ns *zns) + */ + ret = netlink_tunneldump_read(zns); + if (ret < 0) +- return ret; ++ return; + +- /* fixup linkages */ +- zebra_if_update_all_links(zns); +- return 0; ++ zebra_dplane_startup_stage(zns, ZEBRA_DPLANE_TUNNELS_READ); + } + ++ + /** + * interface_addr_lookup_netlink() - Look up interface addresses + * +@@ -1046,8 +860,8 @@ static int interface_addr_lookup_netlink(struct zebra_ns *zns) + ret = netlink_request_intf_addr(netlink_cmd, AF_INET, RTM_GETADDR, 0); + if (ret < 0) + return ret; +- ret = netlink_parse_info(netlink_interface_addr, netlink_cmd, &dp_info, +- 0, true); ++ ret = netlink_parse_info(netlink_interface_addr_dplane, netlink_cmd, ++ &dp_info, 0, true); + if (ret < 0) + return ret; + +@@ -1055,8 +869,8 @@ static int interface_addr_lookup_netlink(struct zebra_ns *zns) + ret = netlink_request_intf_addr(netlink_cmd, AF_INET6, RTM_GETADDR, 0); + if (ret < 0) + return ret; +- ret = netlink_parse_info(netlink_interface_addr, netlink_cmd, &dp_info, +- 0, true); ++ ret = netlink_parse_info(netlink_interface_addr_dplane, netlink_cmd, ++ &dp_info, 0, true); + if (ret < 0) + return ret; + +@@ -1616,7 +1430,6 @@ int netlink_interface_addr_dplane(struct nlmsghdr *h, ns_id_t ns_id, + + /* Enqueue ctx for main pthread to process */ + dplane_provider_enqueue_to_zebra(ctx); +- + return 0; + } + +@@ -1626,27 +1439,21 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) + struct ifinfomsg *ifi; + struct rtattr *tb[IFLA_MAX + 1]; + struct rtattr *linkinfo[IFLA_MAX + 1]; +- struct interface *ifp; + char *name = NULL; + char *kind = NULL; +- char *desc = NULL; + char *slave_kind = NULL; +- struct zebra_ns *zns; + vrf_id_t vrf_id = VRF_DEFAULT; + enum zebra_iftype zif_type = ZEBRA_IF_OTHER; + enum zebra_slave_iftype zif_slave_type = ZEBRA_IF_SLAVE_NONE; + ifindex_t bridge_ifindex = IFINDEX_INTERNAL; + ifindex_t bond_ifindex = IFINDEX_INTERNAL; + ifindex_t link_ifindex = IFINDEX_INTERNAL; +- uint8_t old_hw_addr[INTERFACE_HWADDR_MAX]; +- struct zebra_if *zif; + ns_id_t link_nsid = ns_id; + ifindex_t master_infindex = IFINDEX_INTERNAL; + uint8_t bypass = 0; + + frrtrace(3, frr_zebra, netlink_interface, h, ns_id, startup); + +- zns = zebra_ns_lookup(ns_id); + ifi = NLMSG_DATA(h); + + /* assume if not default zns, then new VRF */ +@@ -1675,10 +1482,6 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) + return -1; + } + +- /* We are interested in some AF_BRIDGE notifications. */ +- if (ifi->ifi_family == AF_BRIDGE) +- return netlink_bridge_interface(h, len, ns_id, startup); +- + /* Looking up interface name. */ + memset(linkinfo, 0, sizeof(linkinfo)); + netlink_parse_rtattr_flags(tb, IFLA_MAX, IFLA_RTA(ifi), len, +@@ -1728,18 +1531,47 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) + link_nsid = *(ns_id_t *)RTA_DATA(tb[IFLA_LINK_NETNSID]); + link_nsid = ns_id_get_absolute(ns_id, link_nsid); + } +- if (tb[IFLA_IFALIAS]) { +- desc = (char *)RTA_DATA(tb[IFLA_IFALIAS]); +- } + +- /* See if interface is present. */ +- ifp = if_lookup_by_name_per_ns(zns, name); ++ struct zebra_dplane_ctx *ctx = dplane_ctx_alloc(); ++ dplane_ctx_set_ns_id(ctx, ns_id); ++ dplane_ctx_set_ifp_link_nsid(ctx, link_nsid); ++ dplane_ctx_set_ifp_zif_type(ctx, zif_type); ++ dplane_ctx_set_ifindex(ctx, ifi->ifi_index); ++ dplane_ctx_set_ifname(ctx, name); ++ dplane_ctx_set_ifp_startup(ctx, startup); ++ dplane_ctx_set_ifp_family(ctx, ifi->ifi_family); ++ ++ /* We are interested in some AF_BRIDGE notifications. */ ++#ifndef AF_BRIDGE ++#define AF_BRIDGE 7 ++#endif ++ if (ifi->ifi_family == AF_BRIDGE) { ++ dplane_ctx_set_op(ctx, DPLANE_OP_INTF_INSTALL); ++ return netlink_bridge_interface(ctx, tb[IFLA_AF_SPEC], startup); ++ } + + if (h->nlmsg_type == RTM_NEWLINK) { ++ dplane_ctx_set_ifp_link_ifindex(ctx, link_ifindex); ++ dplane_ctx_set_op(ctx, DPLANE_OP_INTF_INSTALL); ++ dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_QUEUED); ++ if (tb[IFLA_IFALIAS]) { ++ dplane_ctx_set_ifp_desc(ctx, ++ RTA_DATA(tb[IFLA_IFALIAS])); ++ } ++ if (!tb[IFLA_MTU]) { ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "RTM_NEWLINK for interface %s(%u) without MTU set", ++ name, ifi->ifi_index); ++ return 0; ++ } ++ dplane_ctx_set_ifp_mtu(ctx, *(int *)RTA_DATA(tb[IFLA_MTU])); ++ + /* If VRF, create or update the VRF structure itself. */ + if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) { +- netlink_vrf_change(h, tb[IFLA_LINKINFO], ns_id, name); +- vrf_id = (vrf_id_t)ifi->ifi_index; ++ netlink_vrf_change(h, tb[IFLA_LINKINFO], ns_id, name, ++ ctx); ++ vrf_id = ifi->ifi_index; + } + + if (tb[IFLA_MASTER]) { +@@ -1762,279 +1594,45 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup) + } else + zif_slave_type = ZEBRA_IF_SLAVE_OTHER; + } ++ dplane_ctx_set_ifp_zif_slave_type(ctx, zif_slave_type); ++ dplane_ctx_set_ifp_vrf_id(ctx, vrf_id); ++ dplane_ctx_set_ifp_master_ifindex(ctx, master_infindex); ++ dplane_ctx_set_ifp_bridge_ifindex(ctx, bridge_ifindex); ++ dplane_ctx_set_ifp_bond_ifindex(ctx, bond_ifindex); ++ dplane_ctx_set_ifp_bypass(ctx, bypass); ++ dplane_ctx_set_ifp_zltype( ++ ctx, netlink_to_zebra_link_type(ifi->ifi_type)); ++ + if (vrf_is_backend_netns()) +- vrf_id = (vrf_id_t)ns_id; +- if (ifp == NULL +- || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { +- /* Add interface notification from kernel */ +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d sl_type %d master %u flags 0x%x", +- name, ifi->ifi_index, vrf_id, zif_type, +- zif_slave_type, master_infindex, +- ifi->ifi_flags); +- +- if (ifp == NULL) { +- /* unknown interface */ +- ifp = if_get_by_name(name, vrf_id, NULL); +- } else { +- /* pre-configured interface, learnt now */ +- if (ifp->vrf->vrf_id != vrf_id) +- if_update_to_new_vrf(ifp, vrf_id); +- } +- +- /* Update interface information. */ +- set_ifindex(ifp, ifi->ifi_index, zns); +- ifp->flags = ifi->ifi_flags & 0x0000fffff; +- if (!tb[IFLA_MTU]) { +- zlog_debug( +- "RTM_NEWLINK for interface %s(%u) without MTU set", +- name, ifi->ifi_index); +- return 0; +- } +- ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]); +- ifp->metric = 0; +- ifp->speed = get_iflink_speed(ifp, NULL); +- ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; +- +- /* Set interface type */ +- zebra_if_set_ziftype(ifp, zif_type, zif_slave_type); +- if (IS_ZEBRA_IF_VRF(ifp)) +- SET_FLAG(ifp->status, +- ZEBRA_INTERFACE_VRF_LOOPBACK); +- +- /* Update link. */ +- zebra_if_update_link(ifp, link_ifindex, link_nsid); +- +- /* +- * Just set the @link/lower-device ifindex. During +- * nldump interfaces are not ordered in any fashion so +- * we may end up getting upper devices before lower +- * devices. We will setup the real linkage once the dump +- * is complete. +- */ +- zif = (struct zebra_if *)ifp->info; +- zif->link_ifindex = link_ifindex; +- +- ifp->ll_type = +- netlink_to_zebra_link_type(ifi->ifi_type); +- netlink_interface_update_hw_addr(tb, ifp); +- +- /* Inform clients, install any configured addresses. */ +- if_add_update(ifp); +- +- /* Extract and save L2 interface information, take +- * additional actions. */ +- netlink_interface_update_l2info( +- ifp, linkinfo[IFLA_INFO_DATA], +- 1, link_nsid); +- if (IS_ZEBRA_IF_BOND(ifp)) +- zebra_l2if_update_bond(ifp, true); +- if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) +- zebra_l2if_update_bridge_slave( +- ifp, bridge_ifindex, ns_id, +- ZEBRA_BRIDGE_NO_ACTION); +- else if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) +- zebra_l2if_update_bond_slave(ifp, bond_ifindex, +- !!bypass); +- +- if (tb[IFLA_PROTO_DOWN]) { +- netlink_proc_dplane_if_protodown(ifp->info, tb); +- if (startup) +- if_sweep_protodown(zif); +- } +- if (IS_ZEBRA_IF_BRIDGE(ifp)) { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "RTM_NEWLINK ADD for %s(%u), vlan-aware %d", +- name, ifp->ifindex, +- IS_ZEBRA_IF_BRIDGE_VLAN_AWARE( +- zif)); +- } +- } else if (ifp->vrf->vrf_id != vrf_id) { +- /* VRF change for an interface. */ +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "RTM_NEWLINK vrf-change for %s(%u) vrf_id %u -> %u flags 0x%x", +- name, ifp->ifindex, ifp->vrf->vrf_id, +- vrf_id, ifi->ifi_flags); ++ dplane_ctx_set_ifp_vrf_id(ctx, ns_id); + +- if_handle_vrf_change(ifp, vrf_id); +- } else { +- bool was_bridge_slave, was_bond_slave; +- uint8_t chgflags = ZEBRA_BRIDGE_NO_ACTION; +- zif = ifp->info; ++ dplane_ctx_set_ifp_flags(ctx, ifi->ifi_flags & 0x0000fffff); + +- /* Interface update. */ +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "RTM_NEWLINK update for %s(%u) sl_type %d master %u flags 0x%x", +- name, ifp->ifindex, zif_slave_type, +- master_infindex, ifi->ifi_flags); ++ if (tb[IFLA_PROTO_DOWN]) { ++ dplane_ctx_set_ifp_protodown_set(ctx, true); ++ netlink_proc_dplane_if_protodown(ctx, tb); ++ } else ++ dplane_ctx_set_ifp_protodown_set(ctx, false); + +- set_ifindex(ifp, ifi->ifi_index, zns); +- if (!tb[IFLA_MTU]) { +- zlog_debug( +- "RTM_NEWLINK for interface %s(%u) without MTU set", +- name, ifi->ifi_index); +- return 0; +- } +- ifp->mtu6 = ifp->mtu = *(int *)RTA_DATA(tb[IFLA_MTU]); +- ifp->metric = 0; +- +- /* Update interface type - NOTE: Only slave_type can +- * change. */ +- was_bridge_slave = IS_ZEBRA_IF_BRIDGE_SLAVE(ifp); +- was_bond_slave = IS_ZEBRA_IF_BOND_SLAVE(ifp); +- zebra_if_set_ziftype(ifp, zif_type, zif_slave_type); +- +- memcpy(old_hw_addr, ifp->hw_addr, INTERFACE_HWADDR_MAX); +- +- /* Update link. */ +- zebra_if_update_link(ifp, link_ifindex, link_nsid); +- +- ifp->ll_type = +- netlink_to_zebra_link_type(ifi->ifi_type); +- netlink_interface_update_hw_addr(tb, ifp); +- +- if (tb[IFLA_PROTO_DOWN]) +- netlink_proc_dplane_if_protodown(ifp->info, tb); +- +- if (if_is_no_ptm_operative(ifp)) { +- bool is_up = if_is_operative(ifp); +- ifp->flags = ifi->ifi_flags & 0x0000fffff; +- if (!if_is_no_ptm_operative(ifp) || +- CHECK_FLAG(zif->flags, +- ZIF_FLAG_PROTODOWN)) { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "Intf %s(%u) has gone DOWN", +- name, ifp->ifindex); +- if_down(ifp); +- rib_update(RIB_UPDATE_KERNEL); +- } else if (if_is_operative(ifp)) { +- bool mac_updated = false; +- +- /* Must notify client daemons of new +- * interface status. */ +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "Intf %s(%u) PTM up, notifying clients", +- name, ifp->ifindex); +- if_up(ifp, !is_up); +- +- /* Update EVPN VNI when SVI MAC change +- */ +- if (memcmp(old_hw_addr, ifp->hw_addr, +- INTERFACE_HWADDR_MAX)) +- mac_updated = true; +- if (IS_ZEBRA_IF_VLAN(ifp) +- && mac_updated) { +- struct interface *link_if; +- +- link_if = +- if_lookup_by_index_per_ns( +- zebra_ns_lookup(NS_DEFAULT), +- link_ifindex); +- if (link_if) +- zebra_vxlan_svi_up(ifp, +- link_if); +- } else if (mac_updated +- && IS_ZEBRA_IF_BRIDGE(ifp)) { +- zlog_debug( +- "Intf %s(%u) bridge changed MAC address", +- name, ifp->ifindex); +- chgflags = +- ZEBRA_BRIDGE_MASTER_MAC_CHANGE; +- } +- } +- } else { +- ifp->flags = ifi->ifi_flags & 0x0000fffff; +- if (if_is_operative(ifp) && +- !CHECK_FLAG(zif->flags, +- ZIF_FLAG_PROTODOWN)) { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "Intf %s(%u) has come UP", +- name, ifp->ifindex); +- if_up(ifp, true); +- if (IS_ZEBRA_IF_BRIDGE(ifp)) +- chgflags = +- ZEBRA_BRIDGE_MASTER_UP; +- } else { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "Intf %s(%u) has gone DOWN", +- name, ifp->ifindex); +- if_down(ifp); +- rib_update(RIB_UPDATE_KERNEL); +- } +- } +- +- /* Extract and save L2 interface information, take +- * additional actions. */ +- netlink_interface_update_l2info( +- ifp, linkinfo[IFLA_INFO_DATA], +- 0, link_nsid); +- if (IS_ZEBRA_IF_BRIDGE(ifp)) +- zebra_l2if_update_bridge(ifp, chgflags); +- if (IS_ZEBRA_IF_BOND(ifp)) +- zebra_l2if_update_bond(ifp, true); +- if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave) +- zebra_l2if_update_bridge_slave( +- ifp, bridge_ifindex, ns_id, chgflags); +- else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave) +- zebra_l2if_update_bond_slave(ifp, bond_ifindex, +- !!bypass); +- if (IS_ZEBRA_IF_BRIDGE(ifp)) { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "RTM_NEWLINK update for %s(%u), vlan-aware %d", +- name, ifp->ifindex, +- IS_ZEBRA_IF_BRIDGE_VLAN_AWARE( +- zif)); +- } +- } ++ netlink_interface_update_hw_addr(tb, ctx); + +- zif = ifp->info; +- if (zif) { +- XFREE(MTYPE_ZIF_DESC, zif->desc); +- if (desc) +- zif->desc = XSTRDUP(MTYPE_ZIF_DESC, desc); +- } ++ /* Extract and save L2 interface information, take ++ * additional actions. */ ++ netlink_interface_update_l2info( ++ ctx, zif_type, linkinfo[IFLA_INFO_DATA], 1, link_nsid); + } else { +- /* Delete interface notification from kernel */ +- if (ifp == NULL) { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "RTM_DELLINK for unknown interface %s(%u)", +- name, ifi->ifi_index); +- return 0; +- } +- + if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug("RTM_DELLINK for %s(%u)", name, +- ifp->ifindex); +- +- UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK); +- +- if (IS_ZEBRA_IF_BOND(ifp)) +- zebra_l2if_update_bond(ifp, false); +- if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) +- zebra_l2if_update_bond_slave(ifp, bond_ifindex, false); +- /* Special handling for bridge or VxLAN interfaces. */ +- if (IS_ZEBRA_IF_BRIDGE(ifp)) +- zebra_l2_bridge_del(ifp); +- else if (IS_ZEBRA_IF_VXLAN(ifp)) +- zebra_l2_vxlanif_del(ifp); +- +- if_delete_update(&ifp); +- +- /* If VRF, delete the VRF structure itself. */ +- if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) +- netlink_vrf_change(h, tb[IFLA_LINKINFO], ns_id, name); ++ zlog_debug("RTM_DELLINK for %s(%u), enqueuing to zebra", ++ name, ifi->ifi_index); ++ ++ dplane_ctx_set_op(ctx, DPLANE_OP_INTF_DELETE); ++ dplane_ctx_set_status(ctx, ZEBRA_DPLANE_REQUEST_QUEUED); ++ ++ dplane_ctx_set_ifp_bond_ifindex(ctx, bond_ifindex); + } + ++ dplane_provider_enqueue_to_zebra(ctx); ++ + return 0; + } + +@@ -2111,6 +1709,13 @@ ssize_t netlink_intf_msg_encode(uint16_t cmd, + void interface_list(struct zebra_ns *zns) + { + interface_lookup_netlink(zns); ++ ++ zebra_dplane_startup_stage(zns, ZEBRA_DPLANE_INTERFACES_READ); ++} ++ ++void interface_list_second(struct zebra_ns *zns) ++{ ++ zebra_if_update_all_links(zns); + /* We add routes for interface address, + * so we need to get the nexthop info + * from the kernel before we can do that +@@ -2118,6 +1723,8 @@ void interface_list(struct zebra_ns *zns) + netlink_nexthop_read(zns); + + interface_addr_lookup_netlink(zns); ++ ++ zebra_dplane_startup_stage(zns, ZEBRA_DPLANE_ADDRESSES_READ); + } + + /** +diff --git a/zebra/interface.c b/zebra/interface.c +index a05b9690ef..bfe7a06896 100644 +--- a/zebra/interface.c ++++ b/zebra/interface.c +@@ -1298,6 +1298,9 @@ static void zebra_if_addr_update_ctx(struct zebra_dplane_ctx *ctx, + const struct prefix *addr, *dest = NULL; + enum dplane_op_e op; + ++ if (!ifp) ++ return; ++ + op = dplane_ctx_get_op(ctx); + addr = dplane_ctx_get_intf_addr(ctx); + +@@ -1416,6 +1419,13 @@ static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx, + enum dplane_netconf_status_e mpls, mcast_on, linkdown; + bool *mcast_set, *linkdown_set; + ++ if (!ifp && ifindex != -1 && ifindex != -2) { ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug("%s: Can't find ifp(%u)", __func__, ifindex); ++ ++ return; ++ } ++ + afi = dplane_ctx_get_afi(ctx); + mpls = dplane_ctx_get_netconf_mpls(ctx); + linkdown = dplane_ctx_get_netconf_linkdown(ctx); +@@ -1485,6 +1495,686 @@ static void zebra_if_netconf_update_ctx(struct zebra_dplane_ctx *ctx, + (*linkdown_set ? "ON" : "OFF")); + } + ++static void interface_vrf_change(enum dplane_op_e op, ifindex_t ifindex, ++ const char *name, uint32_t tableid, ++ ns_id_t ns_id) ++{ ++ struct vrf *vrf; ++ struct zebra_vrf *zvrf = NULL; ++ ++ if (op == DPLANE_OP_INTF_DELETE) { ++ if (IS_ZEBRA_DEBUG_DPLANE) ++ zlog_debug("DPLANE_OP_INTF_DELETE for VRF %s(%u)", name, ++ ifindex); ++ ++ vrf = vrf_lookup_by_id((vrf_id_t)ifindex); ++ if (!vrf) { ++ flog_warn(EC_ZEBRA_VRF_NOT_FOUND, ++ "%s(%u): vrf not found", name, ifindex); ++ return; ++ } ++ ++ vrf_delete(vrf); ++ } else { ++ if (IS_ZEBRA_DEBUG_DPLANE) ++ zlog_debug( ++ "DPLANE_OP_INTF_UPDATE for VRF %s(%u) table %u", ++ name, ifindex, tableid); ++ ++ if (!vrf_lookup_by_id((vrf_id_t)ifindex)) { ++ vrf_id_t exist_id; ++ ++ exist_id = zebra_vrf_lookup_by_table(tableid, ns_id); ++ if (exist_id != VRF_DEFAULT) { ++ vrf = vrf_lookup_by_id(exist_id); ++ ++ flog_err( ++ EC_ZEBRA_VRF_MISCONFIGURED, ++ "VRF %s id %u table id overlaps existing vrf %s(%d), misconfiguration exiting", ++ name, ifindex, vrf->name, vrf->vrf_id); ++ exit(-1); ++ } ++ } ++ ++ vrf = vrf_update((vrf_id_t)ifindex, name); ++ if (!vrf) { ++ flog_err(EC_LIB_INTERFACE, "VRF %s id %u not created", ++ name, ifindex); ++ return; ++ } ++ ++ /* ++ * This is the only place that we get the actual kernel table_id ++ * being used. We need it to set the table_id of the routes ++ * we are passing to the kernel.... And to throw some totally ++ * awesome parties. that too. ++ * ++ * At this point we *must* have a zvrf because the vrf_create ++ * callback creates one. We *must* set the table id ++ * before the vrf_enable because of( at the very least ) ++ * static routes being delayed for installation until ++ * during the vrf_enable callbacks. ++ */ ++ zvrf = (struct zebra_vrf *)vrf->info; ++ zvrf->table_id = tableid; ++ ++ /* Enable the created VRF. */ ++ if (!vrf_enable(vrf)) { ++ flog_err(EC_LIB_INTERFACE, ++ "Failed to enable VRF %s id %u", name, ++ ifindex); ++ return; ++ } ++ } ++} ++ ++/* ++ * Note: on netlink systems, there should be a 1-to-1 mapping ++ * between interface names and ifindex values. ++ */ ++static void set_ifindex(struct interface *ifp, ifindex_t ifi_index, ++ struct zebra_ns *zns) ++{ ++ struct interface *oifp; ++ ++ oifp = if_lookup_by_index_per_ns(zns, ifi_index); ++ if ((oifp != NULL) && (oifp != ifp)) { ++ if (ifi_index == IFINDEX_INTERNAL) ++ flog_err( ++ EC_LIB_INTERFACE, ++ "Netlink is setting interface %s ifindex to reserved internal value %u", ++ ifp->name, ifi_index); ++ else { ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "interface index %d was renamed from %s to %s", ++ ifi_index, oifp->name, ifp->name); ++ if (if_is_up(oifp)) ++ flog_err( ++ EC_LIB_INTERFACE, ++ "interface rename detected on up interface: index %d was renamed from %s to %s, results are uncertain!", ++ ifi_index, oifp->name, ifp->name); ++ if_delete_update(&oifp); ++ } ++ } ++ if_set_index(ifp, ifi_index); ++} ++ ++static inline void zebra_if_set_ziftype(struct interface *ifp, ++ enum zebra_iftype zif_type, ++ enum zebra_slave_iftype zif_slave_type) ++{ ++ struct zebra_if *zif; ++ ++ zif = (struct zebra_if *)ifp->info; ++ zif->zif_slave_type = zif_slave_type; ++ ++ if (zif->zif_type != zif_type) { ++ zif->zif_type = zif_type; ++ /* If the if_type has been set to bond initialize ES info ++ * against it. XXX - note that we don't handle the case where ++ * a zif changes from bond to non-bond; it is really ++ * an unexpected/error condition. ++ */ ++ zebra_evpn_if_init(zif); ++ } ++} ++ ++static void interface_update_hw_addr(struct zebra_dplane_ctx *ctx, ++ struct interface *ifp) ++{ ++ int i; ++ ++ ifp->hw_addr_len = dplane_ctx_get_ifp_hw_addr_len(ctx); ++ memcpy(ifp->hw_addr, dplane_ctx_get_ifp_hw_addr(ctx), ifp->hw_addr_len); ++ ++ for (i = 0; i < ifp->hw_addr_len; i++) ++ if (ifp->hw_addr[i] != 0) ++ break; ++ ++ if (i == ifp->hw_addr_len) ++ ifp->hw_addr_len = 0; ++} ++ ++static void interface_update_l2info(struct zebra_dplane_ctx *ctx, ++ struct interface *ifp, ++ enum zebra_iftype zif_type, int add, ++ ns_id_t link_nsid) ++{ ++ const struct zebra_l2info_vxlan *vxlan_info; ++ const struct zebra_l2info_gre *gre_info; ++ ++ switch (zif_type) { ++ case ZEBRA_IF_BRIDGE: ++ zebra_l2_bridge_add_update(ifp, ++ dplane_ctx_get_ifp_bridge_info(ctx)); ++ break; ++ case ZEBRA_IF_VLAN: ++ zebra_l2_vlanif_update(ifp, dplane_ctx_get_ifp_vlan_info(ctx)); ++ zebra_evpn_acc_bd_svi_set(ifp->info, NULL, ++ !!if_is_operative(ifp)); ++ break; ++ case ZEBRA_IF_VXLAN: ++ vxlan_info = dplane_ctx_get_ifp_vxlan_info(ctx); ++ zebra_l2_vxlanif_add_update(ifp, vxlan_info, add); ++ if (link_nsid != NS_UNKNOWN && vxlan_info->ifindex_link) ++ zebra_if_update_link(ifp, vxlan_info->ifindex_link, ++ link_nsid); ++ break; ++ case ZEBRA_IF_GRE: ++ gre_info = dplane_ctx_get_ifp_gre_info(ctx); ++ zebra_l2_greif_add_update(ifp, gre_info, add); ++ if (link_nsid != NS_UNKNOWN && gre_info->ifindex_link) ++ zebra_if_update_link(ifp, gre_info->ifindex_link, ++ link_nsid); ++ break; ++ case ZEBRA_IF_OTHER: ++ case ZEBRA_IF_VRF: ++ case ZEBRA_IF_MACVLAN: ++ case ZEBRA_IF_VETH: ++ case ZEBRA_IF_BOND: ++ case ZEBRA_IF_BOND_SLAVE: ++ break; ++ } ++} ++ ++static bool is_if_protodown_reason_only_frr(uint32_t rc_bitfield) ++{ ++ uint8_t frr_protodown_r_bit = if_netlink_get_frr_protodown_r_bit(); ++ ++ return (rc_bitfield == (((uint32_t)1) << frr_protodown_r_bit)); ++} ++ ++static void interface_if_protodown(struct interface *ifp, bool protodown, ++ uint32_t rc_bitfield) ++{ ++ struct zebra_if *zif = ifp->info; ++ bool old_protodown; ++ ++ /* ++ * Set our reason code to note it wasn't us. ++ * If the reason we got from the kernel is ONLY frr though, don't ++ * set it. ++ */ ++ COND_FLAG(zif->protodown_rc, ZEBRA_PROTODOWN_EXTERNAL, ++ protodown && rc_bitfield && ++ !is_if_protodown_reason_only_frr(rc_bitfield)); ++ ++ ++ old_protodown = !!ZEBRA_IF_IS_PROTODOWN(zif); ++ if (protodown == old_protodown) ++ return; ++ ++ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_DPLANE) ++ zlog_debug("interface %s dplane change, protodown %s", ++ ifp->name, protodown ? "on" : "off"); ++ ++ /* Set protodown, respectively */ ++ COND_FLAG(zif->flags, ZIF_FLAG_PROTODOWN, protodown); ++ ++ if (zebra_evpn_is_es_bond_member(ifp)) { ++ /* Check it's not already being sent to the dplane first */ ++ if (protodown && ++ CHECK_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN)) { ++ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "bond mbr %s protodown on recv'd but already sent protodown on to the dplane", ++ ifp->name); ++ return; ++ } ++ ++ if (!protodown && ++ CHECK_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN)) { ++ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "bond mbr %s protodown off recv'd but already sent protodown off to the dplane", ++ ifp->name); ++ return; ++ } ++ ++ if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "bond mbr %s reinstate protodown %s in the dplane", ++ ifp->name, old_protodown ? "on" : "off"); ++ ++ if (old_protodown) ++ SET_FLAG(zif->flags, ZIF_FLAG_SET_PROTODOWN); ++ else ++ SET_FLAG(zif->flags, ZIF_FLAG_UNSET_PROTODOWN); ++ ++ dplane_intf_update(zif->ifp); ++ } ++} ++ ++static void if_sweep_protodown(struct zebra_if *zif) ++{ ++ bool protodown; ++ ++ protodown = !!ZEBRA_IF_IS_PROTODOWN(zif); ++ ++ if (!protodown) ++ return; ++ ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug("interface %s sweeping protodown %s reason 0x%x", ++ zif->ifp->name, protodown ? "on" : "off", ++ zif->protodown_rc); ++ ++ /* Only clear our reason codes, leave external if it was set */ ++ UNSET_FLAG(zif->protodown_rc, ZEBRA_PROTODOWN_ALL); ++ dplane_intf_update(zif->ifp); ++} ++ ++static void interface_bridge_vxlan_update(struct zebra_dplane_ctx *ctx, ++ struct interface *ifp) ++{ ++ const struct zebra_dplane_bridge_vlan_info *bvinfo; ++ ++ bvinfo = dplane_ctx_get_ifp_bridge_vlan_info(ctx); ++ ++ if (!(bvinfo->flags & DPLANE_BRIDGE_VLAN_INFO_PVID)) ++ return; ++ ++ if (IS_ZEBRA_DEBUG_DPLANE) ++ zlog_debug("Access VLAN %u for VxLAN IF %s(%u)", bvinfo->vid, ++ ifp->name, ifp->ifindex); ++ ++ zebra_l2_vxlanif_update_access_vlan(ifp, bvinfo->vid); ++} ++ ++static void interface_bridge_vlan_update(struct zebra_dplane_ctx *ctx, ++ struct interface *ifp) ++{ ++ struct zebra_if *zif = ifp->info; ++ const struct zebra_dplane_bridge_vlan_info_array *bvarray; ++ struct zebra_dplane_bridge_vlan_info bvinfo; ++ bitfield_t old_vlan_bitmap; ++ uint16_t vid_range_start = 0; ++ int32_t i; ++ ++ /* cache the old bitmap addrs */ ++ old_vlan_bitmap = zif->vlan_bitmap; ++ /* create a new bitmap space for re-eval */ ++ bf_init(zif->vlan_bitmap, IF_VLAN_BITMAP_MAX); ++ ++ /* Could we have multiple bridge vlan infos? */ ++ bvarray = dplane_ctx_get_ifp_bridge_vlan_info_array(ctx); ++ if (!bvarray) ++ return; ++ ++ for (i = 0; i < bvarray->count; i++) { ++ bvinfo = bvarray->array[i]; ++ ++ if (bvinfo.flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_BEGIN) { ++ vid_range_start = bvinfo.vid; ++ continue; ++ } ++ ++ if (!(bvinfo.flags & DPLANE_BRIDGE_VLAN_INFO_RANGE_END)) ++ vid_range_start = bvinfo.vid; ++ ++ zebra_vlan_bitmap_compute(ifp, vid_range_start, bvinfo.vid); ++ } ++ ++ zebra_vlan_mbr_re_eval(ifp, old_vlan_bitmap); ++ bf_free(old_vlan_bitmap); ++} ++ ++static void interface_bridge_handling(struct zebra_dplane_ctx *ctx, ++ struct interface *ifp, ++ enum zebra_iftype zif_type) ++{ ++ struct zebra_if *zif; ++ ++ if (!ifp) { ++ zlog_warn("Cannot find bridge if %s(%u)", ++ dplane_ctx_get_ifname(ctx), ++ dplane_ctx_get_ifindex(ctx)); ++ return; ++ } ++ ++ if (IS_ZEBRA_IF_VXLAN(ifp)) ++ return interface_bridge_vxlan_update(ctx, ifp); ++ ++ /* ++ * build vlan bitmap associated with this interface if that ++ * device type is interested in the vlans ++ */ ++ zif = ifp->info; ++ if (bf_is_inited(zif->vlan_bitmap)) ++ interface_bridge_vlan_update(ctx, ifp); ++} ++ ++static void zebra_if_dplane_ifp_handling(struct zebra_dplane_ctx *ctx) ++{ ++ enum dplane_op_e op = dplane_ctx_get_op(ctx); ++ const char *name = dplane_ctx_get_ifname(ctx); ++ ns_id_t ns_id = dplane_ctx_get_ns_id(ctx); ++ ifindex_t ifindex = dplane_ctx_get_ifindex(ctx); ++ ifindex_t bond_ifindex = dplane_ctx_get_ifp_bond_ifindex(ctx); ++ uint32_t tableid = dplane_ctx_get_ifp_table_id(ctx); ++ enum zebra_iftype zif_type = dplane_ctx_get_ifp_zif_type(ctx); ++ struct interface *ifp; ++ struct zebra_ns *zns; ++ ++ zns = zebra_ns_lookup(ns_id); ++ if (!zns) { ++ zlog_err("Where is our namespace?"); ++ return; ++ } ++ ++ if (IS_ZEBRA_DEBUG_DPLANE) ++ zlog_debug("%s for %s(%u)", dplane_op2str(op), name, ifindex); ++ ++ ifp = if_lookup_by_name_per_ns(zns, name); ++ if (op == DPLANE_OP_INTF_DELETE) { ++ /* Delete interface notification from kernel */ ++ if (ifp == NULL) { ++ if (IS_ZEBRA_DEBUG_EVENT) ++ zlog_debug( ++ "Delete LINK received for unknown interface %s(%u)", ++ name, ifindex); ++ return; ++ } ++ ++ if (IS_ZEBRA_IF_BOND(ifp)) ++ zebra_l2if_update_bond(ifp, false); ++ if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) ++ zebra_l2if_update_bond_slave(ifp, bond_ifindex, false); ++ /* Special handling for bridge or VxLAN interfaces. */ ++ if (IS_ZEBRA_IF_BRIDGE(ifp)) ++ zebra_l2_bridge_del(ifp); ++ else if (IS_ZEBRA_IF_VXLAN(ifp)) ++ zebra_l2_vxlanif_del(ifp); ++ ++ if_delete_update(&ifp); ++ ++ if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) ++ interface_vrf_change(op, ifindex, name, tableid, ns_id); ++ } else { ++ ifindex_t master_ifindex, bridge_ifindex, bond_ifindex, ++ link_ifindex; ++ enum zebra_slave_iftype zif_slave_type; ++ uint8_t bypass; ++ uint64_t flags; ++ vrf_id_t vrf_id; ++ uint32_t mtu; ++ ns_id_t link_nsid; ++ struct zebra_if *zif; ++ bool protodown, protodown_set, startup; ++ uint32_t rc_bitfield; ++ uint8_t old_hw_addr[INTERFACE_HWADDR_MAX]; ++ char *desc; ++ uint8_t family; ++ ++ /* If VRF, create or update the VRF structure itself. */ ++ if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns()) ++ interface_vrf_change(op, ifindex, name, tableid, ns_id); ++ ++ master_ifindex = dplane_ctx_get_ifp_master_ifindex(ctx); ++ zif_slave_type = dplane_ctx_get_ifp_zif_slave_type(ctx); ++ bridge_ifindex = dplane_ctx_get_ifp_bridge_ifindex(ctx); ++ bond_ifindex = dplane_ctx_get_ifp_bond_ifindex(ctx); ++ bypass = dplane_ctx_get_ifp_bypass(ctx); ++ flags = dplane_ctx_get_ifp_flags(ctx); ++ vrf_id = dplane_ctx_get_ifp_vrf_id(ctx); ++ mtu = dplane_ctx_get_ifp_mtu(ctx); ++ link_ifindex = dplane_ctx_get_ifp_link_ifindex(ctx); ++ link_nsid = dplane_ctx_get_ifp_link_nsid(ctx); ++ protodown_set = dplane_ctx_get_ifp_protodown_set(ctx); ++ protodown = dplane_ctx_get_ifp_protodown(ctx); ++ rc_bitfield = dplane_ctx_get_ifp_rc_bitfield(ctx); ++ startup = dplane_ctx_get_ifp_startup(ctx); ++ desc = dplane_ctx_get_ifp_desc(ctx); ++ family = dplane_ctx_get_ifp_family(ctx); ++ ++#ifndef AF_BRIDGE ++ /* ++ * Work around to make free bsd happy at the moment ++ */ ++#define AF_BRIDGE 7 ++#endif ++ if (family == AF_BRIDGE) ++ return interface_bridge_handling(ctx, ifp, zif_type); ++ ++ if (ifp == NULL || ++ !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE)) { ++ /* Add interface notification from kernel */ ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d sl_type %d master %u", ++ name, ifindex, vrf_id, zif_type, ++ zif_slave_type, master_ifindex); ++ ++ if (ifp == NULL) { ++ /* unknown interface */ ++ ifp = if_get_by_name(name, vrf_id, NULL); ++ } else { ++ /* pre-configured interface, learnt now */ ++ if (ifp->vrf->vrf_id != vrf_id) ++ if_update_to_new_vrf(ifp, vrf_id); ++ } ++ ++ /* Update interface information. */ ++ set_ifindex(ifp, ifindex, zns); ++ ifp->flags = flags; ++ ifp->mtu6 = ifp->mtu = mtu; ++ ifp->metric = 0; ++ ifp->speed = kernel_get_speed(ifp, NULL); ++ ifp->ptm_status = ZEBRA_PTM_STATUS_UNKNOWN; ++ ++ /* Set interface type */ ++ zebra_if_set_ziftype(ifp, zif_type, zif_slave_type); ++ if (IS_ZEBRA_IF_VRF(ifp)) ++ SET_FLAG(ifp->status, ++ ZEBRA_INTERFACE_VRF_LOOPBACK); ++ ++ /* Update link. */ ++ zebra_if_update_link(ifp, link_ifindex, link_nsid); ++ ++ /* ++ * Just set the @link/lower-device ifindex. During ++ * nldump interfaces are not ordered in any fashion so ++ * we may end up getting upper devices before lower ++ * devices. We will setup the real linkage once the dump ++ * is complete. ++ */ ++ zif = (struct zebra_if *)ifp->info; ++ zif->link_ifindex = link_ifindex; ++ ++ ifp->ll_type = dplane_ctx_get_ifp_zltype(ctx); ++ interface_update_hw_addr(ctx, ifp); ++ ++ /* Inform clients, install any configured addresses. */ ++ if_add_update(ifp); ++ ++ /* ++ * Extract and save L2 interface information, take ++ * additional actions. ++ */ ++ interface_update_l2info(ctx, ifp, zif_type, 1, ++ link_nsid); ++ if (IS_ZEBRA_IF_BOND(ifp)) ++ zebra_l2if_update_bond(ifp, true); ++ if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)) ++ zebra_l2if_update_bridge_slave( ++ ifp, bridge_ifindex, ns_id, ++ ZEBRA_BRIDGE_NO_ACTION); ++ else if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) ++ zebra_l2if_update_bond_slave(ifp, bond_ifindex, ++ !!bypass); ++ ++ if (protodown_set) { ++ interface_if_protodown(ifp, protodown, ++ rc_bitfield); ++ if (startup) ++ if_sweep_protodown(zif); ++ } ++ ++ if (IS_ZEBRA_IF_BRIDGE(ifp)) { ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "RTM_NEWLINK ADD for %s(%u), vlan-aware %d", ++ name, ifp->ifindex, ++ IS_ZEBRA_IF_BRIDGE_VLAN_AWARE( ++ zif)); ++ } ++ } else if (ifp->vrf->vrf_id != vrf_id) { ++ /* VRF change for an interface. */ ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "RTM_NEWLINK vrf-change for %s(%u) vrf_id %u -> %u", ++ name, ifp->ifindex, ifp->vrf->vrf_id, ++ vrf_id); ++ ++ if_handle_vrf_change(ifp, vrf_id); ++ } else { ++ bool was_bridge_slave, was_bond_slave; ++ uint8_t chgflags = ZEBRA_BRIDGE_NO_ACTION; ++ ++ zif = ifp->info; ++ ++ /* Interface update. */ ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "RTM_NEWLINK update for %s(%u) sl_type %d master %u", ++ name, ifp->ifindex, zif_slave_type, ++ master_ifindex); ++ ++ set_ifindex(ifp, ifindex, zns); ++ ifp->mtu6 = ifp->mtu = mtu; ++ ifp->metric = 0; ++ ++ /* ++ * Update interface type - NOTE: Only slave_type can ++ * change. ++ */ ++ was_bridge_slave = IS_ZEBRA_IF_BRIDGE_SLAVE(ifp); ++ was_bond_slave = IS_ZEBRA_IF_BOND_SLAVE(ifp); ++ zebra_if_set_ziftype(ifp, zif_type, zif_slave_type); ++ ++ memcpy(old_hw_addr, ifp->hw_addr, INTERFACE_HWADDR_MAX); ++ ++ /* Update link. */ ++ zebra_if_update_link(ifp, link_ifindex, link_nsid); ++ ++ ifp->ll_type = dplane_ctx_get_ifp_zltype(ctx); ++ interface_update_hw_addr(ctx, ifp); ++ ++ if (protodown_set) ++ interface_if_protodown(ifp, protodown, ++ rc_bitfield); ++ ++ if (if_is_no_ptm_operative(ifp)) { ++ bool is_up = if_is_operative(ifp); ++ ++ ifp->flags = flags; ++ if (!if_is_no_ptm_operative(ifp) || ++ CHECK_FLAG(zif->flags, ++ ZIF_FLAG_PROTODOWN)) { ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "Intf %s(%u) has gone DOWN", ++ name, ifp->ifindex); ++ if_down(ifp); ++ rib_update(RIB_UPDATE_KERNEL); ++ } else if (if_is_operative(ifp)) { ++ bool mac_updated = false; ++ ++ /* ++ * Must notify client daemons of new ++ * interface status. ++ */ ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "Intf %s(%u) PTM up, notifying clients", ++ name, ifp->ifindex); ++ if_up(ifp, !is_up); ++ ++ /* ++ * Update EVPN VNI when SVI MAC change ++ */ ++ if (memcmp(old_hw_addr, ifp->hw_addr, ++ INTERFACE_HWADDR_MAX)) ++ mac_updated = true; ++ if (IS_ZEBRA_IF_VLAN(ifp) && ++ mac_updated) { ++ struct interface *link_if; ++ ++ link_if = if_lookup_by_index_per_ns( ++ zebra_ns_lookup( ++ NS_DEFAULT), ++ link_ifindex); ++ if (link_if) ++ zebra_vxlan_svi_up( ++ ifp, link_if); ++ } else if (mac_updated && ++ IS_ZEBRA_IF_BRIDGE(ifp)) { ++ zlog_debug( ++ "Intf %s(%u) bridge changed MAC address", ++ name, ifp->ifindex); ++ chgflags = ++ ZEBRA_BRIDGE_MASTER_MAC_CHANGE; ++ } ++ } ++ } else { ++ ifp->flags = flags; ++ if (if_is_operative(ifp) && ++ !CHECK_FLAG(zif->flags, ++ ZIF_FLAG_PROTODOWN)) { ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "Intf %s(%u) has come UP", ++ name, ifp->ifindex); ++ if_up(ifp, true); ++ if (IS_ZEBRA_IF_BRIDGE(ifp)) ++ chgflags = ++ ZEBRA_BRIDGE_MASTER_UP; ++ } else { ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "Intf %s(%u) has gone DOWN", ++ name, ifp->ifindex); ++ if_down(ifp); ++ rib_update(RIB_UPDATE_KERNEL); ++ } ++ } ++ ++ /* ++ * Extract and save L2 interface information, take ++ * additional actions. ++ */ ++ interface_update_l2info(ctx, ifp, zif_type, 0, ++ link_nsid); ++ if (IS_ZEBRA_IF_BRIDGE(ifp)) ++ zebra_l2if_update_bridge(ifp, chgflags); ++ if (IS_ZEBRA_IF_BOND(ifp)) ++ zebra_l2if_update_bond(ifp, true); ++ if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave) ++ zebra_l2if_update_bridge_slave( ++ ifp, bridge_ifindex, ns_id, chgflags); ++ else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave) ++ zebra_l2if_update_bond_slave(ifp, bond_ifindex, ++ !!bypass); ++ if (IS_ZEBRA_IF_BRIDGE(ifp)) { ++ if (IS_ZEBRA_DEBUG_KERNEL) ++ zlog_debug( ++ "RTM_NEWLINK update for %s(%u), vlan-aware %d", ++ name, ifp->ifindex, ++ IS_ZEBRA_IF_BRIDGE_VLAN_AWARE( ++ zif)); ++ } ++ } ++ ++ zif = ifp->info; ++ if (zif) { ++ XFREE(MTYPE_ZIF_DESC, zif->desc); ++ if (desc[0]) ++ zif->desc = XSTRDUP(MTYPE_ZIF_DESC, desc); ++ } ++ } ++} ++ + void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx) + { + struct zebra_ns *zns; +@@ -1514,17 +2204,6 @@ void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx) + } + + ifp = if_lookup_by_index_per_ns(zns, ifindex); +- if (ifp == NULL) { +- if (op != DPLANE_OP_INTF_NETCONFIG || +- (ifindex != -1 && ifindex != -2)) { +- if (IS_ZEBRA_DEBUG_KERNEL) +- zlog_debug( +- "%s: can't find ifp at nsid %u index %d", +- __func__, ns_id, ifindex); +- +- return; +- } +- } + + switch (op) { + case DPLANE_OP_INTF_ADDR_ADD: +@@ -1535,7 +2214,15 @@ void zebra_if_dplane_result(struct zebra_dplane_ctx *ctx) + case DPLANE_OP_INTF_INSTALL: + case DPLANE_OP_INTF_UPDATE: + case DPLANE_OP_INTF_DELETE: +- zebra_if_update_ctx(ctx, ifp); ++ /* ++ * Queued from the dplane means it is something ++ * that we need to handle( create/delete the ++ * interface as needed ) ++ */ ++ if (dp_res == ZEBRA_DPLANE_REQUEST_QUEUED) ++ zebra_if_dplane_ifp_handling(ctx); ++ else ++ zebra_if_update_ctx(ctx, ifp); + break; + + case DPLANE_OP_INTF_NETCONFIG: +diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c +index 4cd84cada2..3756a4ab0c 100644 +--- a/zebra/kernel_netlink.c ++++ b/zebra/kernel_netlink.c +@@ -410,7 +410,7 @@ static int netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id, + case RTM_NEWLINK: + return netlink_link_change(h, ns_id, startup); + case RTM_DELLINK: +- return netlink_link_change(h, ns_id, startup); ++ return 0; + case RTM_NEWNEIGH: + case RTM_DELNEIGH: + case RTM_GETNEIGH: +@@ -482,6 +482,7 @@ static int dplane_netlink_information_fetch(struct nlmsghdr *h, ns_id_t ns_id, + + case RTM_NEWLINK: + case RTM_DELLINK: ++ return netlink_link_change(h, ns_id, startup); + + default: + break; +@@ -1170,7 +1171,6 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int), + h->nlmsg_type, h->nlmsg_len, + h->nlmsg_seq, h->nlmsg_pid); + +- + /* + * Ignore messages that maybe sent from + * other actors besides the kernel +@@ -1774,17 +1774,11 @@ void kernel_init(struct zebra_ns *zns) + * lead to confusion, so we need to convert the + * RTNLGRP_XXX to a bit position for ourself + */ +- groups = RTMGRP_LINK | +- RTMGRP_IPV4_ROUTE | +- RTMGRP_IPV4_IFADDR | +- RTMGRP_IPV6_ROUTE | +- RTMGRP_IPV6_IFADDR | +- RTMGRP_IPV4_MROUTE | +- RTMGRP_NEIGH | +- ((uint32_t) 1 << (RTNLGRP_IPV4_RULE - 1)) | +- ((uint32_t) 1 << (RTNLGRP_IPV6_RULE - 1)) | +- ((uint32_t) 1 << (RTNLGRP_NEXTHOP - 1)) | +- ((uint32_t) 1 << (RTNLGRP_TC - 1)); ++ groups = RTMGRP_IPV4_ROUTE | RTMGRP_IPV6_ROUTE | RTMGRP_IPV4_MROUTE | ++ RTMGRP_NEIGH | ((uint32_t)1 << (RTNLGRP_IPV4_RULE - 1)) | ++ ((uint32_t)1 << (RTNLGRP_IPV6_RULE - 1)) | ++ ((uint32_t)1 << (RTNLGRP_NEXTHOP - 1)) | ++ ((uint32_t)1 << (RTNLGRP_TC - 1)); + + dplane_groups = (RTMGRP_LINK | + RTMGRP_IPV4_IFADDR | +diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c +index f3462b9f22..98553edae6 100644 +--- a/zebra/kernel_socket.c ++++ b/zebra/kernel_socket.c +@@ -1482,6 +1482,14 @@ static void routing_socket(struct zebra_ns *zns) + thread_add_read(zrouter.master, kernel_read, NULL, routing_sock, NULL); + } + ++void interface_list_second(struct zebra_ns *zns) ++{ ++} ++ ++void interface_list_tunneldump(struct zebra_ns *zns) ++{ ++} ++ + /* Exported interface function. This function simply calls + routing_socket (). */ + void kernel_init(struct zebra_ns *zns) +diff --git a/zebra/rt.h b/zebra/rt.h +index 6f4dd48a54..3e91cdfffa 100644 +--- a/zebra/rt.h ++++ b/zebra/rt.h +@@ -99,6 +99,8 @@ extern int kernel_get_ipmr_sg_stats(struct zebra_vrf *zvrf, void *mroute); + * state. + */ + extern void interface_list(struct zebra_ns *zns); ++extern void interface_list_tunneldump(struct zebra_ns *zns); ++extern void interface_list_second(struct zebra_ns *zns); + extern void kernel_init(struct zebra_ns *zns); + extern void kernel_terminate(struct zebra_ns *zns, bool complete); + extern void macfdb_read(struct zebra_ns *zns); +diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c +index 135f065428..4cc4281c1e 100644 +--- a/zebra/rule_netlink.c ++++ b/zebra/rule_netlink.c +@@ -416,6 +416,7 @@ int netlink_rules_read(struct zebra_ns *zns) + + ret = netlink_parse_info(netlink_rule_change, &zns->netlink_cmd, + &dp_info, 0, true); ++ + return ret; + } + +diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h +index c10482ed96..9f9496c8f4 100644 +--- a/zebra/zebra_dplane.h ++++ b/zebra/zebra_dplane.h +@@ -422,6 +422,19 @@ uint8_t dplane_ctx_get_ifp_family(const struct zebra_dplane_ctx *ctx); + struct zebra_vxlan_vni_array; + void dplane_ctx_set_ifp_vxlan_vni_array(struct zebra_dplane_ctx *ctx, + struct zebra_vxlan_vni_array *vniarray); ++ ++/* ++ * These defines mirror the values for bridge values in linux ++ * at this point since we only have a linux implementation ++ * we don't need to do any type of translation. Let's just ++ * pass these through and use them ++ */ ++#define DPLANE_BRIDGE_VLAN_INFO_PVID \ ++ (1 << 1) /* VLAN is PVID, ingress untagged */ ++#define DPLANE_BRIDGE_VLAN_INFO_RANGE_BEGIN \ ++ (1 << 3) /* VLAN is start of vlan range */ ++#define DPLANE_BRIDGE_VLAN_INFO_RANGE_END \ ++ (1 << 4) /* VLAN is end of vlan range */ + const struct zebra_vxlan_vni_array * + dplane_ctx_get_ifp_vxlan_vni_array(const struct zebra_dplane_ctx *ctx); + struct zebra_dplane_bridge_vlan_info { +diff --git a/zebra/zebra_l2.c b/zebra/zebra_l2.c +index 07bbc6e3bc..4ad262a21d 100644 +--- a/zebra/zebra_l2.c ++++ b/zebra/zebra_l2.c +@@ -258,7 +258,7 @@ void zebra_l2if_update_bond(struct interface *ifp, bool add) + * map slaves (if any) to the bridge. + */ + void zebra_l2_bridge_add_update(struct interface *ifp, +- struct zebra_l2info_bridge *bridge_info) ++ const struct zebra_l2info_bridge *bridge_info) + { + struct zebra_if *zif; + +@@ -293,7 +293,7 @@ void zebra_l2if_update_bridge(struct interface *ifp, uint8_t chgflags) + * VLAN Id and this cannot change. + */ + void zebra_l2_vlanif_update(struct interface *ifp, +- struct zebra_l2info_vlan *vlan_info) ++ const struct zebra_l2info_vlan *vlan_info) + { + struct zebra_if *zif; + +@@ -310,7 +310,7 @@ void zebra_l2_vlanif_update(struct interface *ifp, + * clients about GRE information. + */ + void zebra_l2_greif_add_update(struct interface *ifp, +- struct zebra_l2info_gre *gre_info, int add) ++ const struct zebra_l2info_gre *gre_info, int add) + { + struct zebra_if *zif; + struct in_addr old_vtep_ip; +@@ -337,7 +337,8 @@ void zebra_l2_greif_add_update(struct interface *ifp, + * IP and VLAN mapping, but the latter is handled separately. + */ + void zebra_l2_vxlanif_add_update(struct interface *ifp, +- struct zebra_l2info_vxlan *vxlan_info, int add) ++ const struct zebra_l2info_vxlan *vxlan_info, ++ int add) + { + struct zebra_if *zif; + struct in_addr old_vtep_ip; +diff --git a/zebra/zebra_l2.h b/zebra/zebra_l2.h +index 8fef008f52..e3c5544f8f 100644 +--- a/zebra/zebra_l2.h ++++ b/zebra/zebra_l2.h +@@ -71,6 +71,18 @@ struct zebra_l2info_gre { + ns_id_t link_nsid; + }; + ++struct zebra_vxlan_vni { ++ vni_t vni; /* VNI */ ++ vlanid_t access_vlan; /* Access VLAN - for VLAN-aware bridge. */ ++ struct in_addr mcast_grp; ++ uint16_t flags; ++}; ++ ++struct zebra_vxlan_vni_array { ++ uint16_t count; ++ struct zebra_vxlan_vni vnis[0]; ++}; ++ + /* zebra L2 interface information - VXLAN interface */ + struct zebra_l2info_vxlan { + vni_t vni; /* VNI */ +@@ -108,17 +120,19 @@ extern void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave, + struct zebra_ns *zns); + extern void + zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave); +-extern void zebra_l2_bridge_add_update(struct interface *ifp, +- struct zebra_l2info_bridge *bridge_info); ++extern void ++zebra_l2_bridge_add_update(struct interface *ifp, ++ const struct zebra_l2info_bridge *bridge_info); + extern void zebra_l2_bridge_del(struct interface *ifp); + extern void zebra_l2_vlanif_update(struct interface *ifp, +- struct zebra_l2info_vlan *vlan_info); ++ const struct zebra_l2info_vlan *vlan_info); + extern void zebra_l2_greif_add_update(struct interface *ifp, +- struct zebra_l2info_gre *vxlan_info, ++ const struct zebra_l2info_gre *vxlan_info, + int add); +-extern void zebra_l2_vxlanif_add_update(struct interface *ifp, +- struct zebra_l2info_vxlan *vxlan_info, +- int add); ++extern void ++zebra_l2_vxlanif_add_update(struct interface *ifp, ++ const struct zebra_l2info_vxlan *vxlan_info, ++ int add); + extern void zebra_l2_vxlanif_update_access_vlan(struct interface *ifp, + vlanid_t access_vlan); + extern void zebra_l2_greif_del(struct interface *ifp); +diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c +index 7b076b8a4a..4714cdbff8 100644 +--- a/zebra/zebra_ns.c ++++ b/zebra/zebra_ns.c +@@ -38,6 +38,7 @@ + #include "rib.h" + #include "table_manager.h" + #include "zebra_errors.h" ++#include "zebra_dplane.h" + + extern struct zebra_privs_t zserv_privs; + +@@ -116,6 +117,35 @@ int zebra_ns_disabled(struct ns *ns) + return zebra_ns_disable_internal(zns, true); + } + ++void zebra_ns_startup_continue(struct zebra_dplane_ctx *ctx) ++{ ++ struct zebra_ns *zns = zebra_ns_lookup(dplane_ctx_get_ns_id(ctx)); ++ enum zebra_dplane_startup_notifications spot; ++ ++ if (!zns) { ++ zlog_err("%s: No Namespace associated with %u", __func__, ++ dplane_ctx_get_ns_id(ctx)); ++ return; ++ } ++ ++ spot = dplane_ctx_get_startup_spot(ctx); ++ ++ switch (spot) { ++ case ZEBRA_DPLANE_INTERFACES_READ: ++ interface_list_tunneldump(zns); ++ break; ++ case ZEBRA_DPLANE_TUNNELS_READ: ++ interface_list_second(zns); ++ break; ++ case ZEBRA_DPLANE_ADDRESSES_READ: ++ route_read(zns); ++ ++ kernel_read_pbr_rules(zns); ++ kernel_read_tc_qdisc(zns); ++ break; ++ } ++} ++ + /* Do global enable actions - open sockets, read kernel config etc. */ + int zebra_ns_enable(ns_id_t ns_id, void **info) + { +@@ -126,9 +156,6 @@ int zebra_ns_enable(ns_id_t ns_id, void **info) + kernel_init(zns); + zebra_dplane_ns_enable(zns, true); + interface_list(zns); +- route_read(zns); +- kernel_read_pbr_rules(zns); +- kernel_read_tc_qdisc(zns); + + return 0; + } +diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h +index 7a0ffbc1ee..3d7d96c83f 100644 +--- a/zebra/zebra_ns.h ++++ b/zebra/zebra_ns.h +@@ -83,6 +83,8 @@ int zebra_ns_final_shutdown(struct ns *ns, + void **param_out __attribute__((unused))); + int zebra_ns_config_write(struct vty *vty, struct ns *ns); + ++void zebra_ns_startup_continue(struct zebra_dplane_ctx *ctx); ++ + #ifdef __cplusplus + } + #endif +diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c +index 201fc761ae..fd6df441c6 100644 +--- a/zebra/zebra_rib.c ++++ b/zebra/zebra_rib.c +@@ -4770,7 +4770,9 @@ static void rib_process_dplane_results(struct thread *thread) + case DPLANE_OP_NEIGH_TABLE_UPDATE: + case DPLANE_OP_GRE_SET: + case DPLANE_OP_NONE: ++ break; + case DPLANE_OP_STARTUP_STAGE: ++ zebra_ns_startup_continue(ctx); + break; + + } /* Dispatch by op code */ +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0019-zebra-Abstract-dplane_ctx_route_init-to-init-route-w.patch b/src/sonic-frr/patch/0019-zebra-Abstract-dplane_ctx_route_init-to-init-route-w.patch new file mode 100644 index 000000000000..583609209e71 --- /dev/null +++ b/src/sonic-frr/patch/0019-zebra-Abstract-dplane_ctx_route_init-to-init-route-w.patch @@ -0,0 +1,74 @@ +From 6fe32f784f57b4f10b96c9cdb938bf5ebf097fa2 Mon Sep 17 00:00:00 2001 +From: Carmine Scarpitta +Date: Fri, 7 Jul 2023 02:55:18 +0200 +Subject: [PATCH 1/2] zebra: Abstract `dplane_ctx_route_init` to init route + without copying + +The function `dplane_ctx_route_init` initializes a dplane route context +from the route object passed as an argument. Let's abstract this +function to allow initializing the dplane route context without actually +copying a route object. + +This allows us to use this function for initializing a dplane route +context when we don't have any route to copy in it. + +Signed-off-by: Carmine Scarpitta + +diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c +index 83a38c2199..ae87e4f8b6 100644 +--- a/zebra/zebra_dplane.c ++++ b/zebra/zebra_dplane.c +@@ -3257,7 +3257,7 @@ int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx, + { + int ret = EINVAL; + +- if (!ctx || !re) ++ if (!ctx) + return ret; + + dplane_intf_extra_list_init(&ctx->u.rinfo.intf_extra_list); +@@ -3265,6 +3265,13 @@ int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx, + ctx->zd_op = op; + ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS; + ++ /* This function may be called to create/init a dplane context, not ++ * necessarily to copy a route object. Let's return if there is no route ++ * object to copy. ++ */ ++ if (!re) ++ return AOK; ++ + ctx->u.rinfo.zd_type = re->type; + ctx->u.rinfo.zd_old_type = re->type; + +@@ -3296,6 +3303,8 @@ int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx, + + /* + * Initialize a context block for a route update from zebra data structs. ++ * If the `rn` or `re` parameters are NULL, this function only initializes the ++ * dplane context without copying a route object into it. + */ + int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, + struct route_node *rn, struct route_entry *re) +@@ -3312,9 +3321,17 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, + const struct interface *ifp; + struct dplane_intf_extra *if_extra; + +- if (!ctx || !rn || !re) ++ if (!ctx) + return ret; + ++ /* ++ * Initialize the dplane context and return, if there is no route ++ * object to copy ++ */ ++ if (!re || !rn) ++ return dplane_ctx_route_init_basic(ctx, op, NULL, NULL, NULL, ++ AFI_UNSPEC, SAFI_UNSPEC); ++ + /* + * Let's grab the data from the route_node + * so that we can call a helper function +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0019-zebra-Rearrange-dplane_ctx_route_init.patch b/src/sonic-frr/patch/0019-zebra-Rearrange-dplane_ctx_route_init.patch deleted file mode 100755 index 5e76f7abdb68..000000000000 --- a/src/sonic-frr/patch/0019-zebra-Rearrange-dplane_ctx_route_init.patch +++ /dev/null @@ -1,135 +0,0 @@ -From 1ecc146b19ea78a34fc5cba08d55aca72527d7c3 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Mon, 3 Oct 2022 13:22:22 -0400 -Subject: [PATCH 5/8] zebra: Rearrange dplane_ctx_route_init - -In order for a future commit to abstract the dplane_ctx_route_init -so that the kernel can use it, let's move some stuff around -and add a dplane_ctx_route_init_basic that can be used by multiple -different paths - -Signed-off-by: Donald Sharp - -create a dplane_ctx_route_init_basic so it can be used - -Signed-off-by: Donald Sharp ---- - zebra/zebra_dplane.c | 64 +++++++++++++++++++++++++++++--------------- - zebra/zebra_dplane.h | 6 +++++ - 2 files changed, 49 insertions(+), 21 deletions(-) - -diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c -index 5d94e1a0b..05f9c2e08 100644 ---- a/zebra/zebra_dplane.c -+++ b/zebra/zebra_dplane.c -@@ -2334,25 +2334,16 @@ static int dplane_ctx_ns_init(struct zebra_dplane_ctx *ctx, - return AOK; - } - --/* -- * Initialize a context block for a route update from zebra data structs. -- */ --int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, -- struct route_node *rn, struct route_entry *re) -+int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx, -+ enum dplane_op_e op, struct route_entry *re, -+ const struct prefix *p, -+ const struct prefix *src_p, afi_t afi, -+ safi_t safi) - { - int ret = EINVAL; -- const struct route_table *table = NULL; -- const struct rib_table_info *info; -- const struct prefix *p, *src_p; -- struct zebra_ns *zns; -- struct zebra_vrf *zvrf; -- struct nexthop *nexthop; -- struct zebra_l3vni *zl3vni; -- const struct interface *ifp; -- struct dplane_intf_extra *if_extra; - -- if (!ctx || !rn || !re) -- goto done; -+ if (!ctx || !re) -+ return ret; - - TAILQ_INIT(&ctx->u.rinfo.intf_extra_q); - -@@ -2362,9 +2353,6 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, - ctx->u.rinfo.zd_type = re->type; - ctx->u.rinfo.zd_old_type = re->type; - -- /* Prefixes: dest, and optional source */ -- srcdest_rnode_prefixes(rn, &p, &src_p); -- - prefix_copy(&(ctx->u.rinfo.zd_dest), p); - - if (src_p) -@@ -2385,11 +2373,45 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, - ctx->u.rinfo.zd_old_tag = re->tag; - ctx->u.rinfo.zd_distance = re->distance; - -+ ctx->u.rinfo.zd_afi = afi; -+ ctx->u.rinfo.zd_safi = safi; -+ -+ return AOK; -+} -+ -+/* -+ * Initialize a context block for a route update from zebra data structs. -+ */ -+int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, -+ struct route_node *rn, struct route_entry *re) -+{ -+ int ret = EINVAL; -+ const struct route_table *table = NULL; -+ const struct rib_table_info *info; -+ const struct prefix *p, *src_p; -+ struct zebra_ns *zns; -+ struct zebra_vrf *zvrf; -+ struct nexthop *nexthop; -+ struct zebra_l3vni *zl3vni; -+ const struct interface *ifp; -+ struct dplane_intf_extra *if_extra; -+ -+ if (!ctx || !rn || !re) -+ return ret; -+ -+ /* -+ * Let's grab the data from the route_node -+ * so that we can call a helper function -+ */ -+ -+ /* Prefixes: dest, and optional source */ -+ srcdest_rnode_prefixes(rn, &p, &src_p); - table = srcdest_rnode_table(rn); - info = table->info; - -- ctx->u.rinfo.zd_afi = info->afi; -- ctx->u.rinfo.zd_safi = info->safi; -+ if (dplane_ctx_route_init_basic(ctx, op, re, p, src_p, info->afi, -+ info->safi) != AOK) -+ return ret; - - /* Copy nexthops; recursive info is included too */ - copy_nexthops(&(ctx->u.rinfo.zd_ng.nexthop), -diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h -index 3210137c0..9d7502828 100644 ---- a/zebra/zebra_dplane.h -+++ b/zebra/zebra_dplane.h -@@ -774,6 +774,12 @@ dplane_pbr_ipset_entry_delete(struct zebra_pbr_ipset_entry *ipset); - int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, - struct route_node *rn, struct route_entry *re); - -+int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx, -+ enum dplane_op_e op, struct route_entry *re, -+ const struct prefix *p, -+ const struct prefix *src_p, afi_t afi, -+ safi_t safi); -+ - /* Encode next hop information into data plane context. */ - int dplane_ctx_nexthop_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, - struct nhg_hash_entry *nhe); --- -2.30.2 - diff --git a/src/sonic-frr/patch/0020-zebra-Add-ctx-to-netlink-message-parsing.patch b/src/sonic-frr/patch/0020-zebra-Add-ctx-to-netlink-message-parsing.patch deleted file mode 100755 index 9c1dd6ac5f76..000000000000 --- a/src/sonic-frr/patch/0020-zebra-Add-ctx-to-netlink-message-parsing.patch +++ /dev/null @@ -1,155 +0,0 @@ -From aebf87ce244c5189cec686ddf1278ae343807a53 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Tue, 4 Oct 2022 15:41:36 -0400 -Subject: [PATCH 6/8] zebra: Add ctx to netlink message parsing - -Add the initial step of passing in a dplane context -to reading route netlink messages. This code -will be run in two contexts: - -a) The normal pthread for reading netlink messages from -the kernel -b) The dplane_fpm_nl pthread. - -The goal of this commit is too just allow a) to work -b) will be filled in in the future. Effectively -everything should still be working as it should -pre this change. We will just possibly allow -the passing of the context around( but not used ) - -Signed-off-by: Donald Sharp ---- - zebra/rt_netlink.c | 31 +++++++++++++++++++++++-------- - zebra/rt_netlink.h | 4 ++++ - zebra/zebra_dplane.c | 11 +++++++++++ - zebra/zebra_dplane.h | 10 ++++++++++ - 4 files changed, 48 insertions(+), 8 deletions(-) - -diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c -index 24c01b7f5..b2df2cd8a 100644 ---- a/zebra/rt_netlink.c -+++ b/zebra/rt_netlink.c -@@ -667,8 +667,9 @@ static uint8_t parse_multipath_nexthops_unicast(ns_id_t ns_id, - } - - /* Looking up routing table by netlink interface. */ --static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, -- int startup) -+int netlink_route_change_read_unicast_internal(struct nlmsghdr *h, -+ ns_id_t ns_id, int startup, -+ struct zebra_dplane_ctx *ctx) - { - int len; - struct rtmsg *rtm; -@@ -740,9 +741,8 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, - - selfroute = is_selfroute(rtm->rtm_protocol); - -- if (!startup && selfroute -- && h->nlmsg_type == RTM_NEWROUTE -- && !zrouter.asic_offloaded) { -+ if (!startup && selfroute && h->nlmsg_type == RTM_NEWROUTE && -+ !zrouter.asic_offloaded && !ctx) { - if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("Route type: %d Received that we think we have originated, ignoring", - rtm->rtm_protocol); -@@ -963,12 +963,20 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, - } - - if (nhe_id || ng) -- rib_add_multipath(afi, SAFI_UNICAST, &p, -- &src_p, re, ng); -+ dplane_rib_add_multipath(afi, SAFI_UNICAST, &p, -+ &src_p, re, ng, -+ startup, ctx); - else - XFREE(MTYPE_RE, re); - } - } else { -+ if (ctx) { -+ zlog_err( -+ "%s: %pFX RTM_DELROUTE received but received a context as well", -+ __func__, &p); -+ return 0; -+ } -+ - if (nhe_id) { - rib_delete(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, - &p, &src_p, NULL, nhe_id, table, metric, -@@ -993,7 +1001,14 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, - } - } - -- return 0; -+ return 1; -+} -+ -+static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id, -+ int startup) -+{ -+ return netlink_route_change_read_unicast_internal(h, ns_id, startup, -+ NULL); - } - - static struct mcast_route_data *mroute = NULL; -diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h -index 93c06e555..da044c2c4 100644 ---- a/zebra/rt_netlink.h -+++ b/zebra/rt_netlink.h -@@ -122,6 +122,10 @@ netlink_put_lsp_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx); - extern enum netlink_msg_status - netlink_put_pw_update_msg(struct nl_batch *bth, struct zebra_dplane_ctx *ctx); - -+int netlink_route_change_read_unicast_internal(struct nlmsghdr *h, -+ ns_id_t ns_id, int startup, -+ struct zebra_dplane_ctx *ctx); -+ - #ifdef NETLINK_DEBUG - const char *nlmsg_type2str(uint16_t type); - const char *af_type2str(int type); -diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c -index 05f9c2e08..5048bf7dc 100644 ---- a/zebra/zebra_dplane.c -+++ b/zebra/zebra_dplane.c -@@ -5320,6 +5320,17 @@ kernel_dplane_process_ipset_entry(struct zebra_dplane_provider *prov, - dplane_provider_enqueue_out_ctx(prov, ctx); - } - -+void dplane_rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, -+ struct prefix_ipv6 *src_p, struct route_entry *re, -+ struct nexthop_group *ng, int startup, -+ struct zebra_dplane_ctx *ctx) -+{ -+ if (!ctx) -+ rib_add_multipath(afi, safi, p, src_p, re, ng); -+ else { -+ } -+} -+ - /* - * Kernel provider callback - */ -diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h -index 9d7502828..4732a1628 100644 ---- a/zebra/zebra_dplane.h -+++ b/zebra/zebra_dplane.h -@@ -938,6 +938,16 @@ void zebra_dplane_pre_finish(void); - void zebra_dplane_finish(void); - void zebra_dplane_shutdown(void); - -+/* -+ * decision point for sending a routing update through the old -+ * straight to zebra master pthread or through the dplane to -+ * the master pthread for handling -+ */ -+void dplane_rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, -+ struct prefix_ipv6 *src_p, struct route_entry *re, -+ struct nexthop_group *ng, int startup, -+ struct zebra_dplane_ctx *ctx); -+ - #ifdef __cplusplus - } - #endif --- -2.30.2 - diff --git a/src/sonic-frr/patch/0020-zebra-Fix-crash-when-dplane_fpm_nl-fails-to-process-.patch b/src/sonic-frr/patch/0020-zebra-Fix-crash-when-dplane_fpm_nl-fails-to-process-.patch new file mode 100644 index 000000000000..f1bbf13061f2 --- /dev/null +++ b/src/sonic-frr/patch/0020-zebra-Fix-crash-when-dplane_fpm_nl-fails-to-process-.patch @@ -0,0 +1,50 @@ +From 6d7a251e5075a6fbced11e43fcdaa9e324c3871f Mon Sep 17 00:00:00 2001 +From: Carmine Scarpitta +Date: Fri, 7 Jul 2023 02:57:07 +0200 +Subject: [PATCH 2/2] zebra: Fix crash when `dplane_fpm_nl` fails to process + received routes + +When `dplane_fpm_nl` receives a route, it allocates memory for a dplane +context and calls `netlink_route_change_read_unicast_internal` without +initializing the `intf_extra_list` contained in the dplane context. If +`netlink_route_change_read_unicast_internal` is not able to process the +route, we call `dplane_ctx_fini` to free the dplane context. This causes +a crash because `dplane_ctx_fini` attempts to access the intf_extra_list +which is not initialized. + +To solve this issue, we can call `dplane_ctx_route_init`to initialize +the dplane route context properly, just after the dplane context +allocation. + +(gdb) bt +#0 0x0000555dd5ceae80 in dplane_intf_extra_list_pop (h=0x7fae1c007e68) at ../zebra/zebra_dplane.c:427 +#1 dplane_ctx_free_internal (ctx=0x7fae1c0074b0) at ../zebra/zebra_dplane.c:724 +#2 0x0000555dd5cebc99 in dplane_ctx_free (pctx=0x7fae2aa88c98) at ../zebra/zebra_dplane.c:869 +#3 dplane_ctx_free (pctx=0x7fae2aa88c98, pctx@entry=0x7fae2aa78c28) at ../zebra/zebra_dplane.c:855 +#4 dplane_ctx_fini (pctx=pctx@entry=0x7fae2aa88c98) at ../zebra/zebra_dplane.c:890 +#5 0x00007fae31e93f29 in fpm_read (t=) at ../zebra/dplane_fpm_nl.c:605 +#6 0x00007fae325191dd in thread_call (thread=thread@entry=0x7fae2aa98da0) at ../lib/thread.c:2006 +#7 0x00007fae324c42b8 in fpt_run (arg=0x555dd74777c0) at ../lib/frr_pthread.c:309 +#8 0x00007fae32405ea7 in start_thread () from /lib/x86_64-linux-gnu/libpthread.so.0 +#9 0x00007fae32325a2f in clone () from /lib/x86_64-linux-gnu/libc.so.6 + +Fixes: #13754 +Signed-off-by: Carmine Scarpitta + +diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c +index 9f38401618..caa2f988e2 100644 +--- a/zebra/dplane_fpm_nl.c ++++ b/zebra/dplane_fpm_nl.c +@@ -599,7 +599,8 @@ static void fpm_read(struct thread *t) + switch (hdr->nlmsg_type) { + case RTM_NEWROUTE: + ctx = dplane_ctx_alloc(); +- dplane_ctx_set_op(ctx, DPLANE_OP_ROUTE_NOTIFY); ++ dplane_ctx_route_init(ctx, DPLANE_OP_ROUTE_NOTIFY, NULL, ++ NULL); + if (netlink_route_change_read_unicast_internal( + hdr, 0, false, ctx) != 1) { + dplane_ctx_fini(&ctx); +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0021-zebra-Read-from-the-dplane_fpm_nl-a-route-update.patch b/src/sonic-frr/patch/0021-zebra-Read-from-the-dplane_fpm_nl-a-route-update.patch deleted file mode 100755 index 0af36d76172a..000000000000 --- a/src/sonic-frr/patch/0021-zebra-Read-from-the-dplane_fpm_nl-a-route-update.patch +++ /dev/null @@ -1,289 +0,0 @@ -From 95fac14ae8076ef4f5749aa3b761a7603b8c05cc Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Fri, 7 Oct 2022 08:02:44 -0400 -Subject: [PATCH 7/8] zebra: Read from the dplane_fpm_nl a route update - -Read from the fpm dplane a route update that will -include status about whether or not the asic was -successfull in offloading the route. - -Have this data passed up to zebra for processing and disseminate -this data as appropriate. - -Signed-off-by: Donald Sharp ---- - doc/developer/fpm.rst | 16 ++++++ - zebra/dplane_fpm_nl.c | 122 +++++++++++++++++++++++++++++++++++++++++- - zebra/zebra_dplane.c | 10 ++-- - zebra/zebra_dplane.h | 2 +- - zebra/zebra_rib.c | 16 +++++- - 5 files changed, 158 insertions(+), 8 deletions(-) - -diff --git a/doc/developer/fpm.rst b/doc/developer/fpm.rst -index 984986913..56d33671d 100644 ---- a/doc/developer/fpm.rst -+++ b/doc/developer/fpm.rst -@@ -101,3 +101,19 @@ Data - ^^^^ - - The netlink or protobuf message payload. -+ -+ -+Route Status Notification from ASIC -+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -+ -+The dplane_fpm_nl has the ability to read route netlink messages -+from the underlying fpm implementation that can tell zebra -+whether or not the route has been Offloaded/Failed or Trapped. -+The end developer must send the data up the same socket that has -+been created to listen for FPM messages from Zebra. The data sent -+must have a Frame Header with Version set to 1, Message Type set to 1 -+and an appropriate message Length. The message data must contain -+a RTM_NEWROUTE netlink message that sends the prefix and nexthops -+associated with the route. Finally rtm_flags must contain -+RTM_F_OFFLOAD, RTM_F_TRAP and or RTM_F_OFFLOAD_FAILED to signify -+what has happened to the route in the ASIC. -diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c -index 8d41f3b07..893ee5845 100644 ---- a/zebra/dplane_fpm_nl.c -+++ b/zebra/dplane_fpm_nl.c -@@ -51,6 +51,7 @@ - #include "zebra/kernel_netlink.h" - #include "zebra/rt_netlink.h" - #include "zebra/debug.h" -+#include "fpm/fpm.h" - - #define SOUTHBOUND_DEFAULT_ADDR INADDR_LOOPBACK - #define SOUTHBOUND_DEFAULT_PORT 2620 -@@ -461,7 +462,13 @@ static void fpm_reconnect(struct fpm_nl_ctx *fnc) - static int fpm_read(struct thread *t) - { - struct fpm_nl_ctx *fnc = THREAD_ARG(t); -+ fpm_msg_hdr_t fpm; - ssize_t rv; -+ char buf[65535]; -+ struct nlmsghdr *hdr; -+ struct zebra_dplane_ctx *ctx; -+ size_t available_bytes; -+ size_t hdr_available_bytes; - - /* Let's ignore the input at the moment. */ - rv = stream_read_try(fnc->ibuf, fnc->socket, -@@ -493,12 +500,123 @@ static int fpm_read(struct thread *t) - if (rv == -2) - return 0; - -- stream_reset(fnc->ibuf); -- - /* Account all bytes read. */ - atomic_fetch_add_explicit(&fnc->counters.bytes_read, rv, - memory_order_relaxed); - -+ available_bytes = STREAM_READABLE(fnc->ibuf); -+ while (available_bytes) { -+ if (available_bytes < (ssize_t)FPM_MSG_HDR_LEN) { -+ stream_pulldown(fnc->ibuf); -+ return 0; -+ } -+ -+ fpm.version = stream_getc(fnc->ibuf); -+ fpm.msg_type = stream_getc(fnc->ibuf); -+ fpm.msg_len = stream_getw(fnc->ibuf); -+ -+ if (fpm.version != FPM_PROTO_VERSION && -+ fpm.msg_type != FPM_MSG_TYPE_NETLINK) { -+ stream_reset(fnc->ibuf); -+ zlog_warn( -+ "%s: Received version/msg_type %u/%u, expected 1/1", -+ __func__, fpm.version, fpm.msg_type); -+ -+ FPM_RECONNECT(fnc); -+ return 0; -+ } -+ -+ /* -+ * If the passed in length doesn't even fill in the header -+ * something is wrong and reset. -+ */ -+ if (fpm.msg_len < FPM_MSG_HDR_LEN) { -+ zlog_warn( -+ "%s: Received message length: %u that does not even fill the FPM header", -+ __func__, fpm.msg_len); -+ FPM_RECONNECT(fnc); -+ return 0; -+ } -+ -+ /* -+ * If we have not received the whole payload, reset the stream -+ * back to the beginning of the header and move it to the -+ * top. -+ */ -+ if (fpm.msg_len > available_bytes) { -+ stream_rewind_getp(fnc->ibuf, FPM_MSG_HDR_LEN); -+ stream_pulldown(fnc->ibuf); -+ return 0; -+ } -+ -+ available_bytes -= FPM_MSG_HDR_LEN; -+ -+ /* -+ * Place the data from the stream into a buffer -+ */ -+ hdr = (struct nlmsghdr *)buf; -+ stream_get(buf, fnc->ibuf, fpm.msg_len - FPM_MSG_HDR_LEN); -+ hdr_available_bytes = fpm.msg_len - FPM_MSG_HDR_LEN; -+ available_bytes -= hdr_available_bytes; -+ -+ /* Sanity check: must be at least header size. */ -+ if (hdr->nlmsg_len < sizeof(*hdr)) { -+ zlog_warn( -+ "%s: [seq=%u] invalid message length %u (< %zu)", -+ __func__, hdr->nlmsg_seq, hdr->nlmsg_len, -+ sizeof(*hdr)); -+ continue; -+ } -+ -+ if (hdr->nlmsg_len > fpm.msg_len) { -+ zlog_warn( -+ "%s: Received a inner header length of %u that is greater than the fpm total length of %u", -+ __func__, hdr->nlmsg_len, fpm.msg_len); -+ FPM_RECONNECT(fnc); -+ } -+ -+ /* Not enough bytes available. */ -+ if (hdr->nlmsg_len > hdr_available_bytes) { -+ zlog_warn( -+ "%s: [seq=%u] invalid message length %u (> %zu)", -+ __func__, hdr->nlmsg_seq, hdr->nlmsg_len, -+ available_bytes); -+ continue; -+ } -+ -+ if (!(hdr->nlmsg_flags & NLM_F_REQUEST)) { -+ if (IS_ZEBRA_DEBUG_FPM) -+ zlog_debug( -+ "%s: [seq=%u] not a request, skipping", -+ __func__, hdr->nlmsg_seq); -+ -+ /* -+ * This request is a bust, go to the next one -+ */ -+ continue; -+ } -+ -+ switch (hdr->nlmsg_type) { -+ case RTM_NEWROUTE: -+ ctx = dplane_ctx_alloc(); -+ dplane_ctx_set_op(ctx, DPLANE_OP_ROUTE_NOTIFY); -+ if (netlink_route_change_read_unicast_internal( -+ hdr, 0, false, ctx) != 1) { -+ dplane_ctx_fini(&ctx); -+ stream_pulldown(fnc->ibuf); -+ return 0; -+ } -+ break; -+ default: -+ if (IS_ZEBRA_DEBUG_FPM) -+ zlog_debug( -+ "%s: Received message type %u which is not currently handled", -+ __func__, hdr->nlmsg_type); -+ break; -+ } -+ } -+ -+ stream_reset(fnc->ibuf); - return 0; - } - -diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c -index 5048bf7dc..336056abb 100644 ---- a/zebra/zebra_dplane.c -+++ b/zebra/zebra_dplane.c -@@ -2337,7 +2337,7 @@ static int dplane_ctx_ns_init(struct zebra_dplane_ctx *ctx, - int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx, - enum dplane_op_e op, struct route_entry *re, - const struct prefix *p, -- const struct prefix *src_p, afi_t afi, -+ const struct prefix_ipv6 *src_p, afi_t afi, - safi_t safi) - { - int ret = EINVAL; -@@ -2388,7 +2388,8 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, - int ret = EINVAL; - const struct route_table *table = NULL; - const struct rib_table_info *info; -- const struct prefix *p, *src_p; -+ const struct prefix *p; -+ const struct prefix_ipv6 *src_p; - struct zebra_ns *zns; - struct zebra_vrf *zvrf; - struct nexthop *nexthop; -@@ -2405,7 +2406,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, - */ - - /* Prefixes: dest, and optional source */ -- srcdest_rnode_prefixes(rn, &p, &src_p); -+ srcdest_rnode_prefixes(rn, &p, (const struct prefix **)&src_p); - table = srcdest_rnode_table(rn); - info = table->info; - -@@ -5328,6 +5329,9 @@ void dplane_rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p, - if (!ctx) - rib_add_multipath(afi, safi, p, src_p, re, ng); - else { -+ dplane_ctx_route_init_basic(ctx, dplane_ctx_get_op(ctx), re, p, -+ src_p, afi, safi); -+ dplane_provider_enqueue_to_zebra(ctx); - } - } - -diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h -index 4732a1628..c3fe3ba40 100644 ---- a/zebra/zebra_dplane.h -+++ b/zebra/zebra_dplane.h -@@ -777,7 +777,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, - int dplane_ctx_route_init_basic(struct zebra_dplane_ctx *ctx, - enum dplane_op_e op, struct route_entry *re, - const struct prefix *p, -- const struct prefix *src_p, afi_t afi, -+ const struct prefix_ipv6 *src_p, afi_t afi, - safi_t safi); - - /* Encode next hop information into data plane context. */ -diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index abd6e07f9..50f19adcc 100644 ---- a/zebra/zebra_rib.c -+++ b/zebra/zebra_rib.c -@@ -2138,8 +2138,7 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) - } - - /* Ensure we clear the QUEUED flag */ -- if (!zrouter.asic_offloaded) -- UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED); -+ UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED); - - /* Is this a notification that ... matters? We mostly care about - * the route that is currently selected for installation; we may also -@@ -2182,6 +2181,19 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx) - dplane_ctx_get_type(ctx))); - } - goto done; -+ } else { -+ uint32_t flags = dplane_ctx_get_flags(ctx); -+ -+ if (CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOADED)) { -+ UNSET_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED); -+ SET_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED); -+ } -+ if (CHECK_FLAG(flags, ZEBRA_FLAG_OFFLOAD_FAILED)) { -+ UNSET_FLAG(re->flags, ZEBRA_FLAG_OFFLOADED); -+ SET_FLAG(re->flags, ZEBRA_FLAG_OFFLOAD_FAILED); -+ } -+ if (CHECK_FLAG(flags, ZEBRA_FLAG_TRAPPED)) -+ SET_FLAG(re->flags, ZEBRA_FLAG_TRAPPED); - } - - /* We'll want to determine whether the installation status of the --- -2.30.2 - diff --git a/src/sonic-frr/patch/0022-zebra-Fix-code-because-missing-backport.patch b/src/sonic-frr/patch/0022-zebra-Fix-code-because-missing-backport.patch deleted file mode 100755 index 4fa3a490ffac..000000000000 --- a/src/sonic-frr/patch/0022-zebra-Fix-code-because-missing-backport.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 0104413e893f3e2d41da101b6788aea240e5a21a Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Thu, 15 Dec 2022 10:52:38 -0500 -Subject: [PATCH 8/8] zebra: Fix code because missing backport - -The commit: -commit 07fd1f7e9420efd480e85a9ab72b88fff274f791 -Author: Donald Sharp -Date: Tue Aug 9 20:07:09 2022 -0400 - - zebra: use rib_add_multipath in rt_netlink.c - - The new route code path was using a combination of - both rib_add() and rib_add_multipath() let's clean - it up some to use rib_add_multipath() - - Signed-off-by: Donald Sharp - -Abstracted the calling of rib_add and rib_add_multipath in -netlink_route_change_read_unicast to just calling rib_add_multipath -one time. Since this commit was not backported the netlink_route_change_read_unicast -function had an additional rib_add that is not going through the new dplane -code to make a decision point about how to send up the message. - -Make it so the non multipath case uses the new decision point. - -Signed-off-by: Donald Sharp ---- - zebra/rt_netlink.c | 41 ++++++++++++++++++++++++----------------- - 1 file changed, 24 insertions(+), 17 deletions(-) - -diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c -index b2df2cd8a..76402561e 100644 ---- a/zebra/rt_netlink.c -+++ b/zebra/rt_netlink.c -@@ -909,37 +909,44 @@ int netlink_route_change_read_unicast_internal(struct nlmsghdr *h, - afi = AFI_IP6; - - if (h->nlmsg_type == RTM_NEWROUTE) { -+ struct route_entry *re; -+ struct nexthop_group *ng = NULL; -+ -+ re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); -+ re->type = proto; -+ re->distance = distance; -+ re->flags = flags; -+ re->metric = metric; -+ re->mtu = mtu; -+ re->vrf_id = vrf_id; -+ re->table = table; -+ re->uptime = monotime(NULL); -+ re->tag = tag; -+ re->nhe_id = nhe_id; -+ -+ if (!nhe_id) -+ ng = nexthop_group_new(); - - if (!tb[RTA_MULTIPATH]) { -- struct nexthop nh = {0}; -+ struct nexthop *nexthop, nh = {0}; - - if (!nhe_id) { - nh = parse_nexthop_unicast( - ns_id, rtm, tb, bh_type, index, prefsrc, - gate, afi, vrf_id); -+ -+ nexthop = nexthop_new(); -+ *nexthop = nh; -+ nexthop_group_add_sorted(ng, nexthop); - } -- rib_add(afi, SAFI_UNICAST, vrf_id, proto, 0, flags, &p, -- &src_p, &nh, nhe_id, table, metric, mtu, -- distance, tag); -+ dplane_rib_add_multipath(afi, SAFI_UNICAST, &p, &src_p, -+ re, ng, startup, ctx); - } else { - /* This is a multipath route */ -- struct route_entry *re; - struct nexthop_group *ng = NULL; - struct rtnexthop *rtnh = - (struct rtnexthop *)RTA_DATA(tb[RTA_MULTIPATH]); - -- re = XCALLOC(MTYPE_RE, sizeof(struct route_entry)); -- re->type = proto; -- re->distance = distance; -- re->flags = flags; -- re->metric = metric; -- re->mtu = mtu; -- re->vrf_id = vrf_id; -- re->table = table; -- re->uptime = monotime(NULL); -- re->tag = tag; -- re->nhe_id = nhe_id; -- - if (!nhe_id) { - uint8_t nhop_num; - --- -2.30.2 - diff --git a/src/sonic-frr/patch/0024-zebra-continue-fpm-read-when-we-decide-a-netlink-message-is-not-needed.patch b/src/sonic-frr/patch/0024-zebra-continue-fpm-read-when-we-decide-a-netlink-message-is-not-needed.patch deleted file mode 100644 index 6014fa3ea400..000000000000 --- a/src/sonic-frr/patch/0024-zebra-continue-fpm-read-when-we-decide-a-netlink-message-is-not-needed.patch +++ /dev/null @@ -1,31 +0,0 @@ -From c0275ab189d619c2f688a383e5e83183f02eaf6f Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Tue, 10 Jan 2023 08:36:50 -0500 -Subject: [PATCH] zebra: Continue fpm_read when we decide a netlink message is - not needed - -When FRR receives a netlink message that it decides to stop parsing -it returns a 0 ( instead of a -1 ). Just make the dplane continue -reading other data instead of aborting the read. - -Signed-off-by: Donald Sharp ---- - zebra/dplane_fpm_nl.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c -index a31e79212..9d9ea7283 100644 ---- a/zebra/dplane_fpm_nl.c -+++ b/zebra/dplane_fpm_nl.c -@@ -605,7 +610,10 @@ static void fpm_read(struct thread *t) - hdr, 0, false, ctx) != 1) { - dplane_ctx_fini(&ctx); - stream_pulldown(fnc->ibuf); -- return 0; -+ /* -+ * Let's continue to read other messages -+ * Even if we ignore this one. -+ */ - } - break; - default: diff --git a/src/sonic-frr/patch/0025-zebra-Send-nht-resolved-entry-up-to-concerned-protoc.patch b/src/sonic-frr/patch/0025-zebra-Send-nht-resolved-entry-up-to-concerned-protoc.patch deleted file mode 100644 index 402515c3c8d4..000000000000 --- a/src/sonic-frr/patch/0025-zebra-Send-nht-resolved-entry-up-to-concerned-protoc.patch +++ /dev/null @@ -1,49 +0,0 @@ -From 49c14222cb0d3cb60b32340976b4e42e5644a563 Mon Sep 17 00:00:00 2001 -From: Stepan Blyschak -Date: Tue, 31 Jan 2023 10:24:30 +0000 -Subject: [PATCH] zebra: Send nht resolved entry up to concerned protocols in - all cases - -There existed the idea, from Volta, that a nexthop group would not have -the same nexthops installed -vs- what FRR actually sent down. The -dplane would notify you. - -With the addition of 06525c4 -the code was put behind a bit of a wall controlled the usage -of it. - -The flag ROUTE_ENTRY_USE_FIB_NHG flag was being used -to control which set was being sent up to concerned parties -in nexthop tracking. Put this flag behind the wall and -do not necessarily set it when we receive a data plane -notification about a route being installed or not. - -Fixes: #12706 -Signed-off-by: Donald Sharp ---- - zebra/zebra_rib.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index 50f19adcc..a8dbe4470 100644 ---- a/zebra/zebra_rib.c -+++ b/zebra/zebra_rib.c -@@ -1666,9 +1666,12 @@ no_nexthops: - ctxnhg->nexthop != NULL ? "" : " (empty)"); - - /* Set the flag about the dedicated fib list */ -- SET_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG); -- if (ctxnhg->nexthop) -- copy_nexthops(&(re->fib_ng.nexthop), ctxnhg->nexthop, NULL); -+ if (zrouter.asic_notification_nexthop_control) { -+ SET_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG); -+ if (ctxnhg->nexthop) -+ copy_nexthops(&(re->fib_ng.nexthop), ctxnhg->nexthop, -+ NULL); -+ } - - check_backups: - --- -2.30.2 - diff --git a/src/sonic-frr/patch/0027-bgpd-Ensure-FRR-has-enough-data-to-read-in-peek_for_as4_capability-and-bgp_open_option_parse.patch b/src/sonic-frr/patch/0027-bgpd-Ensure-FRR-has-enough-data-to-read-in-peek_for_as4_capability-and-bgp_open_option_parse.patch deleted file mode 100644 index fb6352b3fc9d..000000000000 --- a/src/sonic-frr/patch/0027-bgpd-Ensure-FRR-has-enough-data-to-read-in-peek_for_as4_capability-and-bgp_open_option_parse.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 3e46b43e3788f0f87bae56a86b54d412b4710286 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Fri, 30 Sep 2022 08:51:45 -0400 -Subject: [PATCH 1/2] bgpd: Ensure FRR has enough data to read 2 bytes in - peek_for_as4_capability - -In peek_for_as4_capability the code is checking that the -stream has at least 2 bytes to read ( the opt_type and the -opt_length ). However if BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) -is configured then FRR is reading 3 bytes. Which is not good -since the packet could be badly formated. Ensure that -FRR has the appropriate data length to read the data. - -Signed-off-by: Donald Sharp ---- - bgpd/bgp_open.c | 27 +++++++++++++++++++++------ - 1 file changed, 21 insertions(+), 6 deletions(-) - -diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c -index 7248f034a5a..a760a7ca013 100644 ---- a/bgpd/bgp_open.c -+++ b/bgpd/bgp_open.c -@@ -1185,15 +1185,30 @@ as_t peek_for_as4_capability(struct peer *peer, uint16_t length) - uint8_t opt_type; - uint16_t opt_length; - -- /* Check the length. */ -- if (stream_get_getp(s) + 2 > end) -+ /* Ensure we can read the option type */ -+ if (stream_get_getp(s) + 1 > end) - goto end; - -- /* Fetch option type and length. */ -+ /* Fetch the option type */ - opt_type = stream_getc(s); -- opt_length = BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) -- ? stream_getw(s) -- : stream_getc(s); -+ -+ /* -+ * Check the length and fetch the opt_length -+ * If the peer is BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) -+ * then we do a getw which is 2 bytes. So we need to -+ * ensure that we can read that as well -+ */ -+ if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) { -+ if (stream_get_getp(s) + 2 > end) -+ goto end; -+ -+ opt_length = stream_getw(s); -+ } else { -+ if (stream_get_getp(s) + 1 > end) -+ goto end; -+ -+ opt_length = stream_getc(s); -+ } - - /* Option length check. */ - if (stream_get_getp(s) + opt_length > end) - -From 1117baca3c592877a4d8a13ed6a1d9bd83977487 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Fri, 30 Sep 2022 08:57:43 -0400 -Subject: [PATCH 2/2] bgpd: Ensure FRR has enough data to read 2 bytes in - bgp_open_option_parse - -In bgp_open_option_parse the code is checking that the -stream has at least 2 bytes to read ( the opt_type and -the opt_length). However if BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) -is configured then FRR is reading 3 bytes. Which is not good -since the packet could be badly formateed. Ensure that -FRR has the appropriate data length to read the data. - -Signed-off-by: Donald Sharp ---- - bgpd/bgp_open.c | 35 ++++++++++++++++++++++++++++------- - 1 file changed, 28 insertions(+), 7 deletions(-) - -diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c -index a760a7ca013..d1667fac261 100644 ---- a/bgpd/bgp_open.c -+++ b/bgpd/bgp_open.c -@@ -1278,19 +1278,40 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length, - uint8_t opt_type; - uint16_t opt_length; - -- /* Must have at least an OPEN option header */ -- if (STREAM_READABLE(s) < 2) { -+ /* -+ * Check that we can read the opt_type and fetch it -+ */ -+ if (STREAM_READABLE(s) < 1) { - zlog_info("%s Option length error", peer->host); - bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, - BGP_NOTIFY_OPEN_MALFORMED_ATTR); - return -1; - } -- -- /* Fetch option type and length. */ - opt_type = stream_getc(s); -- opt_length = BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer) -- ? stream_getw(s) -- : stream_getc(s); -+ -+ /* -+ * Check the length of the stream to ensure that -+ * FRR can properly read the opt_length. Then read it -+ */ -+ if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) { -+ if (STREAM_READABLE(s) < 2) { -+ zlog_info("%s Option length error", peer->host); -+ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, -+ BGP_NOTIFY_OPEN_MALFORMED_ATTR); -+ return -1; -+ } -+ -+ opt_length = stream_getw(s); -+ } else { -+ if (STREAM_READABLE(s) < 1) { -+ zlog_info("%s Option length error", peer->host); -+ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, -+ BGP_NOTIFY_OPEN_MALFORMED_ATTR); -+ return -1; -+ } -+ -+ opt_length = stream_getc(s); -+ } - - /* Option length check. */ - if (STREAM_READABLE(s) < opt_length) { diff --git a/src/sonic-frr/patch/0028-bgpd-Ensure-that-bgp-open-message-stream-has-enough-data-to-read.patch b/src/sonic-frr/patch/0028-bgpd-Ensure-that-bgp-open-message-stream-has-enough-data-to-read.patch deleted file mode 100644 index 73fcfc30266b..000000000000 --- a/src/sonic-frr/patch/0028-bgpd-Ensure-that-bgp-open-message-stream-has-enough-data-to-read.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 766eec1b7accffe2c04a5c9ebb14e9f487bb9f78 Mon Sep 17 00:00:00 2001 -From: Donald Sharp -Date: Wed, 2 Nov 2022 13:24:48 -0400 -Subject: [PATCH] bgpd: Ensure that bgp open message stream has enough data to - read - -If a operator receives an invalid packet that is of insufficient size -then it is possible for BGP to assert during reading of the packet -instead of gracefully resetting the connection with the peer. - -Signed-off-by: Donald Sharp ---- - bgpd/bgp_packet.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c -index 769f9613da8..72d6a923175 100644 ---- a/bgpd/bgp_packet.c -+++ b/bgpd/bgp_packet.c -@@ -1386,8 +1386,27 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size) - || CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_OPT_PARAMS)) { - uint8_t opttype; - -+ if (STREAM_READABLE(peer->curr) < 1) { -+ flog_err( -+ EC_BGP_PKT_OPEN, -+ "%s: stream does not have enough bytes for extended optional parameters", -+ peer->host); -+ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, -+ BGP_NOTIFY_OPEN_MALFORMED_ATTR); -+ return BGP_Stop; -+ } -+ - opttype = stream_getc(peer->curr); - if (opttype == BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH) { -+ if (STREAM_READABLE(peer->curr) < 2) { -+ flog_err( -+ EC_BGP_PKT_OPEN, -+ "%s: stream does not have enough bytes to read the extended optional parameters optlen", -+ peer->host); -+ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR, -+ BGP_NOTIFY_OPEN_MALFORMED_ATTR); -+ return BGP_Stop; -+ } - optlen = stream_getw(peer->curr); - SET_FLAG(peer->sflags, - PEER_STATUS_EXT_OPT_PARAMS_LENGTH); diff --git a/src/sonic-frr/patch/0029-bgpd-Change-log-level-for-graceful-restart-events.patch b/src/sonic-frr/patch/0029-bgpd-Change-log-level-for-graceful-restart-events.patch deleted file mode 100644 index a3474ae64f71..000000000000 --- a/src/sonic-frr/patch/0029-bgpd-Change-log-level-for-graceful-restart-events.patch +++ /dev/null @@ -1,122 +0,0 @@ -From c423bce4db804c1d07d65ce3d06a9e62c4eceb2b Mon Sep 17 00:00:00 2001 -From: stormliang -Date: Mon, 19 Jun 2023 13:57:01 +0000 -Subject: [PATCH] change log level for graceful restart events - ---- - bgpd/bgp_fsm.c | 44 ++++++++++++++++++++------------------------ - bgpd/bgpd.c | 12 +++++------- - 2 files changed, 25 insertions(+), 31 deletions(-) - -diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c -index 672fa4512..e392cd6e1 100644 ---- a/bgpd/bgp_fsm.c -+++ b/bgpd/bgp_fsm.c -@@ -786,9 +786,9 @@ static int bgp_graceful_restart_timer_expire(struct thread *thread) - - peer = THREAD_ARG(thread); - -- if (bgp_debug_neighbor_events(peer)) { -- zlog_debug("%s graceful restart timer expired", peer->host); -- zlog_debug("%s graceful restart stalepath timer stopped", -+ if (peer) { -+ zlog_info("%s graceful restart timer expired", peer->host); -+ zlog_info("%s graceful restart stalepath timer stopped", - peer->host); - } - -@@ -852,8 +852,8 @@ static int bgp_graceful_stale_timer_expire(struct thread *thread) - - peer = THREAD_ARG(thread); - -- if (bgp_debug_neighbor_events(peer)) -- zlog_debug("%s graceful restart stalepath timer expired", -+ if (peer) -+ zlog_info("%s graceful restart stalepath timer expired", - peer->host); - - /* NSF delete stale route */ -@@ -1427,20 +1427,18 @@ int bgp_stop(struct peer *peer) - /* graceful restart */ - if (peer->t_gr_stale) { - BGP_TIMER_OFF(peer->t_gr_stale); -- if (bgp_debug_neighbor_events(peer)) -- zlog_debug( -- "%s graceful restart stalepath timer stopped", -- peer->host); -+ zlog_info( -+ "%s graceful restart stalepath timer stopped", -+ peer->host); - } - if (CHECK_FLAG(peer->sflags, PEER_STATUS_NSF_WAIT)) { -- if (bgp_debug_neighbor_events(peer)) { -- zlog_debug( -- "%s graceful restart timer started for %d sec", -- peer->host, peer->v_gr_restart); -- zlog_debug( -- "%s graceful restart stalepath timer started for %d sec", -- peer->host, peer->bgp->stalepath_time); -- } -+ zlog_info( -+ "%s graceful restart timer started for %d sec", -+ peer->host, peer->v_gr_restart); -+ zlog_info( -+ "%s graceful restart stalepath timer started for %d sec", -+ peer->host, peer->bgp->stalepath_time); -+ - BGP_TIMER_ON(peer->t_gr_restart, - bgp_graceful_restart_timer_expire, - peer->v_gr_restart); -@@ -2205,18 +2203,16 @@ static int bgp_establish(struct peer *peer) - UNSET_FLAG(peer->sflags, PEER_STATUS_NSF_MODE); - if (peer->t_gr_stale) { - BGP_TIMER_OFF(peer->t_gr_stale); -- if (bgp_debug_neighbor_events(peer)) -- zlog_debug( -- "%s graceful restart stalepath timer stopped", -- peer->host); -+ zlog_info( -+ "%s graceful restart stalepath timer stopped", -+ peer->host); - } - } - - if (peer->t_gr_restart) { - BGP_TIMER_OFF(peer->t_gr_restart); -- if (bgp_debug_neighbor_events(peer)) -- zlog_debug("%s graceful restart timer stopped", -- peer->host); -+ zlog_info("%s graceful restart timer stopped", -+ peer->host); - } - - /* Reset uptime, turn on keepalives, send current table. */ -diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c -index 7e528b219..2fc471555 100644 ---- a/bgpd/bgpd.c -+++ b/bgpd/bgpd.c -@@ -2346,16 +2346,14 @@ void peer_nsf_stop(struct peer *peer) - - if (peer->t_gr_restart) { - BGP_TIMER_OFF(peer->t_gr_restart); -- if (bgp_debug_neighbor_events(peer)) -- zlog_debug("%s graceful restart timer stopped", -- peer->host); -+ zlog_info("%s graceful restart timer stopped", -+ peer->host); - } - if (peer->t_gr_stale) { - BGP_TIMER_OFF(peer->t_gr_stale); -- if (bgp_debug_neighbor_events(peer)) -- zlog_debug( -- "%s graceful restart stalepath timer stopped", -- peer->host); -+ zlog_info( -+ "%s graceful restart stalepath timer stopped", -+ peer->host); - } - bgp_clear_route_all(peer); - } --- -2.25.1 - diff --git a/src/sonic-frr/patch/0030-zebra-Static-routes-async-notification-do-not-need-t.patch b/src/sonic-frr/patch/0030-zebra-Static-routes-async-notification-do-not-need-t.patch deleted file mode 100644 index aab240f018ab..000000000000 --- a/src/sonic-frr/patch/0030-zebra-Static-routes-async-notification-do-not-need-t.patch +++ /dev/null @@ -1,46 +0,0 @@ -From cb89515f7751c23368bc8dcaf0bcf768a42a0c11 Mon Sep 17 00:00:00 2001 -From: dgsudharsan -Date: Wed, 28 Jun 2023 19:42:16 +0000 -Subject: [PATCH] zebra: Static routes async notification do not need this test - When using asic_offload with an asynchronous notification the - rib_route_match_ctx function is testing for distance and tag being correct - against the re. This is no longer necessary. - -Normal route notification for static routes is this(well really all routes): a) zebra dplane generates a ctx to send to the dplane for route install b) dplane installs it in the kernel -c) if the dplane_fpm_nl.c module is being used it installs it. d) The context's success code is set to it worked and passes the context back up to zebra for processing. -e) Zebra master receives this and checks the distance and tag are correct for static routes and accepts the route and marks it installed. - -If the operator is using a wait for install mechansim where the dplane is asynchronously sending the result back up at a future time and it is using the dplane_fpm_nl.c code where it uses the rt_netlink.c route parsing code, then there is no way to set distance as that we do not pass distance to the kernel. - -As such static routes were never being properly handled since the re and context would not match and the route would still be marked as queued. - -This code is historical in nature and is no longer necessary. rib_route_match_ctx is only ever used with dplane notifications. Additionally static routes are now handled more intelligently from staticd and the distance changes are held in staticd not zebra, thus it can be removed. - -diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index a8dbe4470..e021ed142 100644 ---- a/zebra/zebra_rib.c -+++ b/zebra/zebra_rib.c -@@ -1385,15 +1385,12 @@ static bool rib_route_match_ctx(const struct route_entry *re, - (re->instance == dplane_ctx_get_instance(ctx))) { - result = true; - -- /* We use an extra test for statics, and another for -- * kernel routes. -+ /* -+ * We use different tests for kernel and for -+ * connected routes. - */ -- if (re->type == ZEBRA_ROUTE_STATIC && -- (re->distance != dplane_ctx_get_distance(ctx) || -- re->tag != dplane_ctx_get_tag(ctx))) { -- result = false; -- } else if (re->type == ZEBRA_ROUTE_KERNEL && -- re->metric != dplane_ctx_get_metric(ctx)) { -+ if (re->type == ZEBRA_ROUTE_KERNEL && -+ re->metric != dplane_ctx_get_metric(ctx)) { - result = false; - } else if (re->type == ZEBRA_ROUTE_CONNECT) { - result = nexthop_group_equal_no_recurse( --- -2.17.1 - diff --git a/src/sonic-frr/patch/Disable-ipv6-src-address-test-in-pceplib.patch b/src/sonic-frr/patch/Disable-ipv6-src-address-test-in-pceplib.patch index b924b9a66fc4..3bf2fa42eae7 100644 --- a/src/sonic-frr/patch/Disable-ipv6-src-address-test-in-pceplib.patch +++ b/src/sonic-frr/patch/Disable-ipv6-src-address-test-in-pceplib.patch @@ -1,13 +1,11 @@ -From dfe0158344ea581370dd2dba8e4db189cf369147 Mon Sep 17 00:00:00 2001 +From 54ac159d360a8fc9e8fcb19d984e8230e16f6fc0 Mon Sep 17 00:00:00 2001 From: Syed Hasan Raza Naqvi Date: Wed, 4 May 2022 05:11:01 +0000 -Subject: [PATCH] Disable ipv6 src address test in pcep. Docker lo interface - doesn't have ipv6 enabled. Socket bind returns cannot assign requested - address. +Subject: [PATCH] From dfe0158344ea581370dd2dba8e4db189cf369147 Mon Sep 17 + 00:00:00 2001 Subject: [PATCH] Disable ipv6 src address test in pcep. Docker + lo interface doesn't have ipv6 enabled. Socket bind returns cannot assign + requested address. ---- - pceplib/test/pcep_socket_comm_test.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pceplib/test/pcep_socket_comm_test.c b/pceplib/test/pcep_socket_comm_test.c index 116531f12..8b71a5090 100644 @@ -23,5 +21,5 @@ index 116531f12..8b71a5090 100644 void pcep_socket_comm_test_teardown() -- -2.20.1 +2.17.1 diff --git a/src/sonic-frr/patch/cross-compile-changes.patch b/src/sonic-frr/patch/cross-compile-changes.patch index 621a8a66985d..2e618f059fc6 100644 --- a/src/sonic-frr/patch/cross-compile-changes.patch +++ b/src/sonic-frr/patch/cross-compile-changes.patch @@ -1,52 +1,47 @@ -From ece218405fe4c086017f2a4f2b2b4c86b9790db0 Mon Sep 17 00:00:00 2001 +From 611505531a96375000184fdf191d91bd021bd35f Mon Sep 17 00:00:00 2001 From: Saikrishna Arcot Date: Wed, 6 Jul 2022 11:28:16 -0700 -Subject: [PATCH] Make changes to support crosscompilation in SONiC +Subject: [PATCH] From ece218405fe4c086017f2a4f2b2b4c86b9790db0 Mon Sep 17 + 00:00:00 2001 Subject: [PATCH] Make changes to support crosscompilation in + SONiC Signed-off-by: Saikrishna Arcot ---- - debian/frr-doc.info | 1 - - debian/frr.manpages | 16 ---------------- - debian/rules | 17 ++++++++++++----- - 3 files changed, 12 insertions(+), 22 deletions(-) - delete mode 100644 debian/frr-doc.info - delete mode 100644 debian/frr.manpages diff --git a/debian/frr-doc.info b/debian/frr-doc.info deleted file mode 100644 -index a83255a24..000000000 +index 1976365e3..000000000 --- a/debian/frr-doc.info +++ /dev/null @@ -1 +0,0 @@ --doc/user/_build/texinfo/frr.info +-build/doc/user/_build/texinfo/frr.info diff --git a/debian/frr.manpages b/debian/frr.manpages deleted file mode 100644 -index 5075fd763..000000000 +index 5a1b74cfc..000000000 --- a/debian/frr.manpages +++ /dev/null @@ -1,16 +0,0 @@ --doc/manpages/_build/man/frr-bgpd.8 --doc/manpages/_build/man/frr-eigrpd.8 --doc/manpages/_build/man/frr-fabricd.8 --doc/manpages/_build/man/frr-isisd.8 --doc/manpages/_build/man/frr-ldpd.8 --doc/manpages/_build/man/frr-nhrpd.8 --doc/manpages/_build/man/frr-ospf6d.8 --doc/manpages/_build/man/frr-ospfd.8 --doc/manpages/_build/man/frr-pimd.8 --doc/manpages/_build/man/frr-ripd.8 --doc/manpages/_build/man/frr-ripngd.8 --doc/manpages/_build/man/frr-watchfrr.8 --doc/manpages/_build/man/frr-zebra.8 --doc/manpages/_build/man/frr.1 --doc/manpages/_build/man/mtracebis.8 --doc/manpages/_build/man/vtysh.1 +-build/doc/manpages/_build/man/frr-bgpd.8 +-build/doc/manpages/_build/man/frr-eigrpd.8 +-build/doc/manpages/_build/man/frr-fabricd.8 +-build/doc/manpages/_build/man/frr-isisd.8 +-build/doc/manpages/_build/man/frr-ldpd.8 +-build/doc/manpages/_build/man/frr-nhrpd.8 +-build/doc/manpages/_build/man/frr-ospf6d.8 +-build/doc/manpages/_build/man/frr-ospfd.8 +-build/doc/manpages/_build/man/frr-pimd.8 +-build/doc/manpages/_build/man/frr-ripd.8 +-build/doc/manpages/_build/man/frr-ripngd.8 +-build/doc/manpages/_build/man/frr-watchfrr.8 +-build/doc/manpages/_build/man/frr-zebra.8 +-build/doc/manpages/_build/man/frr.1 +-build/doc/manpages/_build/man/mtracebis.8 +-build/doc/manpages/_build/man/vtysh.1 diff --git a/debian/rules b/debian/rules -index 0fa9c3a3b..6b005ea5f 100755 +index 43e5d7e61..aa13106fe 100755 --- a/debian/rules +++ b/debian/rules -@@ -27,10 +27,17 @@ else - CONF_LUA=--enable-scripting +@@ -33,10 +33,17 @@ else + CONF_PIM6=--disable-pim6d endif +DEB_BUILD_ARCH ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH) @@ -59,28 +54,26 @@ index 0fa9c3a3b..6b005ea5f 100755 +endif %: -- dh $@ -+ dh $@ --builddirectory=build +- dh $@ -Bbuild --with=sphinxdoc ++ dh $@ -Bbuild --with=sphinxdoc --builddirectory=build override_dh_auto_configure: $(shell dpkg-buildflags --export=sh); \ -@@ -67,12 +74,12 @@ override_dh_auto_configure: +@@ -74,10 +81,10 @@ override_dh_auto_configure: override_dh_auto_install: dh_auto_install - sed -e '1c #!/usr/bin/python3' -i debian/tmp/usr/lib/frr/frr-reload.py - sed -e '1c #!/usr/bin/python3' -i debian/tmp/usr/lib/frr/generate_support_bundle.py +- sed -e '1c #!/usr/bin/python3' -i debian/tmp/usr/lib/frr/frr_babeltrace.py +- sed -e '1c #!/usr/bin/python3' -i debian/tmp/usr/lib/frr/ospfclient.py + sed -e '1c #!$(shell which $PYTHON)' -i debian/tmp/usr/lib/frr/frr-reload.py + sed -e '1c #!$(shell which $PYTHON)' -i debian/tmp/usr/lib/frr/generate_support_bundle.py ++ sed -e '1c #!$(shell which $PYTHON)' -i debian/tmp/usr/lib/frr/frr_babeltrace.py ++ sed -e '1c #!$(shell which $PYTHON)' -i debian/tmp/usr/lib/frr/ospfclient.py # let dh_systemd_* and dh_installinit do their thing automatically -- cp tools/frr.service debian/frr.service -- cp tools/frrinit.sh debian/frr.init -+ cp build/tools/frr.service debian/frr.service -+ cp build/tools/frrinit.sh debian/frr.init - -rm -f debian/tmp/usr/lib/frr/frr - - # install config files + cp build/tools/frr.service debian/frr.service -- -2.25.1 +2.17.1 diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index 0de573f3a596..a0cdde792fac 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -1,31 +1,22 @@ -0001-Add-support-of-bgp-tcp-DSCP-value.patch -0002-Reduce-severity-of-Vty-connected-from-message.patch -0004-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch -0005-nexthops-compare-vrf-only-if-ip-type.patch -0006-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch -0007-Add-support-of-bgp-l3vni-evpn.patch -0008-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch +0001-Reduce-severity-of-Vty-connected-from-message.patch +0002-Allow-BGP-attr-NEXT_HOP-to-be-0.0.0.0-due-to-allevia.patch +0003-nexthops-compare-vrf-only-if-ip-type.patch +0004-frr-remove-frr-log-outchannel-to-var-log-frr.log.patch +0005-Add-support-of-bgp-l3vni-evpn.patch +0006-Link-local-scope-was-not-set-while-binding-socket-for-bgp-ipv6-link-local-neighbors.patch Disable-ipv6-src-address-test-in-pceplib.patch cross-compile-changes.patch -0009-ignore-route-from-default-table.patch -0010-zebra-Note-when-the-netlink-DUMP-command-is-interrup.patch -0011-bgpd-enhanced-capability-is-always-turned-on-for-int.patch -0012-Ensure-ospf_apiclient_lsa_originate-cannot-accidently-write-into-stack.patch -0013-zebra-fix-dplane-fpm-nl-to-allow-for-fast-configuration.patch -0014-bgpd-Allow-network-XXX-to-work-with-bgp-suppress-fib.patch -0015-zebra-Return-statements-do-not-use-paranthesis.patch -0016-zebra-Add-zrouter.asic_notification_nexthop_control.patch -0017-zebra-Re-arrange-fpm_read-to-reduce-code-duplication.patch -0018-zebra-Add-dplane_ctx_get-set_flags.patch -0019-zebra-Rearrange-dplane_ctx_route_init.patch -0020-zebra-Add-ctx-to-netlink-message-parsing.patch -0021-zebra-Read-from-the-dplane_fpm_nl-a-route-update.patch -0022-zebra-Fix-code-because-missing-backport.patch -0023-Use-vrf_id-for-vrf-not-tabled_id.patch -0024-zebra-continue-fpm-read-when-we-decide-a-netlink-message-is-not-needed.patch -0025-zebra-Send-nht-resolved-entry-up-to-concerned-protoc.patch -0026-bgpd-Ensure-suppress-fib-pending-works-with-network-.patch -0027-bgpd-Ensure-FRR-has-enough-data-to-read-in-peek_for_as4_capability-and-bgp_open_option_parse.patch -0028-bgpd-Ensure-that-bgp-open-message-stream-has-enough-data-to-read.patch -0029-bgpd-Change-log-level-for-graceful-restart-events.patch -0030-zebra-Static-routes-async-notification-do-not-need-t.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-Abstract-dplane_ctx_route_init-to-init-route-w.patch +0020-zebra-Fix-crash-when-dplane_fpm_nl-fails-to-process-.patch