]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: take SRv6 locator's prefix length into account when generating SIDs
authorNobuhiro MIKI <nmiki@yahoo-corp.jp>
Thu, 7 Apr 2022 07:09:02 +0000 (16:09 +0900)
committerNobuhiro MIKI <nmiki@yahoo-corp.jp>
Thu, 14 Apr 2022 05:37:55 +0000 (14:37 +0900)
Until now, it has been hard-coded that the position at which the label
is inserted is from the 64th bits. Therefore, when the Locator prefix
was not /64, incorrect SIDs were generated. Also, SIDs are generated
in duplicate on Lines 604 & 613 in bgpd/bgp_mplsvpn.c.

In this patch, the position where the label is inserted is calculated
based on the sum of block_bits_length and node_bits_length (i.e., the
user-specified Locator prefix length). In addition, SID generation is
performed at one location in alloc_new_sid.

Signed-off-by: Nobuhiro MIKI <nmiki@yahoo-corp.jp>
bgpd/bgp_mplsvpn.c

index bb6b35680c3f9e3d713d750c5017a66d8080d698..b3d8d1b82dd8b707ffc51390c42841565b9b64be 100644 (file)
@@ -516,28 +516,35 @@ static bool sid_exist(struct bgp *bgp, const struct in6_addr *sid)
 }
 
 /*
+ * This function generates a new SID based on bgp->srv6_locator_chunks and
+ * index. The locator and generated SID are stored in arguments sid_locator
+ * and sid, respectively.
+ *
  * if index != 0: try to allocate as index-mode
  * 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 in6_addr *sid_locator,
+                             struct in6_addr *sid)
 {
        struct listnode *node;
        struct srv6_locator_chunk *chunk;
-       struct in6_addr sid_buf;
        bool alloced = false;
        int label = 0;
+       uint8_t offset = 0;
 
-       if (!bgp || !sid_locator)
+       if (!bgp || !sid_locator || !sid)
                return false;
 
        for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) {
                *sid_locator = chunk->prefix.prefix;
-               sid_buf = chunk->prefix.prefix;
+               *sid = chunk->prefix.prefix;
+               offset = chunk->block_bits_length + chunk->node_bits_length;
+
                if (index != 0) {
                        label = index << 12;
-                       transpose_sid(&sid_buf, label, 64, 16);
-                       if (sid_exist(bgp, &sid_buf))
+                       transpose_sid(sid, label, offset, 16);
+                       if (sid_exist(bgp, sid))
                                return false;
                        alloced = true;
                        break;
@@ -545,8 +552,8 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
 
                for (size_t i = 1; i < 255; i++) {
                        label = i << 12;
-                       transpose_sid(&sid_buf, label, 64, 16);
-                       if (sid_exist(bgp, &sid_buf))
+                       transpose_sid(sid, label, offset, 16);
+                       if (sid_exist(bgp, sid))
                                continue;
                        alloced = true;
                        break;
@@ -556,7 +563,7 @@ static uint32_t alloc_new_sid(struct bgp *bgp, uint32_t index,
        if (!alloced)
                return 0;
 
-       sid_register(bgp, &sid_buf, bgp->srv6_locator_name);
+       sid_register(bgp, sid, bgp->srv6_locator_name);
        return label;
 }
 
@@ -600,21 +607,19 @@ void ensure_vrf_tovpn_sid(struct bgp *bgp_vpn, struct bgp *bgp_vrf, afi_t afi)
 
        tovpn_sid_locator =
                XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
-       tovpn_sid_transpose_label =
-               alloc_new_sid(bgp_vpn, tovpn_sid_index, tovpn_sid_locator);
+       tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
+
+       tovpn_sid_transpose_label = alloc_new_sid(bgp_vpn, tovpn_sid_index,
+                                                 tovpn_sid_locator, tovpn_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));
                XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid_locator);
+               XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid);
                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, tovpn_sid, buf, sizeof(buf));
                zlog_debug("%s: new sid %s allocated for vrf %s: afi %s",