diff --git a/rules/frr.mk b/rules/frr.mk index b062016fbc09..da42179a0312 100644 --- a/rules/frr.mk +++ b/rules/frr.mk @@ -1,9 +1,9 @@ # FRRouting (frr) package -FRR_VERSION = 8.5.1 +FRR_VERSION = 8.5.4 FRR_SUBVERSION = 0 FRR_BRANCH = frr/8.5 -FRR_TAG = frr-8.5.1 +FRR_TAG = frr-8.5.4 export FRR_VERSION FRR_SUBVERSION FRR_BRANCH FRR_TAG diff --git a/src/sonic-frr/frr b/src/sonic-frr/frr index 7a2b85ae52b3..de0e358b877a 160000 --- a/src/sonic-frr/frr +++ b/src/sonic-frr/frr @@ -1 +1 @@ -Subproject commit 7a2b85ae52b354248fa9da04100efba0ec6c70c9 +Subproject commit de0e358b877ac9b595e7fb387a302c960a4c02d1 diff --git a/src/sonic-frr/patch/0005-Add-support-of-bgp-l3vni-evpn.patch b/src/sonic-frr/patch/0005-Add-support-of-bgp-l3vni-evpn.patch index fe2636c2e289..c2c04f0ff3dc 100644 --- a/src/sonic-frr/patch/0005-Add-support-of-bgp-l3vni-evpn.patch +++ b/src/sonic-frr/patch/0005-Add-support-of-bgp-l3vni-evpn.patch @@ -1,8 +1,9 @@ -From f5f0018266c98ad96cdbe69ae60d501de21e5600 Mon Sep 17 00:00:00 2001 +From a0846dcf6f496bcfb51dd11c03d1a6c666d4020a Mon Sep 17 00:00:00 2001 From: Stepan Blyschak Date: Thu, 20 Oct 2022 13:19:31 +0000 -Subject: [PATCH] From 369bbb4d62aa47d5a6d5157ca6ea819c4cb80f15 Mon Sep 17 - 00:00:00 2001 Subject: [PATCH 07/13] Added support of L3VNI EVPN +Subject: [PATCH] From f5f0018266c98ad96cdbe69ae60d501de21e5600 Mon Sep 17 + 00:00:00 2001 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 @@ -10,19 +11,19 @@ Signed-off-by: Kishore Kunal Signed-off-by: Stepan Blyschak diff --git a/lib/nexthop.c b/lib/nexthop.c -index 7ebc4fefb..2f7bb0e7b 100644 +index c03d37487a..52679388fd 100644 --- a/lib/nexthop.c +++ b/lib/nexthop.c -@@ -813,6 +813,7 @@ void nexthop_copy_no_recurse(struct nexthop *copy, - memcpy(©->src, &nexthop->src, sizeof(nexthop->src)); +@@ -814,6 +814,7 @@ void nexthop_copy_no_recurse(struct nexthop *copy, memcpy(©->rmap_src, &nexthop->rmap_src, sizeof(nexthop->rmap_src)); + memcpy(©->rmac, &nexthop->rmac, sizeof(nexthop->rmac)); copy->rparent = rparent; + memcpy(©->nh_encap.encap_data.rmac, &nexthop->nh_encap.encap_data.rmac, ETH_ALEN); if (nexthop->nh_label) nexthop_add_labels(copy, nexthop->nh_label_type, nexthop->nh_label->num_labels, diff --git a/lib/nexthop.h b/lib/nexthop.h -index f1309aa52..7b4bbbafd 100644 +index f35cc5e4e2..f6fb6ec2b7 100644 --- a/lib/nexthop.h +++ b/lib/nexthop.h @@ -66,6 +66,11 @@ enum nh_encap_type { @@ -45,9 +46,9 @@ index f1309aa52..7b4bbbafd 100644 + struct vxlan_nh_encap encap_data; } nh_encap; - /* SR-TE color used for matching SR-TE policies */ + /* EVPN router's MAC. diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c -index 79d79d74b..325199eff 100644 +index 79d79d74be..325199eff9 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -1969,6 +1969,7 @@ static int netlink_route_nexthop_encap(struct nlmsghdr *n, size_t nlen, @@ -82,32 +83,32 @@ index 79d79d74b..325199eff 100644 break; } diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c -index c0945eae2..157c33ced 100644 +index 68bb9783f8..c478f83795 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c -@@ -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)); +@@ -1606,6 +1606,8 @@ static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh, + * the nexthop and associated MAC need to be installed. + */ + if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) { + memcpy(&(nexthop->nh_encap.encap_data.rmac), + &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); -@@ -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)); + nexthop->rmac = api_nh->rmac; + } +@@ -1635,6 +1637,8 @@ static struct nexthop *nexthop_from_zapi(const struct zapi_nexthop *api_nh, + * the nexthop and associated MAC need to be installed. + */ + if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) { + memcpy(&(nexthop->nh_encap.encap_data.rmac), + &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); + nexthop->rmac = api_nh->rmac; + } diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c -index f6f436f39..c8511bd28 100644 +index 639f3cd918..6f8d37e701 100644 --- a/zebra/zebra_dplane.c +++ b/zebra/zebra_dplane.c -@@ -2917,7 +2917,7 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op, +@@ -2934,7 +2934,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; 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 deleted file mode 100644 index 583609209e71..000000000000 --- a/src/sonic-frr/patch/0019-zebra-Abstract-dplane_ctx_route_init-to-init-route-w.patch +++ /dev/null @@ -1,74 +0,0 @@ -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/0021-zebra-remove-duplicated-nexthops-when-sending-fpm-msg.patch b/src/sonic-frr/patch/0019-zebra-remove-duplicated-nexthops-when-sending-fpm-msg.patch similarity index 100% rename from src/sonic-frr/patch/0021-zebra-remove-duplicated-nexthops-when-sending-fpm-msg.patch rename to src/sonic-frr/patch/0019-zebra-remove-duplicated-nexthops-when-sending-fpm-msg.patch 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 deleted file mode 100644 index f1bbf13061f2..000000000000 --- a/src/sonic-frr/patch/0020-zebra-Fix-crash-when-dplane_fpm_nl-fails-to-process-.patch +++ /dev/null @@ -1,50 +0,0 @@ -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/0027-zebra-Fix-non-notification-of-better-admin-won.patch b/src/sonic-frr/patch/0020-zebra-Fix-non-notification-of-better-admin-won.patch similarity index 60% rename from src/sonic-frr/patch/0027-zebra-Fix-non-notification-of-better-admin-won.patch rename to src/sonic-frr/patch/0020-zebra-Fix-non-notification-of-better-admin-won.patch index a1e06a7f5f21..324242a48770 100644 --- a/src/sonic-frr/patch/0027-zebra-Fix-non-notification-of-better-admin-won.patch +++ b/src/sonic-frr/patch/0020-zebra-Fix-non-notification-of-better-admin-won.patch @@ -1,23 +1,29 @@ -From 41b759505afb261211f40e386a30f6cf3870a094 Mon Sep 17 00:00:00 2001 -From: dgsudharsan -Date: Tue, 21 Nov 2023 17:55:24 +0000 -Subject: [PATCH] zebra: Fix non-notification of better admin won If there - happens to be a entry in the zebra rib that has a lower admin distance then a - newly received re, zebra would not notify the upper level protocol about this - happening. Imagine a case where there is a connected route for say a /32 and - bgp receives a route from a peer that is the same route as the connected. - Since BGP has no network statement and perceives the route as being `good` - bgp will install the route into zebra. Zebra will look at the new bgp re and - correctly identify that the re is not something that it will use and do - nothing. This change notices this and sends up a BETTER_ADMIN_WON route - notification. +From 9513d3a158e493623a6bc1e5e3e44b6ed277ac28 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Tue, 14 Nov 2023 10:15:42 -0500 +Subject: [PATCH] zebra: Fix non-notification of better admin won +If there happens to be a entry in the zebra rib +that has a lower admin distance then a newly received +re, zebra would not notify the upper level protocol +about this happening. Imagine a case where there +is a connected route for say a /32 and bgp receives +a route from a peer that is the same route as the +connected. Since BGP has no network statement and +perceives the route as being `good` bgp will install +the route into zebra. Zebra will look at the new +bgp re and correctly identify that the re is not +something that it will use and do nothing. This +change notices this and sends up a BETTER_ADMIN_WON +route notification. + +Signed-off-by: Donald Sharp diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index 039c44cc09..f2f20bcf7b 100644 +index 2c3bb28d6..d37fe98f8 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c -@@ -1209,6 +1209,7 @@ static void rib_process(struct route_node *rn) +@@ -1227,6 +1227,7 @@ static void rib_process(struct route_node *rn) rib_dest_t *dest; struct zebra_vrf *zvrf = NULL; struct vrf *vrf; @@ -25,7 +31,7 @@ index 039c44cc09..f2f20bcf7b 100644 vrf_id_t vrf_id = VRF_UNKNOWN; -@@ -1278,6 +1279,7 @@ static void rib_process(struct route_node *rn) +@@ -1296,6 +1297,7 @@ static void rib_process(struct route_node *rn) * skip it. */ if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)) { @@ -33,7 +39,7 @@ index 039c44cc09..f2f20bcf7b 100644 if (!nexthop_active_update(rn, re)) { const struct prefix *p; struct rib_table_info *info; -@@ -1363,6 +1365,8 @@ static void rib_process(struct route_node *rn) +@@ -1381,6 +1383,8 @@ static void rib_process(struct route_node *rn) * new_selected --- RE entry that is newly SELECTED * old_fib --- RE entry currently in kernel FIB * new_fib --- RE entry that is newly to be in kernel FIB @@ -42,7 +48,7 @@ index 039c44cc09..f2f20bcf7b 100644 * * new_selected will get SELECTED flag, and is going to be redistributed * the zclients. new_fib (which can be new_selected) will be installed -@@ -1417,6 +1421,22 @@ static void rib_process(struct route_node *rn) +@@ -1435,6 +1439,22 @@ static void rib_process(struct route_node *rn) } } diff --git a/src/sonic-frr/patch/Disable-ipv6-src-address-test-in-pceplib.patch b/src/sonic-frr/patch/0021-Disable-ipv6-src-address-test-in-pceplib.patch similarity index 100% rename from src/sonic-frr/patch/Disable-ipv6-src-address-test-in-pceplib.patch rename to src/sonic-frr/patch/0021-Disable-ipv6-src-address-test-in-pceplib.patch diff --git a/src/sonic-frr/patch/0022-bgpd-Don-t-read-the-first-byte-of-ORF-header-if-we-a.patch b/src/sonic-frr/patch/0022-bgpd-Don-t-read-the-first-byte-of-ORF-header-if-we-a.patch deleted file mode 100644 index 1ee76a180004..000000000000 --- a/src/sonic-frr/patch/0022-bgpd-Don-t-read-the-first-byte-of-ORF-header-if-we-a.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 4fcb9d0764b14463f797f2819905ab819dd770f5 Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Sun, 20 Aug 2023 22:15:27 +0300 -Subject: [PATCH] bgpd: Don't read the first byte of ORF header if we are ahead - of stream - -Reported-by: Iggy Frankovic iggyfran@amazon.com -Signed-off-by: Donatas Abraitis -(cherry picked from commit 9b855a692e68e0d16467e190b466b4ecb6853702) - -diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c -index a2959ef6e..60f1dcbcd 100644 ---- a/bgpd/bgp_packet.c -+++ b/bgpd/bgp_packet.c -@@ -2408,7 +2408,8 @@ static int bgp_route_refresh_receive(struct peer *peer, bgp_size_t size) - * and 7 bytes of ORF Address-filter entry from - * the stream - */ -- if (*p_pnt & ORF_COMMON_PART_REMOVE_ALL) { -+ if (p_pnt < p_end && -+ *p_pnt & ORF_COMMON_PART_REMOVE_ALL) { - if (bgp_debug_neighbor_events(peer)) - zlog_debug( - "%pBP rcvd Remove-All pfxlist ORF request", --- -2.17.1 - diff --git a/src/sonic-frr/patch/cross-compile-changes.patch b/src/sonic-frr/patch/0022-cross-compile-changes.patch similarity index 100% rename from src/sonic-frr/patch/cross-compile-changes.patch rename to src/sonic-frr/patch/0022-cross-compile-changes.patch diff --git a/src/sonic-frr/patch/0023-bgpd-Make-sure-we-have-enough-data-to-read-two-bytes.patch b/src/sonic-frr/patch/0023-bgpd-Make-sure-we-have-enough-data-to-read-two-bytes.patch deleted file mode 100644 index cde176c58e41..000000000000 --- a/src/sonic-frr/patch/0023-bgpd-Make-sure-we-have-enough-data-to-read-two-bytes.patch +++ /dev/null @@ -1,51 +0,0 @@ -From da62ad75f69f2e0e4ec51c7dd5e79bd810f636b6 Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Fri, 18 Aug 2023 11:28:03 +0300 -Subject: [PATCH] bgpd: Make sure we have enough data to read two bytes when - validating AIGP - -Found when fuzzing: - -``` -==3470861==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xffff77801ef7 at pc 0xaaaaba7b3dbc bp 0xffffcff0e760 sp 0xffffcff0df50 -READ of size 2 at 0xffff77801ef7 thread T0 - 0 0xaaaaba7b3db8 in __asan_memcpy (/home/ubuntu/frr_8_5_2/frr_8_5_2_fuzz_clang/bgpd/bgpd+0x363db8) (BuildId: cc710a2356e31c7f4e4a17595b54de82145a6e21) - 1 0xaaaaba81a8ac in ptr_get_be16 /home/ubuntu/frr_8_5_2/frr_8_5_2_fuzz_clang/./lib/stream.h:399:2 - 2 0xaaaaba819f2c in bgp_attr_aigp_valid /home/ubuntu/frr_8_5_2/frr_8_5_2_fuzz_clang/bgpd/bgp_attr.c:504:3 - 3 0xaaaaba808c20 in bgp_attr_aigp /home/ubuntu/frr_8_5_2/frr_8_5_2_fuzz_clang/bgpd/bgp_attr.c:3275:7 - 4 0xaaaaba7ff4e0 in bgp_attr_parse /home/ubuntu/frr_8_5_2/frr_8_5_2_fuzz_clang/bgpd/bgp_attr.c:3678:10 -``` - -Reported-by: Iggy Frankovic -Signed-off-by: Donatas Abraitis -(cherry picked from commit f96201e104892e18493f24cf67bb713678e8237b) - -diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c -index 8e66a229c..2ef50ffe5 100644 ---- a/bgpd/bgp_attr.c -+++ b/bgpd/bgp_attr.c -@@ -513,6 +513,7 @@ static bool bgp_attr_aigp_valid(uint8_t *pnt, int length) - uint8_t *data = pnt; - uint8_t tlv_type; - uint16_t tlv_length; -+ uint8_t *end = data + length; - - if (length < 3) { - zlog_err("Bad AIGP attribute length (MUST be minimum 3): %u", -@@ -521,7 +522,13 @@ static bool bgp_attr_aigp_valid(uint8_t *pnt, int length) - } - - while (length) { -+ size_t data_len = end - data; -+ - tlv_type = *data; -+ -+ if (data_len - 1 < 2) -+ return false; -+ - ptr_get_be16(data + 1, &tlv_length); - (void)data; - --- -2.17.1 - diff --git a/src/sonic-frr/patch/0033-zebra-The-dplane_fpm_nl-return-path-leaks-memory.patch b/src/sonic-frr/patch/0023-zebra-The-dplane_fpm_nl-return-path-leaks-memory.patch similarity index 86% rename from src/sonic-frr/patch/0033-zebra-The-dplane_fpm_nl-return-path-leaks-memory.patch rename to src/sonic-frr/patch/0023-zebra-The-dplane_fpm_nl-return-path-leaks-memory.patch index 00e8cc0062ca..980f1d87cdf7 100644 --- a/src/sonic-frr/patch/0033-zebra-The-dplane_fpm_nl-return-path-leaks-memory.patch +++ b/src/sonic-frr/patch/0023-zebra-The-dplane_fpm_nl-return-path-leaks-memory.patch @@ -1,4 +1,4 @@ -From c13964525dae96299dc54daf635609971576a09e Mon Sep 17 00:00:00 2001 +From bcb608d988b3de282ff832fd398e95080be8ad86 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 11 Dec 2023 13:41:36 -0500 Subject: [PATCH] zebra: The dplane_fpm_nl return path leaks memory @@ -8,9 +8,10 @@ entry data backup to the master pthread in zebra is being leaked. Prevent this from happening. Signed-off-by: Donald Sharp +(cherry picked from commit 7f9c5c7fa2d927033549a806fd9025a9459f22bc) diff --git a/zebra/rib.h b/zebra/rib.h -index 016106312..e99eee67c 100644 +index a02a461e8..2e62148ea 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -352,6 +352,8 @@ extern void _route_entry_dump(const char *func, union prefixconstptr pp, @@ -36,10 +37,10 @@ index 6bdc15592..fc9e8c457 100644 /* * I really don't see how this is possible diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c -index f2f20bcf7..1cefdfae7 100644 +index 2b47e229a..1ff3d9854 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c -@@ -4136,6 +4136,12 @@ struct route_entry *zebra_rib_route_entry_new(vrf_id_t vrf_id, int type, +@@ -4178,6 +4178,12 @@ struct route_entry *zebra_rib_route_entry_new(vrf_id_t vrf_id, int type, return re; } diff --git a/src/sonic-frr/patch/0024-bgpd-Do-not-process-NLRIs-if-the-attribute-length-is.patch b/src/sonic-frr/patch/0024-bgpd-Do-not-process-NLRIs-if-the-attribute-length-is.patch deleted file mode 100644 index ceac479b48a5..000000000000 --- a/src/sonic-frr/patch/0024-bgpd-Do-not-process-NLRIs-if-the-attribute-length-is.patch +++ /dev/null @@ -1,97 +0,0 @@ -From fc5cb12121cb1858c162f9ed8f6206fc61439455 Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Tue, 22 Aug 2023 22:52:04 +0300 -Subject: [PATCH] bgpd: Do not process NLRIs if the attribute length is zero - -``` -3 0x00007f423aa42476 in __GI_raise (sig=sig@entry=11) at ../sysdeps/posix/raise.c:26 -4 0x00007f423aef9740 in core_handler (signo=11, siginfo=0x7fffc414deb0, context=) at lib/sigevent.c:246 -5 -6 0x0000564dea2fc71e in route_set_aspath_prepend (rule=0x564debd66d50, prefix=0x7fffc414ea30, object=0x7fffc414e400) - at bgpd/bgp_routemap.c:2258 -7 0x00007f423aeec7e0 in route_map_apply_ext (map=, prefix=prefix@entry=0x7fffc414ea30, - match_object=match_object@entry=0x7fffc414e400, set_object=set_object@entry=0x7fffc414e400, pref=pref@entry=0x0) at lib/routemap.c:2690 -8 0x0000564dea2d277e in bgp_input_modifier (peer=peer@entry=0x7f4238f59010, p=p@entry=0x7fffc414ea30, attr=attr@entry=0x7fffc414e770, - afi=afi@entry=AFI_IP, safi=safi@entry=SAFI_UNICAST, rmap_name=rmap_name@entry=0x0, label=0x0, num_labels=0, dest=0x564debdd5130) - at bgpd/bgp_route.c:1772 -9 0x0000564dea2df762 in bgp_update (peer=peer@entry=0x7f4238f59010, p=p@entry=0x7fffc414ea30, addpath_id=addpath_id@entry=0, - attr=0x7fffc414eb50, afi=afi@entry=AFI_IP, safi=, safi@entry=SAFI_UNICAST, type=9, sub_type=0, prd=0x0, label=0x0, - num_labels=0, soft_reconfig=0, evpn=0x0) at bgpd/bgp_route.c:4374 -10 0x0000564dea2e2047 in bgp_nlri_parse_ip (peer=0x7f4238f59010, attr=attr@entry=0x7fffc414eb50, packet=0x7fffc414eaf0) - at bgpd/bgp_route.c:6249 -11 0x0000564dea2c5a58 in bgp_nlri_parse (peer=peer@entry=0x7f4238f59010, attr=attr@entry=0x7fffc414eb50, - packet=packet@entry=0x7fffc414eaf0, mp_withdraw=mp_withdraw@entry=false) at bgpd/bgp_packet.c:339 -12 0x0000564dea2c5d66 in bgp_update_receive (peer=peer@entry=0x7f4238f59010, size=size@entry=109) at bgpd/bgp_packet.c:2024 -13 0x0000564dea2c901d in bgp_process_packet (thread=) at bgpd/bgp_packet.c:2933 -14 0x00007f423af0bf71 in event_call (thread=thread@entry=0x7fffc414ee40) at lib/event.c:1995 -15 0x00007f423aebb198 in frr_run (master=0x564deb73c670) at lib/libfrr.c:1213 -16 0x0000564dea261b83 in main (argc=, argv=) at bgpd/bgp_main.c:505 -``` - -With the configuration: - -``` -frr version 9.1-dev-MyOwnFRRVersion -frr defaults traditional -hostname ip-172-31-13-140 -log file /tmp/debug.log -log syslog -service integrated-vtysh-config -! -debug bgp keepalives -debug bgp neighbor-events -debug bgp updates in -debug bgp updates out -! -router bgp 100 - bgp router-id 9.9.9.9 - no bgp ebgp-requires-policy - bgp bestpath aigp - neighbor 172.31.2.47 remote-as 200 - ! - address-family ipv4 unicast - neighbor 172.31.2.47 default-originate - neighbor 172.31.2.47 route-map RM_IN in - exit-address-family -exit -! -route-map RM_IN permit 10 - set as-path prepend 200 -exit -! -``` - -The issue is that we try to process NLRIs even if the attribute length is 0. - -Later bgp_update() will handle route-maps and a crash occurs because all the -attributes are NULL, including aspath, where we dereference. - -According to the RFC 4271: - -A value of 0 indicates that neither the Network Layer - Reachability Information field nor the Path Attribute field is - present in this UPDATE message. - -But with a fuzzed UPDATE message this can be faked. I think it's reasonable -to skip processing NLRIs if both update_len and attribute_len are 0. - -Reported-by: Iggy Frankovic -Signed-off-by: Donatas Abraitis -(cherry picked from commit 28ccc24d38df1d51ed8a563507e5d6f6171fdd38) - -diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c -index 60f1dcbcd..a02d54894 100644 ---- a/bgpd/bgp_packet.c -+++ b/bgpd/bgp_packet.c -@@ -1983,7 +1983,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) - /* Network Layer Reachability Information. */ - update_len = end - stream_pnt(s); - -- if (update_len) { -+ if (update_len && attribute_len) { - /* Set NLRI portion to structure. */ - nlris[NLRI_UPDATE].afi = AFI_IP; - nlris[NLRI_UPDATE].safi = SAFI_UNICAST; --- -2.17.1 - diff --git a/src/sonic-frr/patch/0024-lib-use-snmp-s-large-fd-sets-for-agentx.patch b/src/sonic-frr/patch/0024-lib-use-snmp-s-large-fd-sets-for-agentx.patch new file mode 100644 index 000000000000..ad3da2a0ad2e --- /dev/null +++ b/src/sonic-frr/patch/0024-lib-use-snmp-s-large-fd-sets-for-agentx.patch @@ -0,0 +1,143 @@ +From 7e1857bf4315ae01e065fc8bc881338977c1ef87 Mon Sep 17 00:00:00 2001 +From: Edwin Brossette +Date: Fri, 8 Dec 2023 16:02:11 +0100 +Subject: [PATCH] lib: use snmp's large fd sets for agentx + +The maximum number of file descriptors in an fd set is limited by +FD_SETSIZE. This limitation is important because the libc macros +FD_SET(), FD_CLR() and FD_ISSET() will invoke a sigabort if the size of +the fd set given to them is above FD_SETSIZE. + +We ran into such a sigabort with bgpd because snmp can return an fd set +of size higher than FD_SETSIZE when calling snmp_select_info(). An +unfortunate FD_ISSET() call later causes the following abort: + +Received signal 6 at 1701115534 (si_addr 0xb94, PC 0x7ff289a16a7c); aborting... +/lib/x86_64-linux-gnu/libfrr.so.0(zlog_backtrace_sigsafe+0xb3) [0x7ff289d62bba] +/lib/x86_64-linux-gnu/libfrr.so.0(zlog_signal+0x1b4) [0x7ff289d62a1f] +/lib/x86_64-linux-gnu/libfrr.so.0(+0x102860) [0x7ff289da4860] +/lib/x86_64-linux-gnu/libc.so.6(+0x42520) [0x7ff2899c2520] +/lib/x86_64-linux-gnu/libc.so.6(pthread_kill+0x12c) [0x7ff289a16a7c] +/lib/x86_64-linux-gnu/libc.so.6(raise+0x16) [0x7ff2899c2476] +/lib/x86_64-linux-gnu/libc.so.6(abort+0xd3) [0x7ff2899a87f3] +/lib/x86_64-linux-gnu/libc.so.6(+0x896f6) [0x7ff289a096f6] +/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x2a) [0x7ff289ab676a] +/lib/x86_64-linux-gnu/libc.so.6(+0x1350c6) [0x7ff289ab50c6] +/lib/x86_64-linux-gnu/libc.so.6(+0x1366ab) [0x7ff289ab66ab] +/lib/x86_64-linux-gnu/libfrrsnmp.so.0(+0x36f5) [0x7ff2897736f5] +/lib/x86_64-linux-gnu/libfrrsnmp.so.0(+0x3c27) [0x7ff289773c27] +/lib/x86_64-linux-gnu/libfrr.so.0(thread_call+0x1c2) [0x7ff289dbe105] +/lib/x86_64-linux-gnu/libfrr.so.0(frr_run+0x257) [0x7ff289d56e69] +/usr/bin/bgpd(main+0x4f4) [0x560965c40488] +/lib/x86_64-linux-gnu/libc.so.6(+0x29d90) [0x7ff2899a9d90] +/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0x80) [0x7ff2899a9e40] +/usr/bin/bgpd(_start+0x25) [0x560965c3e965] +in thread agentx_timeout scheduled from /build/make-pkg/output/_packages/cp-routing/src/lib/agentx.c:122 agentx_events_update() + +Also, the following error is logged by snmp just before the abort: +snmp[err]: Use snmp_sess_select_info2() for processing large file descriptors + +snmp uses a custom struct netsnmp_large_fd_set to work above the limit +imposed by FD_SETSIZE. It is noteworthy that, when calling +snmp_select_info() instead of snmp_select_info2(), snmp uses the same +code working with its custom, large structs, and copy/paste the result +to a regular, libc compatible fd_set. So there should be no downside +working with snmp_select_info2() instead of snmp_select_info(). + +Replace every use of the libc file descriptors sets by snmp's extended +file descriptors sets in agentx to acommodate for the high number of +file descriptors that can come out of snmp. This should prevent the +abort seen above. + +Signed-off-by: Edwin Brossette + +diff --git a/lib/agentx.c b/lib/agentx.c +index 5f6245980..be8277c53 100644 +--- a/lib/agentx.c ++++ b/lib/agentx.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #include "command.h" + #include "smux.h" +@@ -58,7 +59,7 @@ static void agentx_timeout(struct thread *t) + + static void agentx_read(struct thread *t) + { +- fd_set fds; ++ netsnmp_large_fd_set lfds; + int flags, new_flags = 0; + int nonblock = false; + struct listnode *ln = THREAD_ARG(t); +@@ -83,9 +84,9 @@ static void agentx_read(struct thread *t) + flog_err(EC_LIB_SYSTEM_CALL, "Failed to set snmp fd non blocking: %s(%d)", + strerror(errno), errno); + +- FD_ZERO(&fds); +- FD_SET(THREAD_FD(t), &fds); +- snmp_read(&fds); ++ netsnmp_large_fd_set_init(&lfds, FD_SETSIZE); ++ netsnmp_large_fd_setfd(t->u.fd, &lfds); ++ snmp_read2(&lfds); + + /* Reset the flag */ + if (!nonblock) { +@@ -100,6 +101,7 @@ static void agentx_read(struct thread *t) + + netsnmp_check_outstanding_agent_requests(); + agentx_events_update(); ++ netsnmp_large_fd_set_cleanup(&lfds); + } + + static void agentx_events_update(void) +@@ -107,15 +109,15 @@ static void agentx_events_update(void) + int maxfd = 0; + int block = 1; + struct timeval timeout = {.tv_sec = 0, .tv_usec = 0}; +- fd_set fds; ++ netsnmp_large_fd_set lfds; + struct listnode *ln; + struct thread **thr; + int fd, thr_fd; + + thread_cancel(&timeout_thr); + +- FD_ZERO(&fds); +- snmp_select_info(&maxfd, &fds, &timeout, &block); ++ netsnmp_large_fd_set_init(&lfds, FD_SETSIZE); ++ snmp_select_info2(&maxfd, &lfds, &timeout, &block); + + if (!block) { + thread_add_timer_tv(agentx_tm, agentx_timeout, NULL, &timeout, +@@ -133,7 +135,7 @@ static void agentx_events_update(void) + /* caught up */ + if (thr_fd == fd) { + struct listnode *nextln = listnextnode(ln); +- if (!FD_ISSET(fd, &fds)) { ++ if (!netsnmp_large_fd_is_set(fd, &lfds)) { + thread_cancel(thr); + XFREE(MTYPE_TMP, thr); + list_delete_node(events, ln); +@@ -143,7 +145,7 @@ static void agentx_events_update(void) + thr_fd = thr ? THREAD_FD(*thr) : -1; + } + /* need listener, but haven't hit one where it would be */ +- else if (FD_ISSET(fd, &fds)) { ++ else if (netsnmp_large_fd_is_set(fd, &lfds)) { + struct listnode *newln; + thr = XCALLOC(MTYPE_TMP, sizeof(struct thread *)); + +@@ -162,6 +164,7 @@ static void agentx_events_update(void) + list_delete_node(events, ln); + ln = nextln; + } ++ netsnmp_large_fd_set_cleanup(&lfds); + } + + /* AgentX node. */ +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0025-bgp-community-memory-leak-fix.patch b/src/sonic-frr/patch/0025-bgp-community-memory-leak-fix.patch new file mode 100644 index 000000000000..f8215e07f0f8 --- /dev/null +++ b/src/sonic-frr/patch/0025-bgp-community-memory-leak-fix.patch @@ -0,0 +1,395 @@ +From 92323cf4b506c40376be74e955836da30980ae54 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Wed, 13 Mar 2024 10:26:58 -0400 +Subject: [PATCH 1/3] bgpd: Ensure that the correct aspath is free'd + +Currently in subgroup_default_originate the attr.aspath +is set in bgp_attr_default_set, which hashs the aspath +and creates a refcount for it. If this is a withdraw +the subgroup_announce_check and bgp_adj_out_set_subgroup +is called which will intern the attribute. This will +cause the the attr.aspath to be set to a new value +finally at the bottom of the function it intentionally +uninterns the aspath which is not the one that was +created for this function. This reduces the other +aspath's refcount by 1 and if a clear bgp * is issued +fast enough the aspath for that will be removed +and the system will crash. + +Signed-off-by: Donald Sharp +--- + bgpd/bgp_updgrp_adv.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c +index de2b3206b7..dcde4263da 100644 +--- a/bgpd/bgp_updgrp_adv.c ++++ b/bgpd/bgp_updgrp_adv.c +@@ -813,6 +813,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) + struct bgp *bgp; + struct attr attr; + struct attr *new_attr = &attr; ++ struct aspath *aspath; + struct prefix p; + struct peer *from; + struct bgp_dest *dest; +@@ -850,6 +851,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) + /* make coverity happy */ + assert(attr.aspath); + ++ aspath = attr.aspath; + attr.med = 0; + attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC); + +@@ -1005,7 +1007,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) + } + } + +- aspath_unintern(&attr.aspath); ++ aspath_unintern(&aspath); + } + + /* +-- +2.14.1 + + +From 07545c1879775f155f228c81393eed9697b699de Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Sat, 2 Mar 2024 09:42:30 -0500 +Subject: [PATCH 2/3] bgpd: Include unsuppress-map as a valid outgoing policy + +If unsuppress-map is setup for outgoing peers, consider that +policy is being applied as for RFC 8212. + +Signed-off-by: Donald Sharp +--- + bgpd/bgp_route.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c +index 473168d9be..fb14fc7f20 100644 +--- a/bgpd/bgp_route.c ++++ b/bgpd/bgp_route.c +@@ -5816,10 +5816,10 @@ bool bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter) + if (peer->sort == BGP_PEER_IBGP) + return true; + +- if (peer->sort == BGP_PEER_EBGP +- && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter) +- || FILTER_LIST_OUT_NAME(filter) +- || DISTRIBUTE_OUT_NAME(filter))) ++ if (peer->sort == BGP_PEER_EBGP && ++ (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter) || ++ FILTER_LIST_OUT_NAME(filter) || DISTRIBUTE_OUT_NAME(filter) || ++ UNSUPPRESS_MAP_NAME(filter))) + return true; + return false; + } +-- +2.14.1 + + +From e3493d5be0156fa9c8c522b818ae6448dbe371f2 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Sat, 2 Mar 2024 09:50:38 -0500 +Subject: [PATCH 3/3] bgpd: Ensure community data is freed in some cases. + +Customer has this valgrind trace: + +Direct leak of 2829120 byte(s) in 70728 object(s) allocated from: + 0 in community_new ../bgpd/bgp_community.c:39 + 1 in community_uniq_sort ../bgpd/bgp_community.c:170 + 2 in route_set_community ../bgpd/bgp_routemap.c:2342 + 3 in route_map_apply_ext ../lib/routemap.c:2673 + 4 in subgroup_announce_check ../bgpd/bgp_route.c:2367 + 5 in subgroup_process_announce_selected ../bgpd/bgp_route.c:2914 + 6 in group_announce_route_walkcb ../bgpd/bgp_updgrp_adv.c:199 + 7 in hash_walk ../lib/hash.c:285 + 8 in update_group_af_walk ../bgpd/bgp_updgrp.c:2061 + 9 in group_announce_route ../bgpd/bgp_updgrp_adv.c:1059 + 10 in bgp_process_main_one ../bgpd/bgp_route.c:3221 + 11 in bgp_process_wq ../bgpd/bgp_route.c:3221 + 12 in work_queue_run ../lib/workqueue.c:282 + +The above leak detected by valgrind was from a screenshot so I copied it +by hand. Any mistakes in line numbers are purely from my transcription. +Additionally this is against a slightly modified 8.5.1 version of FRR. +Code inspection of 8.5.1 -vs- latest master shows the same problem +exists. Code should be able to be followed from there to here. + +What is happening: + +There is a route-map being applied that modifes the outgoing community +to a peer. This is saved in the attr copy created in +subgroup_process_announce_selected. This community pointer is not +interned. So the community->refcount is still 0. Normally when +a prefix is announced, the attr and the prefix are placed on a +adjency out structure where the attribute is interned. This will +cause the community to be saved in the community hash list as well. +In a non-normal operation when the decision to send is aborted after +the route-map application, the attribute is just dropped and the +pointer to the community is just dropped too, leading to situations +where the memory is leaked. The usage of bgp suppress-fib would +would be a case where the community is caused to be leaked. +Additionally the previous commit where an unsuppress-map is used +to modify the outgoing attribute but since unsuppress-map was +not considered part of outgoing policy the attribute would be dropped as +well. This pointer drop also extends to any dynamically allocated +memory saved by the attribute pointer that was not interned yet as well. + +So let's modify the return case where the decision is made to +not send the prefix to the peer to always just flush the attribute +to ensure memory is not leaked. + +Fixes: #15459 +Signed-off-by: Donald Sharp +--- + bgpd/bgp_conditional_adv.c | 5 ++-- + bgpd/bgp_route.c | 30 +++++++++++++----------- + bgpd/bgp_updgrp.h | 2 +- + bgpd/bgp_updgrp_adv.c | 58 +++++++++++++++++++++++++--------------------- + 4 files changed, 51 insertions(+), 44 deletions(-) + +diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c +index 24d822a745..edb9bc8bb7 100644 +--- a/bgpd/bgp_conditional_adv.c ++++ b/bgpd/bgp_conditional_adv.c +@@ -135,8 +135,9 @@ static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi, + if (update_type == UPDATE_TYPE_ADVERTISE && + subgroup_announce_check(dest, pi, subgrp, dest_p, + &attr, &advmap_attr)) { +- bgp_adj_out_set_subgroup(dest, subgrp, &attr, +- pi); ++ if (!bgp_adj_out_set_subgroup(dest, subgrp, ++ &attr, pi)) ++ bgp_attr_flush(&attr); + } else { + /* If default originate is enabled for + * the peer, do not send explicit +diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c +index fb14fc7f20..2976042dda 100644 +--- a/bgpd/bgp_route.c ++++ b/bgpd/bgp_route.c +@@ -2879,7 +2879,7 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, + { + const struct prefix *p; + struct peer *onlypeer; +- struct attr attr; ++ struct attr attr = {0}, *pattr = &attr; + afi_t afi; + safi_t safi; + struct bgp *bgp; +@@ -2900,7 +2900,7 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, + PEER_STATUS_ORF_WAIT_REFRESH)) + return; + +- memset(&attr, 0, sizeof(attr)); ++ memset(pattr, 0, sizeof(*pattr)); + /* It's initialized in bgp_announce_check() */ + + /* Announcement to the subgroup. If the route is filtered withdraw it. +@@ -2911,32 +2911,34 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp, + advertise = bgp_check_advertise(bgp, dest); + + if (selected) { +- if (subgroup_announce_check(dest, selected, subgrp, p, &attr, ++ if (subgroup_announce_check(dest, selected, subgrp, p, pattr, + NULL)) { + /* Route is selected, if the route is already installed + * in FIB, then it is advertised + */ + if (advertise) { + if (!bgp_check_withdrawal(bgp, dest)) { +- struct attr *adv_attr = +- bgp_attr_intern(&attr); +- +- bgp_adj_out_set_subgroup(dest, subgrp, +- adv_attr, +- selected); +- } else ++ if (!bgp_adj_out_set_subgroup( ++ dest, subgrp, pattr, ++ selected)) ++ bgp_attr_flush(pattr); ++ } else { + bgp_adj_out_unset_subgroup( + dest, subgrp, 1, addpath_tx_id); +- } +- } else ++ bgp_attr_flush(pattr); ++ } ++ } else ++ bgp_attr_flush(pattr); ++ } else { + bgp_adj_out_unset_subgroup(dest, subgrp, 1, + addpath_tx_id); ++ bgp_attr_flush(pattr); ++ } + } + + /* If selected is NULL we must withdraw the path using addpath_tx_id */ +- else { ++ else + bgp_adj_out_unset_subgroup(dest, subgrp, 1, addpath_tx_id); +- } + } + + /* +diff --git a/bgpd/bgp_updgrp.h b/bgpd/bgp_updgrp.h +index e27c1e7b67..b7b6aa07e9 100644 +--- a/bgpd/bgp_updgrp.h ++++ b/bgpd/bgp_updgrp.h +@@ -458,7 +458,7 @@ extern struct bgp_adj_out *bgp_adj_out_alloc(struct update_subgroup *subgrp, + extern void bgp_adj_out_remove_subgroup(struct bgp_dest *dest, + struct bgp_adj_out *adj, + struct update_subgroup *subgrp); +-extern void bgp_adj_out_set_subgroup(struct bgp_dest *dest, ++extern bool bgp_adj_out_set_subgroup(struct bgp_dest *dest, + struct update_subgroup *subgrp, + struct attr *attr, + struct bgp_path_info *path); +diff --git a/bgpd/bgp_updgrp_adv.c b/bgpd/bgp_updgrp_adv.c +index dcde4263da..7902d40bd9 100644 +--- a/bgpd/bgp_updgrp_adv.c ++++ b/bgpd/bgp_updgrp_adv.c +@@ -454,7 +454,7 @@ bgp_advertise_clean_subgroup(struct update_subgroup *subgrp, + return next; + } + +-void bgp_adj_out_set_subgroup(struct bgp_dest *dest, ++bool bgp_adj_out_set_subgroup(struct bgp_dest *dest, + struct update_subgroup *subgrp, struct attr *attr, + struct bgp_path_info *path) + { +@@ -474,7 +474,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, + bgp = SUBGRP_INST(subgrp); + + if (DISABLE_BGP_ANNOUNCE) +- return; ++ return false; + + /* Look for adjacency information. */ + adj = adj_lookup( +@@ -490,7 +490,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, + bgp_addpath_id_for_peer(peer, afi, safi, + &path->tx_addpath)); + if (!adj) +- return; ++ return false; + + subgrp->pscount++; + } +@@ -529,7 +529,7 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, + * will never be able to coalesce the 3rd peer down + */ + subgrp->version = MAX(subgrp->version, dest->version); +- return; ++ return false; + } + + if (adj->adv) +@@ -576,6 +576,8 @@ void bgp_adj_out_set_subgroup(struct bgp_dest *dest, + bgp_adv_fifo_add_tail(&subgrp->sync->update, adv); + + subgrp->version = MAX(subgrp->version, dest->version); ++ ++ return true; + } + + /* The only time 'withdraw' will be false is if we are sending +@@ -668,7 +670,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp, + { + struct bgp_dest *dest; + struct bgp_path_info *ri; +- struct attr attr; ++ struct attr attr = {0}, *pattr = &attr; + struct peer *peer; + afi_t afi; + safi_t safi; +@@ -712,24 +714,25 @@ void subgroup_announce_table(struct update_subgroup *subgrp, + continue; + + if (subgroup_announce_check(dest, ri, subgrp, dest_p, +- &attr, NULL)) { ++ pattr, NULL)) { + /* Check if route can be advertised */ + if (advertise) { + if (!bgp_check_withdrawal(bgp, dest)) { +- struct attr *adv_attr = +- bgp_attr_intern(&attr); +- +- bgp_adj_out_set_subgroup( +- dest, subgrp, adv_attr, +- ri); +- } else ++ if (!bgp_adj_out_set_subgroup( ++ dest, subgrp, pattr, ++ ri)) ++ bgp_attr_flush(pattr); ++ } else { + bgp_adj_out_unset_subgroup( + dest, subgrp, 1, + bgp_addpath_id_for_peer( + peer, afi, + safi_rib, + &ri->tx_addpath)); +- } ++ bgp_attr_flush(pattr); ++ } ++ } else ++ bgp_attr_flush(pattr); + } else { + /* If default originate is enabled for + * the peer, do not send explicit +@@ -748,6 +751,7 @@ void subgroup_announce_table(struct update_subgroup *subgrp, + bgp_addpath_id_for_peer( + peer, afi, safi_rib, + &ri->tx_addpath)); ++ bgp_attr_flush(pattr); + } + } + } +@@ -811,7 +815,7 @@ void subgroup_announce_route(struct update_subgroup *subgrp) + void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) + { + struct bgp *bgp; +- struct attr attr; ++ struct attr attr = {0}; + struct attr *new_attr = &attr; + struct aspath *aspath; + struct prefix p; +@@ -952,18 +956,18 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw) + if (dest) { + for (pi = bgp_dest_get_bgp_path_info(dest); pi; + pi = pi->next) { +- if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) +- if (subgroup_announce_check( +- dest, pi, subgrp, +- bgp_dest_get_prefix(dest), +- &attr, NULL)) { +- struct attr *default_attr = +- bgp_attr_intern(&attr); +- +- bgp_adj_out_set_subgroup( +- dest, subgrp, +- default_attr, pi); +- } ++ if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) ++ continue; ++ ++ if (subgroup_announce_check( ++ dest, pi, subgrp, ++ bgp_dest_get_prefix(dest), &attr, ++ NULL)) { ++ if (!bgp_adj_out_set_subgroup( ++ dest, subgrp, &attr, pi)) ++ bgp_attr_flush(&attr); ++ } else ++ bgp_attr_flush(&attr); + } + bgp_dest_unlock_node(dest); + } +-- +2.14.1 + diff --git a/src/sonic-frr/patch/0025-bgpd-Use-treat-as-withdraw-for-tunnel-encapsulation-.patch b/src/sonic-frr/patch/0025-bgpd-Use-treat-as-withdraw-for-tunnel-encapsulation-.patch deleted file mode 100644 index 6a7aae3c6c39..000000000000 --- a/src/sonic-frr/patch/0025-bgpd-Use-treat-as-withdraw-for-tunnel-encapsulation-.patch +++ /dev/null @@ -1,129 +0,0 @@ -From 35b98f89f6a2ca5a79ed8893b4df612c0c6b4a37 Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Thu, 13 Jul 2023 22:32:03 +0300 -Subject: [PATCH] bgpd: Use treat-as-withdraw for tunnel encapsulation - attribute - -Before this path we used session reset method, which is discouraged by rfc7606. - -Handle this as rfc requires. - -Signed-off-by: Donatas Abraitis -(cherry picked from commit bcb6b58d9530173df41d3a3cbc4c600ee0b4b186) - -diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c -index 2ef50ffe5..ee20da332 100644 ---- a/bgpd/bgp_attr.c -+++ b/bgpd/bgp_attr.c -@@ -1416,6 +1416,7 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode, - case BGP_ATTR_LARGE_COMMUNITIES: - case BGP_ATTR_ORIGINATOR_ID: - case BGP_ATTR_CLUSTER_LIST: -+ case BGP_ATTR_ENCAP: - case BGP_ATTR_OTC: - return BGP_ATTR_PARSE_WITHDRAW; - case BGP_ATTR_MP_REACH_NLRI: -@@ -2644,26 +2645,21 @@ ipv6_ext_community_ignore: - } - - /* Parse Tunnel Encap attribute in an UPDATE */ --static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */ -- bgp_size_t length, /* IN: attr's length field */ -- struct attr *attr, /* IN: caller already allocated */ -- uint8_t flag, /* IN: attr's flags field */ -- uint8_t *startp) -+static int bgp_attr_encap(struct bgp_attr_parser_args *args) - { -- bgp_size_t total; - uint16_t tunneltype = 0; -- -- total = length + (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3); -+ struct peer *const peer = args->peer; -+ struct attr *const attr = args->attr; -+ bgp_size_t length = args->length; -+ uint8_t type = args->type; -+ uint8_t flag = args->flags; - - if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS) - || !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) { -- zlog_info( -- "Tunnel Encap attribute flag isn't optional and transitive %d", -- flag); -- bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, -- BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR, -- startp, total); -- return -1; -+ zlog_err("Tunnel Encap attribute flag isn't optional and transitive %d", -+ flag); -+ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, -+ args->total); - } - - if (BGP_ATTR_ENCAP == type) { -@@ -2671,12 +2667,11 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */ - uint16_t tlv_length; - - if (length < 4) { -- zlog_info( -+ zlog_err( - "Tunnel Encap attribute not long enough to contain outer T,L"); -- bgp_notify_send_with_data( -- peer, BGP_NOTIFY_UPDATE_ERR, -- BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total); -- return -1; -+ return bgp_attr_malformed(args, -+ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, -+ args->total); - } - tunneltype = stream_getw(BGP_INPUT(peer)); - tlv_length = stream_getw(BGP_INPUT(peer)); -@@ -2706,13 +2701,11 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */ - } - - if (sublength > length) { -- zlog_info( -- "Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d", -- sublength, length); -- bgp_notify_send_with_data( -- peer, BGP_NOTIFY_UPDATE_ERR, -- BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total); -- return -1; -+ zlog_err("Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d", -+ sublength, length); -+ return bgp_attr_malformed(args, -+ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, -+ args->total); - } - - /* alloc and copy sub-tlv */ -@@ -2760,13 +2753,10 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */ - - if (length) { - /* spurious leftover data */ -- zlog_info( -- "Tunnel Encap attribute length is bad: %d leftover octets", -- length); -- bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR, -- BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, -- startp, total); -- return -1; -+ zlog_err("Tunnel Encap attribute length is bad: %d leftover octets", -+ length); -+ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, -+ args->total); - } - - return 0; -@@ -3718,8 +3708,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, - case BGP_ATTR_VNC: - #endif - case BGP_ATTR_ENCAP: -- ret = bgp_attr_encap(type, peer, length, attr, flag, -- startp); -+ ret = bgp_attr_encap(&attr_args); - break; - case BGP_ATTR_PREFIX_SID: - ret = bgp_attr_prefix_sid(&attr_args); --- -2.17.1 - diff --git a/src/sonic-frr/patch/0026-bgp-fib-suppress-announce-fix.patch b/src/sonic-frr/patch/0026-bgp-fib-suppress-announce-fix.patch new file mode 100644 index 000000000000..a6e9d4d4633e --- /dev/null +++ b/src/sonic-frr/patch/0026-bgp-fib-suppress-announce-fix.patch @@ -0,0 +1,122 @@ +From bf292bfd8b4e2d7ba181ce6efde4e43e066d1a88 Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Thu, 28 Mar 2024 12:25:05 -0400 +Subject: [PATCH 1/2] bgpd: Note when receiving but not understanding a route + notification + +When BGP has been asked to wait for FIB installation, on route +removal a return call is likely to not have the dest since BGP +will have cleaned up the node, entirely. Let's just note that +the prefix cannot be found if debugs are turned on and move on. + +Signed-off-by: Donald Sharp +--- + bgpd/bgp_zebra.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c +index efcf497850..ff79746b4c 100644 +--- a/bgpd/bgp_zebra.c ++++ b/bgpd/bgp_zebra.c +@@ -2610,8 +2610,12 @@ static int bgp_zebra_route_notify_owner(int command, struct zclient *zclient, + /* Find the bgp route node */ + dest = bgp_afi_node_lookup(bgp->rib[afi][safi], afi, safi, &p, + &bgp->vrf_prd); +- if (!dest) ++ if (!dest) { ++ if (BGP_DEBUG(zebra, ZEBRA)) ++ zlog_debug("%s: %pFX does not exist in the BGP table, nothing to do for %u", ++ __func__, &p, note); + return -1; ++ } + + switch (note) { + case ZAPI_ROUTE_INSTALLED: +-- +2.17.1 + + +From ada2e1099373e69e0eb29f4b1f3ba79c0cacf75a Mon Sep 17 00:00:00 2001 +From: Donald Sharp +Date: Thu, 28 Mar 2024 12:27:38 -0400 +Subject: [PATCH 2/2] bgpd: Arrange peer notification to after zebra announce + +Currently BGP attempts to send route change information +to it's peers *before* the route is installed into zebra. +This creates a bug in suppress-fib-pending in the following +scenario: + +a) bgp suppress-fib-pending and bgp has a route with +2 way ecmp. +b) bgp receives a route withdraw from peer 1. BGP +will send the route to zebra and mark the route as +FIB_INSTALL_PENDING. +c) bgp receives a route withdraw from peer 2. BGP +will see the route has the FIB_INSTALL_PENDING and +not send the withdrawal of the route to the peer. +bgp will then send the route deletion to zebra and +clean up the bgp_path_info's. + +At this point BGP is stuck where it has not sent +a route withdrawal to downstream peers. + +Let's modify the code in bgp_process_main_one to +send the route notification to zebra first before +attempting to announce the route. The route withdrawal +will remove the FIB_INSTALL_PENDING flag from the dest +and this will allow group_announce_route to believe +it can send the route withdrawal. + +For the master branch this is ok because the recent +backpressure commits are in place and nothing is going +to change from an ordering perspective in that regards. +Ostensibly this fix is also for operators of Sonic and +will be backported to the 8.5 branch as well. This will +change the order of the send to peers to be after the +zebra installation but sonic users are using suppress-fib-pending +anyways so updates won't go out until rib ack has been +received anyways. + +Signed-off-by: Donald Sharp +--- + bgpd/bgp_route.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c +index 2976042dda..fbff57634a 100644 +--- a/bgpd/bgp_route.c ++++ b/bgpd/bgp_route.c +@@ -3297,14 +3297,6 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, + } + #endif + +- group_announce_route(bgp, afi, safi, dest, new_select); +- +- /* unicast routes must also be annouced to labeled-unicast update-groups +- */ +- if (safi == SAFI_UNICAST) +- group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest, +- new_select); +- + /* FIB update. */ + if (bgp_fibupd_safi(safi) && (bgp->inst_type != BGP_INSTANCE_TYPE_VIEW) + && !bgp_option_check(BGP_OPT_NO_FIB)) { +@@ -3334,6 +3326,15 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, + } + } + ++ group_announce_route(bgp, afi, safi, dest, new_select); ++ ++ /* unicast routes must also be annouced to labeled-unicast update-groups ++ */ ++ if (safi == SAFI_UNICAST) ++ group_announce_route(bgp, afi, SAFI_LABELED_UNICAST, dest, ++ new_select); ++ ++ + bgp_process_evpn_route_injection(bgp, afi, safi, dest, new_select, + old_select); + +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0026-zebra-Add-encap-type-when-building-packet-for-FPM.patch b/src/sonic-frr/patch/0026-zebra-Add-encap-type-when-building-packet-for-FPM.patch deleted file mode 100644 index 8d7cdc34f415..000000000000 --- a/src/sonic-frr/patch/0026-zebra-Add-encap-type-when-building-packet-for-FPM.patch +++ /dev/null @@ -1,50 +0,0 @@ -From b914b0ad506649b5d341b549a37d3cb73e72b494 Mon Sep 17 00:00:00 2001 -From: Stepan Blyschak -Date: Mon, 30 Oct 2023 14:31:45 +0200 -Subject: [PATCH] zebra: Add encap type when building packet for FPM - -Signed-off-by: Donald Sharp -Signed-off-by: Stepan Blyschak ---- - zebra/rt_netlink.c | 22 ++++++++++++---------- - 1 file changed, 12 insertions(+), 10 deletions(-) - -diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c -index 6b9b04785..71505e037 100644 ---- a/zebra/rt_netlink.c -+++ b/zebra/rt_netlink.c -@@ -2269,19 +2269,21 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, - p, routedesc, bytelen, nexthop, - &req->n, &req->r, datalen, cmd)) - return 0; -+ -+ /* -+ * Add encapsulation information when -+ * installing via FPM. -+ */ -+ if (fpm) { -+ if (!netlink_route_nexthop_encap(&req->n, -+ datalen, -+ nexthop)) -+ return 0; -+ } -+ - nexthop_num++; - break; - } -- -- /* -- * Add encapsulation information when installing via -- * FPM. -- */ -- if (fpm) { -- if (!netlink_route_nexthop_encap( -- &req->n, datalen, nexthop)) -- return 0; -- } - } - - if (setsrc) { --- -2.17.1 - diff --git a/src/sonic-frr/patch/0027-lib-Do-not-convert-EVPN-prefixes-into-IPv4-IPv6-if-n.patch b/src/sonic-frr/patch/0027-lib-Do-not-convert-EVPN-prefixes-into-IPv4-IPv6-if-n.patch new file mode 100644 index 000000000000..fd9ec4608dff --- /dev/null +++ b/src/sonic-frr/patch/0027-lib-Do-not-convert-EVPN-prefixes-into-IPv4-IPv6-if-n.patch @@ -0,0 +1,77 @@ +From 37204cdc64999f8215deb99d4a5aa1a4222389af Mon Sep 17 00:00:00 2001 +From: Donatas Abraitis +Date: Thu, 15 Feb 2024 12:07:43 +0200 +Subject: [PATCH] lib: Do not convert EVPN prefixes into IPv4/IPv6 if not + needed + +Convert only when this is really needed, e.g. `match ip address prefix-list ...`. + +Otherwise, we can't have mixed match clauses, like: + +``` +match ip address prefix-list p1 +match evpn route-type prefix +``` + +This won't work, because the prefix is already converted, and we can't extract +route type, vni, etc. from the original EVPN prefix. + +Signed-off-by: Donatas Abraitis +(cherry picked from commit 439b739495e86912c8b9ec36b84e55311c549ba0) + +diff --git a/lib/routemap.c b/lib/routemap.c +index 683943eb6d..ed7c4ed72c 100644 +--- a/lib/routemap.c ++++ b/lib/routemap.c +@@ -2553,7 +2553,6 @@ route_map_result_t route_map_apply_ext(struct route_map *map, + struct route_map_index *index = NULL; + struct route_map_rule *set = NULL; + bool skip_match_clause = false; +- struct prefix conv; + + if (recursion > RMAP_RECURSION_LIMIT) { + flog_warn( +@@ -2571,27 +2570,14 @@ route_map_result_t route_map_apply_ext(struct route_map *map, + + map->applied++; + +- /* +- * Handling for matching evpn_routes in the prefix table. +- * +- * We convert type2/5 prefix to ipv4/6 prefix to do longest +- * prefix matching on. +- */ + if (prefix->family == AF_EVPN) { +- if (evpn_prefix2prefix(prefix, &conv) != 0) { +- zlog_debug( +- "Unable to convert EVPN prefix %pFX into IPv4/IPv6 prefix. Falling back to non-optimized route-map lookup", +- prefix); +- } else { +- zlog_debug( +- "Converted EVPN prefix %pFX into %pFX for optimized route-map lookup", +- prefix, &conv); +- +- prefix = &conv; +- } ++ index = map->head; ++ } else { ++ skip_match_clause = true; ++ index = route_map_get_index(map, prefix, match_object, ++ &match_ret); + } + +- index = route_map_get_index(map, prefix, match_object, &match_ret); + if (index) { + index->applied++; + if (rmap_debug) +@@ -2615,7 +2601,6 @@ route_map_result_t route_map_apply_ext(struct route_map *map, + ret = RMAP_DENYMATCH; + goto route_map_apply_end; + } +- skip_match_clause = true; + + for (; index; index = index->next) { + if (!skip_match_clause) { +-- +2.17.1 + diff --git a/src/sonic-frr/patch/0028-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch b/src/sonic-frr/patch/0028-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch deleted file mode 100644 index 7dbf3a85e738..000000000000 --- a/src/sonic-frr/patch/0028-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch +++ /dev/null @@ -1,112 +0,0 @@ -From fcc818160be57a1304481402c08962454e1dee5b Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Mon, 23 Oct 2023 23:34:10 +0300 -Subject: [PATCH 1/4] bgpd: Check mandatory attributes more carefully for - UPDATE message - -If we send a crafted BGP UPDATE message without mandatory attributes, we do -not check if the length of the path attributes is zero or not. We only check -if attr->flag is at least set or not. Imagine we send only unknown transit -attribute, then attr->flag is always 0. Also, this is true only if graceful-restart -capability is received. - -A crash: - -``` -bgpd[7834]: [TJ23Y-GY0RH] 127.0.0.1 Unknown attribute is received (type 31, length 16) -bgpd[7834]: [PCFFM-WMARW] 127.0.0.1(donatas-pc) rcvd UPDATE wlen 0 attrlen 20 alen 17 -BGP[7834]: Received signal 11 at 1698089639 (si_addr 0x0, PC 0x55eefd375b4a); aborting... -BGP[7834]: /usr/local/lib/libfrr.so.0(zlog_backtrace_sigsafe+0x6d) [0x7f3205ca939d] -BGP[7834]: /usr/local/lib/libfrr.so.0(zlog_signal+0xf3) [0x7f3205ca9593] -BGP[7834]: /usr/local/lib/libfrr.so.0(+0xf5181) [0x7f3205cdd181] -BGP[7834]: /lib/x86_64-linux-gnu/libpthread.so.0(+0x12980) [0x7f3204ff3980] -BGP[7834]: /usr/lib/frr/bgpd(+0x18ab4a) [0x55eefd375b4a] -BGP[7834]: /usr/local/lib/libfrr.so.0(route_map_apply_ext+0x310) [0x7f3205cd1290] -BGP[7834]: /usr/lib/frr/bgpd(+0x163610) [0x55eefd34e610] -BGP[7834]: /usr/lib/frr/bgpd(bgp_update+0x9a5) [0x55eefd35c1d5] -BGP[7834]: /usr/lib/frr/bgpd(bgp_nlri_parse_ip+0xb7) [0x55eefd35e867] -BGP[7834]: /usr/lib/frr/bgpd(+0x1555e6) [0x55eefd3405e6] -BGP[7834]: /usr/lib/frr/bgpd(bgp_process_packet+0x747) [0x55eefd345597] -BGP[7834]: /usr/local/lib/libfrr.so.0(event_call+0x83) [0x7f3205cef4a3] -BGP[7834]: /usr/local/lib/libfrr.so.0(frr_run+0xc0) [0x7f3205ca10a0] -BGP[7834]: /usr/lib/frr/bgpd(main+0x409) [0x55eefd2dc979] -``` - -Sending: - -``` -import socket -import time - -OPEN = (b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" -b"\xff\xff\x00\x62\x01\x04\xfd\xea\x00\x5a\x0a\x00\x00\x01\x45\x02" -b"\x06\x01\x04\x00\x01\x00\x01\x02\x02\x02\x00\x02\x02\x46\x00\x02" -b"\x06\x41\x04\x00\x00\xfd\xea\x02\x02\x06\x00\x02\x06\x45\x04\x00" -b"\x01\x01\x03\x02\x0e\x49\x0c\x0a\x64\x6f\x6e\x61\x74\x61\x73\x2d" -b"\x70\x63\x00\x02\x04\x40\x02\x00\x78\x02\x09\x47\x07\x00\x01\x01" -b"\x80\x00\x00\x00") - -KEEPALIVE = (b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" -b"\xff\xff\xff\xff\xff\xff\x00\x13\x04") - -UPDATE = bytearray.fromhex("ffffffffffffffffffffffffffffffff003c0200000014ff1f001000040146464646460004464646464646664646f50d05800100010200ffff000000") - -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -s.connect(('127.0.0.2', 179)) -s.send(OPEN) -data = s.recv(1024) -s.send(KEEPALIVE) -data = s.recv(1024) -s.send(UPDATE) -data = s.recv(1024) -time.sleep(1000) -s.close() -``` - -Reported-by: Iggy Frankovic -Signed-off-by: Donatas Abraitis -(cherry picked from commit d8482bf011cb2b173e85b65b4bf3d5061250cdb9) - -diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c -index ee20da3326..3a2d93ccd9 100644 ---- a/bgpd/bgp_attr.c -+++ b/bgpd/bgp_attr.c -@@ -3429,13 +3429,15 @@ bgp_attr_unknown(struct bgp_attr_parser_args *args) - } - - /* Well-known attribute check. */ --static int bgp_attr_check(struct peer *peer, struct attr *attr) -+static int bgp_attr_check(struct peer *peer, struct attr *attr, -+ bgp_size_t length) - { - uint8_t type = 0; - - /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an - * empty UPDATE. */ -- if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag) -+ if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag && -+ !length) - return BGP_ATTR_PARSE_PROCEED; - - /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required -@@ -3487,7 +3489,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, - enum bgp_attr_parse_ret ret; - uint8_t flag = 0; - uint8_t type = 0; -- bgp_size_t length; -+ bgp_size_t length = 0; - uint8_t *startp, *endp; - uint8_t *attr_endp; - uint8_t seen[BGP_ATTR_BITMAP_SIZE]; -@@ -3812,7 +3814,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, - } - - /* Check all mandatory well-known attributes are present */ -- ret = bgp_attr_check(peer, attr); -+ ret = bgp_attr_check(peer, attr, length); - if (ret < 0) - goto done; - --- -2.17.1 - diff --git a/src/sonic-frr/patch/0029-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch b/src/sonic-frr/patch/0029-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch deleted file mode 100644 index a1f848f12706..000000000000 --- a/src/sonic-frr/patch/0029-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 971f8684efceb2453accc5dcb5cbd8e4266c906d Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Fri, 20 Oct 2023 17:49:18 +0300 -Subject: [PATCH 2/4] bgpd: Handle MP_REACH_NLRI malformed packets with session - reset - -Avoid crashing bgpd. - -``` -(gdb) -bgp_mp_reach_parse (args=, mp_update=0x7fffffffe140) at bgpd/bgp_attr.c:2341 -2341 stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN); -(gdb) -stream_get (dst=0x7fffffffe1ac, s=0x7ffff0006e80, size=16) at lib/stream.c:320 -320 { -(gdb) -321 STREAM_VERIFY_SANE(s); -(gdb) -323 if (STREAM_READABLE(s) < size) { -(gdb) -34 return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); -(gdb) - -Thread 1 "bgpd" received signal SIGSEGV, Segmentation fault. -0x00005555556e37be in route_set_aspath_prepend (rule=0x555555aac0d0, prefix=0x7fffffffe050, - object=0x7fffffffdb00) at bgpd/bgp_routemap.c:2282 -2282 if (path->attr->aspath->refcnt) -(gdb) -``` - -With the configuration: - -``` - neighbor 127.0.0.1 remote-as external - neighbor 127.0.0.1 passive - neighbor 127.0.0.1 ebgp-multihop - neighbor 127.0.0.1 disable-connected-check - neighbor 127.0.0.1 update-source 127.0.0.2 - neighbor 127.0.0.1 timers 3 90 - neighbor 127.0.0.1 timers connect 1 - address-family ipv4 unicast - redistribute connected - neighbor 127.0.0.1 default-originate - neighbor 127.0.0.1 route-map RM_IN in - exit-address-family -! -route-map RM_IN permit 10 - set as-path prepend 200 -exit -``` - -Reported-by: Iggy Frankovic -Signed-off-by: Donatas Abraitis -(cherry picked from commit b08afc81c60607a4f736f418f2e3eb06087f1a35) - -diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c -index 3a2d93ccd9..a3fee07058 100644 ---- a/bgpd/bgp_attr.c -+++ b/bgpd/bgp_attr.c -@@ -2418,7 +2418,7 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args, - - mp_update->afi = afi; - mp_update->safi = safi; -- return BGP_ATTR_PARSE_EOR; -+ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_ATTR, 0); - } - - mp_update->afi = afi; -@@ -3739,10 +3739,6 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, - goto done; - } - -- if (ret == BGP_ATTR_PARSE_EOR) { -- goto done; -- } -- - if (ret == BGP_ATTR_PARSE_ERROR) { - flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR, - "%s: Attribute %s, parse error", peer->host, -diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h -index 33283f4bf6..ba8d4fc735 100644 ---- a/bgpd/bgp_attr.h -+++ b/bgpd/bgp_attr.h -@@ -379,7 +379,6 @@ enum bgp_attr_parse_ret { - /* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR - */ - BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3, -- BGP_ATTR_PARSE_EOR = -4, - }; - - struct bpacket_attr_vec_arr; -diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c -index a02d548941..5e0312a72d 100644 ---- a/bgpd/bgp_packet.c -+++ b/bgpd/bgp_packet.c -@@ -2060,8 +2060,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) - * Non-MP IPv4/Unicast EoR is a completely empty UPDATE - * and MP EoR should have only an empty MP_UNREACH - */ -- if ((!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0) -- || (attr_parse_ret == BGP_ATTR_PARSE_EOR)) { -+ if (!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0) { - afi_t afi = 0; - safi_t safi; - struct graceful_restart_info *gr_info; -@@ -2082,9 +2081,6 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) - && nlris[NLRI_MP_WITHDRAW].length == 0) { - afi = nlris[NLRI_MP_WITHDRAW].afi; - safi = nlris[NLRI_MP_WITHDRAW].safi; -- } else if (attr_parse_ret == BGP_ATTR_PARSE_EOR) { -- afi = nlris[NLRI_MP_UPDATE].afi; -- safi = nlris[NLRI_MP_UPDATE].safi; - } - - if (afi && peer->afc[afi][safi]) { --- -2.17.1 - diff --git a/src/sonic-frr/patch/0030-bgpd-Treat-EOR-as-withdrawn-to-avoid-unwanted-handli.patch b/src/sonic-frr/patch/0030-bgpd-Treat-EOR-as-withdrawn-to-avoid-unwanted-handli.patch deleted file mode 100644 index 4639e8c87cd4..000000000000 --- a/src/sonic-frr/patch/0030-bgpd-Treat-EOR-as-withdrawn-to-avoid-unwanted-handli.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 621f2efd64b305e96bb2941110e93bfbe5f9eda2 Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Fri, 27 Oct 2023 11:56:45 +0300 -Subject: [PATCH 3/4] bgpd: Treat EOR as withdrawn to avoid unwanted handling - of malformed attrs - -Treat-as-withdraw, otherwise if we just ignore it, we will pass it to be -processed as a normal UPDATE without mandatory attributes, that could lead -to harmful behavior. In this case, a crash for route-maps with the configuration -such as: - -``` -router bgp 65001 - no bgp ebgp-requires-policy - neighbor 127.0.0.1 remote-as external - neighbor 127.0.0.1 passive - neighbor 127.0.0.1 ebgp-multihop - neighbor 127.0.0.1 disable-connected-check - neighbor 127.0.0.1 update-source 127.0.0.2 - neighbor 127.0.0.1 timers 3 90 - neighbor 127.0.0.1 timers connect 1 - ! - address-family ipv4 unicast - neighbor 127.0.0.1 addpath-tx-all-paths - neighbor 127.0.0.1 default-originate - neighbor 127.0.0.1 route-map RM_IN in - exit-address-family -exit -! -route-map RM_IN permit 10 - set as-path prepend 200 -exit -``` - -Send a malformed optional transitive attribute: - -``` -import socket -import time - -OPEN = (b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" -b"\xff\xff\x00\x62\x01\x04\xfd\xea\x00\x5a\x0a\x00\x00\x01\x45\x02" -b"\x06\x01\x04\x00\x01\x00\x01\x02\x02\x02\x00\x02\x02\x46\x00\x02" -b"\x06\x41\x04\x00\x00\xfd\xea\x02\x02\x06\x00\x02\x06\x45\x04\x00" -b"\x01\x01\x03\x02\x0e\x49\x0c\x0a\x64\x6f\x6e\x61\x74\x61\x73\x2d" -b"\x70\x63\x00\x02\x04\x40\x02\x00\x78\x02\x09\x47\x07\x00\x01\x01" -b"\x80\x00\x00\x00") - -KEEPALIVE = (b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" -b"\xff\xff\xff\xff\xff\xff\x00\x13\x04") - -UPDATE = bytearray.fromhex("ffffffffffffffffffffffffffffffff002b0200000003c0ff00010100eb00ac100b0b001ad908ac100b0b") - -s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) -s.connect(('127.0.0.2', 179)) -s.send(OPEN) -data = s.recv(1024) -s.send(KEEPALIVE) -data = s.recv(1024) -s.send(UPDATE) -data = s.recv(1024) -time.sleep(100) -s.close() -``` - -Reported-by: Iggy Frankovic -Signed-off-by: Donatas Abraitis - -diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c -index a3fee07058..bdf078e7c8 100644 ---- a/bgpd/bgp_attr.c -+++ b/bgpd/bgp_attr.c -@@ -3435,10 +3435,13 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr, - uint8_t type = 0; - - /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an -- * empty UPDATE. */ -+ * empty UPDATE. Treat-as-withdraw, otherwise if we just ignore it, -+ * we will pass it to be processed as a normal UPDATE without mandatory -+ * attributes, that could lead to harmful behavior. -+ */ - if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag && - !length) -- return BGP_ATTR_PARSE_PROCEED; -+ return BGP_ATTR_PARSE_WITHDRAW; - - /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required - to carry any other path attributes.", though if MP_REACH_NLRI or NLRI -@@ -3866,7 +3869,13 @@ done: - aspath_unintern(&as4_path); - - transit = bgp_attr_get_transit(attr); -- if (ret != BGP_ATTR_PARSE_ERROR) { -+ /* If we received an UPDATE with mandatory attributes, then -+ * the unrecognized transitive optional attribute of that -+ * path MUST be passed. Otherwise, it's an error, and from -+ * security perspective it might be very harmful if we continue -+ * here with the unrecognized attributes. -+ */ -+ if (ret == BGP_ATTR_PARSE_PROCEED) { - /* Finally intern unknown attribute. */ - if (transit) - bgp_attr_set_transit(attr, transit_intern(transit)); --- -2.17.1 - diff --git a/src/sonic-frr/patch/0031-bgpd-Ignore-handling-NLRIs-if-we-received-MP_UNREACH.patch b/src/sonic-frr/patch/0031-bgpd-Ignore-handling-NLRIs-if-we-received-MP_UNREACH.patch deleted file mode 100644 index 12f1d909509f..000000000000 --- a/src/sonic-frr/patch/0031-bgpd-Ignore-handling-NLRIs-if-we-received-MP_UNREACH.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 4f75184ed110ffb002b0125797e0395cfa6e9ce8 Mon Sep 17 00:00:00 2001 -From: Donatas Abraitis -Date: Sun, 29 Oct 2023 22:44:45 +0200 -Subject: [PATCH 4/4] bgpd: Ignore handling NLRIs if we received - MP_UNREACH_NLRI - -If we receive MP_UNREACH_NLRI, we should stop handling remaining NLRIs if -no mandatory path attributes received. - -In other words, if MP_UNREACH_NLRI received, the remaining NLRIs should be handled -as a new data, but without mandatory attributes, it's a malformed packet. - -In normal case, this MUST not happen at all, but to avoid crashing bgpd, we MUST -handle that. - -Reported-by: Iggy Frankovic -Signed-off-by: Donatas Abraitis - -diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c -index bdf078e7c8..43a3cc91af 100644 ---- a/bgpd/bgp_attr.c -+++ b/bgpd/bgp_attr.c -@@ -3443,15 +3443,6 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr, - !length) - return BGP_ATTR_PARSE_WITHDRAW; - -- /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required -- to carry any other path attributes.", though if MP_REACH_NLRI or NLRI -- are present, it should. Check for any other attribute being present -- instead. -- */ -- if ((!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) && -- CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI)))) -- return BGP_ATTR_PARSE_PROCEED; -- - if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN))) - type = BGP_ATTR_ORIGIN; - -@@ -3470,6 +3461,16 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr, - && !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF))) - type = BGP_ATTR_LOCAL_PREF; - -+ /* An UPDATE message that contains the MP_UNREACH_NLRI is not required -+ * to carry any other path attributes. Though if MP_REACH_NLRI or NLRI -+ * are present, it should. Check for any other attribute being present -+ * instead. -+ */ -+ if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) && -+ CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI))) -+ return type ? BGP_ATTR_PARSE_MISSING_MANDATORY -+ : BGP_ATTR_PARSE_PROCEED; -+ - /* If any of the well-known mandatory attributes are not present - * in an UPDATE message, then "treat-as-withdraw" MUST be used. - */ -diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h -index ba8d4fc735..275965fe62 100644 ---- a/bgpd/bgp_attr.h -+++ b/bgpd/bgp_attr.h -@@ -379,6 +379,7 @@ enum bgp_attr_parse_ret { - /* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR - */ - BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3, -+ BGP_ATTR_PARSE_MISSING_MANDATORY = -4, - }; - - struct bpacket_attr_vec_arr; -diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c -index 5e0312a72d..59f895ac58 100644 ---- a/bgpd/bgp_packet.c -+++ b/bgpd/bgp_packet.c -@@ -1983,7 +1983,12 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) - /* Network Layer Reachability Information. */ - update_len = end - stream_pnt(s); - -- if (update_len && attribute_len) { -+ /* If we received MP_UNREACH_NLRI attribute, but also NLRIs, then -+ * NLRIs should be handled as a new data. Though, if we received -+ * NLRIs without mandatory attributes, they should be ignored. -+ */ -+ if (update_len && attribute_len && -+ attr_parse_ret != BGP_ATTR_PARSE_MISSING_MANDATORY) { - /* Set NLRI portion to structure. */ - nlris[NLRI_UPDATE].afi = AFI_IP; - nlris[NLRI_UPDATE].safi = SAFI_UNICAST; --- -2.17.1 - diff --git a/src/sonic-frr/patch/0032-zebra-Fix-fpm-multipath-encap-addition.patch b/src/sonic-frr/patch/0032-zebra-Fix-fpm-multipath-encap-addition.patch deleted file mode 100644 index 5e3ce1441206..000000000000 --- a/src/sonic-frr/patch/0032-zebra-Fix-fpm-multipath-encap-addition.patch +++ /dev/null @@ -1,58 +0,0 @@ -From b7ac2397103fe7d347d0766bd9966ff2302403c5 Mon Sep 17 00:00:00 2001 -From: dgsudharsan -Date: Tue, 21 Nov 2023 01:17:24 +0000 -Subject: [PATCH] zebra: Fix fpm multipath encap addition The fpm code path in - building a ecmp route for evpn has a bug that caused it to not add the encap - attribute to the netlink message. See - #f0f7b285b99dbd971400d33feea007232c0bd4a9 for the single path case being - fixed. - - -diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c -index 71505e037a..6bdc15592c 100644 ---- a/zebra/rt_netlink.c -+++ b/zebra/rt_netlink.c -@@ -2330,6 +2330,16 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, - tag)) - return 0; - -+ /* -+ * Add encapsulation information when installing via -+ * FPM. -+ */ -+ if (fpm) { -+ if (!netlink_route_nexthop_encap( -+ &req->n, datalen, nexthop)) -+ return 0; -+ } -+ - if (!setsrc && src1) { - if (p->family == AF_INET) - src.ipv4 = src1->ipv4; -@@ -2343,23 +2353,6 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, - - nl_attr_nest_end(&req->n, nest); - -- /* -- * Add encapsulation information when installing via -- * FPM. -- */ -- if (fpm) { -- for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), -- nexthop)) { -- if (CHECK_FLAG(nexthop->flags, -- NEXTHOP_FLAG_RECURSIVE)) -- continue; -- if (!netlink_route_nexthop_encap( -- &req->n, datalen, nexthop)) -- return 0; -- } -- } -- -- - if (setsrc) { - if (p->family == AF_INET) { - if (!nl_attr_put(&req->n, datalen, RTA_PREFSRC, --- -2.17.1 - diff --git a/src/sonic-frr/patch/series b/src/sonic-frr/patch/series index bcb29008824f..9874e27aea8a 100644 --- a/src/sonic-frr/patch/series +++ b/src/sonic-frr/patch/series @@ -4,8 +4,6 @@ 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 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 @@ -18,18 +16,12 @@ cross-compile-changes.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 -0021-zebra-remove-duplicated-nexthops-when-sending-fpm-msg.patch -0022-bgpd-Don-t-read-the-first-byte-of-ORF-header-if-we-a.patch -0023-bgpd-Make-sure-we-have-enough-data-to-read-two-bytes.patch -0024-bgpd-Do-not-process-NLRIs-if-the-attribute-length-is.patch -0025-bgpd-Use-treat-as-withdraw-for-tunnel-encapsulation-.patch -0026-zebra-Add-encap-type-when-building-packet-for-FPM.patch -0027-zebra-Fix-non-notification-of-better-admin-won.patch -0028-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch -0029-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch -0030-bgpd-Treat-EOR-as-withdrawn-to-avoid-unwanted-handli.patch -0031-bgpd-Ignore-handling-NLRIs-if-we-received-MP_UNREACH.patch -0032-zebra-Fix-fpm-multipath-encap-addition.patch -0033-zebra-The-dplane_fpm_nl-return-path-leaks-memory.patch +0019-zebra-remove-duplicated-nexthops-when-sending-fpm-msg.patch +0020-zebra-Fix-non-notification-of-better-admin-won.patch +0021-Disable-ipv6-src-address-test-in-pceplib.patch +0022-cross-compile-changes.patch +0023-zebra-The-dplane_fpm_nl-return-path-leaks-memory.patch +0024-lib-use-snmp-s-large-fd-sets-for-agentx.patch +0025-bgp-community-memory-leak-fix.patch +0026-bgp-fib-suppress-announce-fix.patch +0027-lib-Do-not-convert-EVPN-prefixes-into-IPv4-IPv6-if-n.patch