Skip to content

Commit

Permalink
staticd: fix NB dependency hack
Browse files Browse the repository at this point in the history
Currently, staticd configuration is tightly coupled with VRF existence.
Because of that, it has to use a hack in NB infrastructure to create a
VRF configuration when at least one static route is configured for this
VRF. This hack is incompatible with mgmtd, because mgmtd doesn't execute
configuration callbacks. Because of that, the configuration may become
out of sync between mgmtd and staticd. There are two main cases:

1. Create static route in a VRF. The VRF data node will be created
   automatically in staticd by the NB hack, but not in mgmtd.
2. Delete VRF which has some static routes configured. The static route
   configuration will be deleted from staticd by the NB hack, but not
   from mgmtd.

To fix the problem, decouple configuration of static routes from VRF
configuration. Now it is possible to configure static routes even if the
VRF doesn't exist yet. Once the VRF is created, staticd applies all the
preconfigured routes.

This change also fixes the problem with static routes being preserved in
the system when staticd "control-plane-protocol" container is deleted
but the VRF is still configured.

Signed-off-by: Igor Ryzhov <[email protected]>
  • Loading branch information
idryzhov committed Feb 1, 2024
1 parent 5dfa36b commit a0086c7
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 166 deletions.
2 changes: 2 additions & 0 deletions lib/routing_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ int routing_control_plane_protocols_control_plane_protocol_destroy(
* based on the control plane protocol
*/
DECLARE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args));
DECLARE_HOOK(routing_create, (struct nb_cb_create_args *args), (args));
DECLARE_KOOH(routing_destroy, (struct nb_cb_destroy_args *args), (args));

void routing_control_plane_protocols_register_vrf_dependency(void);

Expand Down
5 changes: 5 additions & 0 deletions lib/routing_nb_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@


DEFINE_HOOK(routing_conf_event, (struct nb_cb_create_args *args), (args));
DEFINE_HOOK(routing_create, (struct nb_cb_create_args *args), (args));
DEFINE_KOOH(routing_destroy, (struct nb_cb_destroy_args *args), (args));

/*
* XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol
Expand Down Expand Up @@ -49,6 +51,7 @@ int routing_control_plane_protocols_control_plane_protocol_create(
assert(vrf);
nb_running_set_entry(args->dnode, vrf);
}
hook_call(routing_create, args);
break;
};

Expand All @@ -61,6 +64,8 @@ int routing_control_plane_protocols_control_plane_protocol_destroy(
if (args->event != NB_EV_APPLY)
return NB_OK;

hook_call(routing_destroy, args);

/*
* If dependency on VRF module is registered, then VRF
* pointer was stored and must be cleared.
Expand Down
16 changes: 7 additions & 9 deletions staticd/static_bfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -263,14 +263,13 @@ static void static_bfd_show_path_json(struct vty *vty, struct json_object *jo,
static void static_bfd_show_json(struct vty *vty)
{
struct json_object *jo, *jo_path, *jo_afi_safi;
struct vrf *vrf;
struct static_vrf *svrf;

jo = json_object_new_object();
jo_path = json_object_new_object();

json_object_object_add(jo, "path-list", jo_path);
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
const struct static_vrf *svrf = vrf->info;
RB_FOREACH (svrf, svrf_name_head, &svrfs) {
struct route_table *rt;

jo_afi_safi = json_object_new_array();
Expand Down Expand Up @@ -346,7 +345,7 @@ static void static_bfd_show_path(struct vty *vty, struct route_table *rt)

void static_bfd_show(struct vty *vty, bool json)
{
struct vrf *vrf;
struct static_vrf *svrf;

if (json) {
static_bfd_show_json(vty);
Expand All @@ -355,21 +354,20 @@ void static_bfd_show(struct vty *vty, bool json)

vty_out(vty, "Showing BFD monitored static routes:\n");
vty_out(vty, "\n Next hops:\n");
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
const struct static_vrf *svrf = vrf->info;
RB_FOREACH (svrf, svrf_name_head, &svrfs) {
struct route_table *rt;

vty_out(vty, " VRF %s IPv4 Unicast:\n", vrf->name);
vty_out(vty, " VRF %s IPv4 Unicast:\n", svrf->name);
rt = svrf->stable[AFI_IP][SAFI_UNICAST];
if (rt)
static_bfd_show_path(vty, rt);

vty_out(vty, "\n VRF %s IPv4 Multicast:\n", vrf->name);
vty_out(vty, "\n VRF %s IPv4 Multicast:\n", svrf->name);
rt = svrf->stable[AFI_IP][SAFI_MULTICAST];
if (rt)
static_bfd_show_path(vty, rt);

vty_out(vty, "\n VRF %s IPv6 Unicast:\n", vrf->name);
vty_out(vty, "\n VRF %s IPv6 Unicast:\n", svrf->name);
rt = svrf->stable[AFI_IP6][SAFI_UNICAST];
if (rt)
static_bfd_show_path(vty, rt);
Expand Down
4 changes: 2 additions & 2 deletions staticd/static_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -168,8 +168,8 @@ int main(int argc, char **argv, char **envp)

hook_register(routing_conf_event,
routing_control_plane_protocols_name_validate);

routing_control_plane_protocols_register_vrf_dependency();
hook_register(routing_create, routing_control_plane_protocols_staticd_create);
hook_register(routing_destroy, routing_control_plane_protocols_staticd_destroy);

/*
* We set FRR_NO_SPLIT_CONFIG flag to avoid reading our config, but we
Expand Down
3 changes: 3 additions & 0 deletions staticd/static_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ extern "C" {
extern const struct frr_yang_module_info frr_staticd_info;
extern const struct frr_yang_module_info frr_staticd_cli_info;

int routing_control_plane_protocols_staticd_create(struct nb_cb_create_args *args);
int routing_control_plane_protocols_staticd_destroy(struct nb_cb_destroy_args *args);

/* Mandatory callbacks. */
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
struct nb_cb_create_args *args);
Expand Down
51 changes: 45 additions & 6 deletions staticd/static_nb_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,15 +540,55 @@ int routing_control_plane_protocols_name_validate(
}
return NB_OK;
}

