lib,sharpd,pbrd: set installable nhg command

Add a command `set installable` that allows configured nexthop
groups to be treated as separate/installable objects in the RIB.

A callback needs to be implemented per daemon to handle installing
the NHG into the rib via zapi when this command is set. This
patch includes the implementation for sharpd.

Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com>
This commit is contained in:
Stephen Worley 2020-05-27 17:39:41 -04:00
parent 9c6c48bc10
commit 0de1db8f3b
5 changed files with 102 additions and 15 deletions

View File

@ -45,6 +45,17 @@ listing of ECMP nexthops used to forward packets for when a pbr-map is matched.
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
creating nexthops as you would for static routes. creating nexthops as you would for static routes.
.. clicmd:: set installable
Sets the nexthop group to be installable i.e. treated as a separate object in
the protocol client and zebra's RIB. The proto will send down the object
separately from the route to install into into the RIB and dataplane.
.. note::
``set installable`` is only supported for groups with onlink, interface, and
gateway/interface nexthop types at the moment. Recursive nexthops
(gateway only) are considered undefined behavior.
.. clicmd:: [no] pbr table range (10000-4294966272) (10000-4294966272) .. clicmd:: [no] pbr table range (10000-4294966272) (10000-4294966272)
Set or unset the range used to assign numeric table ID's to new Set or unset the range used to assign numeric table ID's to new

View File

@ -54,6 +54,7 @@ struct nexthop_group_hooks {
void (*del_nexthop)(const struct nexthop_group_cmd *nhg, void (*del_nexthop)(const struct nexthop_group_cmd *nhg,
const struct nexthop *nhop); const struct nexthop *nhop);
void (*delete)(const char *name); void (*delete)(const char *name);
void (*installable)(const struct nexthop_group_cmd *nhg);
}; };
static struct nexthop_group_hooks nhg_hooks; static struct nexthop_group_hooks nhg_hooks;
@ -675,6 +676,37 @@ DEFPY(no_nexthop_group_backup, no_nexthop_group_backup_cmd,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
DEFPY(set_installable, set_installable_cmd,
"set installable",
"Set for nexthop-group\n"
"Install nexthop-group into RIB as separate object\n")
{
VTY_DECLVAR_CONTEXT(nexthop_group_cmd, nhgc);
nhgc->installable = true;
if (nhg_hooks.installable)
nhg_hooks.installable(nhgc);
return CMD_SUCCESS;
}
DEFPY(no_set_installable, no_set_installable_cmd,
"no set installable",
NO_STR
"Set for nexthop-group\n"
"Install nexthop-group into RIB as separate object\n")
{
VTY_DECLVAR_CONTEXT(nexthop_group_cmd, nhgc);
nhgc->installable = false;
if (nhg_hooks.installable)
nhg_hooks.installable(nhgc);
return CMD_SUCCESS;
}
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,
@ -1147,6 +1179,9 @@ static int nexthop_group_write(struct vty *vty)
vty_out(vty, "nexthop-group %s\n", nhgc->name); vty_out(vty, "nexthop-group %s\n", nhgc->name);
if (nhgc->installable)
vty_out(vty, " set installable\n");
if (nhgc->backup_list_name[0]) if (nhgc->backup_list_name[0])
vty_out(vty, " backup-group %s\n", vty_out(vty, " backup-group %s\n",
nhgc->backup_list_name); nhgc->backup_list_name);
@ -1316,12 +1351,14 @@ static const struct cmd_variable_handler nhg_name_handlers[] = {
{.tokenname = "NHGNAME", .completions = nhg_name_autocomplete}, {.tokenname = "NHGNAME", .completions = nhg_name_autocomplete},
{.completions = NULL}}; {.completions = NULL}};
void nexthop_group_init(void (*new)(const char *name), void nexthop_group_init(
void (*add_nexthop)(const struct nexthop_group_cmd *nhg, void (*new)(const char *name),
const struct nexthop *nhop), void (*add_nexthop)(const struct nexthop_group_cmd *nhg,
void (*del_nexthop)(const struct nexthop_group_cmd *nhg, const struct nexthop *nhop),
const struct nexthop *nhop), void (*del_nexthop)(const struct nexthop_group_cmd *nhg,
void (*delete)(const char *name)) const struct nexthop *nhop),
void (*delete)(const char *name),
void (*installable)(const struct nexthop_group_cmd *nhg))
{ {
RB_INIT(nhgc_entry_head, &nhgc_entries); RB_INIT(nhgc_entry_head, &nhgc_entries);
@ -1334,6 +1371,8 @@ void nexthop_group_init(void (*new)(const char *name),
install_default(NH_GROUP_NODE); install_default(NH_GROUP_NODE);
install_element(NH_GROUP_NODE, &nexthop_group_backup_cmd); install_element(NH_GROUP_NODE, &nexthop_group_backup_cmd);
install_element(NH_GROUP_NODE, &no_nexthop_group_backup_cmd); install_element(NH_GROUP_NODE, &no_nexthop_group_backup_cmd);
install_element(NH_GROUP_NODE, &set_installable_cmd);
install_element(NH_GROUP_NODE, &no_set_installable_cmd);
install_element(NH_GROUP_NODE, &ecmp_nexthops_cmd); install_element(NH_GROUP_NODE, &ecmp_nexthops_cmd);
memset(&nhg_hooks, 0, sizeof(nhg_hooks)); memset(&nhg_hooks, 0, sizeof(nhg_hooks));
@ -1346,4 +1385,6 @@ void nexthop_group_init(void (*new)(const char *name),
nhg_hooks.del_nexthop = del_nexthop; nhg_hooks.del_nexthop = del_nexthop;
if (delete) if (delete)
nhg_hooks.delete = delete; nhg_hooks.delete = delete;
if (installable)
nhg_hooks.installable = installable;
} }

View File

@ -97,6 +97,9 @@ struct nexthop_group_cmd {
struct list *nhg_list; struct list *nhg_list;
/* Install nhg as separate object in RIB */
bool installable;
QOBJ_FIELDS QOBJ_FIELDS
}; };
RB_HEAD(nhgc_entry_head, nexthp_group_cmd); RB_HEAD(nhgc_entry_head, nexthp_group_cmd);
@ -116,7 +119,8 @@ void nexthop_group_init(
const struct nexthop *nhop), const struct nexthop *nhop),
void (*del_nexthop)(const struct nexthop_group_cmd *nhgc, void (*del_nexthop)(const struct nexthop_group_cmd *nhgc,
const struct nexthop *nhop), const struct nexthop *nhop),
void (*destroy)(const char *name)); void (*destroy)(const char *name),
void (*installable)(const struct nexthop_group_cmd *nhg));
void nexthop_group_enable_vrf(struct vrf *vrf); void nexthop_group_enable_vrf(struct vrf *vrf);
void nexthop_group_disable_vrf(struct vrf *vrf); void nexthop_group_disable_vrf(struct vrf *vrf);

