bgpd: save srv6_locator_chunk in vpn_policy

In order to send correct SRv6 L3VPN advertisement, we need to save
srv6_locator_chunk in vpn_policy. With this information, we can
construct correct SRv6 L3VPN advertisement packets.

Signed-off-by: Ryoga Saito <ryoga.saito@linecorp.com>
This commit is contained in:
Ryoga Saito 2022-09-20 18:41:55 +09:00
parent c4ab9fd927
commit bee2e7d08f
5 changed files with 52 additions and 36 deletions

View File

@ -80,14 +80,6 @@
#define BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE 1
#define BGP_PREFIX_SID_SRV6_L3_SERVICE_SID_STRUCTURE_LENGTH 6
/* SRv6 SID Structure default values */
#define BGP_PREFIX_SID_SRV6_LOCATOR_BLOCK_LENGTH 40
#define BGP_PREFIX_SID_SRV6_LOCATOR_NODE_LENGTH 24
#define BGP_PREFIX_SID_SRV6_FUNCTION_LENGTH 16
#define BGP_PREFIX_SID_SRV6_ARGUMENT_LENGTH 0
#define BGP_PREFIX_SID_SRV6_TRANSPOSITION_LENGTH 16
#define BGP_PREFIX_SID_SRV6_TRANSPOSITION_OFFSET 64
#define BGP_ATTR_NH_AFI(afi, attr) \
((afi != AFI_L2VPN) ? afi : \
((attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4) ? AFI_IP : AFI_IP6))

View File

@ -524,7 +524,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_locator,
struct srv6_locator_chunk *sid_locator_chunk,
struct in6_addr *sid)
{
int debug = BGP_DEBUG(vpn, VPN_LEAK_LABEL);
@ -536,7 +536,7 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
uint8_t func_len = 0, shift_len = 0;
uint32_t index_max = 0;
if (!bgp || !sid_locator || !sid)
if (!bgp || !sid_locator_chunk || !sid)
return false;
for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) {
@ -560,8 +560,8 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
continue;
}
*sid_locator = chunk->prefix.prefix;
*sid = chunk->prefix.prefix;
*sid_locator_chunk = *chunk;
offset = chunk->block_bits_length + chunk->node_bits_length;
func_len = chunk->function_bits_length;
shift_len = BGP_PREFIX_SID_SRV6_MAX_FUNCTION_LENGTH - func_len;
@ -596,7 +596,8 @@ 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 *tovpn_sid, *tovpn_sid_locator;
struct srv6_locator_chunk *tovpn_sid_locator;
struct in6_addr *tovpn_sid;
uint32_t tovpn_sid_index = 0, tovpn_sid_transpose_label;
bool tovpn_sid_auto = false;
@ -630,8 +631,7 @@ void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
return;
}
tovpn_sid_locator =
XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
tovpn_sid_locator = srv6_locator_chunk_alloc();
tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
tovpn_sid_transpose_label = alloc_new_sid(bgp_vpn, tovpn_sid_index,
@ -640,7 +640,7 @@ void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
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));
XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid_locator);
srv6_locator_chunk_free(tovpn_sid_locator);
XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid);
return;
}
@ -1285,19 +1285,29 @@ void vpn_leak_from_vrf_update(struct bgp *to_bgp, /* to */
static_attr.srv6_l3vpn->sid_flags = 0x00;
static_attr.srv6_l3vpn->endpoint_behavior = 0xffff;
static_attr.srv6_l3vpn->loc_block_len =
BGP_PREFIX_SID_SRV6_LOCATOR_BLOCK_LENGTH;
from_bgp->vpn_policy[afi]
.tovpn_sid_locator->block_bits_length;
static_attr.srv6_l3vpn->loc_node_len =
BGP_PREFIX_SID_SRV6_LOCATOR_NODE_LENGTH;
from_bgp->vpn_policy[afi]
.tovpn_sid_locator->node_bits_length;
static_attr.srv6_l3vpn->func_len =
BGP_PREFIX_SID_SRV6_FUNCTION_LENGTH;
from_bgp->vpn_policy[afi]
.tovpn_sid_locator->function_bits_length;
static_attr.srv6_l3vpn->arg_len =
BGP_PREFIX_SID_SRV6_ARGUMENT_LENGTH;
from_bgp->vpn_policy[afi]
.tovpn_sid_locator->argument_bits_length;
static_attr.srv6_l3vpn->transposition_len =
BGP_PREFIX_SID_SRV6_TRANSPOSITION_LENGTH;
from_bgp->vpn_policy[afi]
.tovpn_sid_locator->function_bits_length;
static_attr.srv6_l3vpn->transposition_offset =
BGP_PREFIX_SID_SRV6_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(&static_attr.srv6_l3vpn->sid,
from_bgp->vpn_policy[afi].tovpn_sid_locator,
&from_bgp->vpn_policy[afi]
.tovpn_sid_locator->prefix.prefix,
sizeof(struct in6_addr));
}

