]> git.puffer.fish Git - mirror/frr.git/commitdiff
staticd: fix NB dependency hack 15279/head
authorIgor Ryzhov <iryzhov@nfware.com>
Thu, 1 Feb 2024 22:57:59 +0000 (00:57 +0200)
committerIgor Ryzhov <iryzhov@nfware.com>
Thu, 1 Feb 2024 22:57:59 +0000 (00:57 +0200)
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 <iryzhov@nfware.com>
12 files changed:
lib/routing_nb.h
lib/routing_nb_config.c
staticd/static_bfd.c
staticd/static_main.c
staticd/static_nb.h
staticd/static_nb_config.c
staticd/static_routes.c
staticd/static_routes.h
staticd/static_vrf.c
staticd/static_vrf.h
staticd/static_zebra.c
tests/lib/test_grpc.cpp

index c185091a4bce114bf471621cf55ccf7c7c04f8bb..cc83d8469d2daec41cc346336f33ba347b0a41c9 100644 (file)
@@ -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);
 
index 2b20e6c14b5c9c3a447c7deeaf4baf96241fc985..d532279a22aac3edda5332b2ff97dae743b1b4b8 100644 (file)
@@ -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
@@ -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;
        };
 
@@ -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.
index b0b256615085a1025c660f7b92538e5c57ba5f46..c35751f3972bc60293963ea4035766b7833aa8da 100644 (file)
@@ -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();
@@ -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);
@@ -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);
index 2fd174194841e057ba37f6876d83edea5f7d8cec..9468a98b833e6c8fa1a8e800df04a81a2484f2d3 100644 (file)
@@ -168,8 +168,10 @@ 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
index f929997a78e7c12c8868daa59c522e56dfd7dc1d..be75d9d38ce3bd83ebd10a82573dac21d6c4f629 100644 (file)
@@ -13,6 +13,11 @@ 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);
index d7605cb34775ffb7a3a66fb90492a86ce9e8e7a7..7de5f0474aad9a03dcfcc421f27948b4f84aabe7 100644 (file)
@@ -540,6 +540,48 @@ 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
@@ -547,8 +589,7 @@ int routing_control_plane_protocols_name_validate(
 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;
@@ -577,15 +618,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",
index 1fbbf7e99d34fa6b40dfbe48970fbbd559389abc..db3fc32fd88e6de3c3392dd94236fa618e8d716f 100644 (file)
@@ -245,21 +245,20 @@ void static_del_path(struct static_path *pn)
        XFREE(MTYPE_STATIC_PATH, pn);
 }
 
