From 54c6fa8e0ac724aad6f9022f1689ff5c111a0e2e Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Mon, 18 May 2020 14:38:19 -0400 Subject: [PATCH] lib,doc: add `onlink` flag to nexthop group config Add an `onlink` flag to nexthop group configuration. Signed-off-by: Stephen Worley --- doc/user/pbr.rst | 2 +- lib/nexthop_group.c | 42 +++++++++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/doc/user/pbr.rst b/doc/user/pbr.rst index 99ef258cb2..c869c6bc45 100644 --- a/doc/user/pbr.rst +++ b/doc/user/pbr.rst @@ -39,7 +39,7 @@ listing of ECMP nexthops used to forward packets for when a pbr-map is matched. sub-mode where you can specify individual nexthops. To exit this mode type exit or end as per normal conventions for leaving a sub-mode. -.. clicmd:: nexthop [A.B.C.D|X:X::X:XX] [interface] [nexthop-vrf NAME] [label LABELS] +.. clicmd:: nexthop [A.B.C.D|X:X::X:XX] [interface [onlink]] [nexthop-vrf NAME] [label LABELS] Create a v4 or v6 nexthop. All normal rules for creating nexthops that you are used to are allowed here. The syntax was intentionally kept the same as diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 687cac4062..83905abe43 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -41,6 +41,7 @@ struct nexthop_hold { char *nhvrf_name; union sockunion *addr; char *intf; + bool onlink; char *labels; uint32_t weight; char *backup_str; @@ -560,6 +561,10 @@ static int nhgl_cmp(struct nexthop_hold *nh1, struct nexthop_hold *nh2) if (ret) return ret; + ret = ((int)nh2->onlink) - ((int)nh1->onlink); + if (ret) + return ret; + return nhgc_cmp_helper(nh1->labels, nh2->labels); } @@ -673,8 +678,8 @@ DEFPY(no_nexthop_group_backup, no_nexthop_group_backup_cmd, 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, + const char *intf, bool onlink, + const char *labels, const uint32_t weight, const char *backup_str) { struct nexthop_hold *nh; @@ -690,6 +695,8 @@ static void nexthop_group_save_nhop(struct nexthop_group_cmd *nhgc, if (labels) nh->labels = XSTRDUP(MTYPE_TMP, labels); + nh->onlink = onlink; + nh->weight = weight; if (backup_str) @@ -738,9 +745,10 @@ static void nexthop_group_unsave_nhop(struct nexthop_group_cmd *nhgc, */ 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, const char *backup_str) + const char *intf, bool onlink, + const char *name, const char *labels, + int *lbl_ret, uint32_t weight, + const char *backup_str) { int ret = 0; struct vrf *vrf; @@ -764,6 +772,9 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, return false; } + if (onlink) + SET_FLAG(nhop->flags, NEXTHOP_FLAG_ONLINK); + if (addr) { if (addr->sa.sa_family == AF_INET) { nhop->gate.ipv4.s_addr = addr->sin.sin_addr.s_addr; @@ -820,15 +831,15 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, static bool nexthop_group_parse_nhh(struct nexthop *nhop, const struct nexthop_hold *nhh) { - return (nexthop_group_parse_nexthop(nhop, nhh->addr, nhh->intf, - nhh->nhvrf_name, nhh->labels, NULL, - nhh->weight, nhh->backup_str)); + return (nexthop_group_parse_nexthop( + nhop, nhh->addr, nhh->intf, nhh->onlink, nhh->nhvrf_name, + nhh->labels, NULL, nhh->weight, nhh->backup_str)); } DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, "[no] nexthop\ <\ - $addr [INTERFACE$intf]\ + $addr [INTERFACE$intf [onlink$onlink]]\ |INTERFACE$intf\ >\ [{ \ @@ -842,6 +853,7 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, "v4 Address\n" "v6 Address\n" "Interface to use\n" + "Treat nexthop as directly attached to the interface\n" "Interface to use\n" "If the nexthop is in a different vrf tell us\n" "The nexthop-vrf Name\n" @@ -870,8 +882,9 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, } } - legal = nexthop_group_parse_nexthop(&nhop, addr, intf, vrf_name, label, - &lbl_ret, weight, backup_idx); + legal = nexthop_group_parse_nexthop(&nhop, addr, intf, !!onlink, + vrf_name, label, &lbl_ret, weight, + backup_idx); if (nhop.type == NEXTHOP_TYPE_IPV6 && IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6)) { @@ -933,8 +946,8 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, } /* Save config always */ - nexthop_group_save_nhop(nhgc, vrf_name, addr, intf, label, - weight, backup_idx); + nexthop_group_save_nhop(nhgc, vrf_name, addr, intf, !!onlink, + label, weight, backup_idx); if (legal && nhg_hooks.add_nexthop) nhg_hooks.add_nexthop(nhgc, nh); @@ -1106,6 +1119,9 @@ static void nexthop_group_write_nexthop_internal(struct vty *vty, if (nh->intf) vty_out(vty, " %s", nh->intf); + if (nh->onlink) + vty_out(vty, " onlink"); + if (nh->nhvrf_name) vty_out(vty, " nexthop-vrf %s", nh->nhvrf_name);