From b3441a6a2235615e03cf5d3db152429fd3fe603f Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Wed, 28 Mar 2018 10:58:28 +0200 Subject: [PATCH] zebra: ns_table list is extended to support multiple NETNS In the case where vrf backend is netns, then the list of ns tables may be extended. A single list is kept,but an attribute is added: the ns_id. Signed-off-by: Philippe Guibert --- zebra/zebra_ns.c | 35 ++++++++++++++++++++++++----------- zebra/zebra_ns.h | 1 + 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 4526a14870..25e68cc081 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -55,10 +55,15 @@ 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 (e1->afi - e2->afi); - - return e1->tableid - e2->tableid; + 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); @@ -177,6 +182,7 @@ struct route_table *zebra_ns_find_table(struct zebra_ns *zns, uint32_t tableid, 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) @@ -193,9 +199,11 @@ unsigned long zebra_ns_score_proto(uint8_t proto, unsigned short instance) zns = zebra_ns_lookup(NS_DEFAULT); - RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables) + 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; } @@ -206,8 +214,11 @@ void zebra_ns_sweep_route(void) zns = zebra_ns_lookup(NS_DEFAULT); - RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables) + RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables) { + if (znst->ns_id != NS_DEFAULT) + continue; rib_sweep_table(znst->table); + } } struct route_table *zebra_ns_get_table(struct zebra_ns *zns, @@ -221,6 +232,7 @@ struct route_table *zebra_ns_get_table(struct zebra_ns *zns, 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) @@ -229,6 +241,7 @@ struct route_table *zebra_ns_get_table(struct zebra_ns *zns, 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(); @@ -257,7 +270,7 @@ static void zebra_ns_free_table(struct zebra_ns_table *znst) int zebra_ns_disable(ns_id_t ns_id, void **info) { - struct zebra_ns_table *znst; + struct zebra_ns_table *znst, *tmp; struct zebra_ns *zns = (struct zebra_ns *)(*info); hash_clean(zns->rules_hash, zebra_pbr_rules_free); @@ -271,9 +284,9 @@ int zebra_ns_disable(ns_id_t ns_id, void **info) zebra_pbr_iptable_free); hash_free(zns->iptable_hash); - while (!RB_EMPTY(zebra_ns_table_head, &zns->ns_tables)) { - znst = RB_ROOT(zebra_ns_table_head, &zns->ns_tables); - + 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); } diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index c93db2a764..ed70a34c0b 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -43,6 +43,7 @@ struct zebra_ns_table { uint32_t tableid; afi_t afi; + ns_id_t ns_id; struct route_table *table; }; -- 2.39.5