diff options
author | Mark Stapp <mjs@voltanet.io> | 2020-02-07 22:50:01 +0100 |
---|---|---|
committer | Mark Stapp <mjs@voltanet.io> | 2020-02-25 16:55:51 +0100 |
commit | c9e5adba735ca856e2294f95e01917a6a80e0aaa (patch) | |
tree | dc8e58726cd777902db5c9739570be6bc8f1e296 | |
parent | Merge pull request #5813 from mjstapp/zapi_labels_use_nh (diff) | |
download | frr-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.rst | 17 | ||||
-rw-r--r-- | sharpd/sharp_vty.c | 122 | ||||
-rw-r--r-- | sharpd/sharp_zebra.c | 92 | ||||
-rw-r--r-- | sharpd/sharp_zebra.h | 4 |
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 |