#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"
work_queue_free_and_null(&zebrad.ribq);
meta_queue_free(zebrad.mq);
+ zebra_router_terminate();
+
frr_fini();
exit(0);
}
zebrad.master = frr_init();
/* Zebra related initialize. */
+ zebra_router_init();
zserv_init();
rib_init();
zebra_if_init();
/* RNH init */
zebra_rnh_init();
-
+
/* Error init */
zebra_error_init();
#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;
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 {
"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) {
zif->rtadv
.MaxRtrAdvInterval;
rtadv_send_packet(
- zns->rtadv.sock, ifp);
+ zrouter.rtadv.sock,
+ ifp);
}
}
}
struct zebra_ns *zns = zvrf->zns;
assert(zns);
- rtadv_send_packet(zns->rtadv.sock, ifp);
+ rtadv_send_packet(zrouter.rtadv.sock, ifp);
}
/*
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);
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
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);
}
}
}
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)) {
}
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;
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)) {
}
if (zif->rtadv.MaxRtrAdvInterval % 1000)
- zns->rtadv.adv_msec_if_count--;
+ zrouter.rtadv.adv_msec_if_count--;
/* convert to milliseconds */
interval = interval * 1000;
{
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);
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:
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)
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 \
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 \
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:
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:
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:
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;
}
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)
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
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)
zebra_ns_notify_parse();
zebra_ns_notify_init();
}
+
return 0;
}
};
#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];
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;
};
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
#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"
};
/* 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_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_wrap_script_update, (struct zebra_ns *zns,
- int cmd,
- struct zebra_pbr_iptable *iptable),
- (zns, 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_wrap_script_update, (struct zebra_ns *zns,
- int cmd,
- struct zebra_pbr_ipset *ipset),
- (zns, cmd, ipset));
+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_get_stat,
+ (struct zebra_pbr_iptable *iptable, uint64_t *pkts,
+ uint64_t *bytes),
+ (iptable, pkts, bytes))
+
+DEFINE_HOOK(zebra_pbr_iptable_update,
+ (int cmd, struct zebra_pbr_iptable *iptable), (cmd, iptable));
+
+DEFINE_HOOK(zebra_pbr_ipset_entry_update,
+ (int cmd, struct zebra_pbr_ipset_entry *ipset), (cmd, ipset));
+
+DEFINE_HOOK(zebra_pbr_ipset_update,
+ (int cmd, struct zebra_pbr_ipset *ipset), (cmd, ipset));
/* Private functions */
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),
if (r1->ifp != r2->ifp)
return false;
+ if (r1->vrf_id != r2->vrf_id)
+ return false;
+
return true;
}
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)
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;
}
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;
}
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);
}
{
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)
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;
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);
}
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)) {
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);
}
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)
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",
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;
}
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(
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;
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;
}
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",
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);
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)
}
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);
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;
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;
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);
}
" 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);
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;
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,
struct pbr_rule rule;
struct interface *ifp;
+
+ vrf_id_t vrf_id;
};
#define IS_RULE_FILTERING_ON_SRC_IP(r) \
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_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_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_pbr_iptable *iptable);
+void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable);
/*
* Install specified rule for a specific interface.
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_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_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_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 */
#include "vrf.h"
#include "workqueue.h"
+#include "zebra/zebra_router.h"
#include "zebra/connected.h"
#include "zebra/debug.h"
#include "zebra/interface.h"
rib_sweep_table(zvrf->table[AFI_IP6][SAFI_UNICAST]);
}
- zebra_ns_sweep_route();
+ zebra_router_sweep_route();
}
/* Remove specific by protocol routes from 'table'. */
proto, instance,
zvrf->table[AFI_IP6][SAFI_UNICAST]);
- cnt += zebra_ns_score_proto(proto, instance);
+ cnt += zebra_router_score_proto(proto, instance);
return cnt;
}
#include "nexthop.h"
#include "vrf.h"
+#include "zebra/zebra_router.h"
#include "zebra/rib.h"
#include "zebra/rt.h"
#include "zebra/zserv.h"
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)
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;
--- /dev/null
+/* 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");
+}
--- /dev/null
+/* 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
#include "vrf.h"
#include "vty.h"
+#include "zebra/zebra_router.h"
#include "zebra/debug.h"
#include "zebra/zapi_msg.h"
#include "zebra/rib.h"
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;
/* 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;
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;
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;
* 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);
}
}
#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"
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);
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);
#include <linux/neighbour.h>
#endif
+#include "zebra/zebra_router.h"
#include "zebra/debug.h"
#include "zebra/interface.h"
#include "zebra/rib.h"
*/
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;
}
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;
*/
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;
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);
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];
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);
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];
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);
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;
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
args);
/* Display all L3-VNIs */
- hash_iterate(zns->l3vni_table,
+ hash_iterate(zrouter.l3vni_table,
(void (*)(struct hash_backet *, void *))zl3vni_print_hash,
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) {
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:
/* 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 */