]> git.puffer.fish Git - matthieu/frr.git/commitdiff
sharpd: add support for install/remove lsps
authorMark Stapp <mjs@voltanet.io>
Fri, 7 Feb 2020 21:50:01 +0000 (16:50 -0500)
committerMark Stapp <mjs@voltanet.io>
Tue, 25 Feb 2020 15:55:51 +0000 (10:55 -0500)
First round of support for exercising the lsp and ftn paths
using sharpd. This supports lsp-only, and binding to
ipv4 prefix. Also use the common lib nexthop-to-zapi
helper api instead of sharpd's open-coded version.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
doc/user/sharp.rst
sharpd/sharp_vty.c
sharpd/sharp_zebra.c
sharpd/sharp_zebra.h

index 111e9dc9e8b1a2d8c6daefcc8a020bcafbde6f36..199685cdfbc87ed8cbb20e648c3d476f85880dc2 100644 (file)
@@ -86,3 +86,20 @@ keyword. At present, no sharp commands will be preserved in the config.
 
    Allow end user to dump associated data with the nexthop tracking that
    may have been turned on.
+
+.. index:: sharp lsp
+.. clicmd:: sharp lsp (0-100000) nexthop-group NAME [prefix A.B.C.D/M TYPE [instance (0-255)]]
+
+   Install an LSP using the specified in-label, with nexthops as
+   listed in nexthop-group ``NAME``. The LSP is installed as type
+   ZEBRA_LSP_SHARP. If ``prefix`` is specified, an existing route with
+   type ``TYPE`` (and optional ``instance`` id) will be updated to use
+   the LSP.
+
+.. index:: sharp remove lsp
+.. clicmd:: sharp remove lsp (0-100000) nexthop-group NAME [prefix A.B.C.D/M TYPE [instance (0-255)]]
+
+   Remove a SHARPD LSP that uses the specified in-label, where the
+   nexthops are specified in nexthop-group ``NAME``. If ``prefix`` is
+   specified, remove label bindings from the route of type ``TYPE``
+   also.
index 486ccf6bfeb9b58f4dd6346b8873edec410fd313..fd2e37e6751d0b541abe1bb8bece803b895f6649 100644 (file)
@@ -337,11 +337,129 @@ DEFUN_NOSH (show_debugging_sharpd,
            DEBUG_STR
            "Sharp Information\n")
 {
-       vty_out(vty, "Sharp debugging status\n");
+       vty_out(vty, "Sharp debugging status:\n");
 
        return CMD_SUCCESS;
 }
 
