diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index e2ea773055..987588947e 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -410,6 +410,8 @@ DEFPY(sharp_lsp_prefix_v4, sharp_lsp_prefix_v4_cmd, "Instance\n") { struct nexthop_group_cmd *nhgc = NULL; + struct nexthop_group_cmd *backup_nhgc = NULL; + struct nexthop_group *backup_nhg = NULL; struct prefix p = {}; int type = 0; @@ -441,9 +443,23 @@ DEFPY(sharp_lsp_prefix_v4, sharp_lsp_prefix_v4_cmd, return CMD_WARNING; } + /* Use group's backup nexthop info if present */ + if (nhgc->backup_list_name[0]) { + backup_nhgc = nhgc_find(nhgc->backup_list_name); + + if (!backup_nhgc) { + vty_out(vty, + "%% Backup group %s not found for group %s\n", + nhgc->backup_list_name, + nhgname); + return CMD_WARNING; + } + backup_nhg = &(backup_nhgc->nhg); + } + if (sharp_install_lsps_helper(true, pfx->family > 0 ? &p : NULL, type, instance, inlabel, - &(nhgc->nhg)) == 0) + &(nhgc->nhg), backup_nhg) == 0) return CMD_SUCCESS; else { vty_out(vty, "%% LSP install failed!\n"); @@ -454,7 +470,7 @@ DEFPY(sharp_lsp_prefix_v4, sharp_lsp_prefix_v4_cmd, DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd, "sharp remove lsp \ (0-100000)$inlabel\ - nexthop-group NHGNAME$nhgname\ + [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" @@ -472,6 +488,7 @@ DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd, struct nexthop_group_cmd *nhgc = NULL; struct prefix p = {}; int type = 0; + struct nexthop_group *nhg = NULL; /* We're offered a v4 prefix */ if (pfx->family > 0 && type_str) { @@ -489,21 +506,24 @@ DEFPY(sharp_remove_lsp_prefix_v4, sharp_remove_lsp_prefix_v4_cmd, return CMD_WARNING; } - nhgc = nhgc_find(nhgname); - if (!nhgc) { - vty_out(vty, "%% Nexthop-group '%s' does not exist\n", - nhgname); - return CMD_WARNING; - } + if (nhgname) { + 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 (nhgc->nhg.nexthop == NULL) { + vty_out(vty, "%% Nexthop-group '%s' is empty\n", + nhgname); + return CMD_WARNING; + } + nhg = &(nhgc->nhg); } if (sharp_install_lsps_helper(false, pfx->family > 0 ? &p : NULL, - type, instance, inlabel, - &(nhgc->nhg)) == 0) + type, instance, inlabel, nhg, NULL) == 0) return CMD_SUCCESS; else { vty_out(vty, "%% LSP remove failed!\n"); diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index e1bd6f5722..0795096440 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -89,7 +89,8 @@ static int sharp_ifp_down(struct interface *ifp) 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) + const struct nexthop_group *nhg, + const struct nexthop_group *backup_nhg) { struct zapi_labels zl = {}; struct zapi_nexthop *znh; @@ -106,32 +107,68 @@ int sharp_install_lsps_helper(bool install_p, const struct prefix *p, zl.route.instance = instance; } + /* List of nexthops is optional for delete */ i = 0; - for (ALL_NEXTHOPS_PTR(nhg, nh)) { - znh = &zl.nexthops[i]; + if (nhg) { + 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; + /* 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; + 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; + ret = zapi_nexthop_from_nexthop(znh, nh); + if (ret < 0) + return -1; - i++; + i++; + } } - /* Whoops - no nexthops isn't very useful */ - if (i == 0) + /* Whoops - no nexthops isn't very useful for install */ + if (i == 0 && install_p) return -1; zl.nexthop_num = i; + /* Add optional backup nexthop info. Since these are used by index, + * we can't just skip over an invalid backup nexthop: we will + * invalidate the entire operation. + */ + if (backup_nhg != NULL) { + i = 0; + for (ALL_NEXTHOPS_PTR(backup_nhg, nh)) { + znh = &zl.backup_nexthops[i]; + + /* Must have labels to be useful */ + if (nh->nh_label == NULL || + nh->nh_label->num_labels == 0) + return -1; + + if (nh->type == NEXTHOP_TYPE_IFINDEX || + nh->type == NEXTHOP_TYPE_BLACKHOLE) + /* Hmm - can't really deal with these types */ + return -1; + + ret = zapi_nexthop_from_nexthop(znh, nh); + if (ret < 0) + return -1; + + i++; + } + + if (i > 0) + SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS); + + zl.backup_nexthop_num = i; + } + if (install_p) ret = zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_ADD, &zl); diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h index 926bff676b..2b8e19dd97 100644 --- a/sharpd/sharp_zebra.h +++ b/sharpd/sharp_zebra.h @@ -42,5 +42,7 @@ extern void sharp_remove_routes_helper(struct prefix *p, vrf_id_t vrf_id, 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); + const struct nexthop_group *nhg, + const struct nexthop_group *backup_nhg); + #endif