struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
babel_interface_nfo *babel_ifp = ifp ? babel_get_if_nfo(ifp) : NULL;
struct prefix p;
- struct distribute *dist;
+ struct distribute *dist = NULL;
struct access_list *alist;
struct prefix_list *plist;
int distribute;
+ struct babel *babel;
p.family = v4mapped(prefix) ? AF_INET : AF_INET6;
p.prefixlen = v4mapped(prefix) ? plen - 96 : plen;
}
/* All interface filter check. */
- dist = distribute_lookup (NULL);
+ babel = babel_lookup();
+ if (babel)
+ dist = distribute_lookup (babel->distribute_ctx, NULL);
if (dist) {
if (dist->list[distribute]) {
alist = access_list_lookup (p.family, dist->list[distribute]);
"Babel information\n"
"Configuration information\n")
{
+ struct babel *babel_ctx;
+
vty_out (vty, " -- Babel running configuration --\n");
show_babel_main_configuration(vty);
- vty_out (vty, " -- distribution lists --\n");
- config_show_distribute(vty);
+ babel_ctx = babel_lookup();
+ if (babel_ctx) {
+ vty_out (vty, " -- distribution lists --\n");
+ config_show_distribute(vty, babel_ctx->distribute_ctx);
+ }
return CMD_SUCCESS;
}
static int babel_main_loop(struct thread *thread);
static void babel_set_timer(struct timeval *timeout);
static void babel_fill_with_next_timeout(struct timeval *tv);
-
+static void
+babel_distribute_update (struct distribute_ctx *ctx, struct distribute *dist);
/* Informations relative to the babel running daemon. */
static struct babel *babel_routing_process = NULL;
}
}
- lines += config_write_distribute (vty);
+ lines += config_write_distribute (vty, babel_routing_process->distribute_ctx);
return lines;
}
thread_add_read(master, &babel_read_protocol, NULL, protocol_socket, &babel_routing_process->t_read);
/* wait a little: zebra will announce interfaces, addresses, routes... */
thread_add_timer_msec(master, babel_init_routing_process, NULL, 200L, &babel_routing_process->t_update);
- return 0;
+ /* Distribute list install. */
+ babel_routing_process->distribute_ctx = distribute_list_ctx_create (vrf_lookup_by_id(VRF_DEFAULT));
+ distribute_list_add_hook (babel_routing_process->distribute_ctx, babel_distribute_update);
+ distribute_list_delete_hook (babel_routing_process->distribute_ctx, babel_distribute_update);
+ return 0;
fail:
XFREE(MTYPE_BABEL, babel_routing_process);
babel_routing_process = NULL;
thread_cancel(babel_routing_process->t_update);
}
+ distribute_list_delete(&babel_routing_process->distribute_ctx);
XFREE(MTYPE_BABEL, babel_routing_process);
babel_routing_process = NULL;
}
}
static void
-babel_distribute_update (struct distribute *dist)
+babel_distribute_update (struct distribute_ctx *ctx, struct distribute *dist)
{
struct interface *ifp;
babel_interface_nfo *babel_ifp;
static void
babel_distribute_update_interface (struct interface *ifp)
{
- struct distribute *dist;
+ struct distribute *dist = NULL;
- dist = distribute_lookup (ifp->name);
+ if (babel_routing_process)
+ dist = distribute_lookup(babel_routing_process->distribute_ctx, ifp->name);
if (dist)
- babel_distribute_update (dist);
+ babel_distribute_update (babel_routing_process->distribute_ctx, dist);
}
/* Update all interface's distribute list. */
prefix_list_delete_hook (babel_distribute_update_all);
/* Distribute list install. */
- distribute_list_init (BABEL_NODE);
- distribute_list_add_hook (babel_distribute_update);
- distribute_list_delete_hook (babel_distribute_update);
+ distribute_list_init(BABEL_NODE);
}
/* Stubs to adapt Babel's filtering calls to Quagga's infrastructure. */
return 0;
}
+struct babel *babel_lookup(void)
+{
+ return babel_routing_process;
+}
/* Babel threads. */
struct thread *t_read; /* on Babel protocol's socket */
struct thread *t_update; /* timers */
+ /* distribute_ctx */
+ struct distribute_ctx *distribute_ctx;
};
extern struct zebra_privs_t babeld_privs;
unsigned int ifindex, int proto);
extern int resize_receive_buffer(int size);
extern void schedule_neighbours_check(int msecs, int override);
-
+extern struct babel *babel_lookup(void);
#endif /* BABEL_BABELD_H */
/*
* Distribute-list update functions.
*/
-void eigrp_distribute_update(struct distribute *dist)
+void eigrp_distribute_update(struct distribute_ctx *ctx,
+ struct distribute *dist)
{
struct interface *ifp;
struct eigrp_interface *ei = NULL;
void eigrp_distribute_update_interface(struct interface *ifp)
{
struct distribute *dist;
+ struct eigrp *eigrp;
- dist = distribute_lookup(ifp->name);
+ eigrp = eigrp_lookup();
+ if (!eigrp)
+ return;
+ dist = distribute_lookup(eigrp->distribute_ctx, ifp->name);
if (dist)
- eigrp_distribute_update(dist);
+ eigrp_distribute_update(eigrp->distribute_ctx,
+ dist);
}
/* Update all interface's distribute list.
#ifndef EIGRPD_EIGRP_FILTER_H_
#define EIGRPD_EIGRP_FILTER_H_
-extern void eigrp_distribute_update(struct distribute *);
+extern void eigrp_distribute_update(struct distribute_ctx *ctx,
+ struct distribute *dist);
extern void eigrp_distribute_update_interface(struct interface *);
extern void eigrp_distribute_update_all(struct prefix_list *);
extern void eigrp_distribute_update_all_wrapper(struct access_list *);
/* Distribute list install. */
distribute_list_init(EIGRP_NODE);
- distribute_list_add_hook(eigrp_distribute_update);
- distribute_list_delete_hook(eigrp_distribute_update);
frr_config_fork();
frr_run(master);
uint32_t metric;
} route_map[ZEBRA_ROUTE_MAX];
+ /* distribute_ctx */
+ struct distribute_ctx *distribute_ctx;
+
QOBJ_FIELDS
};
DECLARE_QOBJ_TYPE(eigrp)
int write = 0;
/* Distribute configuration. */
- write += config_write_distribute(vty);
+ write += config_write_distribute(vty, eigrp->distribute_ctx);
return write;
}
#include "keychain.h"
#include "libfrr.h"
#include "lib_errors.h"
+#include "distribute.h"
#include "eigrpd/eigrp_structs.h"
#include "eigrpd/eigrpd.h"
#include "eigrpd/eigrp_network.h"
#include "eigrpd/eigrp_topology.h"
#include "eigrpd/eigrp_memory.h"
+#include "eigrpd/eigrp_filter.h"
DEFINE_QOBJ_TYPE(eigrp)
eigrp->routemap[EIGRP_FILTER_IN] = NULL;
eigrp->routemap[EIGRP_FILTER_OUT] = NULL;
+ /* Distribute list install. */
+ eigrp->distribute_ctx = distribute_list_ctx_create(
+ vrf_lookup_by_id(VRF_DEFAULT));
+ distribute_list_add_hook(eigrp->distribute_ctx,
+ eigrp_distribute_update);
+ distribute_list_delete_hook(eigrp->distribute_ctx,
+ eigrp_distribute_update);
QOBJ_REG(eigrp, eigrp);
return eigrp;
}
listnode_delete(eigrp_om->eigrp, eigrp);
stream_free(eigrp->ibuf);
+ distribute_list_delete(&eigrp->distribute_ctx);
XFREE(MTYPE_EIGRP_TOP, eigrp);
}
#include "distribute.h"
#include "memory.h"
+DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_CTX, "Distribute ctx")
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list")
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname")
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name")
-/* Hash of distribute list. */
-struct hash *disthash;
-
-/* Hook functions. */
-void (*distribute_add_hook)(struct distribute *);
-void (*distribute_delete_hook)(struct distribute *);
+struct list *dist_ctx_list;
static struct distribute *distribute_new(void)
{
XFREE(MTYPE_DISTRIBUTE, dist);
}
-static void distribute_free_if_empty(struct distribute *dist)
+static void distribute_free_if_empty(struct distribute_ctx *ctx,
+ struct distribute *dist)
{
int i;
if (dist->list[i] != NULL || dist->prefix[i] != NULL)
return;
- hash_release(disthash, dist);
+ hash_release(ctx->disthash, dist);
distribute_free(dist);
}
/* Lookup interface's distribute list. */
-struct distribute *distribute_lookup(const char *ifname)
+struct distribute *distribute_lookup(struct distribute_ctx *ctx,
+ const char *ifname)
{
struct distribute key;
struct distribute *dist;
/* temporary reference */
key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
- dist = hash_lookup(disthash, &key);
+ dist = hash_lookup(ctx->disthash, &key);
if (key.ifname)
XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
return dist;
}
-void distribute_list_add_hook(void (*func)(struct distribute *))
+void distribute_list_add_hook(struct distribute_ctx *ctx,
+ void (*func)(struct distribute_ctx *ctx,
+ struct distribute *))
{
- distribute_add_hook = func;
+ ctx->distribute_add_hook = func;
}
-void distribute_list_delete_hook(void (*func)(struct distribute *))
+void distribute_list_delete_hook(struct distribute_ctx *ctx,
+ void (*func)(struct distribute_ctx *ctx,
+ struct distribute *))
{
- distribute_delete_hook = func;
+ ctx->distribute_delete_hook = func;
}
static void *distribute_hash_alloc(struct distribute *arg)
}
/* Make new distribute list and push into hash. */
-static struct distribute *distribute_get(const char *ifname)
+static struct distribute *distribute_get(struct distribute_ctx *ctx,
+ const char *ifname)
{
struct distribute key;
struct distribute *ret;
/* temporary reference */
key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
- ret = hash_get(disthash, &key,
+ ret = hash_get(ctx->disthash, &key,
(void *(*)(void *))distribute_hash_alloc);
if (key.ifname)
}
/* Set access-list name to the distribute list. */
-static void distribute_list_set(const char *ifname, enum distribute_type type,
+static void distribute_list_set(struct distribute_ctx *ctx,
+ const char *ifname, enum distribute_type type,
const char *alist_name)
{
struct distribute *dist;
- dist = distribute_get(ifname);
+ dist = distribute_get(ctx, ifname);
if (dist->list[type])
XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]);
dist->list[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, alist_name);
/* Apply this distribute-list to the interface. */
- (*distribute_add_hook)(dist);
+ (ctx->distribute_add_hook)(ctx, dist);
}
/* Unset distribute-list. If matched distribute-list exist then
return 1. */
-static int distribute_list_unset(const char *ifname, enum distribute_type type,
+static int distribute_list_unset(struct distribute_ctx *ctx,
+ const char *ifname,
+ enum distribute_type type,
const char *alist_name)
{
struct distribute *dist;
- dist = distribute_lookup(ifname);
+ dist = distribute_lookup(ctx, ifname);
if (!dist)
return 0;
dist->list[type] = NULL;
/* Apply this distribute-list to the interface. */
- (*distribute_delete_hook)(dist);
+ (ctx->distribute_delete_hook)(ctx, dist);
/* If all dist are NULL, then free distribute list. */
- distribute_free_if_empty(dist);
+ distribute_free_if_empty(ctx, dist);
return 1;
}
/* Set access-list name to the distribute list. */
-static void distribute_list_prefix_set(const char *ifname,
+static void distribute_list_prefix_set(struct distribute_ctx *ctx,
+ const char *ifname,
enum distribute_type type,
const char *plist_name)
{
struct distribute *dist;
- dist = distribute_get(ifname);
+ dist = distribute_get(ctx, ifname);
if (dist->prefix[type])
XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]);
dist->prefix[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, plist_name);
/* Apply this distribute-list to the interface. */
- (*distribute_add_hook)(dist);
+ (ctx->distribute_add_hook)(ctx, dist);
}
/* Unset distribute-list. If matched distribute-list exist then
return 1. */
-static int distribute_list_prefix_unset(const char *ifname,
+static int distribute_list_prefix_unset(struct distribute_ctx *ctx,
+ const char *ifname,
enum distribute_type type,
const char *plist_name)
{
struct distribute *dist;
- dist = distribute_lookup(ifname);
+ dist = distribute_lookup(ctx, ifname);
if (!dist)
return 0;
dist->prefix[type] = NULL;
/* Apply this distribute-list to the interface. */
- (*distribute_delete_hook)(dist);
+ (ctx->distribute_delete_hook)(ctx, dist);
/* If all dist are NULL, then free distribute list. */
- distribute_free_if_empty(dist);
+ distribute_free_if_empty(ctx, dist);
return 1;
}
"Interface name\n")
{
int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
-
/* Check of distribute list type. */
enum distribute_type type = argv[2 + prefix]->arg[0] == 'i'
? DISTRIBUTE_V4_IN
: DISTRIBUTE_V4_OUT;
/* Set appropriate function call */
- void (*distfn)(const char *, enum distribute_type, const char *) =
+ void (*distfn)(struct distribute_ctx *, const char *,
+ enum distribute_type, const char *) =
prefix ? &distribute_list_prefix_set : &distribute_list_set;
+ struct distribute_ctx *ctx =
+ (struct distribute_ctx *)listnode_head(dist_ctx_list);
/* if interface is present, get name */
const char *ifname = NULL;
ifname = argv[argc - 1]->arg;
/* Get interface name corresponding distribute list. */
- distfn(ifname, type, argv[1 + prefix]->arg);
+ distfn(ctx, ifname, type, argv[1 + prefix]->arg);
return CMD_SUCCESS;
}
"Interface name\n")
{
int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
-
/* Check of distribute list type. */
enum distribute_type type = argv[3 + prefix]->arg[0] == 'i'
? DISTRIBUTE_V6_IN
: DISTRIBUTE_V6_OUT;
/* Set appropriate function call */
- void (*distfn)(const char *, enum distribute_type, const char *) =
+ void (*distfn)(struct distribute_ctx *, const char *,
+ enum distribute_type, const char *) =
prefix ? &distribute_list_prefix_set : &distribute_list_set;
+ struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
/* if interface is present, get name */
const char *ifname = NULL;
ifname = argv[argc - 1]->arg;
/* Get interface name corresponding distribute list. */
- distfn(ifname, type, argv[2 + prefix]->arg);
+ distfn(ctx, ifname, type, argv[2 + prefix]->arg);
return CMD_SUCCESS;
}
"Interface name\n")
{
int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
-
int idx_alname = 2 + prefix;
int idx_disttype = idx_alname + 1;
enum distribute_type type =
DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT;
/* Set appropriate function call */
- int (*distfn)(const char *, enum distribute_type,
- const char *) =
+ int (*distfn)(struct distribute_ctx *, const char *,
+ enum distribute_type, const char *) =
prefix ? &distribute_list_prefix_unset : &distribute_list_unset;
+ struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
/* if interface is present, get name */
const char *ifname = NULL;
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
/* Get interface name corresponding distribute list. */
- int ret = distfn(ifname, type, argv[2 + prefix]->arg);
+ int ret = distfn(ctx, ifname, type, argv[2 + prefix]->arg);
if (!ret) {
vty_out(vty, "distribute list doesn't exist\n");
"Interface name\n")
{
int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
-
int idx_alname = 3 + prefix;
int idx_disttype = idx_alname + 1;
enum distribute_type type =
argv[idx_disttype]->arg[0] == 'i' ?
DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT;
+ struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
/* Set appropriate function call */
- int (*distfn)(const char *, enum distribute_type, const char *) =
+ int (*distfn)(struct distribute_ctx *, const char *,
+ enum distribute_type, const char *) =
prefix ? &distribute_list_prefix_unset : &distribute_list_unset;
/* if interface is present, get name */
if (argv[argc - 1]->type == VARIABLE_TKN)
ifname = argv[argc - 1]->arg;
/* Get interface name corresponding distribute list. */
- int ret = distfn(ifname, type, argv[3 + prefix]->arg);
+ int ret = distfn(ctx, ifname, type, argv[3 + prefix]->arg);
if (!ret) {
vty_out(vty, "distribute list doesn't exist\n");
return has_print;
}
-int config_show_distribute(struct vty *vty)
+int config_show_distribute(struct vty *vty, struct distribute_ctx *dist_ctxt)
{
unsigned int i;
int has_print = 0;
struct distribute *dist;
/* Output filter configuration. */
- dist = distribute_lookup(NULL);
+ dist = distribute_lookup(dist_ctxt, NULL);
vty_out(vty, " Outgoing update filter list for all interface is");
has_print = 0;
if (dist) {
else
vty_out(vty, " not set\n");
- for (i = 0; i < disthash->size; i++)
- for (mp = disthash->index[i]; mp; mp = mp->next) {
+ for (i = 0; i < dist_ctxt->disthash->size; i++)
+ for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) {
dist = mp->data;
if (dist->ifname) {
vty_out(vty, " %s filtered by",
/* Input filter configuration. */
- dist = distribute_lookup(NULL);
+ dist = distribute_lookup(dist_ctxt, NULL);
vty_out(vty, " Incoming update filter list for all interface is");
has_print = 0;
if (dist) {
else
vty_out(vty, " not set\n");
- for (i = 0; i < disthash->size; i++)
- for (mp = disthash->index[i]; mp; mp = mp->next) {
+ for (i = 0; i < dist_ctxt->disthash->size; i++)
+ for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) {
dist = mp->data;
if (dist->ifname) {
vty_out(vty, " %s filtered by",
}
/* Configuration write function. */
-int config_write_distribute(struct vty *vty)
+int config_write_distribute(struct vty *vty,
+ struct distribute_ctx *dist_ctxt)
{
unsigned int i;
int j;
struct hash_backet *mp;
int write = 0;
- for (i = 0; i < disthash->size; i++)
- for (mp = disthash->index[i]; mp; mp = mp->next) {
+ for (i = 0; i < dist_ctxt->disthash->size; i++)
+ for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) {
struct distribute *dist;
dist = mp->data;
return write;
}
-/* Clear all distribute list. */
-void distribute_list_reset()
+void distribute_list_delete(struct distribute_ctx **ctx)
{
- hash_clean(disthash, (void (*)(void *))distribute_free);
+ if ((*ctx)->disthash) {
+ hash_clean((*ctx)->disthash, (void (*)(void *))distribute_free);
+ }
+ if (!dist_ctx_list)
+ dist_ctx_list = list_new();
+ listnode_delete(dist_ctx_list, *ctx);
+ if (list_isempty(dist_ctx_list))
+ list_delete(&dist_ctx_list);
+ XFREE(MTYPE_DISTRIBUTE_CTX, (*ctx));
}
-/* Initialize distribute list related hash. */
-void distribute_list_init(int node)
+/* Initialize distribute list container */
+struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf)
{
- disthash = hash_create(
+ struct distribute_ctx *ctx;
+
+ ctx = XCALLOC(MTYPE_DISTRIBUTE_CTX, sizeof(struct distribute_ctx));
+ ctx->vrf = vrf;
+ ctx->disthash = hash_create(
distribute_hash_make,
(bool (*)(const void *, const void *))distribute_cmp, NULL);
+ if (!dist_ctx_list)
+ dist_ctx_list = list_new();
+ listnode_add(dist_ctx_list, ctx);
+ return ctx;
+}
+/* Initialize distribute list vty commands */
+void distribute_list_init(int node)
+{
/* vtysh command-extraction doesn't grok install_element(node, ) */
if (node == RIP_NODE) {
install_element(RIP_NODE, &distribute_list_cmd);
} else if (node == RIPNG_NODE) {
install_element(RIPNG_NODE, &distribute_list_cmd);
install_element(RIPNG_NODE, &no_distribute_list_cmd);
- }
-
- /* install v6 */
- if (node == RIPNG_NODE) {
+ /* install v6 */
install_element(RIPNG_NODE, &ipv6_distribute_list_cmd);
install_element(RIPNG_NODE, &no_ipv6_distribute_list_cmd);
}
char *prefix[DISTRIBUTE_MAX];
};
+struct distribute_ctx {
+ /* Hash of distribute list. */
+ struct hash *disthash;
+
+ /* Hook functions. */
+ void (*distribute_add_hook)(struct distribute_ctx *ctx,
+ struct distribute *dist);
+ void (*distribute_delete_hook)(struct distribute_ctx *ctx,
+ struct distribute *dist);
+
+ /* vrf information */
+ struct vrf *vrf;
+};
+
/* Prototypes for distribute-list. */
-extern void distribute_list_init(int);
-extern void distribute_list_reset(void);
-extern void distribute_list_add_hook(void (*)(struct distribute *));
-extern void distribute_list_delete_hook(void (*)(struct distribute *));
-extern struct distribute *distribute_lookup(const char *);
-extern int config_write_distribute(struct vty *);
-extern int config_show_distribute(struct vty *);
+extern void distribute_list_init(int node);
+extern struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf);
+extern void distribute_list_delete(struct distribute_ctx **ctx);
+extern void distribute_list_add_hook(struct distribute_ctx *ctx,
+ void (*)(struct distribute_ctx *ctx,
+ struct distribute *));
+extern void distribute_list_delete_hook(struct distribute_ctx *ctx,
+ void (*)(struct distribute_ctx *ctx,
+ struct distribute *));
+extern struct distribute *distribute_lookup(struct distribute_ctx *ctx,
+ const char *ifname);
+extern int config_write_distribute(struct vty *vty,
+ struct distribute_ctx *ctx);
+extern int config_show_distribute(struct vty *vty,
+ struct distribute_ctx *ctx);
extern enum filter_type distribute_apply_in(struct interface *,
struct prefix *);
static int rip_triggered_update(struct thread *);
static int rip_update_jitter(unsigned long);
+static void rip_distribute_update(struct distribute_ctx *ctx,
+ struct distribute *dist);
+
/* RIP output routes type. */
enum { rip_all_route, rip_changed_route };
}
/* All interface filter check. */
- dist = distribute_lookup(NULL);
+ dist = distribute_lookup(rip->distribute_ctx, NULL);
if (dist) {
if (dist->list[distribute]) {
alist = access_list_lookup(AFI_IP,
/* Create read and timer thread. */
rip_event(RIP_READ, rip->sock);
rip_event(RIP_UPDATE_EVENT, 1);
-
+ /* Distribute list install. */
+ rip->distribute_ctx = distribute_list_ctx_create(
+ vrf_lookup_by_id(VRF_DEFAULT));
+ distribute_list_add_hook(rip->distribute_ctx,
+ rip_distribute_update);
+ distribute_list_delete_hook(rip->distribute_ctx,
+ rip_distribute_update);
return 0;
}
vty_out(vty, " garbage collect after %u seconds\n", rip->garbage_time);
/* Filtering status show. */
- config_show_distribute(vty);
+ config_show_distribute(vty, rip->distribute_ctx);
/* Default metric information. */
vty_out(vty, " Default redistribution metric is %u\n",
nb_cli_show_dnode_cmds(vty, dnode, false);
/* Distribute configuration. */
- write += config_write_distribute(vty);
+ write += config_write_distribute(vty,
+ rip->distribute_ctx);
/* Interface routemap configuration */
write += config_write_if_rmap(vty);
static struct cmd_node rip_node = {RIP_NODE, "%s(config-router)# ", 1};
/* Distribute-list update functions. */
-static void rip_distribute_update(struct distribute *dist)
+static void rip_distribute_update(struct distribute_ctx *ctx,
+ struct distribute *dist)
{
struct interface *ifp;
struct rip_interface *ri;
{
struct distribute *dist;
- dist = distribute_lookup(ifp->name);
+ if (!rip)
+ return;
+ dist = distribute_lookup(rip->distribute_ctx, ifp->name);
if (dist)
- rip_distribute_update(dist);
+ rip_distribute_update(rip->distribute_ctx, dist);
}
/* Update all interface's distribute list. */
route_table_finish(rip->table);
route_table_finish(rip->neighbor);
+ distribute_list_delete(&rip->distribute_ctx);
XFREE(MTYPE_RIP, rip);
rip = NULL;
}
return;
ri = ifp->info;
-
if (if_rmap->routemap[IF_RMAP_IN]) {
rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_IN]);
if (rmap)
/* Distribute list install. */
distribute_list_init(RIP_NODE);
- distribute_list_add_hook(rip_distribute_update);
- distribute_list_delete_hook(rip_distribute_update);
/* Route-map */
rip_route_map_init();
#include "hook.h"
#include "nexthop.h"
+#include "distribute.h"
#include "rip_memory.h"
/* RIP version number. */
bool metric_config;
uint8_t metric;
} route_map[ZEBRA_ROUTE_MAX];
+
+ /* For distribute-list container */
+ struct distribute_ctx *distribute_ctx;
};
/* RIP routing table entry which belong to rip_packet. */
ripng_changed_route,
};
+static void ripng_distribute_update(struct distribute_ctx *ctx,
+ struct distribute *dist);
+
/* Prototypes. */
void ripng_output_process(struct interface *, struct sockaddr_in6 *, int);
}
/* All interface filter check. */
- dist = distribute_lookup(NULL);
+ dist = distribute_lookup(ripng->distribute_ctx, NULL);
if (dist) {
if (dist->list[distribute]) {
alist = access_list_lookup(AFI_IP6,
/* Initialize RIPng routig table. */
ripng->table = agg_table_init();
+ /* Distribute list install. */
+ ripng->distribute_ctx = distribute_list_ctx_create(
+ vrf_lookup_by_id(VRF_DEFAULT));
+ distribute_list_add_hook(ripng->distribute_ctx,
+ ripng_distribute_update);
+ distribute_list_delete_hook(ripng->distribute_ctx,
+ ripng_distribute_update);
/* Make socket. */
ripng->sock = socket;
ripng->garbage_time);
/* Filtering status show. */
- config_show_distribute(vty);
+ config_show_distribute(vty, ripng->distribute_ctx);
/* Default metric information. */
vty_out(vty, " Default redistribution metric is %d\n",
if (dnode) {
nb_cli_show_dnode_cmds(vty, dnode, false);
- config_write_distribute(vty);
+ config_write_distribute(vty,
+ ripng->distribute_ctx);
config_write_if_rmap(vty);
RIPNG_NODE, "%s(config-router)# ", 1,
};
-static void ripng_distribute_update(struct distribute *dist)
+static void ripng_distribute_update(struct distribute_ctx *ctx,
+ struct distribute *dist)
{
struct interface *ifp;
struct ripng_interface *ri;
{
struct distribute *dist;
- dist = distribute_lookup(ifp->name);
+ if (!ripng)
+ return;
+ dist = distribute_lookup(ripng->distribute_ctx, ifp->name);
if (dist)
- ripng_distribute_update(dist);
+ ripng_distribute_update(ripng->distribute_ctx, dist);
}
/* Update all interface's distribute list. */
stream_free(ripng->ibuf);
stream_free(ripng->obuf);
+ distribute_list_delete(&ripng->distribute_ctx);
XFREE(MTYPE_RIPNG, ripng);
ripng = NULL;
} /* if (ripng) */
/* Distribute list install. */
distribute_list_init(RIPNG_NODE);
- distribute_list_add_hook(ripng_distribute_update);
- distribute_list_delete_hook(ripng_distribute_update);
/* Route-map for interface. */
ripng_route_map_init();
#include <zclient.h>
#include <vty.h>
+#include <distribute.h>
#include "ripng_memory.h"
bool metric_config;
uint8_t metric;
} route_map[ZEBRA_ROUTE_MAX];
+
+ /* For distribute-list container */
+ struct distribute_ctx *distribute_ctx;
};
/* Routing table entry. */