+DEFPY(sharp_lsp_prefix_v4, sharp_lsp_prefix_v4_cmd,
+      "sharp lsp (0-100000)$inlabel\
+        nexthop-group NHGNAME$nhgname\
+        [prefix A.B.C.D/M$pfx\
+       " FRR_IP_REDIST_STR_SHARPD "$type_str [instance (0-255)$instance]]",
+      "Sharp Routing Protocol\n"
+      "Add an LSP\n"
+      "The ingress label to use\n"
+      "Use nexthops from a nexthop-group\n"
+      "The nexthop-group name\n"
+      "Label a prefix\n"
+      "The v4 prefix to label\n"
+      FRR_IP_REDIST_HELP_STR_SHARPD
+      "Instance to use\n"
+      "Instance\n")
+{
+       struct nexthop_group_cmd *nhgc = NULL;
+       struct prefix p = {};
+       int type = 0;
+
+       /* We're offered a v4 prefix */
+       if (pfx->family > 0 && type_str) {
+               p.family = pfx->family;
+               p.prefixlen = pfx->prefixlen;
+               p.u.prefix4 = pfx->prefix;
+
+               type = proto_redistnum(AFI_IP, type_str);
+               if (type < 0) {
+                       vty_out(vty, "%%  Unknown route type '%s'\n", type_str);
+                       return CMD_WARNING;
+               }
+       } else if (pfx->family > 0 || type_str) {
+               vty_out(vty, "%%  Must supply both prefix and type\n");
+               return CMD_WARNING;
+       }
+
+       nhgc = nhgc_find(nhgname);
+       if (!nhgc) {
+               vty_out(vty, "%%  Nexthop-group '%s' does not exist\n",
+                       nhgname);
+               return CMD_WARNING;
+       }
+
+       if (nhgc->nhg.nexthop == NULL) {
+               vty_out(vty, "%%  Nexthop-group '%s' is empty\n", nhgname);
+               return CMD_WARNING;
+       }
+
+       if (sharp_install_lsps_helper(true, pfx->family > 0 ? &p : NULL,
+                                     type, instance, inlabel,
+                                     &(nhgc->nhg)) == 0)
+               return CMD_SUCCESS;
+       else {
+               vty_out(vty, "%% LSP install failed!\n");
+               return CMD_WARNING;
+       }
+}
+
+DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd,
+      "sharp remove lsp \
+        (0-100000)$inlabel\
+        nexthop-group NHGNAME$nhgname\
+        [prefix A.B.C.D/M$pfx\
+       " FRR_IP_REDIST_STR_SHARPD "$type_str [instance (0-255)$instance]]",
+      "Sharp Routing Protocol\n"
+      "Remove data\n"
+      "Remove an LSP\n"
+      "The ingress label\n"
+      "Use nexthops from a nexthop-group\n"
+      "The nexthop-group name\n"
+      "Specify a v4 prefix\n"
+      "The v4 prefix to label\n"
+      FRR_IP_REDIST_HELP_STR_SHARPD
+      "Routing instance\n"
+      "Instance to use\n")
+{
+       struct nexthop_group_cmd *nhgc = NULL;
+       struct prefix p = {};
+       int type = 0;
+
+       /* We're offered a v4 prefix */
+       if (pfx->family > 0 && type_str) {
+               p.family = pfx->family;
+               p.prefixlen = pfx->prefixlen;
+               p.u.prefix4 = pfx->prefix;
+
+               type = proto_redistnum(AFI_IP, type_str);
+               if (type < 0) {
+                       vty_out(vty, "%%  Unknown route type '%s'\n", type_str);
+                       return CMD_WARNING;
+               }
+       } else if (pfx->family > 0 || type_str) {
+               vty_out(vty, "%%  Must supply both prefix and type\n");
+               return CMD_WARNING;
+       }
+
+       nhgc = nhgc_find(nhgname);
+       if (!nhgc) {
+               vty_out(vty, "%%  Nexthop-group '%s' does not exist\n",
+                       nhgname);
+               return CMD_WARNING;
+       }
+
+       if (nhgc->nhg.nexthop == NULL) {
+               vty_out(vty, "%%  Nexthop-group '%s' is empty\n", nhgname);
+               return CMD_WARNING;
+       }
+
+       if (sharp_install_lsps_helper(false, pfx->family > 0 ? &p : NULL,
+                                     type, instance, inlabel,
+                                     &(nhgc->nhg)) == 0)
+               return CMD_SUCCESS;
+       else {
+               vty_out(vty, "%% LSP remove failed!\n");
+               return CMD_WARNING;
+       }
+}
+
 void sharp_vty_init(void)
 {
        install_element(ENABLE_NODE, &install_routes_data_dump_cmd);
@@ -351,6 +469,8 @@ void sharp_vty_init(void)
        install_element(ENABLE_NODE, &sharp_nht_data_dump_cmd);
        install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
        install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);
+       install_element(ENABLE_NODE, &sharp_lsp_prefix_v4_cmd);
+       install_element(ENABLE_NODE, &sharp_remove_lsp_prefix_v4_cmd);
 
        install_element(VIEW_NODE, &show_debugging_sharpd_cmd);
 
index 4fc8f40ae1c0cb631012f4979ec295db967a4432..3cd80bde49d16081efe2d33fc7a660079b3d4c13 100644 (file)
@@ -87,6 +87,61 @@ static int sharp_ifp_down(struct interface *ifp)
        return 0;
 }
 
