zebra: Move rules_hash to zrouter

Move the rules_hash to the zrouter data structure and provide
the additional bit of work needed to lookup the rule based upon
the namespace id as well.  Make the callers of functions not
care about what namespace id we are in.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
This commit is contained in:
Donald Sharp 2018-08-27 14:36:46 -04:00
parent 89272910f7
commit 7f0ea8a4a2
7 changed files with 47 additions and 31 deletions

View file

@ -2243,10 +2243,11 @@ static inline void zread_rule(ZAPI_HANDLER_ARGS)
if (zpr.rule.filter.fwmark)
zpr.rule.filter.filter_bm |= PBR_FILTER_FWMARK;
zpr.vrf_id = zvrf->vrf->vrf_id;
if (hdr->command == ZEBRA_RULE_ADD)
zebra_pbr_add_rule(zvrf->zns, &zpr);
zebra_pbr_add_rule(&zpr);
else
zebra_pbr_del_rule(zvrf->zns, &zpr);
zebra_pbr_del_rule(&zpr);
}
stream_failure:

View file

@ -121,10 +121,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");
@ -157,9 +153,8 @@ int zebra_ns_disable(ns_id_t ns_id, void **info)
{
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_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);
@ -216,6 +211,7 @@ int zebra_ns_init(void)
zebra_ns_notify_parse();
zebra_ns_notify_init();
}
return 0;
}

View file

