diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 149d2cb6a5..c9325d8443 100644 --- a/zebra/zapi_msg.c +++ b/zebra/zapi_msg.c @@ -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: diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index 75cacc04e1..300989e33c 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -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; } diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h index 8944f0b6f7..2af4304209 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -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; diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 1a528780c1..059930f4e1 100644 --- a/zebra/zebra_pbr.c +++ b/zebra/zebra_pbr.c @@ -26,6 +26,7 @@ #include #include +#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; diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index 093fcfa8b0..bc651d5114 100644 --- a/zebra/zebra_pbr.h +++ b/zebra/zebra_pbr.h @@ -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, diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c index 1116848a89..94d7ab1b8c 100644 --- a/zebra/zebra_router.c +++ b/zebra/zebra_router.c @@ -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"); } diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h index 456f168227..246f3857c2 100644 --- a/zebra/zebra_router.h +++ b/zebra/zebra_router.h @@ -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;