View File

@ -157,10 +157,9 @@ int main(int argc, char **argv, char **envp)
pbr_debug_init(); pbr_debug_init();
nexthop_group_init(pbr_nhgroup_add_cb, nexthop_group_init(pbr_nhgroup_add_cb, pbr_nhgroup_add_nexthop_cb,
pbr_nhgroup_add_nexthop_cb, pbr_nhgroup_del_nexthop_cb, pbr_nhgroup_delete_cb,
pbr_nhgroup_del_nexthop_cb, NULL);
pbr_nhgroup_delete_cb);
/* /*
* So we safely ignore these commands since * So we safely ignore these commands since

View File

@ -78,6 +78,8 @@ struct sharp_nhg {
uint32_t id; uint32_t id;
char name[256]; char name[256];
bool installable;
}; };
static uint32_t nhg_id; static uint32_t nhg_id;
@ -120,7 +122,9 @@ static void sharp_nhgroup_add_nexthop_cb(const struct nexthop_group_cmd *nhgc,
strncpy(lookup.name, nhgc->name, sizeof(lookup.name)); strncpy(lookup.name, nhgc->name, sizeof(lookup.name));
snhg = sharp_nhg_rb_find(&nhg_head, &lookup); snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
nhg_add(snhg->id, &nhgc->nhg); if (snhg->installable)
nhg_add(snhg->id, &nhgc->nhg);
return; return;
} }
@ -133,7 +137,9 @@ static void sharp_nhgroup_del_nexthop_cb(const struct nexthop_group_cmd *nhgc,
strncpy(lookup.name, nhgc->name, sizeof(lookup.name)); strncpy(lookup.name, nhgc->name, sizeof(lookup.name));
snhg = sharp_nhg_rb_find(&nhg_head, &lookup); snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
nhg_add(snhg->id, &nhgc->nhg); if (snhg->installable)
nhg_add(snhg->id, &nhgc->nhg);
return; return;
} }
@ -147,12 +153,34 @@ static void sharp_nhgroup_delete_cb(const char *name)
if (!snhg) if (!snhg)
return; return;
nhg_del(snhg->id); if (snhg->installable)
nhg_del(snhg->id);
sharp_nhg_rb_del(&nhg_head, snhg); sharp_nhg_rb_del(&nhg_head, snhg);
XFREE(MTYPE_NHG, snhg); XFREE(MTYPE_NHG, snhg);
return; return;
} }
static void sharp_nhgroup_installable_cb(const struct nexthop_group_cmd *nhgc)
{
struct sharp_nhg lookup;
struct sharp_nhg *snhg;
strncpy(lookup.name, nhgc->name, sizeof(lookup.name));
snhg = sharp_nhg_rb_find(&nhg_head, &lookup);
if (!snhg)
return;
snhg->installable = nhgc->installable;
if (snhg->installable)
nhg_add(snhg->id, &nhgc->nhg);
else
nhg_del(snhg->id);
return;
}
uint32_t sharp_nhgroup_get_id(const char *name) uint32_t sharp_nhgroup_get_id(const char *name)
{ {
struct sharp_nhg lookup; struct sharp_nhg lookup;
@ -163,6 +191,9 @@ uint32_t sharp_nhgroup_get_id(const char *name)
if (!snhg) if (!snhg)
return 0; return 0;
if (!snhg->installable)
return 0;
return snhg->id; return snhg->id;
} }
@ -173,5 +204,6 @@ void sharp_nhgroup_init(void)
nexthop_group_init(sharp_nhgroup_add_cb, sharp_nhgroup_add_nexthop_cb, nexthop_group_init(sharp_nhgroup_add_cb, sharp_nhgroup_add_nexthop_cb,
sharp_nhgroup_del_nexthop_cb, sharp_nhgroup_del_nexthop_cb,
sharp_nhgroup_delete_cb); sharp_nhgroup_delete_cb,
sharp_nhgroup_installable_cb);
} }