From 5d4af03ff87ca8d0e0537c6f2f372bdc101e6e6c Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 12 Dec 2023 09:16:35 +0100 Subject: [PATCH 1/3] bgpd: rework debug nexthop in separate function When adding/removing a route, the next-hop can be dumped with debugging turned on. Move this function in a separate function. There is no other change in this commit. Signed-off-by: Philippe Guibert --- bgpd/bgp_zebra.c | 131 ++++++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 64 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index dfb8d01f2d..cd459603a5 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1212,6 +1212,71 @@ static bool bgp_zebra_use_nhop_weighted(struct bgp *bgp, struct attr *attr, return true; } +static void bgp_debug_zebra_nh(struct zapi_route *api) +{ + int i; + int nh_family; + char nh_buf[INET6_ADDRSTRLEN]; + char eth_buf[ETHER_ADDR_STRLEN + 7] = { '\0' }; + char buf1[ETHER_ADDR_STRLEN]; + char label_buf[20]; + char sid_buf[20]; + char segs_buf[256]; + struct zapi_nexthop *api_nh; + int count; + + count = api->nexthop_num; + for (i = 0; i < count; i++) { + api_nh = &api->nexthops[i]; + switch (api_nh->type) { + case NEXTHOP_TYPE_IFINDEX: + nh_buf[0] = '\0'; + break; + case NEXTHOP_TYPE_IPV4: + case NEXTHOP_TYPE_IPV4_IFINDEX: + nh_family = AF_INET; + inet_ntop(nh_family, &api_nh->gate, nh_buf, + sizeof(nh_buf)); + break; + case NEXTHOP_TYPE_IPV6: + case NEXTHOP_TYPE_IPV6_IFINDEX: + nh_family = AF_INET6; + inet_ntop(nh_family, &api_nh->gate, nh_buf, + sizeof(nh_buf)); + break; + case NEXTHOP_TYPE_BLACKHOLE: + strlcpy(nh_buf, "blackhole", sizeof(nh_buf)); + break; + default: + /* Note: add new nexthop case */ + assert(0); + break; + } + + label_buf[0] = '\0'; + eth_buf[0] = '\0'; + segs_buf[0] = '\0'; + if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL) && + !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) + snprintf(label_buf, sizeof(label_buf), "label %u", + api_nh->labels[0]); + if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6) && + !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) { + inet_ntop(AF_INET6, &api_nh->seg6_segs[0], sid_buf, + sizeof(sid_buf)); + snprintf(segs_buf, sizeof(segs_buf), "segs %s", sid_buf); + } + if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN) && + !is_zero_mac(&api_nh->rmac)) + snprintf(eth_buf, sizeof(eth_buf), " RMAC %s", + prefix_mac2str(&api_nh->rmac, buf1, + sizeof(buf1))); + zlog_debug(" nhop [%d]: %s if %u VRF %u wt %u %s %s %s", i + 1, + nh_buf, api_nh->ifindex, api_nh->vrf_id, + api_nh->weight, label_buf, segs_buf, eth_buf); + } +} + void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, struct bgp_path_info *info, struct bgp *bgp, afi_t afi, safi_t safi) @@ -1241,6 +1306,7 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, uint32_t ttl = 0; uint32_t bos = 0; uint32_t exp = 0; + int recursion_flag = 0; /* * BGP is installing this route and bgp has been configured @@ -1571,75 +1637,12 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, } if (bgp_debug_zebra(p)) { - char nh_buf[INET6_ADDRSTRLEN]; - char eth_buf[ETHER_ADDR_STRLEN + 7] = {'\0'}; - char buf1[ETHER_ADDR_STRLEN]; - char label_buf[20]; - char sid_buf[20]; - char segs_buf[256]; - int i; - zlog_debug( "Tx route %s VRF %u %pFX metric %u tag %" ROUTE_TAG_PRI " count %d nhg %d", is_add ? "add" : "delete", bgp->vrf_id, &api.prefix, api.metric, api.tag, api.nexthop_num, nhg_id); - for (i = 0; i < api.nexthop_num; i++) { - api_nh = &api.nexthops[i]; - - switch (api_nh->type) { - case NEXTHOP_TYPE_IFINDEX: - nh_buf[0] = '\0'; - break; - case NEXTHOP_TYPE_IPV4: - case NEXTHOP_TYPE_IPV4_IFINDEX: - nh_family = AF_INET; - inet_ntop(nh_family, &api_nh->gate, nh_buf, - sizeof(nh_buf)); - break; - case NEXTHOP_TYPE_IPV6: - case NEXTHOP_TYPE_IPV6_IFINDEX: - nh_family = AF_INET6; - inet_ntop(nh_family, &api_nh->gate, nh_buf, - sizeof(nh_buf)); - break; - case NEXTHOP_TYPE_BLACKHOLE: - strlcpy(nh_buf, "blackhole", sizeof(nh_buf)); - break; - default: - /* Note: add new nexthop case */ - assert(0); - break; - } - - label_buf[0] = '\0'; - eth_buf[0] = '\0'; - segs_buf[0] = '\0'; - if (CHECK_FLAG(api_nh->flags, - ZAPI_NEXTHOP_FLAG_LABEL) && - !CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN)) - snprintf(label_buf, sizeof(label_buf), - "label %u", api_nh->labels[0]); - if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6) && - !CHECK_FLAG(api_nh->flags, - ZAPI_NEXTHOP_FLAG_EVPN)) { - inet_ntop(AF_INET6, &api_nh->seg6_segs[0], - sid_buf, sizeof(sid_buf)); - snprintf(segs_buf, sizeof(segs_buf), "segs %s", - sid_buf); - } - if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN) && - !is_zero_mac(&api_nh->rmac)) - snprintf(eth_buf, sizeof(eth_buf), " RMAC %s", - prefix_mac2str(&api_nh->rmac, - buf1, sizeof(buf1))); - zlog_debug(" nhop [%d]: %s if %u VRF %u wt %u %s %s %s", - i + 1, nh_buf, api_nh->ifindex, - api_nh->vrf_id, api_nh->weight, - label_buf, segs_buf, eth_buf); - } - - int recursion_flag = 0; + bgp_debug_zebra_nh(&api); if (CHECK_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION)) recursion_flag = 1; From 237ebf8d4503c841df8b3615f99b0c780bacccbd Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 12 Dec 2023 09:31:33 +0100 Subject: [PATCH 2/3] bgpd: rework bgp_zebra_announce() function, separate nexthop handling Separate the processing in bgp_zebra_announce(), by separating the nexthop code in a separate function called bgp_zebra_announce_parse_nexthop(). This commit does not bring any functional change. Signed-off-by: Philippe Guibert --- bgpd/bgp_zebra.c | 457 ++++++++++++++++++++++++----------------------- 1 file changed, 237 insertions(+), 220 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index cd459603a5..a550b90e8e 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1212,6 +1212,238 @@ static bool bgp_zebra_use_nhop_weighted(struct bgp *bgp, struct attr *attr, return true; } +static void bgp_zebra_announce_parse_nexthop( + struct bgp_path_info *info, const struct prefix *p, struct bgp *bgp, + struct zapi_route *api, unsigned int *valid_nh_count, afi_t afi, + safi_t safi, uint32_t *nhg_id, uint32_t *metric, route_tag_t *tag, + bool *allow_recursion) +{ + struct zapi_nexthop *api_nh; + int nh_family; + struct bgp_path_info *mpinfo; + struct bgp *bgp_orig; + struct attr local_attr; + struct bgp_path_info local_info; + struct bgp_path_info *mpinfo_cp = &local_info; + mpls_label_t *labels; + uint32_t num_labels = 0; + mpls_label_t nh_label; + int nh_othervrf = 0; + bool nh_updated = false; + bool do_wt_ecmp; + uint32_t ttl = 0; + uint32_t bos = 0; + uint32_t exp = 0; + + /* Determine if we're doing weighted ECMP or not */ + do_wt_ecmp = bgp_path_info_mpath_chkwtd(bgp, info); + + /* + * vrf leaking support (will have only one nexthop) + */ + if (info->extra && info->extra->vrfleak && + info->extra->vrfleak->bgp_orig) + nh_othervrf = 1; + + /* EVPN MAC-IP routes are installed with a L3 NHG id */ + if (nhg_id && bgp_evpn_path_es_use_nhg(bgp, info, nhg_id)) { + mpinfo = NULL; + api->nhgid = *nhg_id; + if (*nhg_id) + SET_FLAG(api->message, ZAPI_MESSAGE_NHG); + } else { + mpinfo = info; + } + + for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) { + labels = NULL; + num_labels = 0; + uint32_t nh_weight; + bool is_evpn; + bool is_parent_evpn; + + if (*valid_nh_count >= multipath_num) + break; + + *mpinfo_cp = *mpinfo; + nh_weight = 0; + + /* Get nexthop address-family */ + if (p->family == AF_INET && + !BGP_ATTR_MP_NEXTHOP_LEN_IP6(mpinfo_cp->attr)) + nh_family = AF_INET; + else if (p->family == AF_INET6 || + (p->family == AF_INET && + BGP_ATTR_MP_NEXTHOP_LEN_IP6(mpinfo_cp->attr))) + nh_family = AF_INET6; + else + continue; + + /* If processing for weighted ECMP, determine the next hop's + * weight. Based on user setting, we may skip the next hop + * in some situations. + */ + if (do_wt_ecmp) { + if (!bgp_zebra_use_nhop_weighted(bgp, mpinfo->attr, + &nh_weight)) + continue; + } + if (CHECK_FLAG(info->flags, BGP_PATH_SELECTED)) + api_nh = &api->nexthops[*valid_nh_count]; + else + api_nh = &api->backup_nexthops[*valid_nh_count]; + + if (CHECK_FLAG(info->attr->flag, + ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR))) + api_nh->srte_color = bgp_attr_get_color(info->attr); + + if (bgp_debug_zebra(&api->prefix)) { + if (mpinfo->extra) { + zlog_debug("%s: p=%pFX, bgp_is_valid_label: %d", + __func__, p, + bgp_is_valid_label( + &mpinfo->extra->label[0])); + } else { + zlog_debug( + "%s: p=%pFX, extra is NULL, no label", + __func__, p); + } + } + + if (bgp->table_map[afi][safi].name) { + /* Copy info and attributes, so the route-map + apply doesn't modify the BGP route info. */ + local_attr = *mpinfo->attr; + mpinfo_cp->attr = &local_attr; + if (!bgp_table_map_apply(bgp->table_map[afi][safi].map, + p, mpinfo_cp)) + continue; + + /* metric/tag is only allowed to be + * overridden on 1st nexthop */ + if (mpinfo == info) { + if (metric) + *metric = mpinfo_cp->attr->med; + if (tag) + *tag = mpinfo_cp->attr->tag; + } + } + + BGP_ORIGINAL_UPDATE(bgp_orig, mpinfo, bgp); + + is_parent_evpn = is_route_parent_evpn(mpinfo); + + if (nh_family == AF_INET) { + nh_updated = update_ipv4nh_for_route_install( + nh_othervrf, bgp_orig, + &mpinfo_cp->attr->nexthop, mpinfo_cp->attr, + is_parent_evpn, api_nh); + } else { + ifindex_t ifindex = IFINDEX_INTERNAL; + struct in6_addr *nexthop; + + nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp, + &ifindex); + + if (!nexthop) + nh_updated = update_ipv4nh_for_route_install( + nh_othervrf, bgp_orig, + &mpinfo_cp->attr->nexthop, + mpinfo_cp->attr, is_parent_evpn, + api_nh); + else + nh_updated = update_ipv6nh_for_route_install( + nh_othervrf, bgp_orig, nexthop, ifindex, + mpinfo, info, is_parent_evpn, api_nh); + } + + is_evpn = !!CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN); + + /* Did we get proper nexthop info to update zebra? */ + if (!nh_updated) + continue; + + /* Allow recursion if it is a multipath group with both + * eBGP and iBGP paths. + */ + if (allow_recursion && !*allow_recursion && + CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX) && + (mpinfo->peer->sort == BGP_PEER_IBGP || + mpinfo->peer->sort == BGP_PEER_CONFED)) + *allow_recursion = true; + + if (mpinfo->extra) { + labels = mpinfo->extra->label; + num_labels = mpinfo->extra->num_labels; + } + + if (labels && (num_labels > 0) && + (is_evpn || bgp_is_valid_label(&labels[0]))) { + enum lsp_types_t nh_label_type = ZEBRA_LSP_NONE; + + if (is_evpn) { + nh_label = *bgp_evpn_path_info_labels_get_l3vni( + labels, num_labels); + nh_label_type = ZEBRA_LSP_EVPN; + } else { + mpls_lse_decode(labels[0], &nh_label, &ttl, + &exp, &bos); + } + + SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL); + api_nh->label_num = 1; + api_nh->label_type = nh_label_type; + api_nh->labels[0] = nh_label; + } + + if (is_evpn + && mpinfo->attr->evpn_overlay.type + != OVERLAY_INDEX_GATEWAY_IP) + memcpy(&api_nh->rmac, &(mpinfo->attr->rmac), + sizeof(struct ethaddr)); + + api_nh->weight = nh_weight; + + if (((mpinfo->attr->srv6_l3vpn && + !sid_zero_ipv6(&mpinfo->attr->srv6_l3vpn->sid)) || + (mpinfo->attr->srv6_vpn && + !sid_zero_ipv6(&mpinfo->attr->srv6_vpn->sid))) && + !is_evpn && bgp_is_valid_label(&labels[0])) { + struct in6_addr *sid_tmp = + mpinfo->attr->srv6_l3vpn + ? (&mpinfo->attr->srv6_l3vpn->sid) + : (&mpinfo->attr->srv6_vpn->sid); + + memcpy(&api_nh->seg6_segs[0], sid_tmp, + sizeof(api_nh->seg6_segs[0])); + + if (mpinfo->attr->srv6_l3vpn && + mpinfo->attr->srv6_l3vpn->transposition_len != 0) { + mpls_lse_decode(labels[0], &nh_label, &ttl, + &exp, &bos); + + if (nh_label < MPLS_LABEL_UNRESERVED_MIN) { + if (bgp_debug_zebra(&api->prefix)) + zlog_debug( + "skip invalid SRv6 routes: transposition scheme is used, but label is too small"); + continue; + } + + transpose_sid(&api_nh->seg6_segs[0], nh_label, + mpinfo->attr->srv6_l3vpn + ->transposition_offset, + mpinfo->attr->srv6_l3vpn + ->transposition_len); + } + + api_nh->seg_num = 1; + SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6); + } + + (*valid_nh_count)++; + } +} + static void bgp_debug_zebra_nh(struct zapi_route *api) { int i; @@ -1282,31 +1514,15 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, safi_t safi) { struct zapi_route api = { 0 }; - struct zapi_nexthop *api_nh; - int nh_family; unsigned int valid_nh_count = 0; bool allow_recursion = false; uint8_t distance; struct peer *peer; - struct bgp_path_info *mpinfo; - struct bgp *bgp_orig; uint32_t metric; - struct attr local_attr; - struct bgp_path_info local_info; - struct bgp_path_info *mpinfo_cp = &local_info; route_tag_t tag; - mpls_label_t *labels; - uint32_t num_labels = 0; - mpls_label_t nh_label; - int nh_othervrf = 0; - bool nh_updated = false; - bool do_wt_ecmp; - uint32_t nhg_id = 0; bool is_add; - uint32_t ttl = 0; - uint32_t bos = 0; - uint32_t exp = 0; - int recursion_flag = 0; + uint32_t nhg_id = 0; + uint32_t recursion_flag = 0; /* * BGP is installing this route and bgp has been configured @@ -1331,13 +1547,6 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, return; } - /* - * vrf leaking support (will have only one nexthop) - */ - if (info->extra && info->extra->vrfleak && - info->extra->vrfleak->bgp_orig) - nh_othervrf = 1; - /* Make Zebra API structure. */ api.vrf_id = bgp->vrf_id; api.type = ZEBRA_ROUTE_BGP; @@ -1383,201 +1592,9 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, /* Metric is currently based on the best-path only */ metric = info->attr->med; - /* Determine if we're doing weighted ECMP or not */ - do_wt_ecmp = bgp_path_info_mpath_chkwtd(bgp, info); - - /* EVPN MAC-IP routes are installed with a L3 NHG id */ - if (bgp_evpn_path_es_use_nhg(bgp, info, &nhg_id)) { - mpinfo = NULL; - api.nhgid = nhg_id; - if (nhg_id) - SET_FLAG(api.message, ZAPI_MESSAGE_NHG); - } else { - mpinfo = info; - } - - for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) { - labels = NULL; - num_labels = 0; - uint32_t nh_weight; - bool is_evpn; - bool is_parent_evpn; - - if (valid_nh_count >= multipath_num) - break; - - *mpinfo_cp = *mpinfo; - nh_weight = 0; - - /* Get nexthop address-family */ - if (p->family == AF_INET && - !BGP_ATTR_MP_NEXTHOP_LEN_IP6(mpinfo_cp->attr)) - nh_family = AF_INET; - else if (p->family == AF_INET6 || - (p->family == AF_INET && - BGP_ATTR_MP_NEXTHOP_LEN_IP6(mpinfo_cp->attr))) - nh_family = AF_INET6; - else - continue; - - /* If processing for weighted ECMP, determine the next hop's - * weight. Based on user setting, we may skip the next hop - * in some situations. - */ - if (do_wt_ecmp) { - if (!bgp_zebra_use_nhop_weighted(bgp, mpinfo->attr, - &nh_weight)) - continue; - } - api_nh = &api.nexthops[valid_nh_count]; - - if (CHECK_FLAG(info->attr->flag, - ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR))) - api_nh->srte_color = bgp_attr_get_color(info->attr); - - if (bgp_debug_zebra(&api.prefix)) { - if (mpinfo->extra) { - zlog_debug("%s: p=%pFX, bgp_is_valid_label: %d", - __func__, p, - bgp_is_valid_label( - &mpinfo->extra->label[0])); - } else { - zlog_debug( - "%s: p=%pFX, extra is NULL, no label", - __func__, p); - } - } - - if (bgp->table_map[afi][safi].name) { - /* Copy info and attributes, so the route-map - apply doesn't modify the BGP route info. */ - local_attr = *mpinfo->attr; - mpinfo_cp->attr = &local_attr; - if (!bgp_table_map_apply(bgp->table_map[afi][safi].map, - p, mpinfo_cp)) - continue; - - /* metric/tag is only allowed to be - * overridden on 1st nexthop */ - if (mpinfo == info) { - metric = mpinfo_cp->attr->med; - tag = mpinfo_cp->attr->tag; - } - } - - BGP_ORIGINAL_UPDATE(bgp_orig, mpinfo, bgp); - - is_parent_evpn = is_route_parent_evpn(mpinfo); - - if (nh_family == AF_INET) { - nh_updated = update_ipv4nh_for_route_install( - nh_othervrf, bgp_orig, - &mpinfo_cp->attr->nexthop, mpinfo_cp->attr, - is_parent_evpn, api_nh); - } else { - ifindex_t ifindex = IFINDEX_INTERNAL; - struct in6_addr *nexthop; - - nexthop = bgp_path_info_to_ipv6_nexthop(mpinfo_cp, - &ifindex); - - if (!nexthop) - nh_updated = update_ipv4nh_for_route_install( - nh_othervrf, bgp_orig, - &mpinfo_cp->attr->nexthop, - mpinfo_cp->attr, is_parent_evpn, - api_nh); - else - nh_updated = update_ipv6nh_for_route_install( - nh_othervrf, bgp_orig, nexthop, ifindex, - mpinfo, info, is_parent_evpn, api_nh); - } - - is_evpn = !!CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN); - - /* Did we get proper nexthop info to update zebra? */ - if (!nh_updated) - continue; - - /* Allow recursion if it is a multipath group with both - * eBGP and iBGP paths. - */ - if (!allow_recursion - && CHECK_FLAG(bgp->flags, BGP_FLAG_PEERTYPE_MULTIPATH_RELAX) - && (mpinfo->peer->sort == BGP_PEER_IBGP - || mpinfo->peer->sort == BGP_PEER_CONFED)) - allow_recursion = true; - - if (mpinfo->extra) { - labels = mpinfo->extra->label; - num_labels = mpinfo->extra->num_labels; - } - - if (labels && (num_labels > 0) && - (is_evpn || bgp_is_valid_label(&labels[0]))) { - enum lsp_types_t nh_label_type = ZEBRA_LSP_NONE; - - if (is_evpn) { - nh_label = *bgp_evpn_path_info_labels_get_l3vni( - labels, num_labels); - nh_label_type = ZEBRA_LSP_EVPN; - } else { - mpls_lse_decode(labels[0], &nh_label, &ttl, - &exp, &bos); - } - - SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL); - api_nh->label_num = 1; - api_nh->label_type = nh_label_type; - api_nh->labels[0] = nh_label; - } - - if (is_evpn - && mpinfo->attr->evpn_overlay.type - != OVERLAY_INDEX_GATEWAY_IP) - memcpy(&api_nh->rmac, &(mpinfo->attr->rmac), - sizeof(struct ethaddr)); - - api_nh->weight = nh_weight; - - if (((mpinfo->attr->srv6_l3vpn && - !sid_zero_ipv6(&mpinfo->attr->srv6_l3vpn->sid)) || - (mpinfo->attr->srv6_vpn && - !sid_zero_ipv6(&mpinfo->attr->srv6_vpn->sid))) && - !is_evpn && bgp_is_valid_label(&labels[0])) { - struct in6_addr *sid_tmp = - mpinfo->attr->srv6_l3vpn - ? (&mpinfo->attr->srv6_l3vpn->sid) - : (&mpinfo->attr->srv6_vpn->sid); - - memcpy(&api_nh->seg6_segs[0], sid_tmp, - sizeof(api_nh->seg6_segs[0])); - - if (mpinfo->attr->srv6_l3vpn && - mpinfo->attr->srv6_l3vpn->transposition_len != 0) { - mpls_lse_decode(labels[0], &nh_label, &ttl, - &exp, &bos); - - if (nh_label < MPLS_LABEL_UNRESERVED_MIN) { - if (bgp_debug_zebra(&api.prefix)) - zlog_debug( - "skip invalid SRv6 routes: transposition scheme is used, but label is too small"); - continue; - } - - transpose_sid(&api_nh->seg6_segs[0], nh_label, - mpinfo->attr->srv6_l3vpn - ->transposition_offset, - mpinfo->attr->srv6_l3vpn - ->transposition_len); - } - - api_nh->seg_num = 1; - SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6); - } - - valid_nh_count++; - } + bgp_zebra_announce_parse_nexthop(info, p, bgp, &api, &valid_nh_count, + afi, safi, &nhg_id, &metric, &tag, + &allow_recursion); is_add = (valid_nh_count || nhg_id) ? true : false; From d8477d4bb534e37121c08b358fd923c703540ae0 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Tue, 12 Dec 2023 21:04:49 +0100 Subject: [PATCH 3/3] bgpd, lib: add zapi_route_set_nhg_id() support There is no function that both sets the nhg id, and sets the ZAPI_MESSAGE_NHG flag if the nhg id is valid. Create a ZAPI API to do this, and apply the changes wherever needed. Signed-off-by: Philippe Guibert --- bgpd/bgp_zebra.c | 4 +--- lib/zclient.h | 9 +++++++++ sharpd/sharp_zebra.c | 3 +-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index a550b90e8e..69afc7ea97 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1248,9 +1248,7 @@ static void bgp_zebra_announce_parse_nexthop( /* EVPN MAC-IP routes are installed with a L3 NHG id */ if (nhg_id && bgp_evpn_path_es_use_nhg(bgp, info, nhg_id)) { mpinfo = NULL; - api->nhgid = *nhg_id; - if (*nhg_id) - SET_FLAG(api->message, ZAPI_MESSAGE_NHG); + zapi_route_set_nhg_id(api, nhg_id); } else { mpinfo = info; } diff --git a/lib/zclient.h b/lib/zclient.h index 8b6aebc2fd..f249afe61e 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -1169,6 +1169,15 @@ static inline void zapi_route_set_blackhole(struct zapi_route *api, SET_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP); }; +static inline void zapi_route_set_nhg_id(struct zapi_route *api, + uint32_t *nhg_id) +{ + api->nexthop_num = 0; + api->nhgid = *nhg_id; + if (api->nhgid) + SET_FLAG(api->message, ZAPI_MESSAGE_NHG); +}; + extern enum zclient_send_status zclient_send_mlag_register(struct zclient *client, uint32_t bit_map); extern enum zclient_send_status diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index ff4895189d..cbfa0d1ccc 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -251,8 +251,7 @@ static bool route_add(const struct prefix *p, vrf_id_t vrf_id, uint8_t instance, /* Only send via ID if nhgroup has been successfully installed */ if (nhgid && sharp_nhgroup_id_is_installed(nhgid)) { - SET_FLAG(api.message, ZAPI_MESSAGE_NHG); - api.nhgid = nhgid; + zapi_route_set_nhg_id(&api, &nhgid); } else { for (ALL_NEXTHOPS_PTR(nhg, nh)) { /* Check if we set a VNI label */