lib,doc: add onlink flag to nexthop group config

Add an `onlink` flag to nexthop group configuration.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
This commit is contained in:
Stephen Worley 2020-05-18 14:38:19 -04:00
parent e90284d77f
commit 54c6fa8e0a
2 changed files with 30 additions and 14 deletions

View File

@ -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 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. 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 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 are used to are allowed here. The syntax was intentionally kept the same as

View File

@ -41,6 +41,7 @@ struct nexthop_hold {
char *nhvrf_name; char *nhvrf_name;
union sockunion *addr; union sockunion *addr;
char *intf; char *intf;
bool onlink;
char *labels; char *labels;
uint32_t weight; uint32_t weight;
char *backup_str; char *backup_str;
@ -560,6 +561,10 @@ static int nhgl_cmp(struct nexthop_hold *nh1, struct nexthop_hold *nh2)
if (ret) if (ret)
return ret; return ret;
ret = ((int)nh2->onlink) - ((int)nh1->onlink);
if (ret)
return ret;
return nhgc_cmp_helper(nh1->labels, nh2->labels); 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, static void nexthop_group_save_nhop(struct nexthop_group_cmd *nhgc,
const char *nhvrf_name, const char *nhvrf_name,
const union sockunion *addr, const union sockunion *addr,
const char *intf, const char *labels, const char *intf, bool onlink,
const uint32_t weight, const char *labels, const uint32_t weight,
const char *backup_str) const char *backup_str)
{ {
struct nexthop_hold *nh; struct nexthop_hold *nh;
@ -690,6 +695,8 @@ static void nexthop_group_save_nhop(struct nexthop_group_cmd *nhgc,
if (labels) if (labels)
nh->labels = XSTRDUP(MTYPE_TMP, labels); nh->labels = XSTRDUP(MTYPE_TMP, labels);
nh->onlink = onlink;
nh->weight = weight; nh->weight = weight;
if (backup_str) 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, static bool nexthop_group_parse_nexthop(struct nexthop *nhop,
const union sockunion *addr, const union sockunion *addr,
const char *intf, const char *name, const char *intf, bool onlink,
const char *labels, int *lbl_ret, const char *name, const char *labels,
uint32_t weight, const char *backup_str) int *lbl_ret, uint32_t weight,
const char *backup_str)
{ {
int ret = 0; int ret = 0;
struct vrf *vrf; struct vrf *vrf;
@ -764,6 +772,9 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop,
return false; return false;
} }
if (onlink)
SET_FLAG(nhop->flags, NEXTHOP_FLAG_ONLINK);
if (addr) { if (addr) {
if (addr->sa.sa_family == AF_INET) { if (addr->sa.sa_family == AF_INET) {
nhop->gate.ipv4.s_addr = addr->sin.sin_addr.s_addr; 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, static bool nexthop_group_parse_nhh(struct nexthop *nhop,
const struct nexthop_hold *nhh) const struct nexthop_hold *nhh)
{ {
return (nexthop_group_parse_nexthop(nhop, nhh->addr, nhh->intf, return (nexthop_group_parse_nexthop(
nhh->nhvrf_name, nhh->labels, NULL, nhop, nhh->addr, nhh->intf, nhh->onlink, nhh->nhvrf_name,
nhh->weight, nhh->backup_str)); nhh->labels, NULL, nhh->weight, nhh->backup_str));
} }
DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, DEFPY(ecmp_nexthops, ecmp_nexthops_cmd,
"[no] nexthop\ "[no] nexthop\
<\ <\
<A.B.C.D|X:X::X:X>$addr [INTERFACE$intf]\ <A.B.C.D|X:X::X:X>$addr [INTERFACE$intf [onlink$onlink]]\
|INTERFACE$intf\ |INTERFACE$intf\
>\ >\
[{ \ [{ \
@ -842,6 +853,7 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd,
"v4 Address\n" "v4 Address\n"
"v6 Address\n" "v6 Address\n"
"Interface to use\n" "Interface to use\n"
"Treat nexthop as directly attached to the interface\n"
"Interface to use\n" "Interface to use\n"
"If the nexthop is in a different vrf tell us\n" "If the nexthop is in a different vrf tell us\n"
"The nexthop-vrf Name\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, legal = nexthop_group_parse_nexthop(&nhop, addr, intf, !!onlink,
&lbl_ret, weight, backup_idx); vrf_name, label, &lbl_ret, weight,
backup_idx);
if (nhop.type == NEXTHOP_TYPE_IPV6 if (nhop.type == NEXTHOP_TYPE_IPV6
&& IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6)) { && IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6)) {
@ -933,8 +946,8 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd,
} }
/* Save config always */ /* Save config always */
nexthop_group_save_nhop(nhgc, vrf_name, addr, intf, label, nexthop_group_save_nhop(nhgc, vrf_name, addr, intf, !!onlink,
weight, backup_idx); label, weight, backup_idx);
if (legal && nhg_hooks.add_nexthop) if (legal && nhg_hooks.add_nexthop)
nhg_hooks.add_nexthop(nhgc, nh); nhg_hooks.add_nexthop(nhgc, nh);
@ -1106,6 +1119,9 @@ static void nexthop_group_write_nexthop_internal(struct vty *vty,
if (nh->intf) if (nh->intf)
vty_out(vty, " %s", nh->intf); vty_out(vty, " %s", nh->intf);
if (nh->onlink)
vty_out(vty, " onlink");
if (nh->nhvrf_name) if (nh->nhvrf_name)
vty_out(vty, " nexthop-vrf %s", nh->nhvrf_name); vty_out(vty, " nexthop-vrf %s", nh->nhvrf_name);