]> git.puffer.fish Git - matthieu/frr.git/commitdiff
lib, zebra: reuse and adapt ns_list walk functionality
authorPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 20 Dec 2019 16:51:37 +0000 (17:51 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Mon, 21 Sep 2020 07:17:11 +0000 (09:17 +0200)
the walk routine is used by vxlan service to identify some contexts in
each specific network namespace, when vrf netns backend is used. that
walk mechanism is extended with some additional paramters to the walk
routine.

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
lib/netns_linux.c
lib/netns_other.c
lib/ns.h
zebra/main.c
zebra/zebra_evpn.c
zebra/zebra_ns.c
zebra/zebra_ns.h
zebra/zebra_vxlan.c

index 0109b3db6a31d5cab0f2c1f4ae414be0805e151a..e8d549b4e0c9a17c7c1c3574c07c45236ef3cc0f 100644 (file)
@@ -51,7 +51,7 @@ static struct ns *ns_lookup_name_internal(const char *name);
 
 RB_GENERATE(ns_head, ns, entry, ns_compare)
 
-struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
+static struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
 
 static struct ns *default_ns;
 static int ns_current_ns_fd;
@@ -379,12 +379,20 @@ struct ns *ns_lookup(ns_id_t ns_id)
        return ns_lookup_internal(ns_id);
 }
 
-void ns_walk_func(int (*func)(struct ns *))
+void ns_walk_func(int (*func)(struct ns *,
+                             void *param_in,
+                             void **param_out),
+                 void *param_in,
+                 void **param_out)
 {
        struct ns *ns = NULL;
+       int ret;
 
-       RB_FOREACH (ns, ns_head, &ns_tree)
-               func(ns);
+       RB_FOREACH (ns, ns_head, &ns_tree) {
+               ret = func(ns, param_in, param_out);
+               if (ret == NS_WALK_STOP)
+                       return;
+       }
 }
 
 const char *ns_get_name(struct ns *ns)
index b0aae4f8df082dd18652478964a226738e1fa9ff..740d2b621ed7d3e0bb2357efb6304fb23a28d8f7 100644 (file)
@@ -34,7 +34,7 @@ static inline int ns_compare(const struct ns *ns, const struct ns *ns2);
 
 RB_GENERATE(ns_head, ns, entry, ns_compare)
 
-struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
+static struct ns_head ns_tree = RB_INITIALIZER(&ns_tree);
 
 static inline int ns_compare(const struct ns *a, const struct ns *b)
 {
index 0dfd977429a4b1f3b95c77795a2cbb51dec93546..286ff5b29517514beae64ce6595dc6c714892af8 100644 (file)
--- a/lib/ns.h
+++ b/lib/ns.h
@@ -76,8 +76,6 @@ struct ns {
 RB_HEAD(ns_head, ns);
 RB_PROTOTYPE(ns_head, ns, entry, ns_compare)
 
-extern struct ns_head ns_tree;
-
 /*
  * API for managing NETNS. eg from zebra daemon
  * one want to manage the list of NETNS, etc...
@@ -127,7 +125,14 @@ int ns_socket(int domain, int type, int protocol, ns_id_t ns_id);
 extern char *ns_netns_pathname(struct vty *vty, const char *name);
 
 /* Parse and execute a function on all the NETNS */
-extern void ns_walk_func(int (*func)(struct ns *));
+#define NS_WALK_CONTINUE 0
+#define NS_WALK_STOP 1
+
+extern void ns_walk_func(int (*func)(struct ns *,
+                                    void *,
+                                    void **),
+                        void *param_in,
+                        void **param_out);
 
 /* API to get the NETNS name, from the ns pointer */
 extern const char *ns_get_name(struct ns *ns);
index cfc45567d718fba79a6af7d431fa5210286aae93..2afef46bb2163cf5f621b1d7c48a10b555fb1452 100644 (file)
@@ -183,7 +183,7 @@ static void sigint(void)
        vrf_terminate();
        rtadv_terminate();
 
-       ns_walk_func(zebra_ns_early_shutdown);
+       ns_walk_func(zebra_ns_early_shutdown, NULL, NULL);
        zebra_ns_notify_close();
 
        access_list_reset();
@@ -214,7 +214,7 @@ int zebra_finalize(struct thread *dummy)
        zlog_info("Zebra final shutdown");
 
        /* Final shutdown of ns resources */
-       ns_walk_func(zebra_ns_final_shutdown);
+       ns_walk_func(zebra_ns_final_shutdown, NULL, NULL);
 
        /* Stop dplane thread and finish any cleanup */
        zebra_dplane_shutdown();
index 542f36156e3d30e23788887539df03eb6fcf162f..0f5e77ac65effc081ac65ed632f12e633cf59956 100644 (file)
@@ -622,10 +622,11 @@ void zebra_evpn_svi_macip_del_for_evpn_hash(struct hash_bucket *bucket,
        return;
 }
 
-static int zebra_evpn_map_vlan_zns(struct zebra_ns *zns,
-                                  void *_in_param,
-                                  void **_p_zevpn)
+static int zebra_evpn_map_vlan_ns(struct ns *ns,
+                                 void *_in_param,
+                                 void **_p_zevpn)
 {
+       struct zebra_ns *zns = ns->info;
        struct route_node *rn;
        struct interface *br_if;
        zebra_evpn_t **p_zevpn = (zebra_evpn_t **)_p_zevpn;
@@ -638,7 +639,7 @@ static int zebra_evpn_map_vlan_zns(struct zebra_ns *zns,
        int found = 0;
 
        if (!in_param)
-               return ZNS_WALK_STOP;
+               return NS_WALK_STOP;
        br_if = in_param->br_if;
        zif = in_param->zif;
        assert(zif);
@@ -667,12 +668,12 @@ static int zebra_evpn_map_vlan_zns(struct zebra_ns *zns,
                }
        }
        if (!found)
-               return ZNS_WALK_CONTINUE;
+               return NS_WALK_CONTINUE;
 
        zevpn = zebra_evpn_lookup(vxl->vni);
        if (p_zevpn)
                *p_zevpn = zevpn;
-       return ZNS_WALK_STOP;
+       return NS_WALK_STOP;
 }
 
 /*
@@ -698,16 +699,17 @@ zebra_evpn_t *zebra_evpn_map_vlan(struct interface *ifp,
        in_param.zif = zif;
        p_zevpn = &zevpn;
 
-       zebra_ns_list_walk(zebra_evpn_map_vlan_zns,
-                          (void *)&in_param,
-                          (void **)p_zevpn);
+       ns_walk_func(zebra_evpn_map_vlan_ns,
+                    (void *)&in_param,
+                    (void **)p_zevpn);
        return zevpn;
 }
 
-static int zebra_evpn_from_svi_zns(struct zebra_ns *zns,
-                                  void *_in_param,
-                                  void **_p_zevpn)
+static int zebra_evpn_from_svi_ns(struct ns *ns,
+                                 void *_in_param,
+                                 void **_p_zevpn)
 {
+       struct zebra_ns *zns = ns->info;
        struct route_node *rn;
        struct interface *br_if;
        zebra_evpn_t **p_zevpn = (zebra_evpn_t **)_p_zevpn;
@@ -720,7 +722,7 @@ static int zebra_evpn_from_svi_zns(struct zebra_ns *zns,
        int found = 0;
 
        if (!in_param)
-               return ZNS_WALK_STOP;
+               return NS_WALK_STOP;
        br_if = in_param->br_if;
        zif = in_param->zif;
        assert(zif);
@@ -748,12 +750,12 @@ static int zebra_evpn_from_svi_zns(struct zebra_ns *zns,
        }
 
        if (!found)
-               return ZNS_WALK_CONTINUE;
+               return NS_WALK_CONTINUE;
 
        zevpn = zebra_evpn_lookup(vxl->vni);
        if (p_zevpn)
                *p_zevpn = zevpn;
-       return ZNS_WALK_STOP;
+       return NS_WALK_STOP;
 }
 
 /*
@@ -799,8 +801,8 @@ zebra_evpn_t *zebra_evpn_from_svi(struct interface *ifp,
        in_param.zif = zif;
        p_zevpn = &zevpn;
        /* See if this interface (or interface plus VLAN Id) maps to a VxLAN */
-       zebra_ns_list_walk(zebra_evpn_from_svi_zns, (void *)&in_param,
-                          (void **)p_zevpn);
+       ns_walk_func(zebra_evpn_from_svi_ns, (void *)&in_param,
+                    (void **)p_zevpn);
        return zevpn;
 }
 
index 13864cd4296db00e022abd22cf89b909778c45ad..6462daf6874ee7963a10233b6aae385b3c66008d 100644 (file)
@@ -153,20 +153,25 @@ static int zebra_ns_disable_internal(struct zebra_ns *zns, bool complete)
 /* During zebra shutdown, do partial cleanup while the async dataplane
  * is still running.
  */
-int zebra_ns_early_shutdown(struct ns *ns)
+int zebra_ns_early_shutdown(struct ns *ns,
+                           void *param_in __attribute__((unused)),
+                           void **param_out __attribute__((unused)))
 {
        struct zebra_ns *zns = ns->info;
 
        if (zns == NULL)
                return 0;
 
-       return zebra_ns_disable_internal(zns, false);
+       zebra_ns_disable_internal(zns, false);
+       return NS_WALK_CONTINUE;
 }
 
 /* During zebra shutdown, do final cleanup
  * after all dataplane work is complete.
  */
-int zebra_ns_final_shutdown(struct ns *ns)
+int zebra_ns_final_shutdown(struct ns *ns,
+                           void *param_in __attribute__((unused)),
+                           void **param_out __attribute__((unused)))
 {
        struct zebra_ns *zns = ns->info;
 
@@ -175,7 +180,7 @@ int zebra_ns_final_shutdown(struct ns *ns)
 
        kernel_terminate(zns, true);
 
-       return 0;
+       return NS_WALK_CONTINUE;
 }
 
 int zebra_ns_init(const char *optional_default_name)
@@ -233,25 +238,3 @@ int zebra_ns_config_write(struct vty *vty, struct ns *ns)
                vty_out(vty, " netns %s\n", ns->name);
        return 0;
 }
