* 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;
}
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;
}
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)
}
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;
__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;
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,