+int sharp_install_lsps_helper(bool install_p, const struct prefix *p,
+                             uint8_t type, int instance, uint32_t in_label,
+                             const struct nexthop_group *nhg)
+{
+       struct zapi_labels zl = {};
+       struct zapi_nexthop *znh;
+       const struct nexthop *nh;
+       int i, ret;
+
+       zl.type = ZEBRA_LSP_SHARP;
+       zl.local_label = in_label;
+
+       if (p) {
+               SET_FLAG(zl.message, ZAPI_LABELS_FTN);
+               prefix_copy(&zl.route.prefix, p);
+               zl.route.type = type;
+               zl.route.instance = instance;
+       }
+
+       i = 0;
+       for (ALL_NEXTHOPS_PTR(nhg, nh)) {
+               znh = &zl.nexthops[i];
+
+               /* Must have labels to be useful */
+               if (nh->nh_label == NULL || nh->nh_label->num_labels == 0)
+                       continue;
+
+               if (nh->type == NEXTHOP_TYPE_IFINDEX ||
+                   nh->type == NEXTHOP_TYPE_BLACKHOLE)
+                       /* Hmm - can't really deal with these types */
+                       continue;
+
+               ret = zapi_nexthop_from_nexthop(znh, nh);
+               if (ret < 0)
+                       return -1;
+
+               i++;
+       }
+
+       /* Whoops - no nexthops isn't very useful */
+       if (i == 0)
+               return -1;
+
+       zl.nexthop_num = i;
+
+       if (install_p)
+               ret = zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_ADD,
+                                            &zl);
+       else
+               ret = zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE,
+                                            &zl);
+
+       return ret;
+}
+
 void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
                                 uint8_t instance, struct nexthop_group *nhg,
                                 uint32_t routes)
@@ -241,43 +296,8 @@ void route_add(struct prefix *p, vrf_id_t vrf_id,
 
        for (ALL_NEXTHOPS_PTR(nhg, nh)) {
                api_nh = &api.nexthops[i];
-               api_nh->vrf_id = nh->vrf_id;
-               api_nh->type = nh->type;
-               api_nh->weight = nh->weight;
-
-               switch (nh->type) {
-               case NEXTHOP_TYPE_IPV4:
-                       api_nh->gate = nh->gate;
-                       break;
-               case NEXTHOP_TYPE_IPV4_IFINDEX:
-                       api_nh->gate = nh->gate;
-                       api_nh->ifindex = nh->ifindex;
-                       break;
-               case NEXTHOP_TYPE_IFINDEX:
-                       api_nh->ifindex = nh->ifindex;
-                       break;
-               case NEXTHOP_TYPE_IPV6:
-                       memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6, 16);
-                       break;
-               case NEXTHOP_TYPE_IPV6_IFINDEX:
-                       api_nh->ifindex = nh->ifindex;
-                       memcpy(&api_nh->gate.ipv6, &nh->gate.ipv6, 16);
-                       break;
-               case NEXTHOP_TYPE_BLACKHOLE:
-                       api_nh->bh_type = nh->bh_type;
-                       break;
-               }
-
-               if (nh->nh_label && nh->nh_label->num_labels > 0) {
-                       int j;
-
-                       SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL);
-
-                       api_nh->label_num = nh->nh_label->num_labels;
-                       for (j = 0; j < nh->nh_label->num_labels; j++)
-                               api_nh->labels[j] = nh->nh_label->label[j];
-               }
 
+               zapi_nexthop_from_nexthop(api_nh, nh);
                i++;
        }
        api.nexthop_num = i;
index 57ffcc7690dabb7ecd0121d16c61b234911b4f83..c995d557af4e3bbefb349436e4ab608562fdc303 100644 (file)
@@ -37,4 +37,8 @@ extern void sharp_install_routes_helper(struct prefix *p, vrf_id_t vrf_id,
                                        uint32_t routes);
 extern void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id,
                                       uint8_t instance, uint32_t routes);
+
+int sharp_install_lsps_helper(bool install_p, const struct prefix *p,
+                             uint8_t type, int instance, uint32_t in_label,
+                             const struct nexthop_group *nhg);
 #endif