/*
* XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol
*/
int routing_control_plane_protocols_staticd_create(struct nb_cb_create_args *args)
{
struct static_vrf *svrf;
const char *vrf;

vrf = yang_dnode_get_string(args->dnode, "vrf");
svrf = static_vrf_alloc(vrf);
nb_running_set_entry(args->dnode, svrf);

return NB_OK;
}

int routing_control_plane_protocols_staticd_destroy(struct nb_cb_destroy_args *args)
{
struct static_vrf *svrf;
struct route_table *stable;
struct route_node *rn;
afi_t afi;
safi_t safi;

svrf = nb_running_unset_entry(args->dnode);

FOREACH_AFI_SAFI (afi, safi) {
stable = svrf->stable[afi][safi];
if (!stable)
continue;

for (rn = route_top(stable); rn; rn = route_next(rn))
static_del_route(rn);
}

static_vrf_free(svrf);

return NB_OK;
}

/*
* XPath:
* /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list
*/
int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create(
struct nb_cb_create_args *args)
{
struct vrf *vrf;
struct static_vrf *s_vrf;
struct static_vrf *svrf;
struct route_node *rn;
const struct lyd_node *vrf_dnode;
struct prefix prefix;
Expand Down Expand Up @@ -577,15 +617,14 @@ int routing_control_plane_protocols_control_plane_protocol_staticd_route_list_cr
case NB_EV_APPLY:
vrf_dnode = yang_dnode_get_parent(args->dnode,
"control-plane-protocol");
vrf = nb_running_get_entry(vrf_dnode, NULL, true);
s_vrf = vrf->info;
svrf = nb_running_get_entry(vrf_dnode, NULL, true);

yang_dnode_get_prefix(&prefix, args->dnode, "prefix");
afi_safi = yang_dnode_get_string(args->dnode, "afi-safi");
yang_afi_safi_identity2value(afi_safi, &afi, &safi);

rn = static_add_route(afi, safi, &prefix, NULL, s_vrf);
if (vrf->vrf_id == VRF_UNKNOWN)
rn = static_add_route(afi, safi, &prefix, NULL, svrf);
if (!svrf->vrf || svrf->vrf->vrf_id == VRF_UNKNOWN)
snprintf(
args->errmsg, args->errmsg_len,
"Static Route to %s not installed currently because dependent config not fully available",
Expand Down
Loading

0 comments on commit a0086c7

Please sign in to comment.