@ -57,8 +57,6 @@ struct zebra_ns {
struct rtadv rtadv;
#endif /* HAVE_RTADV */
struct hash *rules_hash;
struct hash *ipset_hash;
struct hash *ipset_entry_hash;

View file

@ -26,6 +26,7 @@
#include <memory.h>
#include <hook.h>
#include "zebra/zebra_router.h"
#include "zebra/zebra_pbr.h"
#include "zebra/rt.h"
#include "zebra/zapi_msg.h"
@ -158,6 +159,9 @@ uint32_t zebra_pbr_rules_hash_key(void *arg)
key = jhash_1word(rule->rule.filter.fwmark, key);
else
key = jhash_1word(0, key);
key = jhash_1word(rule->vrf_id, key);
return jhash_3words(rule->rule.filter.src_port,
rule->rule.filter.dst_port,
prefix_hash_key(&rule->rule.filter.dst_ip),
@ -201,6 +205,9 @@ bool zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2)
if (r1->ifp != r2->ifp)
return false;
if (r1->vrf_id != r2->vrf_id)
return false;
return true;
}
@ -208,6 +215,7 @@ struct pbr_rule_unique_lookup {
struct zebra_pbr_rule *rule;
uint32_t unique;
struct interface *ifp;
vrf_id_t vrf_id;
};
static int pbr_rule_lookup_unique_walker(struct hash_backet *b, void *data)
@ -215,7 +223,9 @@ static int pbr_rule_lookup_unique_walker(struct hash_backet *b, void *data)
struct pbr_rule_unique_lookup *pul = data;
struct zebra_pbr_rule *rule = b->data;
if (pul->unique == rule->rule.unique && pul->ifp == rule->ifp) {
if (pul->unique == rule->rule.unique
&& pul->ifp == rule->ifp
&& pul->vrf_id == rule->vrf_id) {
pul->rule = rule;
return HASHWALK_ABORT;
}
@ -223,16 +233,15 @@ static int pbr_rule_lookup_unique_walker(struct hash_backet *b, void *data)
return HASHWALK_CONTINUE;
}
static struct zebra_pbr_rule *pbr_rule_lookup_unique(struct zebra_ns *zns,
uint32_t unique,
struct interface *ifp)
static struct zebra_pbr_rule *pbr_rule_lookup_unique(struct zebra_pbr_rule *zrule)
{
struct pbr_rule_unique_lookup pul;
pul.unique = unique;
pul.ifp = ifp;
pul.unique = zrule->rule.unique;
pul.ifp = zrule->ifp;
pul.rule = NULL;
hash_walk(zns->rules_hash, &pbr_rule_lookup_unique_walker, &pul);
pul.vrf_id = zrule->vrf_id;
hash_walk(zrouter.rules_hash, &pbr_rule_lookup_unique_walker, &pul);
return pul.rule;
}
@ -438,30 +447,30 @@ static void *pbr_rule_alloc_intern(void *arg)
return new;
}
void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)
void zebra_pbr_add_rule(struct zebra_pbr_rule *rule)
{
struct zebra_pbr_rule *unique =
pbr_rule_lookup_unique(zns, rule->rule.unique, rule->ifp);
pbr_rule_lookup_unique(rule);
(void)hash_get(zns->rules_hash, rule, pbr_rule_alloc_intern);
(void)hash_get(zrouter.rules_hash, rule, pbr_rule_alloc_intern);
(void)kernel_add_pbr_rule(rule);
/*
* Rule Replace semantics, if we have an old, install the
* new rule, look above, and then delete the old
*/
if (unique)
zebra_pbr_del_rule(zns, unique);
zebra_pbr_del_rule(unique);
}
void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)
void zebra_pbr_del_rule(struct zebra_pbr_rule *rule)
{
struct zebra_pbr_rule *lookup;
lookup = hash_lookup(zns->rules_hash, rule);
lookup = hash_lookup(zrouter.rules_hash, rule);
(void)kernel_del_pbr_rule(rule);
if (lookup) {
hash_release(zns->rules_hash, lookup);
hash_release(zrouter.rules_hash, lookup);
XFREE(MTYPE_TMP, lookup);
} else
zlog_debug("%s: Rule being deleted we know nothing about",
@ -470,13 +479,12 @@ void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)
static void zebra_pbr_cleanup_rules(struct hash_backet *b, void *data)
{
struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
struct zebra_pbr_rule *rule = b->data;
int *sock = data;
if (rule->sock == *sock) {
(void)kernel_del_pbr_rule(rule);
hash_release(zns->rules_hash, rule);
hash_release(zrouter.rules_hash, rule);
XFREE(MTYPE_TMP, rule);
}
}
@ -527,7 +535,7 @@ static int zebra_pbr_client_close_cleanup(struct zserv *client)
if (!sock)
return 0;
hash_iterate(zns->rules_hash, zebra_pbr_cleanup_rules, &sock);
hash_iterate(zrouter.rules_hash, zebra_pbr_cleanup_rules, &sock);
hash_iterate(zns->iptable_hash,
zebra_pbr_cleanup_iptable, &sock);
hash_iterate(zns->ipset_entry_hash,
@ -1136,7 +1144,7 @@ static void zebra_pbr_show_iptable_unit(struct zebra_pbr_iptable *iptable,
prfl.fwmark = iptable->fwmark;
prfl.ptr = NULL;
hash_walk(zns->rules_hash,
hash_walk(zrouter.rules_hash,
&zebra_pbr_rule_lookup_fwmark_walkcb, &prfl);
if (prfl.ptr) {
struct zebra_pbr_rule *zpr = prfl.ptr;

View file

@ -38,6 +38,8 @@ struct zebra_pbr_rule {
struct pbr_rule rule;
struct interface *ifp;
vrf_id_t vrf_id;
};
#define IS_RULE_FILTERING_ON_SRC_IP(r) \
@ -151,8 +153,8 @@ extern const struct message icmp_typecode_str[];
const char *zebra_pbr_ipset_type2str(uint32_t type);
void zebra_pbr_add_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule);
void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule);
void zebra_pbr_add_rule(struct zebra_pbr_rule *rule);
void zebra_pbr_del_rule(struct zebra_pbr_rule *rule);
void zebra_pbr_create_ipset(struct zebra_ns *zns,
struct zebra_pbr_ipset *ipset);
void zebra_pbr_destroy_ipset(struct zebra_ns *zns,

View file

@ -23,6 +23,7 @@
#include "zebra_router.h"
#include "zebra_memory.h"
#include "zebra_pbr.h"
struct zebra_router zrouter;
@ -154,9 +155,16 @@ void zebra_router_terminate(void)
RB_REMOVE(zebra_router_table_head, &zrouter.tables, zrt);
zebra_router_free_table(zrt);
}
hash_clean(zrouter.rules_hash, zebra_pbr_rules_free);
hash_free(zrouter.rules_hash);
}
void zebra_router_init(void)
{
zrouter.l3vni_table = NULL;
zrouter.rules_hash = hash_create_size(8, zebra_pbr_rules_hash_key,
zebra_pbr_rules_hash_equal,
"Rules Hash");
}

View file

@ -47,8 +47,11 @@ RB_PROTOTYPE(zebra_router_table_head, zebra_router_table,
struct zebra_router {
struct zebra_router_table_head tables;
/* L3-VNI hash table (for EVPN). Only in default instance */
struct hash *l3vni_table;
struct hash *rules_hash;
};
extern struct zebra_router zrouter;