summaryrefslogtreecommitdiff
path: root/zebra/zebra_ns.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2018-03-28 10:58:28 +0200
committerPhilippe Guibert <philippe.guibert@6wind.com>2018-06-01 15:24:13 +0200
commitb3441a6a2235615e03cf5d3db152429fd3fe603f (patch)
tree602209fdb8c32c5c2ccadef3eb418e1d42154772 /zebra/zebra_ns.c
parente9748a89019f03cffd1ba2fcc87543171cbe3a26 (diff)
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 <philippe.guibert@6wind.com>
Diffstat (limited to 'zebra/zebra_ns.c')
-rw-r--r--zebra/zebra_ns.c35
1 files changed, 24 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);
}