diff options
| -rw-r--r-- | bgpd/bgp_mplsvpn.c | 58 | ||||
| -rw-r--r-- | bgpd/bgp_mplsvpn.h | 1 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 35 | ||||
| -rw-r--r-- | bgpd/bgp_route.h | 2 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 16 | ||||
| -rw-r--r-- | bgpd/bgpd.h | 1 |
6 files changed, 59 insertions, 54 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index eafc37f20c..32a1d9a152 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -520,7 +520,7 @@ static bool sid_exist(struct bgp *bgp, const struct in6_addr *sid) * else: try to allocate as auto-mode */ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index, - struct in6_addr *sid) + struct in6_addr *sid_locator) { struct listnode *node; struct prefix_ipv6 *chunk; @@ -528,10 +528,11 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index, bool alloced = false; int label = 0; - if (!bgp || !sid) + if (!bgp || !sid_locator) return false; for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) { + *sid_locator = chunk->prefix; sid_buf = chunk->prefix; if (index != 0) { label = index << 12; @@ -556,7 +557,6 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index, return 0; sid_register(bgp, &sid_buf, bgp->srv6_locator_name); - *sid = sid_buf; return label; } @@ -564,7 +564,7 @@ void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi) { int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF); char buf[256]; - struct in6_addr *sid; + struct in6_addr *tovpn_sid, *tovpn_sid_locator; uint32_t tovpn_sid_index = 0, tovpn_sid_transpose_label; bool tovpn_sid_auto = false; @@ -598,24 +598,33 @@ void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi) return; } - sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr)); + tovpn_sid_locator = + XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr)); tovpn_sid_transpose_label = - alloc_new_sid(bgp_vpn, tovpn_sid_index, sid); + alloc_new_sid(bgp_vpn, tovpn_sid_index, tovpn_sid_locator); if (tovpn_sid_transpose_label == 0) { zlog_debug("%s: not allocated new sid for vrf %s: afi %s", __func__, bgp_vrf->name_pretty, afi2str(afi)); return; } + tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr)); + *tovpn_sid = *tovpn_sid_locator; + transpose_sid(tovpn_sid, tovpn_sid_transpose_label, + BGP_PREFIX_SID_SRV6_TRANSPOSITION_OFFSET, + BGP_PREFIX_SID_SRV6_TRANSPOSITION_LENGTH); + if (debug) { - inet_ntop(AF_INET6, sid, buf, sizeof(buf)); + inet_ntop(AF_INET6, tovpn_sid, buf, sizeof(buf)); zlog_debug("%s: new sid %s allocated for vrf %s: afi %s", __func__, buf, bgp_vrf->name_pretty, afi2str(afi)); } + + bgp_vrf->vpn_policy[afi].tovpn_sid = tovpn_sid; + bgp_vrf->vpn_policy[afi].tovpn_sid_locator = tovpn_sid_locator; bgp_vrf->vpn_policy[afi].tovpn_sid_transpose_label = tovpn_sid_transpose_label; - bgp_vrf->vpn_policy[afi].tovpn_sid = sid; } void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset, @@ -847,16 +856,11 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ 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); + extra->sid[0].transposition_len = + new_attr->srv6_l3vpn->transposition_len; + extra->sid[0].transposition_offset = + new_attr->srv6_l3vpn + ->transposition_offset; } else if (new_attr->srv6_vpn) setsids(bpi, &new_attr->srv6_vpn->sid, num_sids); @@ -951,14 +955,10 @@ leak_update(struct bgp *bgp, /* destination bgp instance */ 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); + extra->sid[0].transposition_len = + new_attr->srv6_l3vpn->transposition_len; + extra->sid[0].transposition_offset = + new_attr->srv6_l3vpn->transposition_offset; } else if (new_attr->srv6_vpn) setsids(new, &new_attr->srv6_vpn->sid, num_sids); } else @@ -1235,7 +1235,7 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */ static_attr.originator_id = bgp_vpn->router_id; /* Set SID for SRv6 VPN */ - if (bgp_vrf->vpn_policy[afi].tovpn_sid) { + if (bgp_vrf->vpn_policy[afi].tovpn_sid_locator) { encode_label(bgp_vrf->vpn_policy[afi].tovpn_sid_transpose_label, &label); static_attr.srv6_l3vpn = XCALLOC(MTYPE_BGP_SRV6_L3VPN, @@ -1255,8 +1255,8 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */ static_attr.srv6_l3vpn->transposition_offset = BGP_PREFIX_SID_SRV6_TRANSPOSITION_OFFSET; memcpy(&static_attr.srv6_l3vpn->sid, - bgp_vrf->vpn_policy[afi].tovpn_sid, - sizeof(static_attr.srv6_l3vpn->sid)); + bgp_vrf->vpn_policy[afi].tovpn_sid_locator, + sizeof(struct in6_addr)); } diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h index b0d586223f..5bf772fefe 100644 --- a/bgpd/bgp_mplsvpn.h +++ b/bgpd/bgp_mplsvpn.h @@ -21,6 +21,7 @@ #ifndef _QUAGGA_BGP_MPLSVPN_H #define _QUAGGA_BGP_MPLSVPN_H +#include "bgpd/bgp_attr.h" #include "bgpd/bgp_route.h" #include "bgpd/bgp_rd.h" #include "bgpd/bgp_zebra.h" diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index bd7031defe..eb1e57de2e 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -4198,6 +4198,8 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, extra->sid[0].loc_node_len = 0; extra->sid[0].func_len = 0; extra->sid[0].arg_len = 0; + extra->sid[0].transposition_len = 0; + extra->sid[0].transposition_offset = 0; if (attr->srv6_l3vpn->loc_block_len != 0) { extra->sid[0].loc_block_len = @@ -4208,21 +4210,13 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, 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 the efficient packing. - */ - if (attr->srv6_l3vpn->transposition_len != 0) - transpose_sid( - &extra->sid[0].sid, - decode_label(label), + extra->sid[0].transposition_len = attr->srv6_l3vpn - ->transposition_offset, + ->transposition_len; + extra->sid[0].transposition_offset = attr->srv6_l3vpn - ->transposition_len); + ->transposition_offset; + } } } else if (attr->srv6_vpn) { extra = bgp_path_info_extra_get(pi); @@ -4419,17 +4413,10 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, 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 - * the efficient packing. - */ - if (attr->srv6_l3vpn->transposition_len != 0) - transpose_sid( - &extra->sid[0].sid, decode_label(label), - attr->srv6_l3vpn->transposition_offset, - attr->srv6_l3vpn->transposition_len); + extra->sid[0].transposition_len = + attr->srv6_l3vpn->transposition_len; + extra->sid[0].transposition_offset = + attr->srv6_l3vpn->transposition_offset; } else if (attr->srv6_vpn) { sid_copy(&extra->sid[0].sid, &attr->srv6_vpn->sid); extra->num_sids = 1; diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index a8ec2dc907..743b369bfa 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -154,6 +154,8 @@ struct bgp_sid_info { uint8_t loc_node_len; uint8_t func_len; uint8_t arg_len; + uint8_t transposition_len; + uint8_t transposition_offset; }; /* Ancillary information to struct bgp_path_info, diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index c295b06601..5a060d46f5 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1260,6 +1260,7 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, struct bgp_path_info *mpinfo_cp = &local_info; route_tag_t tag; mpls_label_t label; + struct bgp_sid_info *sid_info; int nh_othervrf = 0; bool is_evpn; bool nh_updated = false; @@ -1476,9 +1477,22 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p, if (mpinfo->extra && !sid_zero(&mpinfo->extra->sid[0].sid) && !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) { - memcpy(&api_nh->seg6_segs, &mpinfo->extra->sid[0].sid, + sid_info = &mpinfo->extra->sid[0]; + + memcpy(&api_nh->seg6_segs, &sid_info->sid, sizeof(api_nh->seg6_segs)); + if (sid_info->transposition_len != 0) { + if (!bgp_is_valid_label( + &mpinfo->extra->label[0])) + continue; + + label = label_pton(&mpinfo->extra->label[0]); + transpose_sid(&api_nh->seg6_segs, label, + sid_info->transposition_offset, + sid_info->transposition_len); + } + SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_SEG6); } diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 926b0b033f..a9475f39a7 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -234,6 +234,7 @@ struct vpn_policy { */ uint32_t tovpn_sid_index; /* unset => set to 0 */ struct in6_addr *tovpn_sid; + struct in6_addr *tovpn_sid_locator; uint32_t tovpn_sid_transpose_label; struct in6_addr *tovpn_zebra_vrf_sid_last_sent; }; |