-
-void zebra_ns_list_walk(int (*exec_for_each_zns)(struct zebra_ns *zns,
-                                                void *param_in,
-                                                void **param_out),
-                       void *param_in,
-                       void **param_out)
-{
-       struct ns *ns;
-       struct zebra_ns *zns;
-       int ret;
-
-       RB_FOREACH (ns, ns_head, &ns_tree) {
-               zns = (struct zebra_ns *)ns->info;
-               if (!zns && ns->ns_id == NS_DEFAULT)
-                       zns = zebra_ns_lookup(ns->ns_id);
-               if (!zns)
-                       continue;
-               ret = exec_for_each_zns(zns, param_in, param_out);
-               if (ret == ZNS_WALK_STOP)
-                       return;
-       }
-}
index fa2fd47c25bd793fb60aa3121c6a04b2e96de0a8..f7d1f40782a7e42b97f0932b7cc2a59be7be21b8 100644 (file)
@@ -67,19 +67,14 @@ struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id);
 int zebra_ns_init(const char *optional_default_name);
 int zebra_ns_enable(ns_id_t ns_id, void **info);
 int zebra_ns_disabled(struct ns *ns);
-int zebra_ns_early_shutdown(struct ns *ns);
-int zebra_ns_final_shutdown(struct ns *ns);
-
+int zebra_ns_early_shutdown(struct ns *ns,
+                           void *param_in __attribute__((unused)),
+                           void **param_out __attribute__((unused)));
+int zebra_ns_final_shutdown(struct ns *ns,
+                           void *param_in __attribute__((unused)),
+                           void **param_out __attribute__((unused)));
 int zebra_ns_config_write(struct vty *vty, struct ns *ns);
 
-#define ZNS_WALK_CONTINUE 0
-#define ZNS_WALK_STOP 1
-void zebra_ns_list_walk(int (*exec_for_each_zns)(struct zebra_ns *zns,
-                                                void *param_in,
-                                                void **param_out),
-                       void *param_in,
-                       void **param_out);
-
 #ifdef __cplusplus
 }
 #endif
