Skip to content

Commit

Permalink
bgpd: introduce new alloc algorithm for SRv6 SID
Browse files Browse the repository at this point in the history
Current implementation of SRv6 SID allocation algorithm sets most least
2 bytes. But, according to RFC8986, function bits is located in the next
to locator. New allocation alogirithm respects this format.

Signed-off-by: Ryoga Saito <contact@proelbtn.com>
  • Loading branch information
proelbtn committed Sep 3, 2021
1 parent 2dc1fa1 commit a45cd34
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
38 changes: 26 additions & 12 deletions bgpd/bgp_mplsvpn.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,31 +522,32 @@ static bool sid_exist(struct bgp *bgp, const struct in6_addr *sid)
* if index != 0: try to allocate as index-mode
* else: try to allocate as auto-mode
*/
static bool alloc_new_sid(struct bgp *bgp, uint32_t index,
struct in6_addr *sid)
static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
struct in6_addr *sid)
{
struct listnode *node;
struct prefix_ipv6 *chunk;
struct in6_addr sid_buf;
bool alloced = false;
int label;

if (!bgp || !sid)
return false;

for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) {
sid_buf = chunk->prefix;
if (index != 0) {
sid_buf.s6_addr[15] = index;
label = index << 12;
transpose_sid(&sid_buf, label, 64, 16);
if (sid_exist(bgp, &sid_buf))
return false;
alloced = true;
break;
}

for (size_t i = 1; i < 255; i++) {
sid_buf.s6_addr[15] = (i & 0xff00) >> 8;
sid_buf.s6_addr[14] = (i & 0x00ff);

label = i << 12;
transpose_sid(&sid_buf, label, 64, 16);
if (sid_exist(bgp, &sid_buf))
continue;
alloced = true;
Expand All @@ -555,20 +556,19 @@ static bool alloc_new_sid(struct bgp *bgp, uint32_t index,
}

if (!alloced)
return false;
return 0;

sid_register(bgp, &sid_buf, bgp->srv6_locator_name);
*sid = sid_buf;
return true;
return label;
}

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);
bool alloced = false;
char buf[256];
struct in6_addr *sid;
uint32_t tovpn_sid_index = 0;
uint32_t tovpn_sid_index = 0, tovpn_sid_transpose_label;
bool tovpn_sid_auto = false;

if (debug)
Expand Down Expand Up @@ -602,8 +602,9 @@ void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
}

sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
alloced = alloc_new_sid(bgp_vpn, tovpn_sid_index, sid);
if (!alloced) {
tovpn_sid_transpose_label =
alloc_new_sid(bgp_vpn, tovpn_sid_index, sid);
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;
Expand All @@ -615,9 +616,22 @@ void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
__func__, buf, bgp_vrf->name_pretty,
afi2str(afi));
}
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,
uint8_t len)
{
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)
sid->s6_addr[tidx / 8] |= 0x1 << (7 - tidx % 8);
}
}

static bool ecom_intersect(struct ecommunity *e1, struct ecommunity *e2)
{
uint32_t i, j;
Expand Down
2 changes: 2 additions & 0 deletions bgpd/bgp_mplsvpn.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ extern void vpn_leak_zebra_vrf_sid_update(struct bgp *bgp, afi_t afi);
extern void vpn_leak_zebra_vrf_sid_withdraw(struct bgp *bgp, afi_t afi);
extern int vpn_leak_label_callback(mpls_label_t label, void *lblid, bool alloc);
extern void ensure_vrf_tovpn_sid(struct bgp *vpn, struct bgp *vrf, afi_t afi);
extern void transpose_sid(struct in6_addr *sid, uint32_t label, uint8_t offset,
uint8_t size);
extern void vrf_import_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
afi_t afi, safi_t safi);
void vrf_unimport_from_vrf(struct bgp *to_bgp, struct bgp *from_bgp,
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgpd.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ struct vpn_policy {
*/
uint32_t tovpn_sid_index; /* unset => set to 0 */
struct in6_addr *tovpn_sid;
uint32_t tovpn_sid_transpose_label;
struct in6_addr *tovpn_zebra_vrf_sid_last_sent;
};

Expand Down

0 comments on commit a45cd34

Please sign in to comment.