mirror of
https://github.com/FRRouting/frr.git
synced 2026-01-11 20:07:27 +00:00
Merge pull request #19223 from pguibert6WIND/sid_extend_to_32bits
Some checks failed
github-ci / Ubuntu 22.04 amd64 Build (push) Has been cancelled
github-ci / Ubuntu 22.04 arm64 Build (push) Has been cancelled
github-ci / Ubuntu 24.04 amd64 Build (push) Has been cancelled
github-ci / Ubuntu 24.04 arm64 Build (push) Has been cancelled
github-ci / Ubuntu 22.04 amd64 Test (push) Has been cancelled
github-ci / Ubuntu 22.04 arm64 Test (push) Has been cancelled
github-ci / Ubuntu 24.04 amd64 Test (push) Has been cancelled
github-ci / Ubuntu 24.04 arm64 Test (push) Has been cancelled
Some checks failed
github-ci / Ubuntu 22.04 amd64 Build (push) Has been cancelled
github-ci / Ubuntu 22.04 arm64 Build (push) Has been cancelled
github-ci / Ubuntu 24.04 amd64 Build (push) Has been cancelled
github-ci / Ubuntu 24.04 arm64 Build (push) Has been cancelled
github-ci / Ubuntu 22.04 amd64 Test (push) Has been cancelled
github-ci / Ubuntu 22.04 arm64 Test (push) Has been cancelled
github-ci / Ubuntu 24.04 amd64 Test (push) Has been cancelled
github-ci / Ubuntu 24.04 arm64 Test (push) Has been cancelled
SID extension to 32bits
This commit is contained in:
commit
74b7eb143a
30 changed files with 852 additions and 143 deletions
|
|
@ -798,19 +798,19 @@ static void *srv6_l3service_hash_alloc(void *p)
|
|||
return p;
|
||||
}
|
||||
|
||||
static void srv6_l3service_free(struct bgp_attr_srv6_l3service *l3service)
|
||||
void bgp_attr_srv6_l3service_free(struct bgp_attr_srv6_l3service *l3service)
|
||||
{
|
||||
XFREE(MTYPE_BGP_SRV6_L3SERVICE, l3service);
|
||||
}
|
||||
|
||||
static struct bgp_attr_srv6_l3service *
|
||||
srv6_l3service_intern(struct bgp_attr_srv6_l3service *l3service)
|
||||
struct bgp_attr_srv6_l3service *
|
||||
bgp_attr_srv6_l3service_intern(struct bgp_attr_srv6_l3service *l3service)
|
||||
{
|
||||
struct bgp_attr_srv6_l3service *find;
|
||||
|
||||
find = hash_get(srv6_l3service_hash, l3service, srv6_l3service_hash_alloc);
|
||||
if (find != l3service)
|
||||
srv6_l3service_free(l3service);
|
||||
bgp_attr_srv6_l3service_free(l3service);
|
||||
find->refcnt++;
|
||||
return find;
|
||||
}
|
||||
|
|
@ -827,7 +827,7 @@ static void srv6_l3service_unintern(struct bgp_attr_srv6_l3service **l3servicep)
|
|||
|
||||
if (l3service->refcnt == 0) {
|
||||
hash_release(srv6_l3service_hash, l3service);
|
||||
srv6_l3service_free(l3service);
|
||||
bgp_attr_srv6_l3service_free(l3service);
|
||||
*l3servicep = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -950,7 +950,7 @@ static void srv6_init(void)
|
|||
|
||||
static void srv6_finish(void)
|
||||
{
|
||||
hash_clean_and_free(&srv6_l3service_hash, (void (*)(void *))srv6_l3service_free);
|
||||
hash_clean_and_free(&srv6_l3service_hash, (void (*)(void *))bgp_attr_srv6_l3service_free);
|
||||
hash_clean_and_free(&srv6_vpn_hash, (void (*)(void *))srv6_vpn_free);
|
||||
}
|
||||
|
||||
|
|
@ -1314,7 +1314,7 @@ struct attr *bgp_attr_intern(struct attr *attr)
|
|||
|
||||
if (attr->srv6_l3service) {
|
||||
if (!attr->srv6_l3service->refcnt)
|
||||
attr->srv6_l3service = srv6_l3service_intern(attr->srv6_l3service);
|
||||
attr->srv6_l3service = bgp_attr_srv6_l3service_intern(attr->srv6_l3service);
|
||||
else
|
||||
attr->srv6_l3service->refcnt++;
|
||||
}
|
||||
|
|
@ -1668,7 +1668,7 @@ void bgp_attr_flush(struct attr *attr)
|
|||
attr->encap_subtlvs = NULL;
|
||||
}
|
||||
if (attr->srv6_l3service && !attr->srv6_l3service->refcnt) {
|
||||
srv6_l3service_free(attr->srv6_l3service);
|
||||
bgp_attr_srv6_l3service_free(attr->srv6_l3service);
|
||||
attr->srv6_l3service = NULL;
|
||||
}
|
||||
if (attr->srv6_vpn && !attr->srv6_vpn->refcnt) {
|
||||
|
|
@ -3415,7 +3415,7 @@ bgp_attr_srv6_service(struct bgp_attr_parser_args *args)
|
|||
return err;
|
||||
}
|
||||
|
||||
attr->srv6_l3service = srv6_l3service_intern(attr->srv6_l3service);
|
||||
attr->srv6_l3service = bgp_attr_srv6_l3service_intern(attr->srv6_l3service);
|
||||
}
|
||||
|
||||
/* Placeholder code for unsupported type */
|
||||
|
|
|
|||
|
|
@ -383,6 +383,9 @@ extern enum bgp_attr_parse_ret
|
|||
bgp_attr_parse(struct peer *peer, struct attr *attr, bgp_size_t size,
|
||||
struct bgp_nlri *mp_update, struct bgp_nlri *mp_withdraw);
|
||||
extern struct attr *bgp_attr_intern(struct attr *attr);
|
||||
extern struct bgp_attr_srv6_l3service *
|
||||
bgp_attr_srv6_l3service_intern(struct bgp_attr_srv6_l3service *vpn);
|
||||
extern void bgp_attr_srv6_l3service_free(struct bgp_attr_srv6_l3service *vpn);
|
||||
extern void bgp_attr_unintern_sub(struct attr *attr);
|
||||
extern void bgp_attr_unintern(struct attr **pattr);
|
||||
extern void bgp_attr_flush(struct attr *attr);
|
||||
|
|
|
|||
|
|
@ -371,9 +371,11 @@ void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp *bgp, afi_t afi)
|
|||
bgp->vpn_policy[afi].tovpn_sid_locator->block_bits_length;
|
||||
ctx.node_len =
|
||||
bgp->vpn_policy[afi].tovpn_sid_locator->node_bits_length;
|
||||
ctx.function_len =
|
||||
bgp->vpn_policy[afi]
|
||||
.tovpn_sid_locator->function_bits_length;
|
||||
if (CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_FUNC_WIDE))
|
||||
ctx.function_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP;
|
||||
else
|
||||
ctx.function_len =
|
||||
bgp->vpn_policy[afi].tovpn_sid_locator->function_bits_length;
|
||||
ctx.argument_len =
|
||||
bgp->vpn_policy[afi]
|
||||
.tovpn_sid_locator->argument_bits_length;
|
||||
|
|
@ -440,7 +442,10 @@ void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp *bgp)
|
|||
if (bgp->tovpn_sid_locator) {
|
||||
ctx.block_len = bgp->tovpn_sid_locator->block_bits_length;
|
||||
ctx.node_len = bgp->tovpn_sid_locator->node_bits_length;
|
||||
ctx.function_len = bgp->tovpn_sid_locator->function_bits_length;
|
||||
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_TOVPN_SID_FUNC_WIDE))
|
||||
ctx.function_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP;
|
||||
else
|
||||
ctx.function_len = bgp->tovpn_sid_locator->function_bits_length;
|
||||
ctx.argument_len = bgp->tovpn_sid_locator->argument_bits_length;
|
||||
if (CHECK_FLAG(bgp->tovpn_sid_locator->flags, SRV6_LOCATOR_USID))
|
||||
SET_SRV6_FLV_OP(ctx.flv.flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID);
|
||||
|
|
@ -508,9 +513,11 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi)
|
|||
bgp->vpn_policy[afi].tovpn_sid_locator->block_bits_length;
|
||||
seg6localctx.node_len =
|
||||
bgp->vpn_policy[afi].tovpn_sid_locator->node_bits_length;
|
||||
seg6localctx.function_len =
|
||||
bgp->vpn_policy[afi]
|
||||
.tovpn_sid_locator->function_bits_length;
|
||||
if (CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_FUNC_WIDE))
|
||||
seg6localctx.function_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP;
|
||||
else
|
||||
seg6localctx.function_len =
|
||||
bgp->vpn_policy[afi].tovpn_sid_locator->function_bits_length;
|
||||
seg6localctx.argument_len =
|
||||
bgp->vpn_policy[afi]
|
||||
.tovpn_sid_locator->argument_bits_length;
|
||||
|
|
@ -526,6 +533,7 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi)
|
|||
ctx.behavior = afi == AFI_IP ? ZEBRA_SEG6_LOCAL_ACTION_END_DT4
|
||||
: ZEBRA_SEG6_LOCAL_ACTION_END_DT6;
|
||||
bgp_zebra_release_srv6_sid(&ctx, bgp->vpn_policy[afi].tovpn_sid_locator->name);
|
||||
UNSET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_FUNC_WIDE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -559,8 +567,10 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp)
|
|||
seg6localctx.block_len =
|
||||
bgp->tovpn_sid_locator->block_bits_length;
|
||||
seg6localctx.node_len = bgp->tovpn_sid_locator->node_bits_length;
|
||||
seg6localctx.function_len =
|
||||
bgp->tovpn_sid_locator->function_bits_length;
|
||||
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_TOVPN_SID_FUNC_WIDE))
|
||||
seg6localctx.function_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP;
|
||||
else
|
||||
seg6localctx.function_len = bgp->tovpn_sid_locator->function_bits_length;
|
||||
seg6localctx.argument_len =
|
||||
bgp->tovpn_sid_locator->argument_bits_length;
|
||||
}
|
||||
|
|
@ -573,6 +583,7 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp)
|
|||
ctx.vrf_id = bgp->vrf_id;
|
||||
ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END_DT46;
|
||||
bgp_zebra_release_srv6_sid(&ctx, bgp->tovpn_sid_locator->name);
|
||||
UNSET_FLAG(bgp->vrf_flags, BGP_VRF_TOVPN_SID_FUNC_WIDE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -704,26 +715,37 @@ bool srv6_sid_compose(struct in6_addr *sid_value, struct srv6_locator *locator,
|
|||
uint8_t offset = 0;
|
||||
uint8_t func_len = 0, shift_len = 0;
|
||||
uint32_t sid_func_max = 0;
|
||||
bool store_in_label = true;
|
||||
|
||||
if (!locator || !sid_value)
|
||||
return false;
|
||||
|
||||
if (locator->function_bits_length >
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH) {
|
||||
if (locator->function_bits_length > BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP) {
|
||||
if (debug)
|
||||
zlog_debug("%s: invalid SRv6 Locator (%pFX): Function Length must be less or equal to %d",
|
||||
__func__, &locator->prefix,
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH);
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Max value that can be encoded in the Function part of the SID */
|
||||
sid_func_max = (1 << locator->function_bits_length) - 1;
|
||||
if ((CHECK_FLAG(locator->flags, SRV6_LOCATOR_F3216) ||
|
||||
CHECK_FLAG(locator->flags, SRV6_LOCATOR_F4816)) &&
|
||||
sid_func > 0xFFFF) {
|
||||
/* f3216 and f4816 supports ewlib. increase sid_func_max */
|
||||
sid_func_max = 0xffffffff;
|
||||
store_in_label = false;
|
||||
} else if (locator->function_bits_length == BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP)
|
||||
/* shifting 32 bits over a 32 bit is not possible. directly encode func_max */
|
||||
sid_func_max = 0xffffffff;
|
||||
else
|
||||
sid_func_max = (1 << locator->function_bits_length) - 1;
|
||||
|
||||
|
||||
if (sid_func > sid_func_max) {
|
||||
if (debug)
|
||||
zlog_debug("%s: invalid SRv6 Locator (%pFX): Function Length is too short to support specified function (%u)",
|
||||
__func__, &locator->prefix, sid_func);
|
||||
zlog_debug("%s: invalid SRv6 Locator (%pFX): Function Length is too short (%u) to support specified function (%u)",
|
||||
__func__, &locator->prefix, sid_func_max, sid_func);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -735,37 +757,45 @@ bool srv6_sid_compose(struct in6_addr *sid_value, struct srv6_locator *locator,
|
|||
/* First, we put the locator (LOC) in the most significant bits of sid_value */
|
||||
*sid_value = locator->prefix.prefix;
|
||||
|
||||
/*
|
||||
* Then, we compute the offset at which we have to place the function (FUNC).
|
||||
* FUNC will be placed immediately after LOC, i.e. at block_bits_length + node_bits_length
|
||||
*/
|
||||
offset = locator->block_bits_length + locator->node_bits_length;
|
||||
|
||||
/*
|
||||
* The FUNC part of the SID is advertised in the label field of SRv6 Service TLV.
|
||||
* (see SID Transposition Scheme, RFC 9252 section #4).
|
||||
* Therefore, we need to encode the FUNC in the most significant bits of the
|
||||
* 20-bit label.
|
||||
*/
|
||||
func_len = locator->function_bits_length;
|
||||
shift_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH - func_len;
|
||||
|
||||
label = sid_func << shift_len;
|
||||
if (label < MPLS_LABEL_UNRESERVED_MIN) {
|
||||
if (debug)
|
||||
zlog_debug("%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
|
||||
__func__, &locator->prefix, label);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sid_exist(bgp_get_default(), sid_value)) {
|
||||
zlog_warn("%s: skipped to allocate SRv6 SID (%pFX): SID %pI6 already in use",
|
||||
__func__, &locator->prefix, sid_value);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Finally, we put the FUNC in sid_value at the computed offset */
|
||||
transpose_sid(sid_value, label, offset, func_len);
|
||||
/*
|
||||
* Then, we compute the offset at which we have to place the function (FUNC).
|
||||
* FUNC will be placed immediately after LOC, i.e. at block_bits_length + node_bits_length
|
||||
*/
|
||||
offset = locator->block_bits_length + locator->node_bits_length;
|
||||
|
||||
if (store_in_label)
|
||||
func_len = locator->function_bits_length;
|
||||
else
|
||||
func_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP;
|
||||
if (store_in_label && func_len <= BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL) {
|
||||
/*
|
||||
* The FUNC part of the SID is advertised in the label field of SRv6 Service TLV.
|
||||
* (see SID Transposition Scheme, RFC 9252 section #4).
|
||||
* Therefore, we need to encode the FUNC in the most significant bits of the
|
||||
* 20-bit label.
|
||||
*/
|
||||
shift_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL - func_len;
|
||||
label = sid_func << shift_len;
|
||||
if (label < MPLS_LABEL_UNRESERVED_MIN) {
|
||||
if (debug)
|
||||
zlog_debug("%s: skipped to allocate SRv6 SID (%pFX): Label (%u) is too small to use",
|
||||
__func__, &locator->prefix, label);
|
||||
return false;
|
||||
}
|
||||
/* Finally, we put the FUNC in sid_value at the computed offset */
|
||||
transpose_sid(sid_value, label, offset, func_len,
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL);
|
||||
} else {
|
||||
label = sid_func;
|
||||
transpose_sid(sid_value, label, offset, func_len,
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -995,6 +1025,7 @@ void delete_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
|
|||
ctx.behavior = afi == AFI_IP ? ZEBRA_SEG6_LOCAL_ACTION_END_DT4
|
||||
: ZEBRA_SEG6_LOCAL_ACTION_END_DT6;
|
||||
bgp_zebra_release_srv6_sid(&ctx, bgp_vrf->vpn_policy[afi].tovpn_sid_locator->name);
|
||||
UNSET_FLAG(bgp_vrf->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_FUNC_WIDE);
|
||||
|
||||
sid_unregister(bgp_vpn, bgp_vrf->vpn_policy[afi].tovpn_sid);
|
||||
XFREE(MTYPE_BGP_SRV6_SID, bgp_vrf->vpn_policy[afi].tovpn_sid);
|
||||
|
|
@ -1041,6 +1072,7 @@ void delete_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
|
|||
ctx.vrf_id = bgp_vrf->vrf_id;
|
||||
ctx.behavior = ZEBRA_SEG6_LOCAL_ACTION_END_DT46;
|
||||
bgp_zebra_release_srv6_sid(&ctx, bgp_vrf->tovpn_sid_locator->name);
|
||||
UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_TOVPN_SID_FUNC_WIDE);
|
||||
|
||||
sid_unregister(bgp_vpn, bgp_vrf->tovpn_sid);
|
||||
XFREE(MTYPE_BGP_SRV6_SID, bgp_vrf->tovpn_sid);
|
||||
|
|
@ -1086,13 +1118,13 @@ void delete_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
|
|||
* |
|
||||
* offset from MSB
|
||||
*/
|
||||
void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
|
||||
uint8_t len)
|
||||
void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset, uint8_t len,
|
||||
uint8_t len_max)
|
||||
{
|
||||
for (uint8_t idx = 0; idx < len; idx++) {
|
||||
uint8_t tidx = offset + idx;
|
||||
sid->s6_addr[tidx / 8] &= ~(0x1 << (7 - tidx % 8));
|
||||
if (label >> (19 - idx) & 0x1)
|
||||
if (label >> (len_max - 1 - idx) & 0x1)
|
||||
sid->s6_addr[tidx / 8] |= 0x1 << (7 - tidx % 8);
|
||||
}
|
||||
}
|
||||
|
|
@ -1716,7 +1748,7 @@ static bool vpn_leak_from_vrf_fill_srv6(struct attr *attr, struct bgp *from_bgp,
|
|||
mpls_label_t *label)
|
||||
{
|
||||
/* Set SID for SRv6 VPN */
|
||||
if (from_bgp->vpn_policy[afi].tovpn_sid_locator) {
|
||||
if (from_bgp->vpn_policy[afi].tovpn_sid_locator && from_bgp->vpn_policy[afi].tovpn_sid) {
|
||||
struct srv6_locator *locator = from_bgp->vpn_policy[afi].tovpn_sid_locator;
|
||||
|
||||
encode_label(from_bgp->vpn_policy[afi].tovpn_sid_transpose_label, label);
|
||||
|
|
@ -1734,22 +1766,32 @@ static bool vpn_leak_from_vrf_fill_srv6(struct attr *attr, struct bgp *from_bgp,
|
|||
from_bgp->vpn_policy[afi].tovpn_sid_locator->block_bits_length;
|
||||
attr->srv6_l3service->loc_node_len =
|
||||
from_bgp->vpn_policy[afi].tovpn_sid_locator->node_bits_length;
|
||||
attr->srv6_l3service->func_len =
|
||||
from_bgp->vpn_policy[afi].tovpn_sid_locator->function_bits_length;
|
||||
if (CHECK_FLAG(from_bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_FUNC_WIDE))
|
||||
attr->srv6_l3service->func_len =
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP;
|
||||
else
|
||||
attr->srv6_l3service->func_len =
|
||||
from_bgp->vpn_policy[afi].tovpn_sid_locator->function_bits_length;
|
||||
attr->srv6_l3service->arg_len =
|
||||
from_bgp->vpn_policy[afi].tovpn_sid_locator->argument_bits_length;
|
||||
attr->srv6_l3service->transposition_len =
|
||||
from_bgp->vpn_policy[afi].tovpn_sid_locator->function_bits_length;
|
||||
attr->srv6_l3service->transposition_offset =
|
||||
from_bgp->vpn_policy[afi].tovpn_sid_locator->block_bits_length +
|
||||
from_bgp->vpn_policy[afi].tovpn_sid_locator->node_bits_length;
|
||||
;
|
||||
memcpy(&attr->srv6_l3service->sid,
|
||||
&from_bgp->vpn_policy[afi].tovpn_sid_locator->prefix.prefix,
|
||||
sizeof(struct in6_addr));
|
||||
if (attr->srv6_l3service->func_len >
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL) {
|
||||
attr->srv6_l3service->transposition_len = 0;
|
||||
attr->srv6_l3service->transposition_offset = 0;
|
||||
IPV6_ADDR_COPY(&attr->srv6_l3service->sid,
|
||||
from_bgp->vpn_policy[afi].tovpn_sid);
|
||||
} else {
|
||||
attr->srv6_l3service->transposition_len =
|
||||
from_bgp->vpn_policy[afi].tovpn_sid_locator->function_bits_length;
|
||||
attr->srv6_l3service->transposition_offset =
|
||||
from_bgp->vpn_policy[afi].tovpn_sid_locator->block_bits_length +
|
||||
from_bgp->vpn_policy[afi].tovpn_sid_locator->node_bits_length;
|
||||
IPV6_ADDR_COPY(&attr->srv6_l3service->sid,
|
||||
&from_bgp->vpn_policy[afi].tovpn_sid_locator->prefix.prefix);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (from_bgp->tovpn_sid_locator) {
|
||||
if (from_bgp->tovpn_sid_locator && from_bgp->tovpn_sid) {
|
||||
struct srv6_locator *locator = from_bgp->tovpn_sid_locator;
|
||||
|
||||
encode_label(from_bgp->tovpn_sid_transpose_label, label);
|
||||
|
|
@ -1763,15 +1805,27 @@ static bool vpn_leak_from_vrf_fill_srv6(struct attr *attr, struct bgp *from_bgp,
|
|||
attr->srv6_l3service->loc_block_len =
|
||||
from_bgp->tovpn_sid_locator->block_bits_length;
|
||||
attr->srv6_l3service->loc_node_len = from_bgp->tovpn_sid_locator->node_bits_length;
|
||||
attr->srv6_l3service->func_len = from_bgp->tovpn_sid_locator->function_bits_length;
|
||||
if (CHECK_FLAG(from_bgp->vrf_flags, BGP_VRF_TOVPN_SID_FUNC_WIDE))
|
||||
attr->srv6_l3service->func_len =
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP;
|
||||
else
|
||||
attr->srv6_l3service->func_len =
|
||||
from_bgp->tovpn_sid_locator->function_bits_length;
|
||||
attr->srv6_l3service->arg_len = from_bgp->tovpn_sid_locator->argument_bits_length;
|
||||
attr->srv6_l3service->transposition_len =
|
||||
from_bgp->tovpn_sid_locator->function_bits_length;
|
||||
attr->srv6_l3service->transposition_offset =
|
||||
from_bgp->tovpn_sid_locator->block_bits_length +
|
||||
from_bgp->tovpn_sid_locator->node_bits_length;
|
||||
memcpy(&attr->srv6_l3service->sid, &from_bgp->tovpn_sid_locator->prefix.prefix,
|
||||
sizeof(struct in6_addr));
|
||||
if (attr->srv6_l3service->func_len >
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL) {
|
||||
attr->srv6_l3service->transposition_len = 0;
|
||||
attr->srv6_l3service->transposition_offset = 0;
|
||||
IPV6_ADDR_COPY(&attr->srv6_l3service->sid, from_bgp->tovpn_sid);
|
||||
} else {
|
||||
attr->srv6_l3service->transposition_len =
|
||||
from_bgp->tovpn_sid_locator->function_bits_length;
|
||||
attr->srv6_l3service->transposition_offset =
|
||||
from_bgp->tovpn_sid_locator->block_bits_length +
|
||||
from_bgp->tovpn_sid_locator->node_bits_length;
|
||||
IPV6_ADDR_COPY(&attr->srv6_l3service->sid,
|
||||
&from_bgp->tovpn_sid_locator->prefix.prefix);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,8 @@
|
|||
#define V4_HEADER_OVERLAY \
|
||||
" Network Next Hop EthTag Overlay Index RouterMac\n"
|
||||
|
||||
#define BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH 20
|
||||
#define BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL 20
|
||||
#define BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_BGP 32
|
||||
|
||||
extern void bgp_mplsvpn_init(void);
|
||||
extern void bgp_mplsvpn_path_nh_label_unlink(struct bgp_path_info *pi);
|
||||
|
|
@ -87,8 +88,8 @@ extern void delete_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
|
|||
extern void ensure_vrf_tovpn_sid_per_af(struct bgp *vpn, struct bgp *vrf,
|
||||
afi_t afi);
|
||||
extern void ensure_vrf_tovpn_sid_per_vrf(struct bgp *vpn, struct bgp *vrf);
|
||||
extern void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
|
||||
uint8_t size);
|
||||
extern void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset, uint8_t size,
|
||||
uint8_t size_max);
|
||||
extern void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp, const char *import_name,
|
||||
afi_t afi, safi_t safi);
|
||||
void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp, const char *import_name,
|
||||
|
|
|
|||
|
|
@ -1111,7 +1111,8 @@ static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p,
|
|||
transpose_sid(&p->u.prefix6,
|
||||
decode_label(&pi->extra->labels->label[0]),
|
||||
pi->attr->srv6_l3service->transposition_offset,
|
||||
pi->attr->srv6_l3service->transposition_len);
|
||||
pi->attr->srv6_l3service->transposition_len,
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL);
|
||||
} else
|
||||
IPV6_ADDR_COPY(&(p->u.prefix6), &(pi->attr->srv6_l3service->sid));
|
||||
} else if (is_bgp_static) {
|
||||
|
|
|
|||
|
|
@ -13007,7 +13007,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
|
|||
IPV6_ADDR_COPY(&sid_transposed, sid_tmp);
|
||||
transpose_sid(&sid_transposed, label_sid,
|
||||
path->attr->srv6_l3service->transposition_offset,
|
||||
path->attr->srv6_l3service->transposition_len);
|
||||
path->attr->srv6_l3service->transposition_len,
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL);
|
||||
json_object_string_addf(json_path, "remoteTransposedSid", "%pI6",
|
||||
&sid_transposed);
|
||||
json_object_string_addf(json_path, "remoteSid", "%pI6",
|
||||
|
|
|
|||
|
|
@ -10546,7 +10546,7 @@ DEFPY (af_label_vpn_export,
|
|||
|
||||
DEFPY (af_sid_vpn_export,
|
||||
af_sid_vpn_export_cmd,
|
||||
"[no] sid vpn export <(1-1048575)$sid_idx|auto$sid_auto|explicit$sid_explicit X:X::X:X$sid_value>",
|
||||
"[no] sid vpn export <(1-4294967295)$sid_idx|auto$sid_auto|explicit$sid_explicit X:X::X:X$sid_value>",
|
||||
NO_STR
|
||||
"sid value for VRF\n"
|
||||
"Between current address-family and vpn\n"
|
||||
|
|
@ -10667,7 +10667,7 @@ DEFPY (af_sid_vpn_export,
|
|||
|
||||
DEFPY (bgp_sid_vpn_export,
|
||||
bgp_sid_vpn_export_cmd,
|
||||
"[no] sid vpn per-vrf export <(1-1048575)$sid_idx|auto$sid_auto|explicit$sid_explicit X:X::X:X$sid_value>",
|
||||
"[no] sid vpn per-vrf export <(1-4294967295)$sid_idx|auto$sid_auto|explicit$sid_explicit X:X::X:X$sid_value>",
|
||||
NO_STR
|
||||
"sid value for VRF\n"
|
||||
"Between current vrf and vpn\n"
|
||||
|
|
@ -19123,8 +19123,7 @@ static void bgp_vpn_policy_config_write_afi(struct vty *vty, struct bgp *bgp,
|
|||
vty_out(vty, "%*ssid vpn export explicit %pI6\n", indent, "",
|
||||
bgp->vpn_policy[afi].tovpn_sid_explicit);
|
||||
} else if (tovpn_sid_index != 0) {
|
||||
vty_out(vty, "%*ssid vpn export %d\n", indent, "",
|
||||
tovpn_sid_index);
|
||||
vty_out(vty, "%*ssid vpn export %u\n", indent, "", tovpn_sid_index);
|
||||
}
|
||||
|
||||
if (CHECK_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET))
|
||||
|
|
@ -20663,8 +20662,7 @@ int bgp_config_write(struct vty *vty)
|
|||
vty_out(vty, " sid vpn per-vrf export explicit %pI6\n",
|
||||
bgp->tovpn_sid_explicit);
|
||||
} else if (tovpn_sid_index != 0) {
|
||||
vty_out(vty, " sid vpn per-vrf export %d\n",
|
||||
tovpn_sid_index);
|
||||
vty_out(vty, " sid vpn per-vrf export %u\n", tovpn_sid_index);
|
||||
}
|
||||
|
||||
/* IPv4 unicast configuration. */
|
||||
|
|
|
|||
|
|
@ -1490,7 +1490,8 @@ static void bgp_zebra_announce_parse_nexthop(struct bgp_path_info *info, const s
|
|||
|
||||
transpose_sid(&api_nh->seg6_segs[0], nh_label,
|
||||
mpinfo->attr->srv6_l3service->transposition_offset,
|
||||
mpinfo->attr->srv6_l3service->transposition_len);
|
||||
mpinfo->attr->srv6_l3service->transposition_len,
|
||||
BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL);
|
||||
}
|
||||
|
||||
api_nh->seg_num = 1;
|
||||
|
|
@ -3662,7 +3663,7 @@ static int bgp_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS)
|
|||
char buf[256];
|
||||
struct in6_addr *tovpn_sid;
|
||||
struct prefix_ipv6 tmp_prefix;
|
||||
uint32_t sid_func;
|
||||
uint32_t sid_func, sid_wide_func = 0;
|
||||
bool found = false;
|
||||
char *loc_name;
|
||||
|
||||
|
|
@ -3684,8 +3685,8 @@ static int bgp_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS)
|
|||
}
|
||||
|
||||
/* Decode the received notification message */
|
||||
if (!zapi_srv6_sid_notify_decode(zclient->ibuf, &ctx, &sid_addr, &sid_func, NULL, ¬e,
|
||||
&loc_name)) {
|
||||
if (!zapi_srv6_sid_notify_decode(zclient->ibuf, &ctx, &sid_addr, &sid_func, &sid_wide_func,
|
||||
¬e, &loc_name)) {
|
||||
zlog_err("%s : error in msg decode", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -3759,10 +3760,21 @@ static int bgp_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS)
|
|||
|
||||
/* Get label */
|
||||
uint8_t func_len = locator_bgp->function_bits_length;
|
||||
uint8_t shift_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH -
|
||||
func_len;
|
||||
mpls_label_t label = MPLS_LABEL_IMPLICIT_NULL;
|
||||
|
||||
int label = sid_func << shift_len;
|
||||
if (sid_wide_func && (CHECK_FLAG(locator_bgp->flags, SRV6_LOCATOR_F3216) ||
|
||||
CHECK_FLAG(locator_bgp->flags, SRV6_LOCATOR_F4816))) {
|
||||
if (ctx.behavior == ZEBRA_SEG6_LOCAL_ACTION_END_DT6)
|
||||
SET_FLAG(bgp_vrf->vpn_policy[AFI_IP6].flags,
|
||||
BGP_VPN_POLICY_TOVPN_SID_FUNC_WIDE);
|
||||
else if (ctx.behavior == ZEBRA_SEG6_LOCAL_ACTION_END_DT4)
|
||||
SET_FLAG(bgp_vrf->vpn_policy[AFI_IP].flags,
|
||||
BGP_VPN_POLICY_TOVPN_SID_FUNC_WIDE);
|
||||
else if (ctx.behavior == ZEBRA_SEG6_LOCAL_ACTION_END_DT46)
|
||||
SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_TOVPN_SID_FUNC_WIDE);
|
||||
} else if (func_len <= BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL)
|
||||
label = sid_func
|
||||
<< (BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH_FOR_LABEL - func_len);
|
||||
|
||||
/* Un-export VPN to VRF routes */
|
||||
if (is_srv6_vpn_enabled(bgp_vrf)) {
|
||||
|
|
|
|||
|
|
@ -294,6 +294,7 @@ struct vpn_policy {
|
|||
#define BGP_VPN_POLICY_TOVPN_SID_EXPLICIT (1 << 6)
|
||||
/* Is this value set by the cli? */
|
||||
#define BGP_VPN_POLICY_TOVPN_RD_CLI_SET (1 << 7)
|
||||
#define BGP_VPN_POLICY_TOVPN_SID_FUNC_WIDE (1 << 8)
|
||||
|
||||
/*
|
||||
* If we are importing another vrf into us keep a list of
|
||||
|
|
@ -982,6 +983,7 @@ struct bgp {
|
|||
/* per-VRF toVPN SID */
|
||||
#define BGP_VRF_TOVPN_SID_AUTO (1 << 7)
|
||||
#define BGP_VRF_TOVPN_SID_EXPLICIT (1 << 8)
|
||||
#define BGP_VRF_TOVPN_SID_FUNC_WIDE (1 << 9)
|
||||
|
||||
/* unique ID for auto derivation of RD for this vrf */
|
||||
uint16_t vrf_rd_id;
|
||||
|
|
|
|||
|
|
@ -149,6 +149,8 @@ struct srv6_locator {
|
|||
uint8_t flags;
|
||||
#define SRV6_LOCATOR_USID (1 << 0) /* The SRv6 Locator is a uSID Locator */
|
||||
#define SRV6_LOCATOR_PSP (1 << 1) /* The SRv6 Locator has the PSP flavor */
|
||||
#define SRV6_LOCATOR_F3216 (1 << 2) /* The SRv6 Locator has F3216 format */
|
||||
#define SRV6_LOCATOR_F4816 (1 << 3) /* The SRv6 Locator has F4816 format */
|
||||
|
||||
/* Pointer to the SID format. */
|
||||
struct srv6_sid_format *sid_format;
|
||||
|
|
|
|||
11
tests/topotests/bgp_srv6_sid_explicit/c31/frr.conf
Normal file
11
tests/topotests/bgp_srv6_sid_explicit/c31/frr.conf
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
frr version 10.3-dev-my-manual-build
|
||||
frr defaults traditional
|
||||
hostname c31
|
||||
!
|
||||
ip route 0.0.0.0/0 192.168.3.254
|
||||
ip route 192.168.0.0/16 192.168.3.254
|
||||
!
|
||||
interface eth10
|
||||
ip address 192.168.3.1/24
|
||||
exit
|
||||
!
|
||||
11
tests/topotests/bgp_srv6_sid_explicit/c32/frr.conf
Normal file
11
tests/topotests/bgp_srv6_sid_explicit/c32/frr.conf
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
frr version 10.3-dev-my-manual-build
|
||||
frr defaults traditional
|
||||
hostname c32
|
||||
!
|
||||
ip route 0.0.0.0/0 192.168.4.254
|
||||
ip route 192.168.0.0/16 192.168.4.254
|
||||
!
|
||||
interface eth10
|
||||
ip address 192.168.4.1/24
|
||||
exit
|
||||
!
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"2001:db8:3:fff7:fe4b::/128":[
|
||||
{
|
||||
"prefix":"2001:db8:3:fff7:fe4b::/128",
|
||||
"prefixLen":128,
|
||||
"protocol":"bgp",
|
||||
"selected":true,
|
||||
"destSelected":true,
|
||||
"distance":20,
|
||||
"metric":0,
|
||||
"installed":true,
|
||||
"table":254,
|
||||
"nexthops":[
|
||||
{
|
||||
"flags":3,
|
||||
"fib":true,
|
||||
"directlyConnected":true,
|
||||
"interfaceName":"Vrf10",
|
||||
"active":true,
|
||||
"weight":1,
|
||||
"seg6local":{
|
||||
"action":"uDT46",
|
||||
"sidStructure":{
|
||||
"blockLen":32,
|
||||
"nodeLen":16,
|
||||
"funcLen":32,
|
||||
"argLen":0
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"2001:db8:3:fff7:fe50::":{
|
||||
"sid":"2001:db8:3:fff7:fe50::",
|
||||
"behavior":"uDT46",
|
||||
"context":{
|
||||
"vrfName":"Vrf10",
|
||||
"table":10
|
||||
},
|
||||
"locator":"MAIN",
|
||||
"allocationMode":"explicit",
|
||||
"clients":[
|
||||
{
|
||||
"protocol":"bgp",
|
||||
"instance":0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"2001:db8:3:fff7:fe4b::":{
|
||||
"sid":"2001:db8:3:fff7:fe4b::",
|
||||
"behavior":"uDT46",
|
||||
"context":{
|
||||
"vrfName":"Vrf10",
|
||||
"table":10
|
||||
},
|
||||
"locator":"MAIN",
|
||||
"allocationMode":"explicit",
|
||||
"clients":[
|
||||
{
|
||||
"protocol":"bgp",
|
||||
"instance":0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
{
|
||||
"2001:db8:3:fff7:fe50::":{
|
||||
"sid":"2001:db8:3:fff7:fe50::",
|
||||
"behavior":"uDT46",
|
||||
"context":{
|
||||
"vrfName":"Vrf10",
|
||||
"table":10
|
||||
},
|
||||
"locator":"MAIN",
|
||||
"allocationMode":"explicit",
|
||||
"clients":[
|
||||
{
|
||||
"protocol":"bgp",
|
||||
"instance":0
|
||||
}
|
||||
]
|
||||
},
|
||||
"2001:db8:3:fff7:fe52::":{
|
||||
"sid":"2001:db8:3:fff7:fe52::",
|
||||
"behavior":"uDT46",
|
||||
"context":{
|
||||
"vrfName":"Vrf20",
|
||||
"table":20
|
||||
},
|
||||
"locator":"MAIN",
|
||||
"allocationMode":"explicit",
|
||||
"clients":[
|
||||
{
|
||||
"protocol":"bgp",
|
||||
"instance":0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
{
|
||||
"65003:10":{
|
||||
"prefix":"192.168.3.0/24",
|
||||
"advertisedTo":{
|
||||
"2001:db8:13::1":{
|
||||
"hostname":"r1"
|
||||
}
|
||||
},
|
||||
"pathCount":1,
|
||||
"paths":[
|
||||
{
|
||||
"aspath":{
|
||||
"string":"Local",
|
||||
"segments":[
|
||||
],
|
||||
"length":0
|
||||
},
|
||||
"nhVrfName":"Vrf10",
|
||||
"announceNexthopSelf":true,
|
||||
"origin":"incomplete",
|
||||
"metric":0,
|
||||
"weight":32768,
|
||||
"valid":true,
|
||||
"sourced":true,
|
||||
"local":true,
|
||||
"bestpath":{
|
||||
"overall":true,
|
||||
"selectionReason":"First path received"
|
||||
},
|
||||
"extendedCommunity":{
|
||||
"string":"RT:0:10"
|
||||
},
|
||||
"originatorId":"192.0.2.3",
|
||||
"remoteLabel":3,
|
||||
"remoteTransposedSid":"2001:db8:3:fff7:fe4b::",
|
||||
"remoteSid":"2001:db8:3:fff7:fe4b::",
|
||||
"remoteSidStructure":{
|
||||
"locatorBlockLen": 32,
|
||||
"locatorNodeLen":16,
|
||||
"functionLen":32,
|
||||
"argumentLen":0,
|
||||
"transpositionLen":0,
|
||||
"transpositionOffset":0
|
||||
},
|
||||
"nexthops":[
|
||||
{
|
||||
"ip":"0.0.0.0",
|
||||
"hostname":"r3",
|
||||
"afi":"ipv4",
|
||||
"metric":0,
|
||||
"accessible":true,
|
||||
"used":true
|
||||
}
|
||||
],
|
||||
"peer":{
|
||||
"peerId":"0.0.0.0",
|
||||
"routerId":"192.0.2.3"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ log commands
|
|||
password zebra
|
||||
!
|
||||
ipv6 route 2001:db8:2:2::/64 2001:db8:12::2
|
||||
ipv6 route 2001:db8:3::/64 2001:db8:13::2
|
||||
!
|
||||
interface eth2
|
||||
ip address 192.168.1.254/24
|
||||
|
|
@ -18,7 +19,9 @@ exit
|
|||
!
|
||||
interface eth10
|
||||
ipv6 address 2001:db8:12::1/64
|
||||
mpls bgp forwarding
|
||||
exit
|
||||
interface eth20
|
||||
ipv6 address 2001:db8:13::1/64
|
||||
exit
|
||||
!
|
||||
interface lo
|
||||
|
|
@ -36,6 +39,10 @@ router bgp 65001
|
|||
neighbor 2001:db8:12::2 timers 3 10
|
||||
neighbor 2001:db8:12::2 timers connect 1
|
||||
neighbor 2001:db8:12::2 capability extended-nexthop
|
||||
neighbor 2001:db8:13::3 remote-as 65003
|
||||
neighbor 2001:db8:13::3 timers 3 10
|
||||
neighbor 2001:db8:13::3 timers connect 1
|
||||
neighbor 2001:db8:13::3 capability extended-nexthop
|
||||
!
|
||||
segment-routing srv6
|
||||
locator MAIN
|
||||
|
|
@ -43,6 +50,7 @@ router bgp 65001
|
|||
!
|
||||
address-family ipv4 vpn
|
||||
neighbor 2001:db8:12::2 activate
|
||||
neighbor 2001:db8:13::3 activate
|
||||
exit-address-family
|
||||
exit
|
||||
!
|
||||
|
|
@ -86,4 +94,4 @@ segment-routing
|
|||
exit
|
||||
exit
|
||||
!
|
||||
end
|
||||
end
|
||||
|
|
|
|||
80
tests/topotests/bgp_srv6_sid_explicit/r3/frr.conf
Normal file
80
tests/topotests/bgp_srv6_sid_explicit/r3/frr.conf
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
frr version 10.4-dev-my-manual-build
|
||||
frr defaults traditional
|
||||
hostname r2
|
||||
log file zebra.log
|
||||
log commands
|
||||
!
|
||||
password zebra
|
||||
!
|
||||
ipv6 route 2001:db8:1:1::/64 2001:db8:13::1
|
||||
!
|
||||
interface eth1
|
||||
ip address 192.168.3.254/24
|
||||
exit
|
||||
!
|
||||
interface eth2
|
||||
ip address 192.168.4.254/24
|
||||
exit
|
||||
!
|
||||
interface eth10
|
||||
ipv6 address 2001:db8:13::3/64
|
||||
exit
|
||||
!
|
||||
interface lo
|
||||
ipv6 address 2001:db8:3::/128
|
||||
exit
|
||||
!
|
||||
router bgp 65003
|
||||
bgp router-id 192.0.2.3
|
||||
no bgp ebgp-requires-policy
|
||||
no bgp default ipv4-unicast
|
||||
neighbor 2001:db8:13::1 remote-as 65001
|
||||
neighbor 2001:db8:13::1 timers 3 10
|
||||
neighbor 2001:db8:13::1 timers connect 1
|
||||
neighbor 2001:db8:13::1 capability extended-nexthop
|
||||
!
|
||||
segment-routing srv6
|
||||
locator MAIN
|
||||
exit
|
||||
!
|
||||
address-family ipv4 vpn
|
||||
neighbor 2001:db8:13::1 activate
|
||||
exit-address-family
|
||||
exit
|
||||
!
|
||||
router bgp 65003 vrf Vrf10
|
||||
bgp router-id 192.0.2.3
|
||||
!
|
||||
address-family ipv4 unicast
|
||||
redistribute connected
|
||||
rd vpn export 65003:10
|
||||
rt vpn both 0:10
|
||||
export vpn
|
||||
import vpn
|
||||
exit-address-family
|
||||
exit
|
||||
!
|
||||
router bgp 65003 vrf Vrf20
|
||||
bgp router-id 192.0.2.3
|
||||
!
|
||||
address-family ipv4 unicast
|
||||
redistribute connected
|
||||
rd vpn export 65002:30
|
||||
rt vpn both 0:20
|
||||
export vpn
|
||||
import vpn
|
||||
exit-address-family
|
||||
exit
|
||||
!
|
||||
segment-routing
|
||||
srv6
|
||||
locators
|
||||
locator MAIN
|
||||
prefix 2001:db8:3::/48
|
||||
format usid-f3216
|
||||
exit
|
||||
exit
|
||||
exit
|
||||
exit
|
||||
!
|
||||
end
|
||||
12
tests/topotests/bgp_srv6_sid_explicit/r3/setup.sh
Normal file
12
tests/topotests/bgp_srv6_sid_explicit/r3/setup.sh
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
ip link add sr0 type dummy
|
||||
ip link set sr0 up
|
||||
|
||||
sysctl -w net.vrf.strict_mode=1
|
||||
|
||||
ip link add Vrf10 type vrf table 10
|
||||
ip link set Vrf10 up
|
||||
ip link add Vrf20 type vrf table 20
|
||||
ip link set Vrf20 up
|
||||
|
||||
ip link set eth1 master Vrf10
|
||||
ip link set eth2 master Vrf20
|
||||
|
|
@ -43,17 +43,23 @@ def open_json_file(filename):
|
|||
def build_topo(tgen):
|
||||
tgen.add_router("r1")
|
||||
tgen.add_router("r2")
|
||||
tgen.add_router("r3")
|
||||
|
||||
tgen.add_router("c11")
|
||||
tgen.add_router("c12")
|
||||
tgen.add_router("c21")
|
||||
tgen.add_router("c22")
|
||||
tgen.add_router("c31")
|
||||
tgen.add_router("c32")
|
||||
|
||||
tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "eth10", "eth10")
|
||||
tgen.add_link(tgen.gears["r1"], tgen.gears["c11"], "eth2", "eth10")
|
||||
tgen.add_link(tgen.gears["r1"], tgen.gears["c12"], "eth3", "eth10")
|
||||
tgen.add_link(tgen.gears["r2"], tgen.gears["c21"], "eth1", "eth10")
|
||||
tgen.add_link(tgen.gears["r2"], tgen.gears["c22"], "eth2", "eth10")
|
||||
tgen.add_link(tgen.gears["r1"], tgen.gears["r3"], "eth20", "eth10")
|
||||
tgen.add_link(tgen.gears["r3"], tgen.gears["c31"], "eth1", "eth10")
|
||||
tgen.add_link(tgen.gears["r3"], tgen.gears["c32"], "eth2", "eth10")
|
||||
|
||||
|
||||
def setup_module(mod):
|
||||
|
|
@ -91,15 +97,17 @@ def check_explicit_srv6_sid_allocated(router, expected_file, exact=False):
|
|||
assert result is None, "Failed"
|
||||
|
||||
|
||||
def _check_sent_bgp_vpn_srv6_sid(router, expected_route_file):
|
||||
def _check_sent_bgp_vpn_srv6_sid(router, expected_route_file, prefix):
|
||||
logger.info("checking bgp vpn route with SRv6 SIDs in sending end")
|
||||
output = json.loads(router.vtysh_cmd("show bgp ipv4 vpn 192.168.1.0/24 json"))
|
||||
output = json.loads(router.vtysh_cmd(f"show bgp ipv4 vpn {prefix} json"))
|
||||
expected = open_json_file("{}/{}".format(CWD, expected_route_file))
|
||||
return topotest.json_cmp(output, expected)
|
||||
|
||||
|
||||
def check_sent_bgp_vpn_srv6_sid(router, expected_file):
|
||||
func = functools.partial(_check_sent_bgp_vpn_srv6_sid, router, expected_file)
|
||||
def check_sent_bgp_vpn_srv6_sid(router, expected_file, prefix="192.168.1.0/24"):
|
||||
func = functools.partial(
|
||||
_check_sent_bgp_vpn_srv6_sid, router, expected_file, prefix
|
||||
)
|
||||
_, result = topotest.run_and_expect(func, None, count=15, wait=1)
|
||||
assert result is None, "Failed"
|
||||
|
||||
|
|
@ -138,22 +146,28 @@ def check_rcvd_bgp_vrf_srv6_sid(router, vrf_name, expected_file):
|
|||
assert result is None, "Failed"
|
||||
|
||||
|
||||
def _check_rcvd_zebra_vrf_srv6_sid(router, vrf_name, expected_route_file):
|
||||
def _check_rcvd_zebra_vrf_srv6_sid(
|
||||
router, vrf_name, expected_route_file, prefix, family
|
||||
):
|
||||
logger.info(
|
||||
"checking zebra vrf {} ipv4 route with SRv6 SIDs in receiving end".format(
|
||||
vrf_name
|
||||
"checking zebra vrf {} {} route with SRv6 SIDs in receiving end".format(
|
||||
vrf_name, family
|
||||
)
|
||||
)
|
||||
output = json.loads(
|
||||
router.vtysh_cmd("show ip route vrf {} 192.168.1.0/24 json".format(vrf_name))
|
||||
router.vtysh_cmd(
|
||||
"show {} route vrf {} {} json".format(family, vrf_name, prefix)
|
||||
)
|
||||
)
|
||||
expected = open_json_file("{}/{}".format(CWD, expected_route_file))
|
||||
return topotest.json_cmp(output, expected)
|
||||
|
||||
|
||||
def check_rcvd_zebra_vrf_srv6_sid(router, vrf_name, expected_file):
|
||||
def check_rcvd_zebra_vrf_srv6_sid(
|
||||
router, vrf_name, expected_file, prefix="192.168.1.0/24", family="ip"
|
||||
):
|
||||
func = functools.partial(
|
||||
_check_rcvd_zebra_vrf_srv6_sid, router, vrf_name, expected_file
|
||||
_check_rcvd_zebra_vrf_srv6_sid, router, vrf_name, expected_file, prefix, family
|
||||
)
|
||||
_, result = topotest.run_and_expect(func, None, count=15, wait=1)
|
||||
assert result is None, "Failed"
|
||||
|
|
@ -397,6 +411,112 @@ def test_explicit_srv6_sid_per_af_disabled():
|
|||
)
|
||||
|
||||
|
||||
# Configure 'sid vpn per-vrf export 4294442571'
|
||||
# this value stands for FFF7FE4B
|
||||
# Demonstrate that when using the index value, the allocation
|
||||
# is possible on f3216 locator format
|
||||
def test_explicit_srv6_sid_explicit_wide_index_1():
|
||||
tgen = get_topogen()
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
router = tgen.gears["r3"]
|
||||
|
||||
router.vtysh_cmd(
|
||||
"""
|
||||
configure terminal
|
||||
router bgp 65003 vrf Vrf10
|
||||
sid vpn per-vrf export 4294442571
|
||||
"""
|
||||
)
|
||||
|
||||
# FOR DEVELOPER:
|
||||
# If you want to stop some specific line and start interactive shell,
|
||||
# please use tgen.mininet_cli() to start it.
|
||||
logger.info(
|
||||
"--13--Test for bgp explicit srv6 sid with wide func allocated in zebra"
|
||||
)
|
||||
check_explicit_srv6_sid_allocated(
|
||||
router, "expected_explicit_srv6_sid_wide_allocated_1.json"
|
||||
)
|
||||
check_rcvd_zebra_vrf_srv6_sid(
|
||||
router,
|
||||
"default",
|
||||
"expected_allocated_srv6_sid_seg6local_wide_1.json",
|
||||
"2001:db8:3:fff7:fe4b::/128",
|
||||
"ipv6",
|
||||
)
|
||||
check_sent_bgp_vpn_srv6_sid(
|
||||
router, "expected_sent_bgp_vpn_srv6_sid_wide_1.json", "192.168.3.0/24"
|
||||
)
|
||||
|
||||
|
||||
# Configure 'sid vpn per-vrf export explicit X:X::X:X'
|
||||
# using wide func specifics
|
||||
# By command 'show segment-routing srv6 sid json'
|
||||
def test_explicit_srv6_sid_explicit_wide():
|
||||
tgen = get_topogen()
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
router = tgen.gears["r3"]
|
||||
|
||||
router.vtysh_cmd(
|
||||
"""
|
||||
configure terminal
|
||||
router bgp 65003 vrf Vrf10
|
||||
no sid vpn per-vrf export 4294442571
|
||||
sid vpn per-vrf export explicit 2001:db8:3:fff7:fe50::
|
||||
"""
|
||||
)
|
||||
|
||||
# FOR DEVELOPER:
|
||||
# If you want to stop some specific line and start interactive shell,
|
||||
# please use tgen.mininet_cli() to start it.
|
||||
logger.info(
|
||||
"--14--Test for bgp explicit srv6 sid with wide func allocated in zebra"
|
||||
)
|
||||
check_explicit_srv6_sid_allocated(
|
||||
router, "expected_explicit_srv6_sid_wide_allocated.json"
|
||||
)
|
||||
|
||||
|
||||
# Configure 'sid vpn per-vrf export 4294442578'
|
||||
# this value stands for FFF7FE52
|
||||
# Demonstrate that when using a func-bits of 32 bits, then
|
||||
# By command 'show segment-routing srv6 sid json' dumps 2 SIDs
|
||||
def test_explicit_srv6_sid_explicit_wide_index():
|
||||
tgen = get_topogen()
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
router = tgen.gears["r3"]
|
||||
|
||||
router.vtysh_cmd(
|
||||
"""
|
||||
configure terminal
|
||||
segment-routing
|
||||
srv6
|
||||
locators
|
||||
locator MAIN
|
||||
no format usid-f3216
|
||||
behavior usid
|
||||
prefix 2001:db8:3:2::/48 block-len 32 node-len 16 func-bits 32
|
||||
end
|
||||
configure terminal
|
||||
router bgp 65003 vrf Vrf20
|
||||
sid vpn per-vrf export 4294442578
|
||||
"""
|
||||
)
|
||||
|
||||
# FOR DEVELOPER:
|
||||
# If you want to stop some specific line and start interactive shell,
|
||||
# please use tgen.mininet_cli() to start it.
|
||||
logger.info(
|
||||
"--15--Test for bgp explicit srv6 sid with 32 bit function space allocated in zebra"
|
||||
)
|
||||
check_explicit_srv6_sid_allocated(
|
||||
router, "expected_explicit_srv6_sid_wide_allocated_2.json"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
args = ["-s"] + sys.argv[1:]
|
||||
sys.exit(pytest.main(args))
|
||||
|
|
|
|||
22
tests/topotests/srv6_sid_manager/dst2/zebra.conf
Normal file
22
tests/topotests/srv6_sid_manager/dst2/zebra.conf
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
log file zebra.log
|
||||
!
|
||||
hostname dst2
|
||||
!
|
||||
! debug zebra kernel
|
||||
! debug zebra packet
|
||||
! debug zebra mpls
|
||||
!
|
||||
interface lo
|
||||
ip address 9.9.9.5/32
|
||||
ipv6 address fc00:0:9::5/128
|
||||
!
|
||||
interface eth-rt5
|
||||
ip address 10.0.11.2/24
|
||||
ipv6 address 2001:db9:10::2/64
|
||||
!
|
||||
ip forwarding
|
||||
!
|
||||
ipv6 route 2001:db8:1::/64 2001:db9:10::1
|
||||
!
|
||||
line vty
|
||||
!
|
||||
|
|
@ -27,9 +27,14 @@ router bgp 1
|
|||
neighbor fc00:0:6::1 timers 3 10
|
||||
neighbor fc00:0:6::1 timers connect 1
|
||||
neighbor fc00:0:6::1 ttl-security hops 20
|
||||
neighbor fc00:0:5::1 remote-as 5
|
||||
neighbor fc00:0:5::1 timers 3 10
|
||||
neighbor fc00:0:5::1 timers connect 1
|
||||
neighbor fc00:0:5::1 ttl-security hops 20
|
||||
!
|
||||
address-family ipv6 vpn
|
||||
neighbor fc00:0:6::1 activate
|
||||
neighbor fc00:0:5::1 activate
|
||||
exit-address-family
|
||||
!
|
||||
segment-routing srv6
|
||||
|
|
|
|||
|
|
@ -82,5 +82,52 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2001:db9:10::/64": [
|
||||
{
|
||||
"prefix": "2001:db9:10::/64",
|
||||
"protocol": "bgp",
|
||||
"vrfName": "vrf10",
|
||||
"selected": true,
|
||||
"destSelected": true,
|
||||
"distance": 20,
|
||||
"metric": 0,
|
||||
"installed": true,
|
||||
"table": 10,
|
||||
"internalStatus": 16,
|
||||
"internalFlags": 9,
|
||||
"internalNextHopNum": 2,
|
||||
"internalNextHopActiveNum": 2,
|
||||
"nexthops": [
|
||||
{
|
||||
"flags": 5,
|
||||
"ip": "fc00:0:5::1",
|
||||
"afi": "ipv6",
|
||||
"vrf": "default",
|
||||
"active": true,
|
||||
"recursive": true,
|
||||
"labels": [3],
|
||||
"weight": 1,
|
||||
"seg6": {
|
||||
"segs": "fc05:0:5:cece:2345::"
|
||||
},
|
||||
"srv6EncapBehavior": "H.Encaps"
|
||||
},
|
||||
{
|
||||
"flags": 3,
|
||||
"fib": true,
|
||||
"afi": "ipv6",
|
||||
"interfaceName": "eth-sw1",
|
||||
"vrf": "default",
|
||||
"active": true,
|
||||
"labels": [3],
|
||||
"weight": 1,
|
||||
"seg6": {
|
||||
"segs": "fc05:0:5:cece:2345::"
|
||||
},
|
||||
"srv6EncapBehavior": "H.Encaps"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,5 +88,52 @@
|
|||
],
|
||||
"asPath": "6"
|
||||
}
|
||||
],
|
||||
"2001:7::/64": [
|
||||
{
|
||||
"prefix": "2001:7::/64",
|
||||
"protocol": "bgp",
|
||||
"vrfName": "vrf20",
|
||||
"selected": true,
|
||||
"destSelected": true,
|
||||
"distance": 20,
|
||||
"metric": 0,
|
||||
"installed": true,
|
||||
"table": 20,
|
||||
"internalStatus": 16,
|
||||
"internalFlags": 9,
|
||||
"internalNextHopNum": 2,
|
||||
"internalNextHopActiveNum": 2,
|
||||
"nexthops": [
|
||||
{
|
||||
"flags": 5,
|
||||
"ip": "fc00:0:5::1",
|
||||
"afi": "ipv6",
|
||||
"vrf": "default",
|
||||
"active": true,
|
||||
"recursive": true,
|
||||
"labels": [3],
|
||||
"weight": 1,
|
||||
"seg6": {
|
||||
"segs": "fc05:0:5:1:4dfc::"
|
||||
},
|
||||
"srv6EncapBehavior": "H.Encaps"
|
||||
},
|
||||
{
|
||||
"flags": 3,
|
||||
"fib": true,
|
||||
"afi": "ipv6",
|
||||
"interfaceName": "eth-sw1",
|
||||
"vrf": "default",
|
||||
"active": true,
|
||||
"labels": [3],
|
||||
"weight": 1,
|
||||
"seg6": {
|
||||
"segs": "fc05:0:5:1:4dfc::"
|
||||
},
|
||||
"srv6EncapBehavior": "H.Encaps"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
|||
67
tests/topotests/srv6_sid_manager/rt5/bgpd.conf
Normal file
67
tests/topotests/srv6_sid_manager/rt5/bgpd.conf
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
frr defaults traditional
|
||||
!
|
||||
bgp send-extra-data zebra
|
||||
!
|
||||
hostname rt5
|
||||
password zebra
|
||||
!
|
||||
log stdout notifications
|
||||
log commands
|
||||
!
|
||||
!debug bgp neighbor-events
|
||||
!debug bgp zebra
|
||||
!debug bgp vnc verbose
|
||||
!debug bgp update-groups
|
||||
!debug bgp updates in
|
||||
!debug bgp updates out
|
||||
!debug bgp updates
|
||||
!debug bgp vpn label
|
||||
!debug bgp vpn leak-from-vrf
|
||||
!debug bgp vpn leak-to-vrf
|
||||
!!debug bgp vpn rmap-event
|
||||
!
|
||||
router bgp 5
|
||||
bgp router-id 5.5.5.5
|
||||
no bgp ebgp-requires-policy
|
||||
no bgp default ipv4-unicast
|
||||
neighbor fc00:0:1::1 remote-as 1
|
||||
neighbor fc00:0:1::1 timers 3 10
|
||||
neighbor fc00:0:1::1 timers connect 1
|
||||
neighbor fc00:0:1::1 ttl-security hops 20
|
||||
!
|
||||
address-family ipv6 vpn
|
||||
neighbor fc00:0:1::1 activate
|
||||
exit-address-family
|
||||
!
|
||||
segment-routing srv6
|
||||
locator loc2
|
||||
!
|
||||
!
|
||||
router bgp 5 vrf vrf10
|
||||
bgp router-id 5.5.5.5
|
||||
no bgp ebgp-requires-policy
|
||||
no bgp default ipv4-unicast
|
||||
!
|
||||
address-family ipv6 unicast
|
||||
sid vpn export explicit fc05:0:5:cece:2345::
|
||||
rd vpn export 5:10
|
||||
rt vpn both 99:99
|
||||
import vpn
|
||||
export vpn
|
||||
redistribute connected
|
||||
exit-address-family
|
||||
!
|
||||
router bgp 5 vrf vrf20
|
||||
bgp router-id 5.5.5.5
|
||||
no bgp ebgp-requires-policy
|
||||
no bgp default ipv4-unicast
|
||||
!
|
||||
address-family ipv6 unicast
|
||||
sid vpn export 85500
|
||||
rd vpn export 5:10
|
||||
rt vpn both 88:88
|
||||
import vpn
|
||||
export vpn
|
||||
redistribute connected
|
||||
exit-address-family
|
||||
!
|
||||
|
|
@ -8,6 +8,7 @@ hostname rt5
|
|||
interface lo
|
||||
ip address 5.5.5.5/32
|
||||
ipv6 address fc00:0:5::1/128
|
||||
ipv6 address fc05:0:5::/48
|
||||
!
|
||||
interface eth-rt3-1
|
||||
ip address 10.0.4.5/24
|
||||
|
|
@ -21,12 +22,21 @@ interface eth-rt4
|
|||
interface eth-rt6
|
||||
ip address 10.0.8.5/24
|
||||
!
|
||||
interface eth-dst2 vrf vrf10
|
||||
ip address 10.0.11.1/24
|
||||
ip address 2001:db9:10::1/64
|
||||
!
|
||||
interface eth-ce7 vrf vrf20
|
||||
ipv6 address 2001:7::1/64
|
||||
!
|
||||
segment-routing
|
||||
srv6
|
||||
locators
|
||||
locator loc1
|
||||
prefix fc00:0:5::/48
|
||||
prefix fc00:0:5::/48 block-len 32 node-len 16 func-bits 16
|
||||
format usid-f3216
|
||||
locator loc2
|
||||
prefix fc05:0:5::/48 block-len 32 node-len 16 func-bits 32
|
||||
!
|
||||
!
|
||||
!
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ test_srv6_sid_manager.py:
|
|||
10.0.2.0/24| |10.0.3.0/24 10.0.4.0/24| |10.0.5.0/24
|
||||
| | | |
|
||||
eth-rt2-1| |eth-rt2-2 eth-rt3-1| |eth-rt3-2
|
||||
+---------+ +---------+
|
||||
| | | |
|
||||
| RT4 | 10.0.6.0/24 | RT5 |
|
||||
| 4.4.4.4 +---------------------+ 5.5.5.5 |
|
||||
| |eth-rt5 eth-rt4| |
|
||||
+---------+ +---------+
|
||||
+---------+ +---------+ +---------+
|
||||
| | | | | |
|
||||
| RT4 | 10.0.6.0/24 | RT5 |eth-dst2 | DST2 |
|
||||
| 4.4.4.4 +---------------------+ 5.5.5.5 |-------------+ 9.9.9.5 |
|
||||
| |eth-rt5 eth-rt4| | eth-rt5| |
|
||||
+---------+ +---------+ +---------+
|
||||
eth-rt6| |eth-rt6
|
||||
| |
|
||||
10.0.7.0/24| |10.0.8.0/24
|
||||
|
|
@ -99,6 +99,8 @@ def build_topo(tgen):
|
|||
tgen.add_router("ce4")
|
||||
tgen.add_router("ce5")
|
||||
tgen.add_router("ce6")
|
||||
tgen.add_router("ce7")
|
||||
tgen.add_router("dst2")
|
||||
|
||||
# Define connections
|
||||
switch = tgen.add_switch("s1")
|
||||
|
|
@ -138,12 +140,17 @@ def build_topo(tgen):
|
|||
switch.add_link(tgen.gears["rt6"], nodeif="eth-dst")
|
||||
switch.add_link(tgen.gears["dst"], nodeif="eth-rt6")
|
||||
|
||||
switch = tgen.add_switch("s10")
|
||||
switch.add_link(tgen.gears["rt5"], nodeif="eth-dst2")
|
||||
switch.add_link(tgen.gears["dst2"], nodeif="eth-rt5")
|
||||
|
||||
tgen.add_link(tgen.gears["ce1"], tgen.gears["rt1"], "eth-rt1", "eth-ce1")
|
||||
tgen.add_link(tgen.gears["ce2"], tgen.gears["rt6"], "eth-rt6", "eth-ce2")
|
||||
tgen.add_link(tgen.gears["ce3"], tgen.gears["rt1"], "eth-rt1", "eth-ce3")
|
||||
tgen.add_link(tgen.gears["ce4"], tgen.gears["rt6"], "eth-rt6", "eth-ce4")
|
||||
tgen.add_link(tgen.gears["ce5"], tgen.gears["rt1"], "eth-rt1", "eth-ce5")
|
||||
tgen.add_link(tgen.gears["ce6"], tgen.gears["rt6"], "eth-rt6", "eth-ce6")
|
||||
tgen.add_link(tgen.gears["ce7"], tgen.gears["rt5"], "eth-rt5", "eth-ce7")
|
||||
|
||||
tgen.gears["rt1"].run("ip link add vrf10 type vrf table 10")
|
||||
tgen.gears["rt1"].run("ip link set vrf10 up")
|
||||
|
|
@ -153,6 +160,13 @@ def build_topo(tgen):
|
|||
tgen.gears["rt1"].run("ip link set eth-ce3 master vrf10")
|
||||
tgen.gears["rt1"].run("ip link set eth-ce5 master vrf20")
|
||||
|
||||
tgen.gears["rt5"].run("ip link add vrf10 type vrf table 10")
|
||||
tgen.gears["rt5"].run("ip link set vrf10 up")
|
||||
tgen.gears["rt5"].run("ip link set eth-dst2 master vrf10")
|
||||
tgen.gears["rt5"].run("ip link add vrf20 type vrf table 20")
|
||||
tgen.gears["rt5"].run("ip link set vrf20 up")
|
||||
tgen.gears["rt5"].run("ip link set eth-ce7 master vrf20")
|
||||
|
||||
tgen.gears["rt6"].run("ip link add vrf10 type vrf table 10")
|
||||
tgen.gears["rt6"].run("ip link set vrf10 up")
|
||||
tgen.gears["rt6"].run("ip link add vrf20 type vrf table 20")
|
||||
|
|
@ -226,15 +240,19 @@ def setup_module(mod):
|
|||
|
||||
# For all registered routers, load the zebra and isis configuration files
|
||||
for rname, router in tgen.routers().items():
|
||||
router.load_config(TopoRouter.RD_ZEBRA,
|
||||
os.path.join(CWD, '{}/zebra.conf'.format(rname)))
|
||||
router.load_config(TopoRouter.RD_ISIS,
|
||||
os.path.join(CWD, '{}/isisd.conf'.format(rname)))
|
||||
router.load_config(TopoRouter.RD_BGP,
|
||||
os.path.join(CWD, '{}/bgpd.conf'.format(rname)))
|
||||
if (os.path.exists('{}/sharpd.conf'.format(rname))):
|
||||
router.load_config(TopoRouter.RD_SHARP,
|
||||
os.path.join(CWD, '{}/sharpd.conf'.format(rname)))
|
||||
router.load_config(
|
||||
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
|
||||
)
|
||||
router.load_config(
|
||||
TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
|
||||
)
|
||||
router.load_config(
|
||||
TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
|
||||
)
|
||||
if os.path.exists("{}/sharpd.conf".format(rname)):
|
||||
router.load_config(
|
||||
TopoRouter.RD_SHARP, os.path.join(CWD, "{}/sharpd.conf".format(rname))
|
||||
)
|
||||
|
||||
# Start routers
|
||||
tgen.start_router()
|
||||
|
|
@ -258,7 +276,9 @@ def router_compare_json_output(rname, command, reference):
|
|||
expected = json.loads(open(filename).read())
|
||||
|
||||
# Run test function until we get an result. Wait at most 60 seconds.
|
||||
test_func = functools.partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
|
||||
test_func = functools.partial(
|
||||
topotest.router_json_cmp, tgen.gears[rname], command, expected
|
||||
)
|
||||
_, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5)
|
||||
assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
|
||||
assert diff is None, assertmsg
|
||||
|
|
@ -332,9 +352,7 @@ def test_rib_ipv6():
|
|||
pytest.skip(tgen.errors)
|
||||
|
||||
for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
|
||||
router_compare_json_output(
|
||||
rname, "show ipv6 route json", "show_ipv6_route.ref"
|
||||
)
|
||||
router_compare_json_output(rname, "show ipv6 route json", "show_ipv6_route.ref")
|
||||
|
||||
|
||||
def test_srv6_locator():
|
||||
|
|
@ -347,8 +365,10 @@ def test_srv6_locator():
|
|||
|
||||
for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
|
||||
router_compare_json_output(
|
||||
rname, "show segment-routing srv6 locator json", "show_srv6_locator_table.ref"
|
||||
)
|
||||
rname,
|
||||
"show segment-routing srv6 locator json",
|
||||
"show_srv6_locator_table.ref",
|
||||
)
|
||||
|
||||
|
||||
def test_vpn_rib():
|
||||
|
|
@ -381,7 +401,9 @@ def test_ping():
|
|||
|
||||
# Setup encap route on rt1, decap route on rt2
|
||||
# tgen.gears["rt1"].vtysh_cmd("sharp install seg6-routes fc00:0:9::1 nexthop-seg6 2001:db8:1::2 encap fc00:0:2:6:fe00:: 1")
|
||||
tgen.gears["rt1"].cmd("ip -6 r a fc00:0:9::1/128 encap seg6 mode encap segs fc00:0:2:6:fe00:: via 2001:db8:1::2")
|
||||
tgen.gears["rt1"].cmd(
|
||||
"ip -6 r a fc00:0:9::1/128 encap seg6 mode encap segs fc00:0:2:6:fe00:: via 2001:db8:1::2"
|
||||
)
|
||||
# tgen.gears["rt6"].vtysh_cmd("sharp install seg6local-routes fc00:0:f00d:: nexthop-seg6local eth-dst End_DT6 254 1")
|
||||
tgen.gears["rt6"].cmd("ip -6 r a fc00:0:9::1/128 via 2001:db8:10::2 vrf vrf10")
|
||||
tgen.gears["dst"].cmd("ip -6 r a 2001:db8:1::1/128 via 2001:db8:10::1")
|
||||
|
|
|
|||
|
|
@ -287,7 +287,21 @@ void zebra_srv6_locator_format_set(struct srv6_locator *locator,
|
|||
|
||||
/* Change format */
|
||||
locator->sid_format = format;
|
||||
|
||||
if (format) {
|
||||
if (strmatch(format->name, SRV6_SID_FORMAT_USID_F3216_NAME)) {
|
||||
SET_FLAG(locator->flags, SRV6_LOCATOR_F3216);
|
||||
UNSET_FLAG(locator->flags, SRV6_LOCATOR_F4816);
|
||||
} else if (strmatch(format->name, SRV6_SID_FORMAT_USID_F4816_NAME)) {
|
||||
SET_FLAG(locator->flags, SRV6_LOCATOR_F4816);
|
||||
UNSET_FLAG(locator->flags, SRV6_LOCATOR_F3216);
|
||||
} else {
|
||||
UNSET_FLAG(locator->flags, SRV6_LOCATOR_F3216);
|
||||
UNSET_FLAG(locator->flags, SRV6_LOCATOR_F4816);
|
||||
}
|
||||
} else {
|
||||
UNSET_FLAG(locator->flags, SRV6_LOCATOR_F3216);
|
||||
UNSET_FLAG(locator->flags, SRV6_LOCATOR_F4816);
|
||||
}
|
||||
/* Allocate the new parent block */
|
||||
zebra_srv6_sid_locator_block_alloc(locator);
|
||||
|
||||
|
|
@ -1910,9 +1924,15 @@ static int get_srv6_sid_explicit(struct zebra_srv6_sid **sid, struct srv6_sid_ct
|
|||
|
||||
zebra_srv6_sid_entry_add(*sid, locator->name, sid_value, is_localonly);
|
||||
|
||||
if (IS_ZEBRA_DEBUG_SRV6)
|
||||
zlog_debug("%s: allocated explicit SRv6 SID function %u for context %s", __func__,
|
||||
(*sid)->func, srv6_sid_ctx2str(buf, sizeof(buf), ctx));
|
||||
if (IS_ZEBRA_DEBUG_SRV6) {
|
||||
if ((*sid)->wide_func == 0)
|
||||
zlog_debug("%s: allocated explicit SRv6 SID function %u for context %s",
|
||||
__func__, (*sid)->func, srv6_sid_ctx2str(buf, sizeof(buf), ctx));
|
||||
else
|
||||
zlog_debug("%s: allocated explicit SRv6 SID function %u (wide SID %u) for context %s",
|
||||
__func__, (*sid)->func, (*sid)->wide_func,
|
||||
srv6_sid_ctx2str(buf, sizeof(buf), ctx));
|
||||
}
|
||||
|
||||
frrtrace(3, frr_zebra, get_srv6_sid_explicit, srv6_sid_ctx2str(buf, sizeof(buf), ctx),
|
||||
sid_value, 2);
|
||||
|
|
|
|||
|
|
@ -949,19 +949,6 @@ DEFPY (locator_prefix,
|
|||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Currently, the SID transposition algorithm implemented in bgpd
|
||||
* handles incorrectly the SRv6 locators with function length greater
|
||||
* than 20 bits. To prevent issues, we currently limit the function
|
||||
* length to 20 bits.
|
||||
* This limit will be removed when the bgpd SID transposition is fixed.
|
||||
*/
|
||||
if (func_bit_len > 20) {
|
||||
vty_out(vty,
|
||||
"%% currently func_bit_len > 20 is not supported\n");
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
locator->block_bits_length = block_bit_len;
|
||||
locator->node_bits_length = node_bit_len;
|
||||
locator->function_bits_length = func_bit_len;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue