From 0de1db8f3bd8d25be9dbebc3a090f85d60b41b14 Mon Sep 17 00:00:00 2001 From: Stephen Worley Date: Wed, 27 May 2020 17:39:41 -0400 Subject: [PATCH] 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 --- doc/user/pbr.rst | 11 ++++++++++ lib/nexthop_group.c | 53 ++++++++++++++++++++++++++++++++++++++++----- lib/nexthop_group.h | 6 ++++- pbrd/pbr_main.c | 7 +++--- sharpd/sharp_nht.c | 40 ++++++++++++++++++++++++++++++---- 5 files changed, 102 insertions(+), 15 deletions(-) diff --git a/doc/user/pbr.rst b/doc/user/pbr.rst index c869c6bc45..a57a176f3c 100644 --- a/doc/user/pbr.rst +++ b/doc/user/pbr.rst @@ -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 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) Set or unset the range used to assign numeric table ID's to new diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 83905abe43..136970cff4 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -54,6 +54,7 @@ struct nexthop_group_hooks { void (*del_nexthop)(const struct nexthop_group_cmd *nhg, const struct nexthop *nhop); void (*delete)(const char *name); + void (*installable)(const struct nexthop_group_cmd *nhg); }; static struct nexthop_group_hooks nhg_hooks; @@ -675,6 +676,37 @@ DEFPY(no_nexthop_group_backup, no_nexthop_group_backup_cmd, 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, const char *nhvrf_name, 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); + if (nhgc->installable) + vty_out(vty, " set installable\n"); + if (nhgc->backup_list_name[0]) vty_out(vty, " backup-group %s\n", nhgc->backup_list_name); @@ -1316,12 +1351,14 @@ static const struct cmd_variable_handler nhg_name_handlers[] = { {.tokenname = "NHGNAME", .completions = nhg_name_autocomplete}, {.completions = NULL}}; -void nexthop_group_init(void (*new)(const char *name), - void (*add_nexthop)(const struct nexthop_group_cmd *nhg, - const struct nexthop *nhop), - void (*del_nexthop)(const struct nexthop_group_cmd *nhg, - const struct nexthop *nhop), - void (*delete)(const char *name)) +void nexthop_group_init( + void (*new)(const char *name), + void (*add_nexthop)(const struct nexthop_group_cmd *nhg, + const struct nexthop *nhop), + void (*del_nexthop)(const struct nexthop_group_cmd *nhg, + const struct nexthop *nhop), + void (*delete)(const char *name), + void (*installable)(const struct nexthop_group_cmd *nhg)) { 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_element(NH_GROUP_NODE, &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); 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; if (delete) nhg_hooks.delete = delete; + if (installable) + nhg_hooks.installable = installable; } diff --git a/lib/nexthop_group.h b/lib/nexthop_group.h index 5f7bde0def..e06035ce68 100644 --- a/lib/nexthop_group.h +++ b/lib/nexthop_group.h @@ -97,6 +97,9 @@ struct nexthop_group_cmd { struct list *nhg_list; + /* Install nhg as separate object in RIB */ + bool installable; + QOBJ_FIELDS }; RB_HEAD(nhgc_entry_head, nexthp_group_cmd); @@ -116,7 +119,8 @@ void nexthop_group_init( const struct nexthop *nhop), void (*del_nexthop)(const struct nexthop_group_cmd *nhgc, 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_disable_vrf(struct vrf *vrf); diff --git a/pbrd/pbr_main.c b/pbrd/pbr_main.c index 9a9edd79c6..bae8be4f95 100644 --- a/pbrd/pbr_main.c +++ b/pbrd/pbr_main.c @@ -157,10 +157,9 @@ int main(int argc, char **argv, char **envp) pbr_debug_init(); - nexthop_group_init(pbr_nhgroup_add_cb, - pbr_nhgroup_add_nexthop_cb, - pbr_nhgroup_del_nexthop_cb, - pbr_nhgroup_delete_cb); + nexthop_group_init(pbr_nhgroup_add_cb, pbr_nhgroup_add_nexthop_cb, + pbr_nhgroup_del_nexthop_cb, pbr_nhgroup_delete_cb, + NULL); /* * So we safely ignore these commands since diff --git a/sharpd/sharp_nht.c b/sharpd/sharp_nht.c index 731d58e560..e76b1016a8 100644 --- a/sharpd/sharp_nht.c +++ b/sharpd/sharp_nht.c @@ -78,6 +78,8 @@ struct sharp_nhg { uint32_t id; char name[256]; + + bool installable; }; 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)); snhg = sharp_nhg_rb_find(&nhg_head, &lookup); - nhg_add(snhg->id, &nhgc->nhg); + if (snhg->installable) + nhg_add(snhg->id, &nhgc->nhg); + 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)); snhg = sharp_nhg_rb_find(&nhg_head, &lookup); - nhg_add(snhg->id, &nhgc->nhg); + if (snhg->installable) + nhg_add(snhg->id, &nhgc->nhg); + return; } @@ -147,12 +153,34 @@ static void sharp_nhgroup_delete_cb(const char *name) if (!snhg) return; - nhg_del(snhg->id); + if (snhg->installable) + nhg_del(snhg->id); + sharp_nhg_rb_del(&nhg_head, snhg); XFREE(MTYPE_NHG, snhg); 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) { struct sharp_nhg lookup; @@ -163,6 +191,9 @@ uint32_t sharp_nhgroup_get_id(const char *name) if (!snhg) return 0; + if (!snhg->installable) + return 0; + return snhg->id; } @@ -173,5 +204,6 @@ void sharp_nhgroup_init(void) nexthop_group_init(sharp_nhgroup_add_cb, sharp_nhgroup_add_nexthop_cb, sharp_nhgroup_del_nexthop_cb, - sharp_nhgroup_delete_cb); + sharp_nhgroup_delete_cb, + sharp_nhgroup_installable_cb); } -- 2.39.5