View File

@ -295,7 +295,7 @@ static int bgp_srv6_locator_unset(struct bgp *bgp)
{
int ret;
struct listnode *node, *nnode;
struct srv6_locator_chunk *chunk;
struct srv6_locator_chunk *chunk, *tovpn_sid_locator;
struct bgp_srv6_function *func;
struct bgp *bgp_vrf;
struct in6_addr *tovpn_sid;
@ -345,12 +345,20 @@ static int bgp_srv6_locator_unset(struct bgp *bgp)
continue;
/* refresh vpnv4 tovpn_sid_locator */
XFREE(MTYPE_BGP_SRV6_SID,
bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator);
tovpn_sid_locator =
bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator;
if (tovpn_sid_locator) {
srv6_locator_chunk_free(tovpn_sid_locator);
bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator = NULL;
}
/* refresh vpnv6 tovpn_sid_locator */
XFREE(MTYPE_BGP_SRV6_SID,
bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator);
tovpn_sid_locator =
bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator;
if (tovpn_sid_locator) {
srv6_locator_chunk_free(tovpn_sid_locator);
bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator = NULL;
}
}
/* clear locator name */

View File

@ -3208,10 +3208,10 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
struct srv6_locator loc = {};
struct bgp *bgp = bgp_get_default();
struct listnode *node, *nnode;
struct srv6_locator_chunk *chunk;
struct srv6_locator_chunk *chunk, *tovpn_sid_locator;
struct bgp_srv6_function *func;
struct bgp *bgp_vrf;
struct in6_addr *tovpn_sid, *tovpn_sid_locator;
struct in6_addr *tovpn_sid;
struct prefix_ipv6 tmp_prefi;
if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
@ -3280,10 +3280,13 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
if (tovpn_sid_locator) {
tmp_prefi.family = AF_INET6;
tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
tmp_prefi.prefix = *tovpn_sid_locator;
tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
if (prefix_match((struct prefix *)&loc.prefix,
(struct prefix *)&tmp_prefi))
XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid_locator);
(struct prefix *)&tmp_prefi)) {
srv6_locator_chunk_free(tovpn_sid_locator);
bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator =
NULL;
}
}
/* refresh vpnv6 tovpn_sid_locator */
@ -3292,10 +3295,13 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
if (tovpn_sid_locator) {
tmp_prefi.family = AF_INET6;
tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
tmp_prefi.prefix = *tovpn_sid_locator;
tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
if (prefix_match((struct prefix *)&loc.prefix,
(struct prefix *)&tmp_prefi))
XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid_locator);
(struct prefix *)&tmp_prefi)) {
srv6_locator_chunk_free(tovpn_sid_locator);
bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator =
NULL;
}
}
}

View File

@ -238,7 +238,7 @@ struct vpn_policy {
*/
uint32_t tovpn_sid_index; /* unset => set to 0 */
struct in6_addr *tovpn_sid;
struct in6_addr *tovpn_sid_locator;
struct srv6_locator_chunk *tovpn_sid_locator;
uint32_t tovpn_sid_transpose_label;
struct in6_addr *tovpn_zebra_vrf_sid_last_sent;
};