index 6332854e73d7c48ef4a608099374785bcd452dee..61498973e97149517334d2100ab1239bf08f2e09 100644 (file)
@@ -782,10 +782,11 @@ static void zl3vni_print_hash_detail(struct hash_bucket *bucket, void *data)
                vty_out(vty, "\n");
 }
 
-static int zvni_map_to_svi_ns(struct zebra_ns *zns,
+static int zvni_map_to_svi_ns(struct ns *ns,
                              void *_in_param,
                              void **_p_ifp)
 {
+       struct zebra_ns *zns = ns->info;
        struct route_node *rn;
        struct zebra_from_svi_param *in_param =
                (struct zebra_from_svi_param *)_in_param;
@@ -795,7 +796,7 @@ static int zvni_map_to_svi_ns(struct zebra_ns *zns,
        struct zebra_if *zif;
 
        if (!in_param)
-               return ZNS_WALK_STOP;
+               return NS_WALK_STOP;
 
        /* TODO: Optimize with a hash. */
        for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
@@ -812,10 +813,10 @@ static int zvni_map_to_svi_ns(struct zebra_ns *zns,
                if (vl->vid == in_param->vid) {
                        if (p_ifp)
                                *p_ifp = tmp_if;
-                       return ZNS_WALK_STOP;
+                       return NS_WALK_STOP;
                }
        }
-       return ZNS_WALK_CONTINUE;
+       return NS_WALK_CONTINUE;
 }
 
 /* Map to SVI on bridge corresponding to specified VLAN. This can be one
@@ -850,8 +851,8 @@ struct interface *zvni_map_to_svi(vlanid_t vid, struct interface *br_if)
        in_param.zif = NULL;
        p_ifp = &tmp_if;
        /* Identify corresponding VLAN interface. */
-       zebra_ns_list_walk(zvni_map_to_svi_ns, (void *)&in_param,
-                          (void **)p_ifp);
+       ns_walk_func(zvni_map_to_svi_ns, (void *)&in_param,
+                    (void **)p_ifp);
        return tmp_if;
 }
 
@@ -865,10 +866,11 @@ static int zebra_evpn_vxlan_del(zebra_evpn_t *zevpn)
        return zebra_evpn_del(zevpn);
 }
 
