summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Stapp <mjs@voltanet.io>2020-02-07 22:50:01 +0100
committerMark Stapp <mjs@voltanet.io>2020-02-25 16:55:51 +0100
commitc9e5adba735ca856e2294f95e01917a6a80e0aaa (patch)
treedc8e58726cd777902db5c9739570be6bc8f1e296
parentMerge pull request #5813 from mjstapp/zapi_labels_use_nh (diff)
downloadfrr-c9e5adba735ca856e2294f95e01917a6a80e0aaa.tar.xz
frr-c9e5adba735ca856e2294f95e01917a6a80e0aaa.zip
sharpd: add support for install/remove lsps
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>
-rw-r--r--doc/user/sharp.rst17
-rw-r--r--sharpd/sharp_vty.c122
-rw-r--r--sharpd/sharp_zebra.c92
-rw-r--r--sharpd/sharp_zebra.h4
4 files changed, 198 insertions, 37 deletions
diff --git a/doc/user/sharp.rst b/doc/user/sharp.rst
index 111e9dc9e..199685cdf 100644
--- a/doc/user/sharp.rst
+++ b/doc/user/sharp.rst
@@ -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.
diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c
index 486ccf6bf..fd2e37e67 100644
--- a/sharpd/sharp_vty.c
+++ b/sharpd/sharp_vty.c
@@ -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);
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index 4fc8f40ae..3cd80bde4 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -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;
diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h
index 57ffcc769..c995d557a 100644
--- a/sharpd/sharp_zebra.h
+++ b/sharpd/sharp_zebra.h
@@ -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