diff options
Diffstat (limited to 'zebra/zebra_ns.c')
| -rw-r--r-- | zebra/zebra_ns.c | 193 |
1 files changed, 37 insertions, 156 deletions
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index e251b26be1..0c743d8678 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -44,29 +44,10 @@ extern struct zebra_privs_t zserv_privs; DEFINE_MTYPE(ZEBRA, ZEBRA_NS, "Zebra Name Space") -static inline int zebra_ns_table_entry_compare(const struct zebra_ns_table *e1, - const struct zebra_ns_table *e2); - -RB_GENERATE(zebra_ns_table_head, zebra_ns_table, zebra_ns_table_entry, - zebra_ns_table_entry_compare); - static struct zebra_ns *dzns; -static inline int zebra_ns_table_entry_compare(const struct zebra_ns_table *e1, - const struct zebra_ns_table *e2) -{ - if (e1->tableid < e2->tableid) - return -1; - if (e1->tableid > e2->tableid) - return 1; - if (e1->ns_id < e2->ns_id) - return -1; - if (e1->ns_id > e2->ns_id) - return 1; - return (e1->afi - e2->afi); -} - static int logicalrouter_config_write(struct vty *vty); +static int zebra_ns_disable_internal(struct zebra_ns *zns, bool complete); struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id) { @@ -92,10 +73,10 @@ static int zebra_ns_new(struct ns *ns) zns = zebra_ns_alloc(); ns->info = zns; zns->ns = ns; + zns->ns_id = ns->ns_id; /* Do any needed per-NS data structure allocation. */ zns->if_table = route_table_init(); - zebra_vxlan_ns_init(zns); return 0; } @@ -131,7 +112,7 @@ int zebra_ns_disabled(struct ns *ns) zlog_info("ZNS %s with id %u (disabled)", ns->name, ns->ns_id); if (!zns) return 0; - return zebra_ns_disable(ns->ns_id, (void **)&zns); + return zebra_ns_disable_internal(zns, true); } /* Do global enable actions - open sockets, read kernel config etc. */ @@ -141,24 +122,6 @@ int zebra_ns_enable(ns_id_t ns_id, void **info) zns->ns_id = ns_id; - zns->rules_hash = - hash_create_size(8, zebra_pbr_rules_hash_key, - zebra_pbr_rules_hash_equal, "Rules Hash"); - - zns->ipset_hash = - hash_create_size(8, zebra_pbr_ipset_hash_key, - zebra_pbr_ipset_hash_equal, "IPset Hash"); - - zns->ipset_entry_hash = - hash_create_size(8, zebra_pbr_ipset_entry_hash_key, - zebra_pbr_ipset_entry_hash_equal, - "IPset Hash Entry"); - - zns->iptable_hash = - hash_create_size(8, zebra_pbr_iptable_hash_key, - zebra_pbr_iptable_hash_equal, - "IPtable Hash Entry"); - #if defined(HAVE_RTADV) rtadv_init(zns); #endif @@ -173,140 +136,54 @@ int zebra_ns_enable(ns_id_t ns_id, void **info) return 0; } -struct route_table *zebra_ns_find_table(struct zebra_ns *zns, uint32_t tableid, - afi_t afi) -{ - struct zebra_ns_table finder; - struct zebra_ns_table *znst; - - memset(&finder, 0, sizeof(finder)); - finder.afi = afi; - finder.tableid = tableid; - finder.ns_id = zns->ns_id; - znst = RB_FIND(zebra_ns_table_head, &zns->ns_tables, &finder); - - if (znst) - return znst->table; - else - return NULL; -} - -unsigned long zebra_ns_score_proto(uint8_t proto, unsigned short instance) +/* Common handler for ns disable - this can be called during ns config, + * or during zebra shutdown. + */ +static int zebra_ns_disable_internal(struct zebra_ns *zns, bool complete) { - struct zebra_ns *zns; - struct zebra_ns_table *znst; - unsigned long cnt = 0; - - zns = zebra_ns_lookup(NS_DEFAULT); - - RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables) { - if (znst->ns_id != NS_DEFAULT) - continue; - cnt += rib_score_proto_table(proto, instance, znst->table); - } - return cnt; -} + route_table_finish(zns->if_table); +#if defined(HAVE_RTADV) + rtadv_terminate(zns); +#endif -void zebra_ns_sweep_route(void) -{ - struct zebra_ns_table *znst; - struct zebra_ns *zns; + kernel_terminate(zns, complete); - zns = zebra_ns_lookup(NS_DEFAULT); + table_manager_disable(zns->ns_id); - RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables) { - if (znst->ns_id != NS_DEFAULT) - continue; - rib_sweep_table(znst->table); - } -} + zns->ns_id = NS_DEFAULT; -struct route_table *zebra_ns_get_table(struct zebra_ns *zns, - struct zebra_vrf *zvrf, uint32_t tableid, - afi_t afi) -{ - struct zebra_ns_table finder; - struct zebra_ns_table *znst; - rib_table_info_t *info; - - memset(&finder, 0, sizeof(finder)); - finder.afi = afi; - finder.tableid = tableid; - finder.ns_id = zns->ns_id; - znst = RB_FIND(zebra_ns_table_head, &zns->ns_tables, &finder); - - if (znst) - return znst->table; - - znst = XCALLOC(MTYPE_ZEBRA_NS, sizeof(*znst)); - znst->tableid = tableid; - znst->afi = afi; - znst->ns_id = zns->ns_id; - znst->table = - (afi == AFI_IP6) ? srcdest_table_init() : route_table_init(); - - info = XCALLOC(MTYPE_RIB_TABLE_INFO, sizeof(*info)); - info->zvrf = zvrf; - info->afi = afi; - info->safi = SAFI_UNICAST; - route_table_set_info(znst->table, info); - znst->table->cleanup = zebra_rtable_node_cleanup; - - RB_INSERT(zebra_ns_table_head, &zns->ns_tables, znst); - return znst->table; + return 0; } -static void zebra_ns_free_table(struct zebra_ns_table *znst) +/* During zebra shutdown, do partial cleanup while the async dataplane + * is still running. + */ +int zebra_ns_early_shutdown(struct ns *ns) { - void *table_info; + struct zebra_ns *zns = ns->info; - rib_close_table(znst->table); + if (zns == NULL) + return 0; - table_info = route_table_get_info(znst->table); - route_table_finish(znst->table); - XFREE(MTYPE_RIB_TABLE_INFO, table_info); - XFREE(MTYPE_ZEBRA_NS, znst); + return zebra_ns_disable_internal(zns, false); } -int zebra_ns_disable(ns_id_t ns_id, void **info) +/* During zebra shutdown, do final cleanup + * after all dataplane work is complete. + */ +int zebra_ns_final_shutdown(struct ns *ns) { - struct zebra_ns_table *znst, *tmp; - struct zebra_ns *zns = (struct zebra_ns *)(*info); - - hash_clean(zns->rules_hash, zebra_pbr_rules_free); - hash_free(zns->rules_hash); - hash_clean(zns->ipset_entry_hash, zebra_pbr_ipset_entry_free); - hash_clean(zns->ipset_hash, zebra_pbr_ipset_free); - hash_free(zns->ipset_hash); - hash_free(zns->ipset_entry_hash); - hash_clean(zns->iptable_hash, - zebra_pbr_iptable_free); - hash_free(zns->iptable_hash); - - RB_FOREACH_SAFE (znst, zebra_ns_table_head, &zns->ns_tables, tmp) { - if (znst->ns_id != ns_id) - continue; - RB_REMOVE(zebra_ns_table_head, &zns->ns_tables, znst); - zebra_ns_free_table(znst); - } - - route_table_finish(zns->if_table); - zebra_vxlan_ns_disable(zns); -#if defined(HAVE_RTADV) - rtadv_terminate(zns); -#endif - - kernel_terminate(zns); + struct zebra_ns *zns = ns->info; - table_manager_disable(zns->ns_id); + if (zns == NULL) + return 0; - zns->ns_id = NS_DEFAULT; + kernel_terminate(zns, true); return 0; } - -int zebra_ns_init(void) +int zebra_ns_init(const char *optional_default_name) { ns_id_t ns_id; ns_id_t ns_id_external; @@ -323,7 +200,6 @@ int zebra_ns_init(void) /* Do any needed per-NS data structure allocation. */ dzns->if_table = route_table_init(); - zebra_vxlan_ns_init(dzns); /* Register zebra VRF callbacks, create and activate default VRF. */ zebra_vrf_init(); @@ -331,6 +207,10 @@ int zebra_ns_init(void) /* Default NS is activated */ zebra_ns_enable(ns_id_external, (void **)&dzns); + if (optional_default_name) + vrf_set_default_name(optional_default_name, + true); + if (vrf_is_backend_netns()) { ns_add_hook(NS_NEW_HOOK, zebra_ns_new); ns_add_hook(NS_ENABLE_HOOK, zebra_ns_enabled); @@ -339,6 +219,7 @@ int zebra_ns_init(void) zebra_ns_notify_parse(); zebra_ns_notify_init(); } + return 0; } |
