]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Deal with SRv6 locator instead of chunk
authorCarmine Scarpitta <cscarpit@cisco.com>
Thu, 9 May 2024 13:45:10 +0000 (15:45 +0200)
committerCarmine Scarpitta <cscarpit@cisco.com>
Thu, 5 Sep 2024 08:59:59 +0000 (10:59 +0200)
Currently, when SRv6 is enabled in BGP, BGP requests a locator chunk
from Zebra. Zebra assigns a locator chunk to BGP, and then BGP can
allocate SIDs from the locator chunk.

Recently, the implementation of SRv6 in Zebra has been improved, and a
new API has been introduced for obtaining/releasing the SIDs.

Now, the daemons no longer need to request a chunk.

Instead, the daemons interact with Zebra to obtain information about the
locator and subsequently to allocate/release the SIDs.

This commit extends BGP to use the new SRv6 API. In particular, it
removes the chunk throughout the BGP code and modifies BGP to
request/save/advertise the locator instead of the chunk.

Signed-off-by: Carmine Scarpitta <cscarpit@cisco.com>
bgpd/bgp_mplsvpn.c
bgpd/bgp_vty.c
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.h

index ad774b2b008c0b2aa60bd1fd2fa4d0bfa6bb25db..b74ed657d59bdc10222654f81f227e51babfccc6 100644 (file)
@@ -733,7 +733,7 @@ void ensure_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
                                 afi_t afi)
 {
        int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
-       struct srv6_locator_chunk *tovpn_sid_locator;
+       struct srv6_locator *tovpn_sid_locator;
        struct in6_addr *tovpn_sid;
        uint32_t tovpn_sid_index = 0, tovpn_sid_transpose_label;
        bool tovpn_sid_auto = false;
@@ -748,9 +748,9 @@ void ensure_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
 
        /*
         * skip when bgp vpn instance ins't allocated
-        * or srv6 locator chunk isn't allocated
+        * or srv6 locator isn't allocated
         */
-       if (!bgp_vpn || !bgp_vpn->srv6_locator_chunks)
+       if (!bgp_vpn || !bgp_vpn->srv6_locator)
                return;
 
        tovpn_sid_index = bgp_vrf->vpn_policy[afi].tovpn_sid_index;
@@ -768,7 +768,9 @@ void ensure_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
                return;
        }
 
-       tovpn_sid_locator = srv6_locator_chunk_alloc();
+       tovpn_sid_locator = srv6_locator_alloc(bgp_vpn->srv6_locator_name);
+       srv6_locator_copy(tovpn_sid_locator, bgp_vpn->srv6_locator);
+
        tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
 
        tovpn_sid_transpose_label = alloc_new_sid(bgp_vpn, tovpn_sid_index,
@@ -779,7 +781,7 @@ void ensure_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
                        zlog_debug(
                                "%s: not allocated new sid for vrf %s: afi %s",
                                __func__, bgp_vrf->name_pretty, afi2str(afi));
-               srv6_locator_chunk_free(&tovpn_sid_locator);
+               srv6_locator_free(tovpn_sid_locator);
                XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid);
                return;
        }
@@ -798,7 +800,7 @@ void ensure_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
 void ensure_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
 {
        int debug = BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF);
-       struct srv6_locator_chunk *tovpn_sid_locator;
+       struct srv6_locator *tovpn_sid_locator;
        struct in6_addr *tovpn_sid;
        uint32_t tovpn_sid_index = 0, tovpn_sid_transpose_label;
        bool tovpn_sid_auto = false;
@@ -813,9 +815,9 @@ void ensure_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
 
        /*
         * skip when bgp vpn instance ins't allocated
-        * or srv6 locator chunk isn't allocated
+        * or srv6 locator isn't allocated
         */
-       if (!bgp_vpn || !bgp_vpn->srv6_locator_chunks)
+       if (!bgp_vpn || !bgp_vpn->srv6_locator)
                return;
 
        tovpn_sid_index = bgp_vrf->tovpn_sid_index;
@@ -832,7 +834,9 @@ void ensure_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
                return;
        }
 
