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
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;
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,
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);
{.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);
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));
nhg_hooks.del_nexthop = del_nexthop;
if (delete)
nhg_hooks.delete = delete;
+ if (installable)
+ nhg_hooks.installable = installable;
}
uint32_t id;
char name[256];
+
+ bool installable;
};
static uint32_t nhg_id;
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;
}
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;
}
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;
if (!snhg)
return 0;
+ if (!snhg->installable)
+ return 0;
+
return snhg->id;
}
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);
}