mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 12:37:10 +00:00
commit
00b7a9ddfe
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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 \
|
||||
|
@ -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;
|
||||
}
|
||||
|
152
zebra/zebra_ns.c
152
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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <memory.h>
|
||||
#include <hook.h>
|
||||
|
||||
#include "zebra/zebra_router.h"
|
||||
#include "zebra/zebra_pbr.h"
|
||||
#include "zebra/rt.h"
|
||||
#include "zebra/zapi_msg.h"
|
||||
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
189
zebra/zebra_router.c
Normal file
189
zebra/zebra_router.c
Normal file
@ -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");
|
||||
}
|
84
zebra/zebra_router.h
Normal file
84
zebra/zebra_router.h
Normal file
@ -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
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <linux/neighbour.h>
|
||||
#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 */
|
||||
|
Loading…
Reference in New Issue
Block a user