-static int zevpn_build_hash_table_zns(struct zebra_ns *zns,
+static int zevpn_build_hash_table_zns(struct ns *ns,
                                     void *param_in __attribute__((unused)),
                                     void **param_out __attribute__((unused)))
 {
+       struct zebra_ns *zns = ns->info;
        struct route_node *rn;
        struct interface *ifp;
        struct zebra_vrf *zvrf;
@@ -876,7 +878,7 @@ static int zevpn_build_hash_table_zns(struct zebra_ns *zns,
        zvrf = zebra_vrf_get_evpn();
 
        if (!zvrf)
-               return ZNS_WALK_STOP;
+               return NS_WALK_STOP;
 
        /* Walk VxLAN interfaces and create EVPN hash. */
        for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
@@ -972,7 +974,7 @@ static int zevpn_build_hash_table_zns(struct zebra_ns *zns,
                                        zlog_debug(
                                                "Failed to add EVPN hash, IF %s(%u) L2-VNI %u",
                                                ifp->name, ifp->ifindex, vni);
-                                       return ZNS_WALK_CONTINUE;
+                                       return NS_WALK_CONTINUE;
                                }
 
                                if (zevpn->local_vtep_ip.s_addr !=
@@ -1014,7 +1016,7 @@ static int zevpn_build_hash_table_zns(struct zebra_ns *zns,
                        }
                }
        }
-       return ZNS_WALK_CONTINUE;
+       return NS_WALK_CONTINUE;
 }
 
 /*
@@ -1024,9 +1026,9 @@ static int zevpn_build_hash_table_zns(struct zebra_ns *zns,
 
 static void zevpn_build_hash_table(void)
 {
-       zebra_ns_list_walk(zevpn_build_hash_table_zns,
-                          (void *)NULL,
-                          (void **)NULL);
+       ns_walk_func(zevpn_build_hash_table_zns,
+                    (void *)NULL,
+                    (void **)NULL);
 }
 
 /*
@@ -1659,10 +1661,11 @@ static int zl3vni_del(zebra_l3vni_t *zl3vni)
        return 0;
 }
 
-static int zl3vni_map_to_vxlan_if_zns(struct zebra_ns *zns,
-                                     void *_zl3vni,
-                                     void **_pifp)
+static int zl3vni_map_to_vxlan_if_ns(struct ns *ns,
+                                    void *_zl3vni,
+                                    void **_pifp)
 {
+       struct zebra_ns *zns = ns->info;
        zebra_l3vni_t *zl3vni = (zebra_l3vni_t *)_zl3vni;
        struct route_node *rn = NULL;
        struct interface *ifp = NULL;
@@ -1671,7 +1674,7 @@ static int zl3vni_map_to_vxlan_if_zns(struct zebra_ns *zns,
        zvrf = zebra_vrf_get_evpn();
 
        if (!zvrf)
-               return ZNS_WALK_STOP;
+               return NS_WALK_STOP;
 
        /* loop through all vxlan-interface */
        for (rn = route_top(zns->if_table); rn; rn = route_next(rn)) {
@@ -1705,10 +1708,10 @@ static int zl3vni_map_to_vxlan_if_zns(struct zebra_ns *zns,
                zl3vni->local_vtep_ip = vxl->vtep_ip;
                if (_pifp)
                        *_pifp = (void *)ifp;
-               return ZNS_WALK_STOP;
+               return NS_WALK_STOP;
        }
 
-       return ZNS_WALK_CONTINUE;
+       return NS_WALK_CONTINUE;
 }
 
 struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
@@ -1718,8 +1721,8 @@ struct interface *zl3vni_map_to_vxlan_if(zebra_l3vni_t *zl3vni)
 
        p_ifp = &ifp;
 
-       zebra_ns_list_walk(zl3vni_map_to_vxlan_if_zns,
-                          (void *)zl3vni, (void **)p_ifp);
+       ns_walk_func(zl3vni_map_to_vxlan_if_ns,
+                    (void *)zl3vni, (void **)p_ifp);
        return ifp;
 }
 
@@ -5521,20 +5524,24 @@ stream_failure:
        return;
 }
 
-static int macfdb_read_zns(struct zebra_ns *zns,
-                            void *_in_param __attribute__((unused)),
-                            void **out_param __attribute__((unused)))
+static int macfdb_read_ns(struct ns *ns,
+                         void *_in_param __attribute__((unused)),
+                         void **out_param __attribute__((unused)))
 {
+       struct zebra_ns *zns = ns->info;
+
        macfdb_read(zns);
-       return ZNS_WALK_CONTINUE;
+       return NS_WALK_CONTINUE;
 }
 
-static int neigh_read_zns(struct zebra_ns *zns,
-                         void *_in_param __attribute__((unused)),
-                         void **out_param __attribute__((unused)))
+static int neigh_read_ns(struct ns *ns,
+                        void *_in_param __attribute__((unused)),
+                        void **out_param __attribute__((unused)))
 {
+       struct zebra_ns *zns = ns->info;
+
        neigh_read(zns);
-       return ZNS_WALK_CONTINUE;
+       return NS_WALK_CONTINUE;
 }
 
 /*
@@ -5588,10 +5595,10 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS)
                             zebra_evpn_gw_macip_add_for_evpn_hash, NULL);
 
                /* Read the MAC FDB */
-               zebra_ns_list_walk(macfdb_read_zns, NULL, NULL);
+               ns_walk_func(macfdb_read_ns, NULL, NULL);
 
                /* Read neighbors */
-               zebra_ns_list_walk(neigh_read_zns, NULL, NULL);
+               ns_walk_func(neigh_read_ns, NULL, NULL);
        } else {
                /* Cleanup VTEPs for all EVPNs - uninstall from
                 * kernel and free entries.