-       tovpn_sid_locator = srv6_locator_chunk_alloc();
+       tovpn_sid_locator = srv6_locator_alloc(bgp_vpn->srv6_locator_name);
+       srv6_locator_copy(tovpn_sid_locator, bgp_vpn->srv6_locator);
+
        tovpn_sid = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
 
        tovpn_sid_transpose_label = alloc_new_sid(bgp_vpn, tovpn_sid_index,
@@ -842,7 +846,7 @@ void ensure_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
                if (debug)
                        zlog_debug("%s: not allocated new sid for vrf %s",
                                   __func__, bgp_vrf->name_pretty);
-               srv6_locator_chunk_free(&tovpn_sid_locator);
+               srv6_locator_free(tovpn_sid_locator);
                XFREE(MTYPE_BGP_SRV6_SID, tovpn_sid);
                return;
        }
@@ -889,7 +893,8 @@ void delete_vrf_tovpn_sid_per_af(struct bgp *bgp_vpn, struct bgp *bgp_vrf,
        if (tovpn_sid_index != 0 || tovpn_sid_auto)
                return;
 
-       srv6_locator_chunk_free(&bgp_vrf->vpn_policy[afi].tovpn_sid_locator);
+       srv6_locator_free(bgp_vrf->vpn_policy[afi].tovpn_sid_locator);
+       bgp_vrf->vpn_policy[afi].tovpn_sid_locator = NULL;
 
        if (bgp_vrf->vpn_policy[afi].tovpn_sid) {
                sid_unregister(bgp_vpn, bgp_vrf->vpn_policy[afi].tovpn_sid);
@@ -916,7 +921,8 @@ void delete_vrf_tovpn_sid_per_vrf(struct bgp *bgp_vpn, struct bgp *bgp_vrf)
        if (tovpn_sid_index != 0 || tovpn_sid_auto)
                return;
 
-       srv6_locator_chunk_free(&bgp_vrf->tovpn_sid_locator);
+       srv6_locator_free(bgp_vrf->tovpn_sid_locator);
+       bgp_vrf->tovpn_sid_locator = NULL;
 
        if (bgp_vrf->tovpn_sid) {
                sid_unregister(bgp_vpn, bgp_vrf->tovpn_sid);
@@ -1763,8 +1769,9 @@ void vpn_leak_from_vrf_update(struct bgp *to_bgp,      /* to */
 
        /* Set SID for SRv6 VPN */
        if (from_bgp->vpn_policy[afi].tovpn_sid_locator) {
-               struct srv6_locator_chunk *locator =
+               struct srv6_locator *locator =
                        from_bgp->vpn_policy[afi].tovpn_sid_locator;
+
                encode_label(
                        from_bgp->vpn_policy[afi].tovpn_sid_transpose_label,
                        &label);
@@ -1805,8 +1812,8 @@ void vpn_leak_from_vrf_update(struct bgp *to_bgp,      /* to */
                                .tovpn_sid_locator->prefix.prefix,
                       sizeof(struct in6_addr));
        } else if (from_bgp->tovpn_sid_locator) {
-               struct srv6_locator_chunk *locator =
-                       from_bgp->tovpn_sid_locator;
+               struct srv6_locator *locator = from_bgp->tovpn_sid_locator;
+
                encode_label(from_bgp->tovpn_sid_transpose_label, &label);
                static_attr.srv6_l3vpn =
                        XCALLOC(MTYPE_BGP_SRV6_L3VPN,
index c9c7b80496448ce68c773d76a0982d12aa97a813..f5d02eda9b671d4fb735cd2b8f41061a7d2d570a 100644 (file)
@@ -302,18 +302,11 @@ static const char *get_afi_safi_json_str(afi_t afi, safi_t safi)
 /* unset srv6 locator */
 static int bgp_srv6_locator_unset(struct bgp *bgp)
 {
-       int ret;
        struct listnode *node, *nnode;
        struct srv6_locator_chunk *chunk;
        struct bgp_srv6_function *func;
        struct bgp *bgp_vrf;
 
-       /* release chunk notification via ZAPI */
-       ret = bgp_zebra_srv6_manager_release_locator_chunk(
-                       bgp->srv6_locator_name);
-       if (ret < 0)
-               return -1;
-
        /* refresh chunks */
        for (ALL_LIST_ELEMENTS(bgp->srv6_locator_chunks, node, nnode, chunk)) {
                listnode_delete(bgp->srv6_locator_chunks, chunk);
@@ -352,20 +345,28 @@ static int bgp_srv6_locator_unset(struct bgp *bgp)
                        continue;
 
                /* refresh vpnv4 tovpn_sid_locator */
-               srv6_locator_chunk_free(
-                       &bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator);
+               srv6_locator_free(bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator);
+               bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator = NULL;
 
                /* refresh vpnv6 tovpn_sid_locator */
-               srv6_locator_chunk_free(
-                       &bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator);
+               srv6_locator_free(
+                       bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator);
+               bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator = NULL;
 
                /* refresh per-vrf tovpn_sid_locator */
-               srv6_locator_chunk_free(&bgp_vrf->tovpn_sid_locator);
+               srv6_locator_free(bgp_vrf->tovpn_sid_locator);
+               bgp_vrf->tovpn_sid_locator = NULL;
        }
 
        /* clear locator name */
        memset(bgp->srv6_locator_name, 0, sizeof(bgp->srv6_locator_name));
 
+       /* clear SRv6 locator */
+       if (bgp->srv6_locator) {
+               srv6_locator_free(bgp->srv6_locator);
+               bgp->srv6_locator = NULL;
+       }
+
        return 0;
 }
 
@@ -10878,7 +10879,7 @@ DEFPY (bgp_srv6_locator,
        snprintf(bgp->srv6_locator_name,
                 sizeof(bgp->srv6_locator_name), "%s", name);
 
-       ret = bgp_zebra_srv6_manager_get_locator_chunk(name);
+       ret = bgp_zebra_srv6_manager_get_locator(name);
        if (ret < 0)
                return CMD_WARNING_CONFIG_FAILED;
 
@@ -10929,6 +10930,17 @@ DEFPY (show_bgp_srv6,
                return CMD_SUCCESS;
 
        vty_out(vty, "locator_name: %s\n", bgp->srv6_locator_name);
+       if (bgp->srv6_locator) {
+               vty_out(vty, "  prefix: %pFX\n", &bgp->srv6_locator->prefix);
+               vty_out(vty, "  block-length: %d\n",
+                       bgp->srv6_locator->block_bits_length);
+               vty_out(vty, "  node-length: %d\n",
+                       bgp->srv6_locator->node_bits_length);
+               vty_out(vty, "  func-length: %d\n",
+                       bgp->srv6_locator->function_bits_length);
+               vty_out(vty, "  arg-length: %d\n",
+                       bgp->srv6_locator->argument_bits_length);
+       }
        vty_out(vty, "locator_chunks:\n");
        for (ALL_LIST_ELEMENTS_RO(bgp->srv6_locator_chunks, node, chunk)) {
                vty_out(vty, "- %pFX\n", &chunk->prefix);
index b2d63cb4f6e3644d6a22dec05e647bb7130b4e33..3557768814ebbcbafba7c2ca987d1f16fd9e1cbb 100644 (file)
@@ -3402,7 +3402,8 @@ 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, *tovpn_sid_locator;
+       struct srv6_locator_chunk *chunk;
+       struct srv6_locator *tovpn_sid_locator;
        struct bgp_srv6_function *func;
        struct bgp *bgp_vrf;
        struct in6_addr *tovpn_sid;
@@ -3414,6 +3415,12 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
        if (zapi_srv6_locator_decode(zclient->ibuf, &loc) < 0)
                return -1;
 
+       // clear SRv6 locator
+       if (bgp->srv6_locator) {
+               srv6_locator_free(bgp->srv6_locator);
+               bgp->srv6_locator = NULL;
+       }
+
        // refresh chunks
        for (ALL_LIST_ELEMENTS(bgp->srv6_locator_chunks, node, nnode, chunk))
                if (prefix_match((struct prefix *)&loc.prefix,
@@ -3490,10 +3497,12 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
                        tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
                        tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
                        if (prefix_match((struct prefix *)&loc.prefix,
-                                        (struct prefix *)&tmp_prefi))
-                               srv6_locator_chunk_free(
-                                       &bgp_vrf->vpn_policy[AFI_IP]
-                                                .tovpn_sid_locator);
+                                        (struct prefix *)&tmp_prefi)) {
+                               srv6_locator_free(bgp_vrf->vpn_policy[AFI_IP]
+                                                         .tovpn_sid_locator);
+                               bgp_vrf->vpn_policy[AFI_IP].tovpn_sid_locator =
+                                       NULL;
+                       }
                }
 
                /* refresh vpnv6 tovpn_sid_locator */
@@ -3504,10 +3513,12 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
                        tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
                        tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
                        if (prefix_match((struct prefix *)&loc.prefix,
-                                        (struct prefix *)&tmp_prefi))
-                               srv6_locator_chunk_free(
-                                       &bgp_vrf->vpn_policy[AFI_IP6]
-                                                .tovpn_sid_locator);
+                                        (struct prefix *)&tmp_prefi)) {
+                               srv6_locator_free(bgp_vrf->vpn_policy[AFI_IP6]
+                                                         .tovpn_sid_locator);
+                               bgp_vrf->vpn_policy[AFI_IP6].tovpn_sid_locator =
+                                       NULL;
+                       }
                }
 
                /* refresh per-vrf tovpn_sid_locator */
@@ -3517,9 +3528,10 @@ static int bgp_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
                        tmp_prefi.prefixlen = IPV6_MAX_BITLEN;
                        tmp_prefi.prefix = tovpn_sid_locator->prefix.prefix;
                        if (prefix_match((struct prefix *)&loc.prefix,
-                                        (struct prefix *)&tmp_prefi))
-                               srv6_locator_chunk_free(
-                                       &bgp_vrf->tovpn_sid_locator);
+                                        (struct prefix *)&tmp_prefi)) {
+                               srv6_locator_free(bgp_vrf->tovpn_sid_locator);
+                               bgp_vrf->tovpn_sid_locator = NULL;
+                       }
                }
        }
 
index a88de651f50c7d8aea8cb2c9081e6a579d283aeb..f0c92824d6183bbc57dbf86ea9c0968dccf6fabc 100644 (file)
@@ -1497,9 +1497,11 @@ static void bgp_srv6_init(struct bgp *bgp)
 static void bgp_srv6_cleanup(struct bgp *bgp)
 {
        for (afi_t afi = AFI_IP; afi < AFI_MAX; afi++) {
-               if (bgp->vpn_policy[afi].tovpn_sid_locator != NULL)
-                       srv6_locator_chunk_free(
-                               &bgp->vpn_policy[afi].tovpn_sid_locator);
+               if (bgp->vpn_policy[afi].tovpn_sid_locator != NULL) {
+                       srv6_locator_free(
+                               bgp->vpn_policy[afi].tovpn_sid_locator);
+                       bgp->vpn_policy[afi].tovpn_sid_locator = NULL;
+               }
                if (bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent != NULL)
                        XFREE(MTYPE_BGP_SRV6_SID,
                              bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent);
@@ -1510,8 +1512,10 @@ static void bgp_srv6_cleanup(struct bgp *bgp)
                }
        }
 
-       if (bgp->tovpn_sid_locator != NULL)
-               srv6_locator_chunk_free(&bgp->tovpn_sid_locator);
+       if (bgp->tovpn_sid_locator != NULL) {
+               srv6_locator_free(bgp->tovpn_sid_locator);
+               bgp->tovpn_sid_locator = NULL;
+       }
        if (bgp->tovpn_zebra_vrf_sid_last_sent != NULL)
                XFREE(MTYPE_BGP_SRV6_SID, bgp->tovpn_zebra_vrf_sid_last_sent);
        if (bgp->tovpn_sid != NULL) {
@@ -1523,6 +1527,9 @@ static void bgp_srv6_cleanup(struct bgp *bgp)
                list_delete(&bgp->srv6_locator_chunks);
        if (bgp->srv6_functions)
                list_delete(&bgp->srv6_functions);
+
+       srv6_locator_free(bgp->srv6_locator);
+       bgp->srv6_locator = NULL;
 }
 
 /* Allocate new peer object, implicitely locked.  */
index 7f1b82d9c763d225694e4f64209d4aff3d998ca0..7d0810c84e6c19ea4ba077b98c33fdbd94a0c399 100644 (file)
@@ -270,7 +270,7 @@ struct vpn_policy {
         */
        uint32_t tovpn_sid_index; /* unset => set to 0 */
        struct in6_addr *tovpn_sid;
-       struct srv6_locator_chunk *tovpn_sid_locator;
+       struct srv6_locator *tovpn_sid_locator;
        uint32_t tovpn_sid_transpose_label;
        struct in6_addr *tovpn_zebra_vrf_sid_last_sent;
 };
@@ -836,11 +836,12 @@ struct bgp {
        /* BGP VPN SRv6 backend */
        bool srv6_enabled;
        char srv6_locator_name[SRV6_LOCNAME_SIZE];
+       struct srv6_locator *srv6_locator;
        struct list *srv6_locator_chunks;
        struct list *srv6_functions;
        uint32_t tovpn_sid_index; /* unset => set to 0 */
        struct in6_addr *tovpn_sid;
-       struct srv6_locator_chunk *tovpn_sid_locator;
+       struct srv6_locator *tovpn_sid_locator;
        uint32_t tovpn_sid_transpose_label;
        struct in6_addr *tovpn_zebra_vrf_sid_last_sent;