Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib,zebra,sharpd: allow recursive resolution of nexthop-groups #16775

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions lib/nexthop_group.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,30 @@ DEFPY(no_nexthop_group_resilience,
return CMD_SUCCESS;
}

DEFPY(nexthop_group_recursive,
mjstapp marked this conversation as resolved.
Show resolved Hide resolved
nexthop_group_recursive_cmd,
"[no] recursive",
NO_STR
"Allow recursive resolution\n")
{
VTY_DECLVAR_CONTEXT(nexthop_group_cmd, nhgc);
uint32_t flags;

flags = nhgc->flags;

if (no)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to add a topotest like was proposed in e60cd34 ?

UNSET_FLAG(nhgc->flags, NHG_CMD_FLAG_RECURSIVE);
else
SET_FLAG(nhgc->flags, NHG_CMD_FLAG_RECURSIVE);

if (flags != nhgc->flags) {
if (nhg_hooks.modify)
nhg_hooks.modify(nhgc);
}

return CMD_SUCCESS;
}

static void nexthop_group_save_nhop(struct nexthop_group_cmd *nhgc,
const char *nhvrf_name,
const union sockunion *addr,
Expand Down Expand Up @@ -1172,6 +1196,10 @@ static int nexthop_group_write(struct vty *vty)

vty_out(vty, "nexthop-group %s\n", nhgc->name);

/* Flags */
if (CHECK_FLAG(nhgc->flags, NHG_CMD_FLAG_RECURSIVE))
vty_out(vty, " recursive\n");

if (nhgc->nhg.nhgr.buckets)
vty_out(vty,
" resilient buckets %u idle-timer %u unbalanced-timer %u\n",
Expand Down Expand Up @@ -1376,6 +1404,8 @@ void nexthop_group_init(void (*new)(const char *name),
install_element(NH_GROUP_NODE, &nexthop_group_resilience_cmd);
install_element(NH_GROUP_NODE, &no_nexthop_group_resilience_cmd);

install_element(NH_GROUP_NODE, &nexthop_group_recursive_cmd);

memset(&nhg_hooks, 0, sizeof(nhg_hooks));

if (new)
Expand Down
9 changes: 9 additions & 0 deletions lib/nexthop_group.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ struct nexthop_group_cmd {

struct nexthop_group nhg;

uint32_t flags;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very similar to what is proposed 1b743ec

struct list *nhg_list;

QOBJ_FIELDS;
Expand All @@ -100,6 +102,13 @@ RB_PROTOTYPE(nhgc_entry_head, nexthop_group_cmd, nhgc_entry,
nexthop_group_cmd_compare)
DECLARE_QOBJ_TYPE(nexthop_group_cmd);

/*
* Flags values
*/
/* Request/allow recursive resolution for an NHG */
#define NHG_CMD_FLAG_RECURSIVE (1 << 0)


/*
* Initialize nexthop_groups. If you are interested in when
* a nexthop_group is added/deleted/modified, then set the
Expand Down
1 change: 1 addition & 0 deletions lib/zclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,7 @@ static int zapi_nhg_encode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)

stream_putw(s, api_nhg->proto);
stream_putl(s, api_nhg->id);
stream_putl(s, api_nhg->flags);

stream_putw(s, api_nhg->resilience.buckets);
stream_putl(s, api_nhg->resilience.idle_timer);
Expand Down
4 changes: 4 additions & 0 deletions lib/zclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ struct zapi_nexthop {
struct zapi_nhg {
uint16_t proto;
uint32_t id;
uint32_t flags;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uint32 isnot it too much?
wht other fields do you intend to push in there?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

frankly I would rather have the bit field be large instead of having a problem 2-3 years down the line when we accidently go beyond the bitfield

struct nhg_resilience resilience;

Expand All @@ -493,6 +494,9 @@ struct zapi_nhg {
struct zapi_nexthop backup_nexthops[MULTIPATH_NUM];
};

/* Flags for the zapi NHG message. */
#define ZAPI_NHG_FLAG_RECURSIVE 0x01

/*
* Some of these data structures do not map easily to
* a actual data structure size giving different compilers
Expand Down
6 changes: 3 additions & 3 deletions sharpd/sharp_nht.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ static void sharp_nhgroup_modify_cb(const struct nexthop_group_cmd *nhgc)
if (nhgc->backup_list_name[0])
bnhgc = nhgc_find(nhgc->backup_list_name);

nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
nhg_add(snhg->id, nhgc, bnhgc);
}

static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhgc,
Expand All @@ -145,7 +145,7 @@ static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhgc,
if (nhgc->backup_list_name[0])
bnhgc = nhgc_find(nhgc->backup_list_name);

nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
nhg_add(snhg->id, nhgc, bnhgc);
}

static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
Expand All @@ -161,7 +161,7 @@ static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
if (nhgc->backup_list_name[0])
bnhgc = nhgc_find(nhgc->backup_list_name);

nhg_add(snhg->id, &nhgc->nhg, (bnhgc ? &bnhgc->nhg : NULL));
nhg_add(snhg->id, nhgc, bnhgc);
}

static void sharp_nhgroup_delete_cb(const char *name)
Expand Down
24 changes: 18 additions & 6 deletions sharpd/sharp_zebra.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,17 +529,24 @@ void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label)
zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP);
}

void nhg_add(uint32_t id, const struct nexthop_group *nhg,
const struct nexthop_group *backup_nhg)
void nhg_add(uint32_t id, const struct nexthop_group_cmd *nhgc,
const struct nexthop_group_cmd *backup_nhgc)
{
struct zapi_nhg api_nhg = {};
const struct nexthop_group *nhg;
struct zapi_nexthop *api_nh;
struct nexthop *nh;
bool is_valid = true;

api_nhg.id = id;

api_nhg.resilience = nhg->nhgr;
nhg = &(nhgc->nhg);

api_nhg.resilience = nhgc->nhg.nhgr;

/* Ask for recursion if needed */
if (CHECK_FLAG(nhgc->flags, NHG_CMD_FLAG_RECURSIVE))
SET_FLAG(api_nhg.flags, ZAPI_NHG_FLAG_RECURSIVE);

for (ALL_NEXTHOPS_PTR(nhg, nh)) {
if (api_nhg.nexthop_num >= MULTIPATH_NUM) {
Expand All @@ -552,7 +559,8 @@ void nhg_add(uint32_t id, const struct nexthop_group *nhg,
/* Unresolved nexthops will lead to failure - only send
* nexthops that zebra will consider valid.
*/
if (nh->ifindex == 0)
if (!CHECK_FLAG(nhgc->flags, NHG_CMD_FLAG_RECURSIVE) &&
nh->ifindex == 0)
continue;

api_nh = &api_nhg.nexthops[api_nhg.nexthop_num];
Expand All @@ -574,15 +582,19 @@ void nhg_add(uint32_t id, const struct nexthop_group *nhg,
goto done;
}

if (backup_nhg) {
for (ALL_NEXTHOPS_PTR(backup_nhg, nh)) {
if (backup_nhgc) {
nhg = &(backup_nhgc->nhg);

for (ALL_NEXTHOPS_PTR(nhg, nh)) {
if (api_nhg.backup_nexthop_num >= MULTIPATH_NUM) {
zlog_warn(
"%s: number of backup nexthops greater than max multipath size, truncating",
__func__);
break;
}

/* TODO-- */

/* Unresolved nexthop: will be rejected by zebra.
* That causes a problem, since the primary nexthops
* rely on array indexing into the backup nexthops. If
Expand Down
4 changes: 2 additions & 2 deletions sharpd/sharp_zebra.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ int sharp_zclient_create(uint32_t session_id);
int sharp_zclient_delete(uint32_t session_id);

extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label);
extern void nhg_add(uint32_t id, const struct nexthop_group *nhg,
const struct nexthop_group *backup_nhg);
extern void nhg_add(uint32_t id, const struct nexthop_group_cmd *nhgc,
const struct nexthop_group_cmd *backup_nhgc);
extern void nhg_del(uint32_t id);
extern void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id,
bool import, bool watch, bool connected);
Expand Down
11 changes: 6 additions & 5 deletions zebra/zapi_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -1944,6 +1944,7 @@ static int zapi_nhg_decode(struct stream *s, int cmd, struct zapi_nhg *api_nhg)

STREAM_GETW(s, api_nhg->proto);
STREAM_GETL(s, api_nhg->id);
STREAM_GETL(s, api_nhg->flags);

if (cmd == ZEBRA_NHG_DEL)
goto done;
Expand Down Expand Up @@ -2073,6 +2074,9 @@ static void zread_nhg_add(ZAPI_HANDLER_ARGS)
nhe->zapi_instance = client->instance;
nhe->zapi_session = client->session_id;

/* TODO -- may need an AFI, so try to derive one */
nhe->afi = zebra_nhg_get_afi(nhg, AF_INET);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let us separate AFI move from this pull request => #17049

/* Take over the list(s) of nexthops */
nhe->nhg.nexthop = nhg->nexthop;
nhg->nexthop = NULL;
Expand All @@ -2084,11 +2088,8 @@ static void zread_nhg_add(ZAPI_HANDLER_ARGS)
bnhg = NULL;
}

/*
* TODO:
* Assume fully resolved for now and install.
* Resolution is going to need some more work.
*/
if (CHECK_FLAG(api_nhg.flags, ZAPI_NHG_FLAG_RECURSIVE))
SET_FLAG(nhe->flags, NEXTHOP_GROUP_RECURSION_REQ);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you intend to offer this flag for protocol nexthop groups that depend of other protocol nexthop groups (without nexthops) ? Because if it is not the case, the nhe->nhg.nexthop flags can be used to store the ALLOW_RECURSION flag.

If it is the case, do you have a use case in mind to proceed like that ?

/* Enqueue to workqueue for processing */
rib_queue_nhe_add(nhe);
Expand Down
Loading