diff --git a/zebra/main.c b/zebra/main.c index 148bcab7e4..d8952a7b28 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -39,6 +39,7 @@ #include "routemap.h" #include "frr_pthread.h" +#include "zebra/zebra_router.h" #include "zebra/zebra_errors.h" #include "zebra/rib.h" #include "zebra/zserv.h" @@ -174,6 +175,8 @@ static void sigint(void) work_queue_free_and_null(&zebrad.ribq); meta_queue_free(zebrad.mq); + zebra_router_terminate(); + frr_fini(); exit(0); } @@ -354,6 +357,7 @@ int main(int argc, char **argv) zebrad.master = frr_init(); /* Zebra related initialize. */ + zebra_router_init(); zserv_init(); rib_init(); zebra_if_init(); @@ -418,7 +422,7 @@ int main(int argc, char **argv) /* RNH init */ zebra_rnh_init(); - + /* Error init */ zebra_error_init(); diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 3bb75f3446..a22f6395c9 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -45,6 +45,7 @@ #include "zebra/zebra_ns.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_errors.h" +#include "zebra/zebra_router.h" extern struct zebra_privs_t zserv_privs; @@ -391,8 +392,8 @@ static int rtadv_timer(struct thread *thread) struct zebra_if *zif; int period; - zns->rtadv.ra_timer = NULL; - if (zns->rtadv.adv_msec_if_count == 0) { + zrouter.rtadv.ra_timer = NULL; + if (zrouter.rtadv.adv_msec_if_count == 0) { period = 1000; /* 1 s */ rtadv_event(zns, RTADV_TIMER, 1 /* 1 s */); } else { @@ -424,7 +425,8 @@ static int rtadv_timer(struct thread *thread) "Fast RA Rexmit on interface %s", ifp->name); - rtadv_send_packet(zns->rtadv.sock, ifp); + rtadv_send_packet(zrouter.rtadv.sock, + ifp); } else { zif->rtadv.AdvIntervalTimer -= period; if (zif->rtadv.AdvIntervalTimer <= 0) { @@ -437,7 +439,8 @@ static int rtadv_timer(struct thread *thread) zif->rtadv .MaxRtrAdvInterval; rtadv_send_packet( - zns->rtadv.sock, ifp); + zrouter.rtadv.sock, + ifp); } } } @@ -452,7 +455,7 @@ static void rtadv_process_solicit(struct interface *ifp) struct zebra_ns *zns = zvrf->zns; assert(zns); - rtadv_send_packet(zns->rtadv.sock, ifp); + rtadv_send_packet(zrouter.rtadv.sock, ifp); } /* @@ -649,7 +652,7 @@ static int rtadv_read(struct thread *thread) struct zebra_ns *zns = THREAD_ARG(thread); sock = THREAD_FD(thread); - zns->rtadv.ra_read = NULL; + zrouter.rtadv.ra_read = NULL; /* Register myself. */ rtadv_event(zns, RTADV_READ, sock); @@ -808,18 +811,18 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp, if (zif->rtadv.AdvSendAdvertisements) { zif->rtadv.AdvSendAdvertisements = 0; zif->rtadv.AdvIntervalTimer = 0; - zns->rtadv.adv_if_count--; + zrouter.rtadv.adv_if_count--; - if_leave_all_router(zns->rtadv.sock, ifp); + if_leave_all_router(zrouter.rtadv.sock, ifp); - if (zns->rtadv.adv_if_count == 0) + if (zrouter.rtadv.adv_if_count == 0) rtadv_event(zns, RTADV_STOP, 0); } } else { if (!zif->rtadv.AdvSendAdvertisements) { zif->rtadv.AdvSendAdvertisements = 1; zif->rtadv.AdvIntervalTimer = 0; - zns->rtadv.adv_if_count++; + zrouter.rtadv.adv_if_count++; if (zif->rtadv.MaxRtrAdvInterval >= 1000) { /* Enable Fast RA only when RA interval is in @@ -829,10 +832,11 @@ static void ipv6_nd_suppress_ra_set(struct interface *ifp, RTADV_NUM_FAST_REXMITS; } - if_join_all_router(zns->rtadv.sock, ifp); + if_join_all_router(zrouter.rtadv.sock, ifp); - if (zns->rtadv.adv_if_count == 1) - rtadv_event(zns, RTADV_START, zns->rtadv.sock); + if (zrouter.rtadv.adv_if_count == 1) + rtadv_event(zns, RTADV_START, + zrouter.rtadv.sock); } } } @@ -972,10 +976,7 @@ DEFUN (ipv6_nd_ra_interval_msec, VTY_DECLVAR_CONTEXT(interface, ifp); unsigned interval; struct zebra_if *zif = ifp->info; - struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id); - struct zebra_ns *zns; - zns = zvrf->zns; interval = strtoul(argv[idx_number]->arg, NULL, 10); if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000)) { @@ -985,10 +986,10 @@ DEFUN (ipv6_nd_ra_interval_msec, } if (zif->rtadv.MaxRtrAdvInterval % 1000) - zns->rtadv.adv_msec_if_count--; + zrouter.rtadv.adv_msec_if_count--; if (interval % 1000) - zns->rtadv.adv_msec_if_count++; + zrouter.rtadv.adv_msec_if_count++; SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); zif->rtadv.MaxRtrAdvInterval = interval; @@ -1010,10 +1011,7 @@ DEFUN (ipv6_nd_ra_interval, VTY_DECLVAR_CONTEXT(interface, ifp); unsigned interval; struct zebra_if *zif = ifp->info; - struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id); - struct zebra_ns *zns; - zns = zvrf->zns; interval = strtoul(argv[idx_number]->arg, NULL, 10); if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime)) { @@ -1023,7 +1021,7 @@ DEFUN (ipv6_nd_ra_interval, } if (zif->rtadv.MaxRtrAdvInterval % 1000) - zns->rtadv.adv_msec_if_count--; + zrouter.rtadv.adv_msec_if_count--; /* convert to milliseconds */ interval = interval * 1000; @@ -1049,14 +1047,9 @@ DEFUN (no_ipv6_nd_ra_interval, { VTY_DECLVAR_CONTEXT(interface, ifp); struct zebra_if *zif = ifp->info; - struct zebra_vrf *zvrf; - struct zebra_ns *zns; - - zvrf = vrf_info_lookup(ifp->vrf_id); - zns = zvrf->zns; if (zif->rtadv.MaxRtrAdvInterval % 1000) - zns->rtadv.adv_msec_if_count--; + zrouter.rtadv.adv_msec_if_count--; UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED); @@ -1701,7 +1694,7 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp) static void rtadv_event(struct zebra_ns *zns, enum rtadv_event event, int val) { - struct rtadv *rtadv = &zns->rtadv; + struct rtadv *rtadv = &zrouter.rtadv; switch (event) { case RTADV_START: @@ -1740,19 +1733,19 @@ static void rtadv_event(struct zebra_ns *zns, enum rtadv_event event, int val) void rtadv_init(struct zebra_ns *zns) { - zns->rtadv.sock = rtadv_make_socket(zns->ns_id); + zrouter.rtadv.sock = rtadv_make_socket(zns->ns_id); } void rtadv_terminate(struct zebra_ns *zns) { rtadv_event(zns, RTADV_STOP, 0); - if (zns->rtadv.sock >= 0) { - close(zns->rtadv.sock); - zns->rtadv.sock = -1; + if (zrouter.rtadv.sock >= 0) { + close(zrouter.rtadv.sock); + zrouter.rtadv.sock = -1; } - zns->rtadv.adv_if_count = 0; - zns->rtadv.adv_msec_if_count = 0; + zrouter.rtadv.adv_if_count = 0; + zrouter.rtadv.adv_msec_if_count = 0; } void rtadv_cmd_init(void) diff --git a/zebra/subdir.am b/zebra/subdir.am index bf2c393233..b8f5e0d409 100644 --- a/zebra/subdir.am +++ b/zebra/subdir.am @@ -79,6 +79,7 @@ zebra_zebra_SOURCES = \ zebra/zebra_ptm_redistribute.c \ zebra/zebra_pw.c \ zebra/zebra_rib.c \ + zebra/zebra_router.c \ zebra/zebra_rnh.c \ zebra/zebra_routemap.c \ zebra/zebra_vrf.c \ @@ -131,6 +132,7 @@ noinst_HEADERS += \ zebra/zebra_pw.h \ zebra/zebra_rnh.h \ zebra/zebra_routemap.h \ + zebra/zebra_router.h \ zebra/zebra_vrf.h \ zebra/zebra_vxlan.h \ zebra/zebra_vxlan_private.h \ diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c index 149d2cb6a5..276b825b34 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: @@ -2272,9 +2273,9 @@ static inline void zread_ipset(ZAPI_HANDLER_ARGS) STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE); if (hdr->command == ZEBRA_IPSET_CREATE) - zebra_pbr_create_ipset(zvrf->zns, &zpi); + zebra_pbr_create_ipset(&zpi); else - zebra_pbr_destroy_ipset(zvrf->zns, &zpi); + zebra_pbr_destroy_ipset(&zpi); } stream_failure: @@ -2327,12 +2328,12 @@ static inline void zread_ipset_entry(ZAPI_HANDLER_ARGS) zpi.filter_bm |= PBR_FILTER_PROTO; /* calculate backpointer */ - zpi.backpointer = zebra_pbr_lookup_ipset_pername( - zvrf->zns, ipset.ipset_name); + zpi.backpointer = + zebra_pbr_lookup_ipset_pername(ipset.ipset_name); if (hdr->command == ZEBRA_IPSET_ENTRY_ADD) - zebra_pbr_add_ipset_entry(zvrf->zns, &zpi); + zebra_pbr_add_ipset_entry(&zpi); else - zebra_pbr_del_ipset_entry(zvrf->zns, &zpi); + zebra_pbr_del_ipset_entry(&zpi); } stream_failure: @@ -2367,9 +2368,9 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS) zebra_pbr_iptable_update_interfacelist(s, &zpi); if (hdr->command == ZEBRA_IPTABLE_ADD) - zebra_pbr_add_iptable(zvrf->zns, &zpi); + zebra_pbr_add_iptable(&zpi); else - zebra_pbr_del_iptable(zvrf->zns, &zpi); + zebra_pbr_del_iptable(&zpi); stream_failure: return; } diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c index e251b26be1..e65f23dc8a 100644 --- a/zebra/zebra_ns.c +++ b/zebra/zebra_ns.c @@ -44,28 +44,8 @@ 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); struct zebra_ns *zebra_ns_lookup(ns_id_t ns_id) @@ -141,24 +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"); - - 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,123 +135,10 @@ 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) -{ - 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; -} - -void zebra_ns_sweep_route(void) -{ - struct zebra_ns_table *znst; - struct zebra_ns *zns; - - zns = zebra_ns_lookup(NS_DEFAULT); - - 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, - 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; -} - -static void zebra_ns_free_table(struct zebra_ns_table *znst) -{ - void *table_info; - - rib_close_table(znst->table); - - 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); -} - int zebra_ns_disable(ns_id_t ns_id, void **info) { - 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) @@ -339,6 +188,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 ed70a34c0b..c1a9b41b8d 100644 --- a/zebra/zebra_ns.h +++ b/zebra/zebra_ns.h @@ -38,19 +38,6 @@ struct nlsock { }; #endif -struct zebra_ns_table { - RB_ENTRY(zebra_ns_table) zebra_ns_table_entry; - - uint32_t tableid; - afi_t afi; - ns_id_t ns_id; - - struct route_table *table; -}; -RB_HEAD(zebra_ns_table_head, zebra_ns_table); -RB_PROTOTYPE(zebra_ns_table_head, zebra_ns_table, zebra_ns_table_entry, - zebra_ns_table_entry_compare) - struct zebra_ns { /* net-ns name. */ char name[VRF_NAMSIZ]; @@ -66,23 +53,6 @@ struct zebra_ns { struct route_table *if_table; - /* L3-VNI hash table (for EVPN). Only in default instance */ - struct hash *l3vni_table; - -#if defined(HAVE_RTADV) - struct rtadv rtadv; -#endif /* HAVE_RTADV */ - - struct zebra_ns_table_head ns_tables; - - struct hash *rules_hash; - - struct hash *ipset_hash; - - struct hash *ipset_entry_hash; - - struct hash *iptable_hash; - /* Back pointer */ struct ns *ns; }; @@ -94,13 +64,6 @@ int zebra_ns_enable(ns_id_t ns_id, void **info); int zebra_ns_disabled(struct ns *ns); int zebra_ns_disable(ns_id_t ns_id, void **info); -extern struct route_table *zebra_ns_find_table(struct zebra_ns *zns, - uint32_t tableid, afi_t afi); -extern struct route_table *zebra_ns_get_table(struct zebra_ns *zns, - struct zebra_vrf *zvrf, - uint32_t tableid, afi_t afi); int zebra_ns_config_write(struct vty *vty, struct ns *ns); -unsigned long zebra_ns_score_proto(uint8_t proto, unsigned short instance); -void zebra_ns_sweep_route(void); #endif diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c index 1a528780c1..833306bcc4 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" @@ -102,30 +103,24 @@ static const struct message fragment_value_str[] = { }; /* static function declarations */ -DEFINE_HOOK(zebra_pbr_ipset_entry_wrap_script_get_stat, (struct zebra_ns *zns, - struct zebra_pbr_ipset_entry *ipset, - uint64_t *pkts, uint64_t *bytes), - (zns, ipset, pkts, bytes)) +DEFINE_HOOK(zebra_pbr_ipset_entry_get_stat, + (struct zebra_pbr_ipset_entry *ipset, uint64_t *pkts, + uint64_t *bytes), + (ipset, pkts, bytes)) -DEFINE_HOOK(zebra_pbr_iptable_wrap_script_get_stat, (struct zebra_ns *zns, - struct zebra_pbr_iptable *iptable, - uint64_t *pkts, uint64_t *bytes), - (zns, iptable, pkts, bytes)) +DEFINE_HOOK(zebra_pbr_iptable_get_stat, + (struct zebra_pbr_iptable *iptable, uint64_t *pkts, + uint64_t *bytes), + (iptable, pkts, bytes)) -DEFINE_HOOK(zebra_pbr_iptable_wrap_script_update, (struct zebra_ns *zns, - int cmd, - struct zebra_pbr_iptable *iptable), - (zns, cmd, iptable)); +DEFINE_HOOK(zebra_pbr_iptable_update, + (int cmd, struct zebra_pbr_iptable *iptable), (cmd, iptable)); -DEFINE_HOOK(zebra_pbr_ipset_entry_wrap_script_update, (struct zebra_ns *zns, - int cmd, - struct zebra_pbr_ipset_entry *ipset), - (zns, cmd, ipset)); +DEFINE_HOOK(zebra_pbr_ipset_entry_update, + (int cmd, struct zebra_pbr_ipset_entry *ipset), (cmd, ipset)); -DEFINE_HOOK(zebra_pbr_ipset_wrap_script_update, (struct zebra_ns *zns, - int cmd, - struct zebra_pbr_ipset *ipset), - (zns, cmd, ipset)); +DEFINE_HOOK(zebra_pbr_ipset_update, + (int cmd, struct zebra_pbr_ipset *ipset), (cmd, ipset)); /* Private functions */ @@ -158,6 +153,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 +199,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 +209,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 +217,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 +227,16 @@ 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; } @@ -240,15 +244,9 @@ static struct zebra_pbr_rule *pbr_rule_lookup_unique(struct zebra_ns *zns, void zebra_pbr_ipset_free(void *arg) { struct zebra_pbr_ipset *ipset; - struct zebra_ns *zns; ipset = (struct zebra_pbr_ipset *)arg; - if (vrf_is_backend_netns()) - zns = zebra_ns_lookup(ipset->vrf_id); - else - zns = zebra_ns_lookup(NS_DEFAULT); - hook_call(zebra_pbr_ipset_wrap_script_update, - zns, 0, ipset); + hook_call(zebra_pbr_ipset_update, 0, ipset); XFREE(MTYPE_TMP, ipset); } @@ -256,8 +254,9 @@ uint32_t zebra_pbr_ipset_hash_key(void *arg) { struct zebra_pbr_ipset *ipset = (struct zebra_pbr_ipset *)arg; uint32_t *pnt = (uint32_t *)&ipset->ipset_name; + uint32_t key = jhash_1word(ipset->vrf_id, 0x63ab42de); - return jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE, 0x63ab42de); + return jhash2(pnt, ZEBRA_IPSET_NAME_HASH_SIZE, key); } bool zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2) @@ -271,6 +270,9 @@ bool zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2) return false; if (r1->unique != r2->unique) return false; + if (r1->vrf_id != r2->vrf_id) + return false; + if (strncmp(r1->ipset_name, r2->ipset_name, ZEBRA_IPSET_NAME_SIZE)) return false; @@ -280,17 +282,10 @@ bool zebra_pbr_ipset_hash_equal(const void *arg1, const void *arg2) void zebra_pbr_ipset_entry_free(void *arg) { struct zebra_pbr_ipset_entry *ipset; - struct zebra_ns *zns; ipset = (struct zebra_pbr_ipset_entry *)arg; - if (ipset->backpointer && vrf_is_backend_netns()) { - struct zebra_pbr_ipset *ips = ipset->backpointer; - zns = zebra_ns_lookup((ns_id_t)ips->vrf_id); - } else - zns = zebra_ns_lookup(NS_DEFAULT); - hook_call(zebra_pbr_ipset_entry_wrap_script_update, - zns, 0, ipset); + hook_call(zebra_pbr_ipset_entry_update, 0, ipset); XFREE(MTYPE_TMP, ipset); } @@ -351,15 +346,9 @@ void zebra_pbr_iptable_free(void *arg) struct zebra_pbr_iptable *iptable; struct listnode *node, *nnode; char *name; - struct zebra_ns *zns; iptable = (struct zebra_pbr_iptable *)arg; - if (vrf_is_backend_netns()) - zns = zebra_ns_lookup((ns_id_t)iptable->vrf_id); - else - zns = zebra_ns_lookup(NS_DEFAULT); - hook_call(zebra_pbr_iptable_wrap_script_update, - zns, 0, iptable); + hook_call(zebra_pbr_iptable_update, 0, iptable); for (ALL_LIST_ELEMENTS(iptable->interface_name_list, node, nnode, name)) { @@ -385,6 +374,8 @@ uint32_t zebra_pbr_iptable_hash_key(void *arg) key = jhash_1word(iptable->tcp_mask_flags, key); key = jhash_1word(iptable->dscp_value, key); key = jhash_1word(iptable->fragment, key); + key = jhash_1word(iptable->vrf_id, key); + return jhash_3words(iptable->filter_bm, iptable->type, iptable->unique, key); } @@ -396,6 +387,8 @@ bool zebra_pbr_iptable_hash_equal(const void *arg1, const void *arg2) r1 = (const struct zebra_pbr_iptable *)arg1; r2 = (const struct zebra_pbr_iptable *)arg2; + if (r1->vrf_id != r2->vrf_id) + return 0; if (r1->type != r2->type) return false; if (r1->unique != r2->unique) @@ -438,30 +431,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,70 +463,60 @@ 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); } } static void zebra_pbr_cleanup_ipset(struct hash_backet *b, void *data) { - struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); struct zebra_pbr_ipset *ipset = b->data; int *sock = data; if (ipset->sock == *sock) { - hook_call(zebra_pbr_ipset_wrap_script_update, - zns, 0, ipset); - hash_release(zns->ipset_hash, ipset); + hook_call(zebra_pbr_ipset_update, 0, ipset); + hash_release(zrouter.ipset_hash, ipset); } } static void zebra_pbr_cleanup_ipset_entry(struct hash_backet *b, void *data) { - struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); struct zebra_pbr_ipset_entry *ipset = b->data; int *sock = data; if (ipset->sock == *sock) { - hook_call(zebra_pbr_ipset_entry_wrap_script_update, - zns, 0, ipset); - hash_release(zns->ipset_entry_hash, ipset); + hook_call(zebra_pbr_ipset_entry_update, 0, ipset); + hash_release(zrouter.ipset_entry_hash, ipset); } } static void zebra_pbr_cleanup_iptable(struct hash_backet *b, void *data) { - struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); struct zebra_pbr_iptable *iptable = b->data; int *sock = data; if (iptable->sock == *sock) { - hook_call(zebra_pbr_iptable_wrap_script_update, - zns, 0, iptable); - hash_release(zns->iptable_hash, iptable); + hook_call(zebra_pbr_iptable_update, 0, iptable); + hash_release(zrouter.iptable_hash, iptable); } } static int zebra_pbr_client_close_cleanup(struct zserv *client) { int sock = client->sock; - struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT); if (!sock) return 0; - hash_iterate(zns->rules_hash, zebra_pbr_cleanup_rules, &sock); - hash_iterate(zns->iptable_hash, - zebra_pbr_cleanup_iptable, &sock); - hash_iterate(zns->ipset_entry_hash, - zebra_pbr_cleanup_ipset_entry, &sock); - hash_iterate(zns->ipset_hash, - zebra_pbr_cleanup_ipset, &sock); + hash_iterate(zrouter.rules_hash, zebra_pbr_cleanup_rules, &sock); + hash_iterate(zrouter.iptable_hash, zebra_pbr_cleanup_iptable, &sock); + hash_iterate(zrouter.ipset_entry_hash, zebra_pbr_cleanup_ipset_entry, + &sock); + hash_iterate(zrouter.ipset_hash, zebra_pbr_cleanup_ipset, &sock); return 1; } @@ -556,29 +539,25 @@ static void *pbr_ipset_alloc_intern(void *arg) return new; } -void zebra_pbr_create_ipset(struct zebra_ns *zns, - struct zebra_pbr_ipset *ipset) +void zebra_pbr_create_ipset(struct zebra_pbr_ipset *ipset) { int ret; - (void)hash_get(zns->ipset_hash, ipset, pbr_ipset_alloc_intern); - ret = hook_call(zebra_pbr_ipset_wrap_script_update, - zns, 1, ipset); + (void)hash_get(zrouter.ipset_hash, ipset, pbr_ipset_alloc_intern); + ret = hook_call(zebra_pbr_ipset_update, 1, ipset); kernel_pbr_ipset_add_del_status(ipset, ret ? ZEBRA_DPLANE_INSTALL_SUCCESS : ZEBRA_DPLANE_INSTALL_FAILURE); } -void zebra_pbr_destroy_ipset(struct zebra_ns *zns, - struct zebra_pbr_ipset *ipset) +void zebra_pbr_destroy_ipset(struct zebra_pbr_ipset *ipset) { struct zebra_pbr_ipset *lookup; - lookup = hash_lookup(zns->ipset_hash, ipset); - hook_call(zebra_pbr_ipset_wrap_script_update, - zns, 0, ipset); + lookup = hash_lookup(zrouter.ipset_hash, ipset); + hook_call(zebra_pbr_ipset_update, 0, ipset); if (lookup) { - hash_release(zns->ipset_hash, lookup); + hash_release(zrouter.ipset_hash, lookup); XFREE(MTYPE_TMP, lookup); } else zlog_debug( @@ -611,8 +590,7 @@ static int zebra_pbr_ipset_pername_walkcb(struct hash_backet *backet, void *arg) return HASHWALK_CONTINUE; } -struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(struct zebra_ns *zns, - char *ipsetname) +struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(char *ipsetname) { struct pbr_ipset_name_lookup pinl; struct pbr_ipset_name_lookup *ptr = &pinl; @@ -622,7 +600,7 @@ struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(struct zebra_ns *zns, memset(ptr, 0, sizeof(struct pbr_ipset_name_lookup)); snprintf((char *)ptr->ipset_name, ZEBRA_IPSET_NAME_SIZE, "%s", ipsetname); - hash_walk(zns->ipset_hash, zebra_pbr_ipset_pername_walkcb, ptr); + hash_walk(zrouter.ipset_hash, zebra_pbr_ipset_pername_walkcb, ptr); return ptr->ipset; } @@ -640,30 +618,26 @@ static void *pbr_ipset_entry_alloc_intern(void *arg) return new; } -void zebra_pbr_add_ipset_entry(struct zebra_ns *zns, - struct zebra_pbr_ipset_entry *ipset) +void zebra_pbr_add_ipset_entry(struct zebra_pbr_ipset_entry *ipset) { int ret; - (void)hash_get(zns->ipset_entry_hash, ipset, + (void)hash_get(zrouter.ipset_entry_hash, ipset, pbr_ipset_entry_alloc_intern); - ret = hook_call(zebra_pbr_ipset_entry_wrap_script_update, - zns, 1, ipset); + ret = hook_call(zebra_pbr_ipset_entry_update, 1, ipset); kernel_pbr_ipset_entry_add_del_status(ipset, ret ? ZEBRA_DPLANE_INSTALL_SUCCESS : ZEBRA_DPLANE_INSTALL_FAILURE); } -void zebra_pbr_del_ipset_entry(struct zebra_ns *zns, - struct zebra_pbr_ipset_entry *ipset) +void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset) { struct zebra_pbr_ipset_entry *lookup; - lookup = hash_lookup(zns->ipset_entry_hash, ipset); - hook_call(zebra_pbr_ipset_entry_wrap_script_update, - zns, 0, ipset); + lookup = hash_lookup(zrouter.ipset_entry_hash, ipset); + hook_call(zebra_pbr_ipset_entry_update, 0, ipset); if (lookup) { - hash_release(zns->ipset_entry_hash, lookup); + hash_release(zrouter.ipset_entry_hash, lookup); XFREE(MTYPE_TMP, lookup); } else zlog_debug("%s: IPSet being deleted we know nothing about", @@ -684,31 +658,28 @@ static void *pbr_iptable_alloc_intern(void *arg) return new; } -void zebra_pbr_add_iptable(struct zebra_ns *zns, - struct zebra_pbr_iptable *iptable) +void zebra_pbr_add_iptable(struct zebra_pbr_iptable *iptable) { int ret; - (void)hash_get(zns->iptable_hash, iptable, - pbr_iptable_alloc_intern); - ret = hook_call(zebra_pbr_iptable_wrap_script_update, zns, 1, iptable); + (void)hash_get(zrouter.iptable_hash, iptable, pbr_iptable_alloc_intern); + ret = hook_call(zebra_pbr_iptable_update, 1, iptable); kernel_pbr_iptable_add_del_status(iptable, ret ? ZEBRA_DPLANE_INSTALL_SUCCESS : ZEBRA_DPLANE_INSTALL_FAILURE); } -void zebra_pbr_del_iptable(struct zebra_ns *zns, - struct zebra_pbr_iptable *iptable) +void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable) { struct zebra_pbr_iptable *lookup; - lookup = hash_lookup(zns->iptable_hash, iptable); - hook_call(zebra_pbr_iptable_wrap_script_update, zns, 0, iptable); + lookup = hash_lookup(zrouter.iptable_hash, iptable); + hook_call(zebra_pbr_iptable_update, 0, iptable); if (lookup) { struct listnode *node, *nnode; char *name; - hash_release(zns->iptable_hash, lookup); + hash_release(zrouter.iptable_hash, lookup); for (ALL_LIST_ELEMENTS(iptable->interface_name_list, node, nnode, name)) { XFREE(MTYPE_PBR_IPTABLE_IFNAME, name); @@ -913,7 +884,6 @@ static int zebra_pbr_show_ipset_entry_walkcb(struct hash_backet *backet, struct zebra_pbr_ipset_entry *zpie = (struct zebra_pbr_ipset_entry *)backet->data; uint64_t pkts = 0, bytes = 0; - struct zebra_ns *zns = unique->zns; int ret = 0; if (zpie->backpointer != zpi) @@ -971,8 +941,8 @@ static int zebra_pbr_show_ipset_entry_walkcb(struct hash_backet *backet, } vty_out(vty, " (%u)\n", zpie->unique); - ret = hook_call(zebra_pbr_ipset_entry_wrap_script_get_stat, - zns, zpie, &pkts, &bytes); + ret = hook_call(zebra_pbr_ipset_entry_get_stat, zpie, &pkts, + &bytes); if (ret && pkts > 0) vty_out(vty, "\t pkts %" PRIu64 ", bytes %" PRIu64"\n", pkts, bytes); @@ -993,7 +963,7 @@ static int zebra_pbr_show_ipset_walkcb(struct hash_backet *backet, void *arg) unique.vty = vty; unique.zpi = zpi; unique.zns = zns; - hash_walk(zns->ipset_entry_hash, zebra_pbr_show_ipset_entry_walkcb, + hash_walk(zrouter.ipset_entry_hash, zebra_pbr_show_ipset_entry_walkcb, &unique); vty_out(vty, "\n"); return HASHWALK_CONTINUE; @@ -1029,7 +999,7 @@ void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname) struct zebra_pbr_env_display uniqueipset; if (ipsetname) { - zpi = zebra_pbr_lookup_ipset_pername(zns, ipsetname); + zpi = zebra_pbr_lookup_ipset_pername(ipsetname); if (!zpi) { vty_out(vty, "No IPset %s found\n", ipsetname); return; @@ -1040,15 +1010,14 @@ void zebra_pbr_show_ipset_list(struct vty *vty, char *ipsetname) unique.vty = vty; unique.zpi = zpi; unique.zns = zns; - hash_walk(zns->ipset_entry_hash, - zebra_pbr_show_ipset_entry_walkcb, - &unique); + hash_walk(zrouter.ipset_entry_hash, + zebra_pbr_show_ipset_entry_walkcb, &unique); return; } uniqueipset.zns = zns; uniqueipset.vty = vty; uniqueipset.name = NULL; - hash_walk(zns->ipset_hash, zebra_pbr_show_ipset_walkcb, + hash_walk(zrouter.ipset_hash, zebra_pbr_show_ipset_walkcb, &uniqueipset); } @@ -1126,8 +1095,8 @@ static void zebra_pbr_show_iptable_unit(struct zebra_pbr_iptable *iptable, " not" : "", lookup_msg(fragment_value_str, iptable->fragment, val_str)); } - ret = hook_call(zebra_pbr_iptable_wrap_script_get_stat, - zns, iptable, &pkts, &bytes); + ret = hook_call(zebra_pbr_iptable_get_stat, iptable, &pkts, + &bytes); if (ret && pkts > 0) vty_out(vty, "\t pkts %" PRIu64 ", bytes %" PRIu64"\n", pkts, bytes); @@ -1136,7 +1105,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; @@ -1174,8 +1143,7 @@ void zebra_pbr_show_iptable(struct vty *vty, char *iptable_name) env.vty = vty; env.zns = zns; env.name = iptable_name; - hash_walk(zns->iptable_hash, zebra_pbr_show_iptable_walkcb, - &env); + hash_walk(zrouter.iptable_hash, zebra_pbr_show_iptable_walkcb, &env); } void zebra_pbr_iptable_update_interfacelist(struct stream *s, diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h index 093fcfa8b0..5b6c23896c 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,23 +153,16 @@ 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_create_ipset(struct zebra_ns *zns, - struct zebra_pbr_ipset *ipset); -void zebra_pbr_destroy_ipset(struct zebra_ns *zns, - struct zebra_pbr_ipset *ipset); -struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(struct zebra_ns *zns, - char *ipsetname); -void zebra_pbr_add_ipset_entry(struct zebra_ns *zns, - struct zebra_pbr_ipset_entry *ipset); -void zebra_pbr_del_ipset_entry(struct zebra_ns *zns, - struct zebra_pbr_ipset_entry *ipset); +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_pbr_ipset *ipset); +void zebra_pbr_destroy_ipset(struct zebra_pbr_ipset *ipset); +struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(char *ipsetname); +void zebra_pbr_add_ipset_entry(struct zebra_pbr_ipset_entry *ipset); +void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset); -void zebra_pbr_add_iptable(struct zebra_ns *zns, - struct zebra_pbr_iptable *iptable); -void zebra_pbr_del_iptable(struct zebra_ns *zns, - struct zebra_pbr_iptable *iptable); +void zebra_pbr_add_iptable(struct zebra_pbr_iptable *iptable); +void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable); /* * Install specified rule for a specific interface. @@ -241,26 +236,20 @@ extern void zebra_pbr_iptable_update_interfacelist(struct stream *s, size_t zebra_pbr_tcpflags_snprintf(char *buffer, size_t len, uint16_t tcp_val); -DECLARE_HOOK(zebra_pbr_ipset_entry_wrap_script_get_stat, (struct zebra_ns *zns, - struct zebra_pbr_ipset_entry *ipset, - uint64_t *pkts, uint64_t *bytes), - (zns, ipset, pkts, bytes)) -DECLARE_HOOK(zebra_pbr_iptable_wrap_script_get_stat, (struct zebra_ns *zns, - struct zebra_pbr_iptable *iptable, - uint64_t *pkts, uint64_t *bytes), - (zns, iptable, pkts, bytes)) -DECLARE_HOOK(zebra_pbr_iptable_wrap_script_update, (struct zebra_ns *zns, - int cmd, - struct zebra_pbr_iptable *iptable), - (zns, cmd, iptable)); +DECLARE_HOOK(zebra_pbr_ipset_entry_get_stat, + (struct zebra_pbr_ipset_entry *ipset, uint64_t *pkts, + uint64_t *bytes), + (ipset, pkts, bytes)) +DECLARE_HOOK(zebra_pbr_iptable_get_stat, + (struct zebra_pbr_iptable *iptable, uint64_t *pkts, + uint64_t *bytes), + (iptable, pkts, bytes)) +DECLARE_HOOK(zebra_pbr_iptable_update, + (int cmd, struct zebra_pbr_iptable *iptable), (cmd, iptable)); -DECLARE_HOOK(zebra_pbr_ipset_entry_wrap_script_update, (struct zebra_ns *zns, - int cmd, - struct zebra_pbr_ipset_entry *ipset), - (zns, cmd, ipset)); -DECLARE_HOOK(zebra_pbr_ipset_wrap_script_update, (struct zebra_ns *zns, - int cmd, - struct zebra_pbr_ipset *ipset), - (zns, cmd, ipset)); +DECLARE_HOOK(zebra_pbr_ipset_entry_update, + (int cmd, struct zebra_pbr_ipset_entry *ipset), (cmd, ipset)); +DECLARE_HOOK(zebra_pbr_ipset_update, + (int cmd, struct zebra_pbr_ipset *ipset), (cmd, ipset)); #endif /* _ZEBRA_PBR_H */ diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index db610098f0..89cbdaf373 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -38,6 +38,7 @@ #include "vrf.h" #include "workqueue.h" +#include "zebra/zebra_router.h" #include "zebra/connected.h" #include "zebra/debug.h" #include "zebra/interface.h" @@ -2930,7 +2931,7 @@ void rib_sweep_route(void) rib_sweep_table(zvrf->table[AFI_IP6][SAFI_UNICAST]); } - zebra_ns_sweep_route(); + zebra_router_sweep_route(); } /* Remove specific by protocol routes from 'table'. */ @@ -2972,7 +2973,7 @@ unsigned long rib_score_proto(uint8_t proto, unsigned short instance) proto, instance, zvrf->table[AFI_IP6][SAFI_UNICAST]); - cnt += zebra_ns_score_proto(proto, instance); + cnt += zebra_router_score_proto(proto, instance); return cnt; } diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c index 0a531990dc..df4435b619 100644 --- a/zebra/zebra_rnh.c +++ b/zebra/zebra_rnh.c @@ -36,6 +36,7 @@ #include "nexthop.h" #include "vrf.h" +#include "zebra/zebra_router.h" #include "zebra/rib.h" #include "zebra/rt.h" #include "zebra/zserv.h" @@ -469,12 +470,11 @@ static void zebra_rnh_process_pbr_tables(int family, struct route_node *prn, struct route_entry *re) { - struct zebra_ns_table *znst; + struct zebra_router_table *zrt; struct route_entry *o_re; struct route_node *o_rn; struct listnode *node; struct zserv *client; - struct zebra_ns *zns; afi_t afi = AFI_IP; if (family == AF_INET6) @@ -492,13 +492,12 @@ static void zebra_rnh_process_pbr_tables(int family, if (!client) return; - zns = zebra_ns_lookup(NS_DEFAULT); - RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables) { - if (afi != znst->afi) + RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) { + if (afi != zrt->afi) continue; - for (o_rn = route_top(znst->table); - o_rn; o_rn = srcdest_route_next(o_rn)) { + for (o_rn = route_top(zrt->table); o_rn; + o_rn = srcdest_route_next(o_rn)) { RNODE_FOREACH_RE (o_rn, o_re) { if (o_re->type == ZEBRA_ROUTE_PBR) break; diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c new file mode 100644 index 0000000000..99d96fd67f --- /dev/null +++ b/zebra/zebra_router.c @@ -0,0 +1,189 @@ +/* Zebra Router Code. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#include "zebra.h" + +#include "zebra_router.h" +#include "zebra_memory.h" +#include "zebra_pbr.h" + +struct zebra_router zrouter; + +static inline int +zebra_router_table_entry_compare(const struct zebra_router_table *e1, + const struct zebra_router_table *e2); + +RB_GENERATE(zebra_router_table_head, zebra_router_table, + zebra_router_table_entry, zebra_router_table_entry_compare); + + +static inline int +zebra_router_table_entry_compare(const struct zebra_router_table *e1, + const struct zebra_router_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; + if (e1->afi < e2->afi) + return -1; + if (e1->afi > e2->afi) + return 1; + return (e1->safi - e2->safi); +} + + +struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf, + uint32_t tableid, afi_t afi, + safi_t safi) +{ + struct zebra_router_table finder; + struct zebra_router_table *zrt; + + memset(&finder, 0, sizeof(finder)); + finder.afi = afi; + finder.safi = safi; + finder.tableid = tableid; + finder.ns_id = zvrf->zns->ns_id; + zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder); + + if (zrt) + return zrt->table; + else + return NULL; +} + +struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf, + uint32_t tableid, afi_t afi, + safi_t safi) +{ + struct zebra_router_table finder; + struct zebra_router_table *zrt; + rib_table_info_t *info; + + memset(&finder, 0, sizeof(finder)); + finder.afi = afi; + finder.safi = safi; + finder.tableid = tableid; + finder.ns_id = zvrf->zns->ns_id; + zrt = RB_FIND(zebra_router_table_head, &zrouter.tables, &finder); + + if (zrt) + return zrt->table; + + zrt = XCALLOC(MTYPE_ZEBRA_NS, sizeof(*zrt)); + zrt->tableid = tableid; + zrt->afi = afi; + zrt->ns_id = zvrf->zns->ns_id; + zrt->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(zrt->table, info); + zrt->table->cleanup = zebra_rtable_node_cleanup; + + RB_INSERT(zebra_router_table_head, &zrouter.tables, zrt); + return zrt->table; +} + +unsigned long zebra_router_score_proto(uint8_t proto, unsigned short instance) +{ + struct zebra_router_table *zrt; + unsigned long cnt = 0; + + RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) { + if (zrt->ns_id != NS_DEFAULT) + continue; + cnt += rib_score_proto_table(proto, instance, zrt->table); + } + return cnt; +} + +void zebra_router_sweep_route(void) +{ + struct zebra_router_table *zrt; + + RB_FOREACH (zrt, zebra_router_table_head, &zrouter.tables) { + if (zrt->ns_id != NS_DEFAULT) + continue; + rib_sweep_table(zrt->table); + } +} + +static void zebra_router_free_table(struct zebra_router_table *zrt) +{ + void *table_info; + + rib_close_table(zrt->table); + + table_info = route_table_get_info(zrt->table); + route_table_finish(zrt->table); + XFREE(MTYPE_RIB_TABLE_INFO, table_info); + XFREE(MTYPE_ZEBRA_NS, zrt); +} + +void zebra_router_terminate(void) +{ + struct zebra_router_table *zrt, *tmp; + + RB_FOREACH_SAFE (zrt, zebra_router_table_head, &zrouter.tables, tmp) { + 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); + + hash_clean(zrouter.ipset_entry_hash, zebra_pbr_ipset_entry_free), + hash_clean(zrouter.ipset_hash, zebra_pbr_ipset_free); + hash_free(zrouter.ipset_hash); + hash_free(zrouter.ipset_entry_hash); + hash_clean(zrouter.iptable_hash, zebra_pbr_iptable_free); + hash_free(zrouter.iptable_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"); + + zrouter.ipset_hash = + hash_create_size(8, zebra_pbr_ipset_hash_key, + zebra_pbr_ipset_hash_equal, "IPset Hash"); + + zrouter.ipset_entry_hash = hash_create_size( + 8, zebra_pbr_ipset_entry_hash_key, + zebra_pbr_ipset_entry_hash_equal, "IPset Hash Entry"); + + zrouter.iptable_hash = hash_create_size(8, zebra_pbr_iptable_hash_key, + zebra_pbr_iptable_hash_equal, + "IPtable Hash Entry"); +} diff --git a/zebra/zebra_router.h b/zebra/zebra_router.h new file mode 100644 index 0000000000..d6b8b66087 --- /dev/null +++ b/zebra/zebra_router.h @@ -0,0 +1,84 @@ +/* Zebra Router header. + * Copyright (C) 2018 Cumulus Networks, Inc. + * Donald Sharp + * + * This file is part of FRR. + * + * FRR is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * FRR is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with FRR; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ +#ifndef __ZEBRA_ROUTER_H__ +#define __ZEBRA_ROUTER_H__ + +#include "zebra/zebra_ns.h" + +/* + * This header file contains the idea of a router and as such + * owns data that is associated with a router from zebra's + * perspective. + */ + +struct zebra_router_table { + RB_ENTRY(zebra_router_table) zebra_router_table_entry; + + uint32_t tableid; + afi_t afi; + safi_t safi; + ns_id_t ns_id; + + struct route_table *table; +}; +RB_HEAD(zebra_router_table_head, zebra_router_table); +RB_PROTOTYPE(zebra_router_table_head, zebra_router_table, + zebra_router_table_entry, zebra_router_table_entry_compare) + +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; + + struct hash *ipset_hash; + + struct hash *ipset_entry_hash; + + struct hash *iptable_hash; + +#if defined(HAVE_RTADV) + struct rtadv rtadv; +#endif /* HAVE_RTADV */ +}; + +extern struct zebra_router zrouter; + +extern void zebra_router_init(void); +extern void zebra_router_terminate(void); + +extern struct route_table *zebra_router_find_table(struct zebra_vrf *zvrf, + uint32_t tableid, afi_t afi, + safi_t safi); +extern struct route_table *zebra_router_get_table(struct zebra_vrf *zvrf, + uint32_t tableid, afi_t afi, + safi_t safi); + +extern int zebra_router_config_write(struct vty *vty); + +extern unsigned long zebra_router_score_proto(uint8_t proto, + unsigned short instance); +extern void zebra_router_sweep_route(void); +#endif diff --git a/zebra/zebra_vrf.c b/zebra/zebra_vrf.c index a1692d3c3e..e98a533609 100644 --- a/zebra/zebra_vrf.c +++ b/zebra/zebra_vrf.c @@ -28,6 +28,7 @@ #include "vrf.h" #include "vty.h" +#include "zebra/zebra_router.h" #include "zebra/debug.h" #include "zebra/zapi_msg.h" #include "zebra/rib.h" @@ -144,7 +145,6 @@ static int zebra_vrf_enable(struct vrf *vrf) static int zebra_vrf_disable(struct vrf *vrf) { struct zebra_vrf *zvrf = vrf->info; - struct route_table *table; struct interface *ifp; afi_t afi; safi_t safi; @@ -202,15 +202,16 @@ static int zebra_vrf_disable(struct vrf *vrf) /* Cleanup (free) routing tables and NHT tables. */ for (afi = AFI_IP; afi <= AFI_IP6; afi++) { - void *table_info; - - for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) { - table = zvrf->table[afi][safi]; - table_info = route_table_get_info(table); - route_table_finish(table); - XFREE(MTYPE_RIB_TABLE_INFO, table_info); + /* + * Set the table pointer to NULL as that + * we no-longer need a copy of it, nor do we + * own this data, the zebra_router structure + * owns these tables. Once we've cleaned up the + * table, see rib_close_table above + * we no-longer need this pointer. + */ + for (safi = SAFI_UNICAST; safi <= SAFI_MULTICAST; safi++) zvrf->table[afi][safi] = NULL; - } route_table_finish(zvrf->rnh_table[afi]); zvrf->rnh_table[afi] = NULL; @@ -374,10 +375,8 @@ static void zebra_vrf_table_create(struct zebra_vrf *zvrf, afi_t afi, assert(!zvrf->table[afi][safi]); - if (afi == AFI_IP6) - table = srcdest_table_init(); - else - table = route_table_init(); + table = zebra_router_get_table(zvrf, zvrf->table_id, afi, safi); + table->cleanup = zebra_rtable_node_cleanup; zvrf->table[afi][safi] = table; @@ -442,14 +441,11 @@ struct route_table *zebra_vrf_other_route_table(afi_t afi, uint32_t table_id, vrf_id_t vrf_id) { struct zebra_vrf *zvrf; - struct zebra_ns *zns; zvrf = vrf_info_lookup(vrf_id); if (!zvrf) return NULL; - zns = zvrf->zns; - if (afi >= AFI_MAX) return NULL; @@ -461,7 +457,8 @@ struct route_table *zebra_vrf_other_route_table(afi_t afi, uint32_t table_id, * so in all cases, it does not use specific table * so it is possible to configure tables in this VRF */ - return zebra_ns_get_table(zns, zvrf, table_id, afi); + return zebra_router_get_table(zvrf, table_id, afi, + SAFI_UNICAST); } } diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index cf704f24be..dd0e270149 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -35,6 +35,7 @@ #include "srcdest_table.h" #include "vxlan.h" +#include "zebra/zebra_router.h" #include "zebra/zserv.h" #include "zebra/zebra_vrf.h" #include "zebra/zebra_mpls.h" @@ -896,7 +897,7 @@ DEFPY (show_route_table, struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); struct route_table *t; - t = zebra_ns_find_table(zvrf->zns, table, afi); + t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST); if (t) do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false, 0, 0, !!json); @@ -925,7 +926,7 @@ DEFPY (show_route_table_vrf, VRF_GET_ID(vrf_id, vrf_name, !!json); zvrf = zebra_vrf_lookup_by_id(vrf_id); - t = zebra_ns_find_table(zvrf->zns, table, afi); + t = zebra_router_find_table(zvrf, table, afi, SAFI_UNICAST); if (t) do_show_route_helper(vty, zvrf, t, afi, false, 0, false, false, 0, 0, !!json); diff --git a/zebra/zebra_vxlan.c b/zebra/zebra_vxlan.c index 974b4d5bef..58cf6eb30f 100644 --- a/zebra/zebra_vxlan.c +++ b/zebra/zebra_vxlan.c @@ -37,6 +37,7 @@ #include #endif +#include "zebra/zebra_router.h" #include "zebra/debug.h" #include "zebra/interface.h" #include "zebra/rib.h" @@ -3643,15 +3644,12 @@ static void *zl3vni_alloc(void *p) */ static zebra_l3vni_t *zl3vni_lookup(vni_t vni) { - struct zebra_ns *zns; zebra_l3vni_t tmp_l3vni; zebra_l3vni_t *zl3vni = NULL; - zns = zebra_ns_lookup(NS_DEFAULT); - assert(zns); memset(&tmp_l3vni, 0, sizeof(zebra_l3vni_t)); tmp_l3vni.vni = vni; - zl3vni = hash_lookup(zns->l3vni_table, &tmp_l3vni); + zl3vni = hash_lookup(zrouter.l3vni_table, &tmp_l3vni); return zl3vni; } @@ -3662,16 +3660,12 @@ static zebra_l3vni_t *zl3vni_lookup(vni_t vni) static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id) { zebra_l3vni_t tmp_zl3vni; - struct zebra_ns *zns = NULL; zebra_l3vni_t *zl3vni = NULL; - zns = zebra_ns_lookup(NS_DEFAULT); - assert(zns); - memset(&tmp_zl3vni, 0, sizeof(zebra_l3vni_t)); tmp_zl3vni.vni = vni; - zl3vni = hash_get(zns->l3vni_table, &tmp_zl3vni, zl3vni_alloc); + zl3vni = hash_get(zrouter.l3vni_table, &tmp_zl3vni, zl3vni_alloc); assert(zl3vni); zl3vni->vrf_id = vrf_id; @@ -3696,12 +3690,8 @@ static zebra_l3vni_t *zl3vni_add(vni_t vni, vrf_id_t vrf_id) */ static int zl3vni_del(zebra_l3vni_t *zl3vni) { - struct zebra_ns *zns; zebra_l3vni_t *tmp_zl3vni; - zns = zebra_ns_lookup(NS_DEFAULT); - assert(zns); - /* free the list of l2vnis */ list_delete(&zl3vni->l2vnis); zl3vni->l2vnis = NULL; @@ -3715,7 +3705,7 @@ static int zl3vni_del(zebra_l3vni_t *zl3vni) zl3vni->nh_table = NULL; /* Free the VNI hash entry and allocated memory. */ - tmp_zl3vni = hash_release(zns->l3vni_table, zl3vni); + tmp_zl3vni = hash_release(zrouter.l3vni_table, zl3vni); if (tmp_zl3vni) XFREE(MTYPE_ZL3VNI, tmp_zl3vni); @@ -4634,7 +4624,6 @@ void zebra_vxlan_print_rmacs_l3vni(struct vty *vty, vni_t l3vni, bool use_json) void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json) { - struct zebra_ns *zns = NULL; json_object *json = NULL; void *args[2]; @@ -4644,19 +4633,12 @@ void zebra_vxlan_print_rmacs_all_l3vni(struct vty *vty, bool use_json) return; } - zns = zebra_ns_lookup(NS_DEFAULT); - if (!zns) { - if (use_json) - vty_out(vty, "{}\n"); - return; - } - if (use_json) json = json_object_new_object(); args[0] = vty; args[1] = json; - hash_iterate(zns->l3vni_table, + hash_iterate(zrouter.l3vni_table, (void (*)(struct hash_backet *, void *))zl3vni_print_rmac_hash_all_vni, args); @@ -4759,7 +4741,6 @@ void zebra_vxlan_print_nh_l3vni(struct vty *vty, vni_t l3vni, bool use_json) void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json) { - struct zebra_ns *zns = NULL; json_object *json = NULL; void *args[2]; @@ -4769,16 +4750,12 @@ void zebra_vxlan_print_nh_all_l3vni(struct vty *vty, bool use_json) return; } - zns = zebra_ns_lookup(NS_DEFAULT); - if (!zns) - return; - if (use_json) json = json_object_new_object(); args[0] = vty; args[1] = json; - hash_iterate(zns->l3vni_table, + hash_iterate(zrouter.l3vni_table, (void (*)(struct hash_backet *, void *))zl3vni_print_nh_hash_all_vni, args); @@ -5273,21 +5250,16 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj) int num_l3vnis = 0; int num_vnis = 0; json_object *json = NULL; - struct zebra_ns *zns = NULL; struct zebra_vrf *zvrf = NULL; if (!is_evpn_enabled()) return; - zns = zebra_ns_lookup(NS_DEFAULT); - if (!zns) - return; - zvrf = vrf_info_lookup(VRF_DEFAULT); if (!zvrf) return; - num_l3vnis = hashcount(zns->l3vni_table); + num_l3vnis = hashcount(zrouter.l3vni_table); num_l2vnis = hashcount(zvrf->vni_table); num_vnis = num_l2vnis + num_l3vnis; @@ -5319,17 +5291,11 @@ void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf, bool use_json) { json_object *json = NULL; - struct zebra_ns *zns = NULL; void *args[2]; if (!is_evpn_enabled()) return; - zns = zebra_ns_lookup(NS_DEFAULT); - if (!zns) - return; - - if (use_json) json = json_object_new_object(); else @@ -5346,7 +5312,7 @@ void zebra_vxlan_print_vnis(struct vty *vty, struct zebra_vrf *zvrf, args); /* Display all L3-VNIs */ - hash_iterate(zns->l3vni_table, + hash_iterate(zrouter.l3vni_table, (void (*)(struct hash_backet *, void *))zl3vni_print_hash, args); @@ -7160,7 +7126,6 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) { struct stream *s = NULL; int advertise = 0; - struct zebra_ns *zns = NULL; enum vxlan_flood_control flood_ctrl; if (zvrf_id(zvrf) != VRF_DEFAULT) { @@ -7206,11 +7171,7 @@ void zebra_vxlan_advertise_all_vni(ZAPI_HANDLER_ARGS) hash_iterate(zvrf->vni_table, zvni_cleanup_all, zvrf); /* cleanup all l3vnis */ - zns = zebra_ns_lookup(NS_DEFAULT); - if (!zns) - return; - - hash_iterate(zns->l3vni_table, zl3vni_cleanup_all, NULL); + hash_iterate(zrouter.l3vni_table, zl3vni_cleanup_all, NULL); } stream_failure: @@ -7249,14 +7210,14 @@ void zebra_vxlan_close_tables(struct zebra_vrf *zvrf) /* init the l3vni table */ void zebra_vxlan_ns_init(struct zebra_ns *zns) { - zns->l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp, - "Zebra VRF L3 VNI table"); + zrouter.l3vni_table = hash_create(l3vni_hash_keymake, l3vni_hash_cmp, + "Zebra VRF L3 VNI table"); } /* free l3vni table */ void zebra_vxlan_ns_disable(struct zebra_ns *zns) { - hash_free(zns->l3vni_table); + hash_free(zrouter.l3vni_table); } /* get the l3vni svi ifindex */