X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=lib%2Fnexthop_group.c;h=0613fc6736ade0d0b43e8d99fd171c1c79653f4f;hb=12906cb1c84b4de54874365d4a02a040ed9632d1;hp=e8c678ad71a416c5a8f0b8cf65d4ed900fc23db5;hpb=3c522938091a074b0ad85460d56e393cd39cc2e9;p=mirror_frr.git diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index e8c678ad7..0613fc673 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -1,21 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0-or-later /* * Nexthop Group structure definition. * Copyright (C) 2018 Cumulus Networks, Inc. * Donald Sharp - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; see the file COPYING; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include @@ -28,9 +15,7 @@ #include #include -#ifndef VTYSH_EXTRACT_PL #include "lib/nexthop_group_clippy.c" -#endif DEFINE_MTYPE_STATIC(LIB, NEXTHOP_GROUP, "Nexthop Group"); @@ -43,12 +28,14 @@ struct nexthop_hold { char *intf; bool onlink; char *labels; + vni_t vni; uint32_t weight; char *backup_str; }; struct nexthop_group_hooks { void (*new)(const char *name); + void (*modify)(const struct nexthop_group_cmd *nhgc); void (*add_nexthop)(const struct nexthop_group_cmd *nhg, const struct nexthop *nhop); void (*del_nexthop)(const struct nexthop_group_cmd *nhg, @@ -132,6 +119,18 @@ nexthop_group_active_nexthop_num_no_recurse(const struct nexthop_group *nhg) return num; } +bool nexthop_group_has_label(const struct nexthop_group *nhg) +{ + struct nexthop *nhop; + + for (ALL_NEXTHOPS_PTR(nhg, nhop)) { + if (nhop->nh_label) + return true; + } + + return false; +} + struct nexthop *nexthop_exists(const struct nexthop_group *nhg, const struct nexthop *nh) { @@ -274,6 +273,7 @@ struct nexthop_group *nexthop_group_new(void) void nexthop_group_copy(struct nexthop_group *to, const struct nexthop_group *from) { + to->nhgr = from->nhgr; /* Copy everything, including recursive info */ copy_nexthops(&to->nexthop, from->nexthop, NULL); } @@ -675,6 +675,50 @@ DEFPY(no_nexthop_group_backup, no_nexthop_group_backup_cmd, return CMD_SUCCESS; } +DEFPY(nexthop_group_resilience, + nexthop_group_resilience_cmd, + "resilient buckets (1-256) idle-timer (1-4294967295) unbalanced-timer (1-4294967295)", + "A resilient Nexthop Group\n" + "Buckets in the Hash for this Group\n" + "Number of buckets\n" + "The Idle timer for this Resilient Nexthop Group in seconds\n" + "Number of seconds of Idle time\n" + "The length of time that the Nexthop Group can be unbalanced\n" + "Number of seconds of Unbalanced time\n") +{ + VTY_DECLVAR_CONTEXT(nexthop_group_cmd, nhgc); + + nhgc->nhg.nhgr.buckets = buckets; + nhgc->nhg.nhgr.idle_timer = idle_timer; + nhgc->nhg.nhgr.unbalanced_timer = unbalanced_timer; + + if (nhg_hooks.modify) + nhg_hooks.modify(nhgc); + + return CMD_SUCCESS; +} + +DEFPY(no_nexthop_group_resilience, + no_nexthop_group_resilience_cmd, + "no resilient [buckets (1-256) idle-timer (1-4294967295) unbalanced-timer (1-4294967295)]", + NO_STR + "A resilient Nexthop Group\n" + "Buckets in the Hash for this Group\n" + "Number of buckets\n" + "The Idle timer for this Resilient Nexthop Group in seconds\n" + "Number of seconds of Idle time\n" + "The length of time that the Nexthop Group can be unbalanced\n" + "Number of seconds of Unbalanced time\n") +{ + VTY_DECLVAR_CONTEXT(nexthop_group_cmd, nhgc); + + nhgc->nhg.nhgr.buckets = 0; + nhgc->nhg.nhgr.idle_timer = 0; + nhgc->nhg.nhgr.unbalanced_timer = 0; + + return CMD_SUCCESS; +} + static void nexthop_group_save_nhop(struct nexthop_group_cmd *nhgc, const char *nhvrf_name, const union sockunion *addr, @@ -747,12 +791,13 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, const union sockunion *addr, const char *intf, bool onlink, const char *name, const char *labels, - int *lbl_ret, uint32_t weight, - const char *backup_str) + vni_t vni, int *lbl_ret, + uint32_t weight, const char *backup_str) { int ret = 0; struct vrf *vrf; int num; + uint8_t labelnum = 0; memset(nhop, 0, sizeof(*nhop)); @@ -793,10 +838,9 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, nhop->type = NEXTHOP_TYPE_IFINDEX; if (labels) { - uint8_t num = 0; mpls_label_t larray[MPLS_MAX_LABELS]; - ret = mpls_str2label(labels, &num, larray); + ret = mpls_str2label(labels, &labelnum, larray); /* Return label parse result */ if (lbl_ret) @@ -804,9 +848,14 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, if (ret < 0) return false; - else if (num > 0) - nexthop_add_labels(nhop, ZEBRA_LSP_NONE, - num, larray); + else if (labelnum > 0) + nexthop_add_labels(nhop, ZEBRA_LSP_NONE, labelnum, + larray); + } else if (vni) { + mpls_label_t label = MPLS_INVALID_LABEL; + + vni2label(vni, &label); + nexthop_add_labels(nhop, ZEBRA_LSP_EVPN, 1, &label); } nhop->weight = weight; @@ -833,7 +882,7 @@ static bool nexthop_group_parse_nhh(struct nexthop *nhop, { return (nexthop_group_parse_nexthop( nhop, nhh->addr, nhh->intf, nhh->onlink, nhh->nhvrf_name, - nhh->labels, NULL, nhh->weight, nhh->backup_str)); + nhh->labels, nhh->vni, NULL, nhh->weight, nhh->backup_str)); } DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, @@ -845,6 +894,7 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, [{ \ nexthop-vrf NAME$vrf_name \ |label WORD \ + |vni (1-16777215) \ |weight (1-255) \ |backup-idx WORD \ }]", @@ -859,6 +909,8 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, "The nexthop-vrf Name\n" "Specify label(s) for this nexthop\n" "One or more labels in the range (16-1048575) separated by '/'\n" + "Specify VNI(s) for this nexthop\n" + "VNI in the range (1-16777215)\n" "Weight to be used by the nexthop for purposes of ECMP\n" "Weight value to be used\n" "Specify backup nexthop indexes in another group\n" @@ -883,8 +935,8 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, } legal = nexthop_group_parse_nexthop(&nhop, addr, intf, !!onlink, - vrf_name, label, &lbl_ret, weight, - backup_idx); + vrf_name, label, vni, &lbl_ret, + weight, backup_idx); if (nhop.type == NEXTHOP_TYPE_IPV6 && IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6)) { @@ -1014,9 +1066,8 @@ void nexthop_group_write_nexthop(struct vty *vty, const struct nexthop *nh) if (nh->nh_label && nh->nh_label->num_labels > 0) { char buf[200]; - mpls_label2str(nh->nh_label->num_labels, - nh->nh_label->label, - buf, sizeof(buf), 0); + mpls_label2str(nh->nh_label->num_labels, nh->nh_label->label, + buf, sizeof(buf), nh->nh_label_type, 0); vty_out(vty, " label %s", buf); } @@ -1073,7 +1124,7 @@ void nexthop_group_json_nexthop(json_object *j, const struct nexthop *nh) char buf[200]; mpls_label2str(nh->nh_label->num_labels, nh->nh_label->label, - buf, sizeof(buf), 0); + buf, sizeof(buf), nh->nh_label_type, 0); json_object_string_add(j, "label", buf); } @@ -1094,12 +1145,10 @@ void nexthop_group_json_nexthop(json_object *j, const struct nexthop *nh) static void nexthop_group_write_nexthop_internal(struct vty *vty, const struct nexthop_hold *nh) { - char buf[100]; - vty_out(vty, "nexthop"); if (nh->addr) - vty_out(vty, " %s", sockunion2str(nh->addr, buf, sizeof(buf))); + vty_out(vty, " %pSU", nh->addr); if (nh->intf) vty_out(vty, " %s", nh->intf); @@ -1113,6 +1162,9 @@ static void nexthop_group_write_nexthop_internal(struct vty *vty, if (nh->labels) vty_out(vty, " label %s", nh->labels); + if (nh->vni) + vty_out(vty, " vni %u", nh->vni); + if (nh->weight) vty_out(vty, " weight %u", nh->weight); @@ -1132,6 +1184,13 @@ static int nexthop_group_write(struct vty *vty) vty_out(vty, "nexthop-group %s\n", nhgc->name); + if (nhgc->nhg.nhgr.buckets) + vty_out(vty, + " resilient buckets %u idle-timer %u unbalanced-timer %u\n", + nhgc->nhg.nhgr.buckets, + nhgc->nhg.nhgr.idle_timer, + nhgc->nhg.nhgr.unbalanced_timer); + if (nhgc->backup_list_name[0]) vty_out(vty, " backup-group %s\n", nhgc->backup_list_name); @@ -1302,6 +1361,7 @@ static const struct cmd_variable_handler nhg_name_handlers[] = { {.completions = NULL}}; void nexthop_group_init(void (*new)(const char *name), + void (*modify)(const struct nexthop_group_cmd *nhgc), void (*add_nexthop)(const struct nexthop_group_cmd *nhg, const struct nexthop *nhop), void (*del_nexthop)(const struct nexthop_group_cmd *nhg, @@ -1321,10 +1381,15 @@ void nexthop_group_init(void (*new)(const char *name), install_element(NH_GROUP_NODE, &no_nexthop_group_backup_cmd); install_element(NH_GROUP_NODE, &ecmp_nexthops_cmd); + install_element(NH_GROUP_NODE, &nexthop_group_resilience_cmd); + install_element(NH_GROUP_NODE, &no_nexthop_group_resilience_cmd); + memset(&nhg_hooks, 0, sizeof(nhg_hooks)); if (new) nhg_hooks.new = new; + if (modify) + nhg_hooks.modify = modify; if (add_nexthop) nhg_hooks.add_nexthop = add_nexthop; if (del_nexthop)