From 28593bccc2c7322b707a628f389d08bf973665f5 Mon Sep 17 00:00:00 2001 From: Mark Stapp Date: Wed, 1 Jul 2020 15:56:37 -0400 Subject: [PATCH] lib: support multiple backup nexthops in nexthop group cli Revise the nexthop-group cli to support multiple backups for a single primary nexthop. Signed-off-by: Mark Stapp --- lib/nexthop_group.c | 80 +++++++++++++++++++++++++++++---------------- lib/nexthop_group.h | 6 ++-- 2 files changed, 55 insertions(+), 31 deletions(-) diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 318f9f6161..97815ceeb9 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -43,12 +43,9 @@ struct nexthop_hold { char *intf; char *labels; uint32_t weight; - int backup_idx; /* Index of backup nexthop, if >= 0 */ + char *backup_str; }; -/* Invalid/unset value for nexthop_hold's backup_idx */ -#define NHH_BACKUP_IDX_INVALID -1 - struct nexthop_group_hooks { void (*new)(const char *name); void (*add_nexthop)(const struct nexthop_group_cmd *nhg, @@ -677,7 +674,8 @@ static void nexthop_group_save_nhop(struct nexthop_group_cmd *nhgc, const char *nhvrf_name, const union sockunion *addr, const char *intf, const char *labels, - const uint32_t weight, int backup_idx) + const uint32_t weight, + const char *backup_str) { struct nexthop_hold *nh; @@ -694,7 +692,8 @@ static void nexthop_group_save_nhop(struct nexthop_group_cmd *nhgc, nh->weight = weight; - nh->backup_idx = backup_idx; + if (backup_str) + nh->backup_str = XSTRDUP(MTYPE_TMP, backup_str); listnode_add_sort(nhgc->nhg_list, nh); } @@ -741,10 +740,11 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, const union sockunion *addr, const char *intf, const char *name, const char *labels, int *lbl_ret, - uint32_t weight, int backup_idx) + uint32_t weight, const char *backup_str) { int ret = 0; struct vrf *vrf; + int num; memset(nhop, 0, sizeof(*nhop)); @@ -800,14 +800,15 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, nhop->weight = weight; - if (backup_idx != NHH_BACKUP_IDX_INVALID) { - /* Validate index value */ - if (backup_idx > NEXTHOP_BACKUP_IDX_MAX) + if (backup_str) { + /* Parse backup indexes */ + ret = nexthop_str2backups(backup_str, + &num, nhop->backup_idx); + if (ret == 0) { + SET_FLAG(nhop->flags, NEXTHOP_FLAG_HAS_BACKUP); + nhop->backup_num = num; + } else return false; - - SET_FLAG(nhop->flags, NEXTHOP_FLAG_HAS_BACKUP); - nhop->backup_num = 1; - nhop->backup_idx[0] = backup_idx; } return true; @@ -821,7 +822,7 @@ static bool nexthop_group_parse_nhh(struct nexthop *nhop, { return (nexthop_group_parse_nexthop(nhop, nhh->addr, nhh->intf, nhh->nhvrf_name, nhh->labels, NULL, - nhh->weight, nhh->backup_idx)); + nhh->weight, nhh->backup_str)); } DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, @@ -834,7 +835,7 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, nexthop-vrf NAME$vrf_name \ |label WORD \ |weight (1-255) \ - |backup-idx$bi_str (0-254)$idx \ + |backup-idx WORD \ }]", NO_STR "Specify one of the nexthops in this ECMP group\n" @@ -848,19 +849,26 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, "One or more labels in the range (16-1048575) separated by '/'\n" "Weight to be used by the nexthop for purposes of ECMP\n" "Weight value to be used\n" - "Backup nexthop index in another group\n" - "Nexthop index value\n") + "Specify backup nexthop indexes in another group\n" + "One or more indexes in the range (0-254) separated by ','\n") { VTY_DECLVAR_CONTEXT(nexthop_group_cmd, nhgc); struct nexthop nhop; struct nexthop *nh; int lbl_ret = 0; bool legal; - int backup_idx = idx; + int num; + uint8_t backups[NEXTHOP_MAX_BACKUPS]; bool yes = !no; - if (bi_str == NULL) - backup_idx = NHH_BACKUP_IDX_INVALID; + /* Pre-parse backup string to validate */ + if (backup_idx) { + lbl_ret = nexthop_str2backups(backup_idx, &num, backups); + if (lbl_ret < 0) { + vty_out(vty, "%% Invalid backups\n"); + return CMD_WARNING_CONFIG_FAILED; + } + } legal = nexthop_group_parse_nexthop(&nhop, addr, intf, vrf_name, label, &lbl_ret, weight, backup_idx); @@ -944,10 +952,11 @@ static struct cmd_node nexthop_group_node = { .config_write = nexthop_group_write, }; -void nexthop_group_write_nexthop(struct vty *vty, struct nexthop *nh) +void nexthop_group_write_nexthop(struct vty *vty, const struct nexthop *nh) { char buf[100]; struct vrf *vrf; + int i; vty_out(vty, "nexthop "); @@ -992,16 +1001,22 @@ void nexthop_group_write_nexthop(struct vty *vty, struct nexthop *nh) if (nh->weight) vty_out(vty, " weight %u", nh->weight); - if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_HAS_BACKUP)) + if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_HAS_BACKUP)) { vty_out(vty, " backup-idx %d", nh->backup_idx[0]); + for (i = 1; i < nh->backup_num; i++) + vty_out(vty, ",%d", nh->backup_idx[i]); + } + vty_out(vty, "\n"); } -void nexthop_group_json_nexthop(json_object *j, struct nexthop *nh) +void nexthop_group_json_nexthop(json_object *j, const struct nexthop *nh) { char buf[100]; struct vrf *vrf; + json_object *json_backups = NULL; + int i; switch (nh->type) { case NEXTHOP_TYPE_IFINDEX: @@ -1048,12 +1063,19 @@ void nexthop_group_json_nexthop(json_object *j, struct nexthop *nh) if (nh->weight) json_object_int_add(j, "weight", nh->weight); - if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_HAS_BACKUP)) - json_object_int_add(j, "backupIdx", nh->backup_idx[0]); + if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_HAS_BACKUP)) { + json_backups = json_object_new_array(); + for (i = 0; i < nh->backup_num; i++) + json_object_array_add( + json_backups, + json_object_new_int(nh->backup_idx[i])); + + json_object_object_add(j, "backupIdx", json_backups); + } } static void nexthop_group_write_nexthop_internal(struct vty *vty, - struct nexthop_hold *nh) + const struct nexthop_hold *nh) { char buf[100]; @@ -1074,8 +1096,8 @@ static void nexthop_group_write_nexthop_internal(struct vty *vty, if (nh->weight) vty_out(vty, " weight %u", nh->weight); - if (nh->backup_idx != NHH_BACKUP_IDX_INVALID) - vty_out(vty, " backup-idx %d", nh->backup_idx); + if (nh->backup_str) + vty_out(vty, " backup-idx %s", nh->backup_str); vty_out(vty, "\n"); } diff --git a/lib/nexthop_group.h b/lib/nexthop_group.h index 9888dad982..0b5ac91bb2 100644 --- a/lib/nexthop_group.h +++ b/lib/nexthop_group.h @@ -135,9 +135,11 @@ extern bool nexthop_group_equal(const struct nexthop_group *nhg1, extern struct nexthop_group_cmd *nhgc_find(const char *name); -extern void nexthop_group_write_nexthop(struct vty *vty, struct nexthop *nh); +extern void nexthop_group_write_nexthop(struct vty *vty, + const struct nexthop *nh); -extern void nexthop_group_json_nexthop(json_object *j, struct nexthop *nh); +extern void nexthop_group_json_nexthop(json_object *j, + const struct nexthop *nh); /* Return the number of nexthops in this nhg */ extern uint8_t nexthop_group_nexthop_num(const struct nexthop_group *nhg); -- 2.39.5