diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index a174cf97a3..477e43ce9f 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -724,7 +724,7 @@ static void setsids(struct bgp_path_info *bpi, extra = bgp_path_info_extra_get(bpi); for (i = 0; i < num_sids; i++) - memcpy(&extra->sid[i], &sid[i], sizeof(struct in6_addr)); + memcpy(&extra->sid[i].sid, &sid[i], sizeof(struct in6_addr)); extra->num_sids = num_sids; } @@ -743,6 +743,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ struct bgp_path_info *bpi; struct bgp_path_info *bpi_ultimate; struct bgp_path_info *new; + struct bgp_path_info_extra *extra; uint32_t num_sids = 0; if (new_attr->srv6_l3vpn || new_attr->srv6_vpn) @@ -829,10 +830,31 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ * rewrite sid */ if (num_sids) { - if (new_attr->srv6_l3vpn) + if (new_attr->srv6_l3vpn) { setsids(bpi, &new_attr->srv6_l3vpn->sid, num_sids); - else if (new_attr->srv6_vpn) + + extra = bgp_path_info_extra_get(bpi); + + extra->sid[0].loc_block_len = + new_attr->srv6_l3vpn->loc_block_len; + extra->sid[0].loc_node_len = + new_attr->srv6_l3vpn->loc_node_len; + extra->sid[0].func_len = + new_attr->srv6_l3vpn->func_len; + extra->sid[0].arg_len = + new_attr->srv6_l3vpn->arg_len; + + if (new_attr->srv6_l3vpn->transposition_len + != 0) + transpose_sid( + &extra->sid[0].sid, + decode_label(label), + new_attr->srv6_l3vpn + ->transposition_offset, + new_attr->srv6_l3vpn + ->transposition_len); + } else if (new_attr->srv6_vpn) setsids(bpi, &new_attr->srv6_vpn->sid, num_sids); } @@ -903,9 +925,26 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ * rewrite sid */ if (num_sids) { - if (new_attr->srv6_l3vpn) + if (new_attr->srv6_l3vpn) { setsids(new, &new_attr->srv6_l3vpn->sid, num_sids); - else if (new_attr->srv6_vpn) + + extra = bgp_path_info_extra_get(new); + + extra->sid[0].loc_block_len = + new_attr->srv6_l3vpn->loc_block_len; + extra->sid[0].loc_node_len = + new_attr->srv6_l3vpn->loc_node_len; + extra->sid[0].func_len = new_attr->srv6_l3vpn->func_len; + extra->sid[0].arg_len = new_attr->srv6_l3vpn->arg_len; + + if (new_attr->srv6_l3vpn->transposition_len != 0) + transpose_sid(&extra->sid[0].sid, + decode_label(label), + new_attr->srv6_l3vpn + ->transposition_offset, + new_attr->srv6_l3vpn + ->transposition_len); + } else if (new_attr->srv6_vpn) setsids(new, &new_attr->srv6_vpn->sid, num_sids); } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7e5521ad2d..d729137226 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4040,11 +4040,28 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, /* Update SRv6 SID */ if (attr->srv6_l3vpn) { extra = bgp_path_info_extra_get(pi); - if (sid_diff(&extra->sid[0], &attr->srv6_l3vpn->sid)) { - sid_copy(&extra->sid[0], + if (sid_diff(&extra->sid[0].sid, + &attr->srv6_l3vpn->sid)) { + sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid); extra->num_sids = 1; + extra->sid[0].loc_block_len = 0; + extra->sid[0].loc_node_len = 0; + extra->sid[0].func_len = 0; + extra->sid[0].arg_len = 0; + + if (attr->srv6_l3vpn->loc_block_len != 0) { + extra->sid[0].loc_block_len = + attr->srv6_l3vpn->loc_block_len; + extra->sid[0].loc_node_len = + attr->srv6_l3vpn->loc_node_len; + extra->sid[0].func_len = + attr->srv6_l3vpn->func_len; + extra->sid[0].arg_len = + attr->srv6_l3vpn->arg_len; + } + /* * draft-ietf-bess-srv6-services-07 * The part of SRv6 SID may be encoded as MPLS @@ -4052,7 +4069,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, */ if (attr->srv6_l3vpn->transposition_len != 0) transpose_sid( - &extra->sid[0], + &extra->sid[0].sid, decode_label(label), attr->srv6_l3vpn ->transposition_offset, @@ -4061,8 +4078,10 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } } else if (attr->srv6_vpn) { extra = bgp_path_info_extra_get(pi); - if (sid_diff(&extra->sid[0], &attr->srv6_vpn->sid)) { - sid_copy(&extra->sid[0], &attr->srv6_vpn->sid); + if (sid_diff(&extra->sid[0].sid, + &attr->srv6_vpn->sid)) { + sid_copy(&extra->sid[0].sid, + &attr->srv6_vpn->sid); extra->num_sids = 1; } } @@ -4243,9 +4262,16 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (safi == SAFI_MPLS_VPN) { extra = bgp_path_info_extra_get(new); if (attr->srv6_l3vpn) { - sid_copy(&extra->sid[0], &attr->srv6_l3vpn->sid); + sid_copy(&extra->sid[0].sid, &attr->srv6_l3vpn->sid); extra->num_sids = 1; + extra->sid[0].loc_block_len = + attr->srv6_l3vpn->loc_block_len; + extra->sid[0].loc_node_len = + attr->srv6_l3vpn->loc_node_len; + extra->sid[0].func_len = attr->srv6_l3vpn->func_len; + extra->sid[0].arg_len = attr->srv6_l3vpn->arg_len; + /* * draft-ietf-bess-srv6-services-07 * The part of SRv6 SID may be encoded as MPLS Label for @@ -4253,11 +4279,11 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, */ if (attr->srv6_l3vpn->transposition_len != 0) transpose_sid( - &extra->sid[0], decode_label(label), + &extra->sid[0].sid, decode_label(label), attr->srv6_l3vpn->transposition_offset, attr->srv6_l3vpn->transposition_len); } else if (attr->srv6_vpn) { - sid_copy(&extra->sid[0], &attr->srv6_vpn->sid); + sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid); extra->num_sids = 1; } } @@ -10479,7 +10505,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn, /* Remote SID */ if (path->extra && path->extra->num_sids > 0 && safi != SAFI_EVPN) { - inet_ntop(AF_INET6, &path->extra->sid, buf, sizeof(buf)); + inet_ntop(AF_INET6, &path->extra->sid[0].sid, buf, sizeof(buf)); if (json_paths) json_object_string_add(json_path, "remoteSid", buf); else diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 75da2723e6..de94a132ff 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -145,6 +145,14 @@ struct bgp_path_mh_info { struct bgp_path_evpn_nh_info *nh_info; }; +struct bgp_sid_info { + struct in6_addr sid; + uint8_t loc_block_len; + uint8_t loc_node_len; + uint8_t func_len; + uint8_t arg_len; +}; + /* Ancillary information to struct bgp_path_info, * used for uncommonly used data (aggregation, MPLS, etc.) * and lazily allocated to save memory. @@ -168,7 +176,7 @@ struct bgp_path_info_extra { #define BGP_EVPN_MACIP_TYPE_SVI_IP (1 << 0) /* SRv6 SID(s) for SRv6-VPN */ - struct in6_addr sid[BGP_MAX_SIDS]; + struct bgp_sid_info sid[BGP_MAX_SIDS]; uint32_t num_sids; #ifdef ENABLE_BGP_VNC diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 51763a0e1a..da8cc89cda 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1434,11 +1434,10 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, api_nh->weight = nh_weight; - if (mpinfo->extra - && !sid_zero(&mpinfo->extra->sid[0]) + if (mpinfo->extra && !sid_zero(&mpinfo->extra->sid[0].sid) && !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) { has_valid_sid = 1; - memcpy(&api_nh->seg6_segs, &mpinfo->extra->sid[0], + memcpy(&api_nh->seg6_segs, &mpinfo->extra->sid[0].sid, sizeof(api_nh->seg6_segs)); }