-struct static_nexthop *static_add_nexthop(struct static_path *pn,
-                                         enum static_nh_type type,
-                                         struct ipaddr *ipaddr,
-                                         const char *ifname,
-                                         const char *nh_vrf, uint32_t color)
+struct static_nexthop *
+static_add_nexthop(struct static_path *pn, enum static_nh_type type,
+                  struct ipaddr *ipaddr, const char *ifname,
+                  const char *nh_vrfname, uint32_t color)
 {
        struct route_node *rn = pn->rn;
        struct static_nexthop *nh;
-       struct static_vrf *nh_svrf;
+       struct vrf *nh_vrf;
        struct interface *ifp;
        struct static_nexthop *cp;
 
        route_lock_node(rn);
 
-       nh_svrf = static_vrf_lookup_by_name(nh_vrf);
+       nh_vrf = vrf_lookup_by_name(nh_vrfname);
 
        /* Make new static route structure. */
        nh = XCALLOC(MTYPE_STATIC_NEXTHOP, sizeof(struct static_nexthop));
@@ -274,8 +273,8 @@ struct static_nexthop *static_add_nexthop(struct static_path *pn,
        if (nh->type == STATIC_BLACKHOLE)
                nh->bh_type = STATIC_BLACKHOLE_NULL;
 
-       nh->nh_vrf_id = nh_svrf ? nh_svrf->vrf->vrf_id : VRF_UNKNOWN;
-       strlcpy(nh->nh_vrfname, nh_vrf, sizeof(nh->nh_vrfname));
+       nh->nh_vrf_id = nh_vrf ? nh_vrf->vrf_id : VRF_UNKNOWN;
+       strlcpy(nh->nh_vrfname, nh_vrfname, sizeof(nh->nh_vrfname));
 
        if (ifname)
                strlcpy(nh->ifname, ifname, sizeof(nh->ifname));
@@ -437,14 +436,10 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi,
        struct route_node *rn;
        struct static_nexthop *nh;
        struct static_path *pn;
-       struct vrf *vrf;
+       struct static_vrf *svrf;
        struct static_route_info *si;
 
-       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
-               struct static_vrf *svrf;
-
-               svrf = vrf->info;
-
+       RB_FOREACH (svrf, svrf_name_head, &svrfs) {
                stable = static_vrf_static_table(afi, safi, svrf);
                if (!stable)
                        continue;
@@ -476,8 +471,8 @@ static void static_ifindex_update_af(struct interface *ifp, bool up, afi_t afi,
  * afi -> The afi to look at
  * safi -> the safi to look at
  */
-static void static_fixup_vrf(struct static_vrf *svrf,
-                            struct route_table *stable, afi_t afi, safi_t safi)
+static void static_fixup_vrf(struct vrf *vrf, struct route_table *stable,
+                            afi_t afi, safi_t safi)
 {
        struct route_node *rn;
        struct static_nexthop *nh;
@@ -491,13 +486,12 @@ static void static_fixup_vrf(struct static_vrf *svrf,
                        continue;
                frr_each(static_path_list, &si->path_list, pn) {
                        frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
-                               if (strcmp(svrf->vrf->name, nh->nh_vrfname)
-                                   != 0)
+                               if (strcmp(vrf->name, nh->nh_vrfname) != 0)
                                        continue;
 
-                               nh->nh_vrf_id = svrf->vrf->vrf_id;
+                               nh->nh_vrf_id = vrf->vrf_id;
                                nh->nh_registered = false;
-                               if (nh->ifindex) {
+                               if (nh->ifname[0]) {
                                        ifp = if_lookup_by_name(nh->ifname,
                                                                nh->nh_vrf_id);
                                        if (ifp)
@@ -521,9 +515,7 @@ static void static_fixup_vrf(struct static_vrf *svrf,
  * afi -> the afi in question
  * safi -> the safi in question
  */
-static void static_enable_vrf(struct static_vrf *svrf,
-                             struct route_table *stable, afi_t afi,
-                             safi_t safi)
+static void static_enable_vrf(struct route_table *stable, afi_t afi, safi_t safi)
 {
        struct route_node *rn;
        struct static_nexthop *nh;
@@ -537,7 +529,9 @@ static void static_enable_vrf(struct static_vrf *svrf,
                        continue;
                frr_each(static_path_list, &si->path_list, pn) {
                        frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
-                               if (nh->ifindex) {
+                               if (nh->nh_vrf_id == VRF_UNKNOWN)
+                                       continue;
+                               if (nh->ifname[0]) {
                                        ifp = if_lookup_by_name(nh->ifname,
                                                                nh->nh_vrf_id);
                                        if (ifp)
@@ -545,8 +539,7 @@ static void static_enable_vrf(struct static_vrf *svrf,
                                        else
                                                continue;
                                }
-                               if (nh->nh_vrf_id == VRF_UNKNOWN)
-                                       continue;
+
                                static_install_path(pn);
                        }
                }
@@ -560,27 +553,26 @@ static void static_enable_vrf(struct static_vrf *svrf,
  *
  * enable_svrf -> the vrf being enabled
  */
-void static_fixup_vrf_ids(struct static_vrf *enable_svrf)
+void static_fixup_vrf_ids(struct vrf *vrf)
 {
        struct route_table *stable;
-       struct vrf *vrf;
+       struct static_vrf *svrf, *enable_svrf;
        afi_t afi;
        safi_t safi;
 
-       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
-               struct static_vrf *svrf;
+       enable_svrf = vrf->info;
 
-               svrf = vrf->info;
+       RB_FOREACH (svrf, svrf_name_head, &svrfs) {
                /* Install any static routes configured for this VRF. */
                FOREACH_AFI_SAFI (afi, safi) {
                        stable = svrf->stable[afi][safi];
                        if (!stable)
                                continue;
 
-                       static_fixup_vrf(enable_svrf, stable, afi, safi);
+                       static_fixup_vrf(vrf, stable, afi, safi);
 
                        if (enable_svrf == svrf)
-                               static_enable_vrf(svrf, stable, afi, safi);
+                               static_enable_vrf(stable, afi, safi);
                }
        }
 }
@@ -595,8 +587,7 @@ void static_fixup_vrf_ids(struct static_vrf *enable_svrf)
  * afi -> the afi in question
  * safi -> the safi in question
  */
-static void static_cleanup_vrf(struct static_vrf *svrf,
-                              struct route_table *stable,
+static void static_cleanup_vrf(struct vrf *vrf, struct route_table *stable,
                               afi_t afi, safi_t safi)
 {
        struct route_node *rn;
@@ -610,11 +601,13 @@ static void static_cleanup_vrf(struct static_vrf *svrf,
                        continue;
                frr_each(static_path_list, &si->path_list, pn) {
                        frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
-                               if (strcmp(svrf->vrf->name, nh->nh_vrfname)
-                                   != 0)
+                               if (strcmp(vrf->name, nh->nh_vrfname) != 0)
                                        continue;
 
                                static_uninstall_path(pn);
+
+                               nh->nh_vrf_id = VRF_UNKNOWN;
+                               nh->ifindex = IFINDEX_INTERNAL;
                        }
                }
        }
@@ -642,6 +635,9 @@ static void static_disable_vrf(struct route_table *stable,
                        continue;
                frr_each(static_path_list, &si->path_list, pn) {
                        frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
+                               if (nh->nh_vrf_id == VRF_UNKNOWN)
+                                       continue;
+
                                static_uninstall_path(pn);
                        }
                }
@@ -656,26 +652,23 @@ static void static_disable_vrf(struct route_table *stable,
  *
  * disable_svrf - The vrf being disabled
  */
-void static_cleanup_vrf_ids(struct static_vrf *disable_svrf)
+void static_cleanup_vrf_ids(struct vrf *vrf)
 {
-       struct vrf *vrf;
+       struct route_table *stable;
+       struct static_vrf *svrf, *disable_svrf;
        afi_t afi;
        safi_t safi;
 
-       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
-               struct static_vrf *svrf;
-
-               svrf = vrf->info;
+       disable_svrf = vrf->info;
 
+       RB_FOREACH (svrf, svrf_name_head, &svrfs) {
                /* Uninstall any static routes configured for this VRF. */
                FOREACH_AFI_SAFI (afi, safi) {
-                       struct route_table *stable;
-
                        stable = svrf->stable[afi][safi];
                        if (!stable)
                                continue;
 
-                       static_cleanup_vrf(disable_svrf, stable, afi, safi);
+                       static_cleanup_vrf(vrf, stable, afi, safi);
 
                        if (disable_svrf == svrf)
                                static_disable_vrf(stable, afi, safi);
@@ -683,71 +676,6 @@ void static_cleanup_vrf_ids(struct static_vrf *disable_svrf)
        }
 }
 
-/*
- * This function enables static routes when an interface it relies
- * on in a different vrf is coming up.
- *
- * stable -> The stable we are looking at.
- * ifp -> interface coming up
- * afi -> the afi in question
- * safi -> the safi in question
- */
-static void static_fixup_intf_nh(struct route_table *stable,
-                                struct interface *ifp,
-                                afi_t afi, safi_t safi)
-{
-       struct route_node *rn;
-       struct static_nexthop *nh;
-       struct static_path *pn;
-       struct static_route_info *si;
-
-       for (rn = route_top(stable); rn; rn = route_next(rn)) {
-               si = static_route_info_from_rnode(rn);
-               if (!si)
-                       continue;
-               frr_each(static_path_list, &si->path_list, pn) {
-                       frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
-                               if (nh->nh_vrf_id != ifp->vrf->vrf_id)
-                                       continue;
-
-                               if (nh->ifindex != ifp->ifindex)
-                                       continue;
-
-                               static_install_path(pn);
-                       }
-               }
-       }
-}
-
-/*
- * This function enables static routes that rely on an interface in
- * a different vrf when that interface comes up.
- */
-void static_install_intf_nh(struct interface *ifp)
-{
-       struct route_table *stable;
-       struct vrf *vrf;
-       afi_t afi;
-       safi_t safi;
-
-       RB_FOREACH(vrf, vrf_name_head, &vrfs_by_name) {
-               struct static_vrf *svrf = vrf->info;
-
-               /* Not needed if same vrf since happens naturally */
-               if (vrf->vrf_id == ifp->vrf->vrf_id)
-                       continue;
-
-               /* Install any static routes configured for this interface. */
-               FOREACH_AFI_SAFI (afi, safi) {
-                       stable = svrf->stable[afi][safi];
-                       if (!stable)
-                               continue;
-
-                       static_fixup_intf_nh(stable, ifp, afi, safi);
-               }
-       }
-}
-
 /* called from if_{add,delete}_update, i.e. when ifindex becomes [in]valid */
 void static_ifindex_update(struct interface *ifp, bool up)
 {
index 1231ead52675700572ff11e03c8045d8d87c69d0..d88ed293645e9770cb7a1a5acde2a144a5004754 100644 (file)
@@ -199,7 +199,8 @@ extern uint32_t zebra_ecmp_count;
 
 extern struct zebra_privs_t static_privs;
 
-void static_fixup_vrf_ids(struct static_vrf *svrf);
+extern void static_fixup_vrf_ids(struct vrf *vrf);
+extern void static_cleanup_vrf_ids(struct vrf *vrf);
 
 extern struct static_nexthop *
 static_add_nexthop(struct static_path *pn, enum static_nh_type type,
@@ -209,10 +210,6 @@ extern void static_install_nexthop(struct static_nexthop *nh);
 
 extern void static_delete_nexthop(struct static_nexthop *nh);
 
-extern void static_cleanup_vrf_ids(struct static_vrf *disable_svrf);
-
-extern void static_install_intf_nh(struct interface *ifp);
-
 extern void static_ifindex_update(struct interface *ifp, bool up);
 
 extern void static_install_path(struct static_path *pn);
index 7a0ff01d0494dbabb4ce1bac9272b7c488399a6d..710827a9ff49dc8c2e443be9de9d1ab8f888fdc6 100644 (file)
 
 DEFINE_MTYPE_STATIC(STATIC, STATIC_RTABLE_INFO, "Static Route Table Info");
 
-static struct static_vrf *static_vrf_alloc(void)
+static int svrf_name_compare(const struct static_vrf *a,
+                            const struct static_vrf *b)
+{
+       return strcmp(a->name, b->name);
+}
+
+RB_GENERATE(svrf_name_head, static_vrf, entry, svrf_name_compare);
+
+struct svrf_name_head svrfs = RB_INITIALIZER(&svrfs);
+
+static struct static_vrf *static_vrf_lookup_by_name(const char *name)
+{
+       struct static_vrf svrf;
+
+       strlcpy(svrf.name, name, sizeof(svrf.name));
+       return RB_FIND(svrf_name_head, &svrfs, &svrf);
+}
+
+struct static_vrf *static_vrf_alloc(const char *name)
 {
        struct route_table *table;
        struct static_vrf *svrf;
        struct stable_info *info;
+       struct vrf *vrf;
        safi_t safi;
        afi_t afi;
 
        svrf = XCALLOC(MTYPE_STATIC_RTABLE_INFO, sizeof(struct static_vrf));
 
+       strlcpy(svrf->name, name, sizeof(svrf->name));
+
        for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
                for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
                        if (afi == AFI_IP6)
@@ -46,16 +67,56 @@ static struct static_vrf *static_vrf_alloc(void)
                        svrf->stable[afi][safi] = table;
                }
        }
+
+       RB_INSERT(svrf_name_head, &svrfs, svrf);
+
+       vrf = vrf_lookup_by_name(name);
+       if (vrf) {
+               svrf->vrf = vrf;
+               vrf->info = svrf;
+       }
+
        return svrf;
 }
 
+void static_vrf_free(struct static_vrf *svrf)
+{
+       struct route_table *table;
+       struct vrf *vrf;
+       safi_t safi;
+       afi_t afi;
+       void *info;
+
+       vrf = svrf->vrf;
+       if (vrf) {
+               vrf->info = NULL;
+               svrf->vrf = NULL;
+       }
+
+       RB_REMOVE(svrf_name_head, &svrfs, svrf);
+
+       for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
+               for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
+                       table = svrf->stable[afi][safi];
+                       info = route_table_get_info(table);
+                       route_table_finish(table);
+                       XFREE(MTYPE_STATIC_RTABLE_INFO, info);
+                       svrf->stable[afi][safi] = NULL;
+               }
+       }
+
+       XFREE(MTYPE_STATIC_RTABLE_INFO, svrf);
+}
+
 static int static_vrf_new(struct vrf *vrf)
 {
        struct static_vrf *svrf;
 
-       svrf = static_vrf_alloc();
-       vrf->info = svrf;
-       svrf->vrf = vrf;
+       svrf = static_vrf_lookup_by_name(vrf->name);
+       if (svrf) {
+               vrf->info = svrf;
+               svrf->vrf = vrf;
+       }
 
        return 0;
 }
@@ -63,37 +124,27 @@ static int static_vrf_new(struct vrf *vrf)
 static int static_vrf_enable(struct vrf *vrf)
 {
        static_zebra_vrf_register(vrf);
-
-       static_fixup_vrf_ids(vrf->info);
-
+       static_fixup_vrf_ids(vrf);
        return 0;
 }
 
 static int static_vrf_disable(struct vrf *vrf)
 {
+       static_cleanup_vrf_ids(vrf);
        static_zebra_vrf_unregister(vrf);
        return 0;
 }
 
 static int static_vrf_delete(struct vrf *vrf)
 {
-       struct route_table *table;
        struct static_vrf *svrf;
-       safi_t safi;
-       afi_t afi;
-       void *info;
 
        svrf = vrf->info;
-       for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
-               for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) {
-                       table = svrf->stable[afi][safi];
-                       info = route_table_get_info(table);
-                       route_table_finish(table);
-                       XFREE(MTYPE_STATIC_RTABLE_INFO, info);
-                       svrf->stable[afi][safi] = NULL;
-               }
+       if (svrf) {
+               svrf->vrf = NULL;
+               vrf->info = NULL;
        }
-       XFREE(MTYPE_STATIC_RTABLE_INFO, svrf);
+
        return 0;
 }
 
@@ -110,20 +161,6 @@ struct route_table *static_vrf_static_table(afi_t afi, safi_t safi,
        return svrf->stable[afi][safi];
 }
 
-struct static_vrf *static_vrf_lookup_by_name(const char *name)
-{
-       struct vrf *vrf;
-
-       if (!name)
-               name = VRF_DEFAULT_NAME;
-
-       vrf = vrf_lookup_by_name(name);
-       if (vrf)
-               return ((struct static_vrf *)vrf->info);
-
-       return NULL;
-}
-
 void static_vrf_init(void)
 {
        vrf_init(static_vrf_new, static_vrf_enable, static_vrf_disable,
@@ -134,5 +171,10 @@ void static_vrf_init(void)
 
 void static_vrf_terminate(void)
 {
+       struct static_vrf *svrf, *svrf_next;
+
+       RB_FOREACH_SAFE (svrf, svrf_name_head, &svrfs, svrf_next)
+               static_vrf_free(svrf);
+
        vrf_terminate();
 }
index 8f55775d3eec43b72163f0c47ea99161cd28e8f6..26ee28fd816d834748af8278f3c682fc713f40d5 100644 (file)
@@ -7,15 +7,27 @@
 #ifndef __STATIC_VRF_H__
 #define __STATIC_VRF_H__
 
+#include "openbsd-tree.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
 
 struct static_vrf {
+       RB_ENTRY(static_vrf) entry;
+
+       char name[VRF_NAMSIZ + 1];
        struct vrf *vrf;
 
        struct route_table *stable[AFI_MAX][SAFI_MAX];
 };
+RB_HEAD(svrf_name_head, static_vrf);
+RB_PROTOTYPE(svrf_name_head, static_vrf, entry, svrf_name_compare)
+
+extern struct svrf_name_head svrfs;
+
+struct static_vrf *static_vrf_alloc(const char *name);
+void static_vrf_free(struct static_vrf *svrf);
 
 struct stable_info {
        struct static_vrf *svrf;
@@ -25,8 +37,6 @@ struct stable_info {
 
 #define GET_STABLE_VRF_ID(info) info->svrf->vrf->vrf_id
 
-struct static_vrf *static_vrf_lookup_by_name(const char *vrf_name);
-
 void static_vrf_init(void);
 
 struct route_table *static_vrf_static_table(afi_t afi, safi_t safi,
index 68761c0084bd61710a8579b8a11e6aae100fb7d9..697afa51564435630a56e3a9c31d1034335c1cee 100644 (file)
@@ -111,8 +111,6 @@ static int interface_address_delete(ZAPI_CALLBACK_ARGS)
 
 static int static_ifp_up(struct interface *ifp)
 {
-       /* Install any static reliant on this interface coming up */
-       static_install_intf_nh(ifp);
        static_ifindex_update(ifp, true);
 
        return 0;
@@ -169,7 +167,7 @@ static void zebra_connected(struct zclient *zclient)
        zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST, zclient, true);
        zclient_send_reg_requests(zclient, VRF_DEFAULT);
 
-       static_fixup_vrf_ids(vrf_info_lookup(VRF_DEFAULT));
+       static_fixup_vrf_ids(vrf_lookup_by_id(VRF_DEFAULT));
 }
 
 /* API to check whether the configured nexthop address is
@@ -388,6 +386,9 @@ extern void static_zebra_route_add(struct static_path *pn, bool install)
        struct zapi_route api;
        uint32_t nh_num = 0;
 
+       if (!si->svrf->vrf)
+               return;
+
        p = src_pp = NULL;
        srcdest_rnode_prefixes(rn, &p, &src_pp);
 
index 957ffdefaae7c1cd038a69e45d28bc3eafeb2750..202313603d0e9a5f022550346715bad712e40c93 100644 (file)
@@ -119,8 +119,10 @@ static void static_startup(void)
 
        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);
 
        // Add a route
        vty = vty_new();