mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 14:29:47 +00:00
lib, rip, ripng, babel, eigrp: add ctx pointer to distribute api
a distribute_ctx context pointer is returned after initialisation to the calling daemon. this context pointer will be further used to do discussion with distribute service. Today, there is no specific problem with old api, since the pointer is the same in all the memory process. but the pointer will be different if we have multiple instances. Right now, this is not the case, but if that happens, that work will be used for that. distribute-list initialisation is split in two. the vty initialisation is done at global level, while the context initialisation is done for each routing daemon instance. babel daemon is being equipped with a routing returning the main babel instance. also, a delete routine is available when the daemon routing instance is suppressed. a list of contexts is used inside distribute_list. This will permit distribute_list utility to handle in the same daemon to handle more than one context. This will be very useful in the vrf context. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
2569910bb6
commit
03a38493f8
@ -39,10 +39,11 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen,
|
||||
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;
|
||||
@ -81,7 +82,9 @@ babel_filter(int output, const unsigned char *prefix, unsigned short 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]);
|
||||
|
@ -1248,11 +1248,16 @@ DEFUN (show_babel_parameters,
|
||||
"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;
|
||||
}
|
||||
|
||||
|
@ -53,7 +53,8 @@ static int babel_read_protocol (struct thread *thread);
|
||||
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;
|
||||
@ -123,7 +124,7 @@ babel_config_write (struct vty *vty)
|
||||
}
|
||||
}
|
||||
|
||||
lines += config_write_distribute (vty);
|
||||
lines += config_write_distribute (vty, babel_routing_process->distribute_ctx);
|
||||
|
||||
return lines;
|
||||
}
|
||||
@ -154,8 +155,12 @@ babel_create_routing_process (void)
|
||||
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;
|
||||
@ -315,6 +320,7 @@ babel_clean_routing_process()
|
||||
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;
|
||||
}
|
||||
@ -539,7 +545,7 @@ resize_receive_buffer(int size)
|
||||
}
|
||||
|
||||
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;
|
||||
@ -574,11 +580,12 @@ babel_distribute_update (struct distribute *dist)
|
||||
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. */
|
||||
@ -736,9 +743,7 @@ babeld_quagga_init(void)
|
||||
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. */
|
||||
@ -767,3 +772,7 @@ redistribute_filter(const unsigned char *prefix, unsigned short plen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct babel *babel_lookup(void)
|
||||
{
|
||||
return babel_routing_process;
|
||||
}
|
||||
|
@ -111,6 +111,8 @@ struct babel
|
||||
/* 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;
|
||||
@ -125,6 +127,6 @@ extern int redistribute_filter(const unsigned char *prefix, unsigned short plen,
|
||||
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 */
|
||||
|
@ -62,7 +62,8 @@
|
||||
/*
|
||||
* 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;
|
||||
@ -285,10 +286,15 @@ void eigrp_distribute_update(struct distribute *dist)
|
||||
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.
|
||||
|
@ -33,7 +33,8 @@
|
||||
#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 *);
|
||||
|
@ -217,8 +217,6 @@ int main(int argc, char **argv, char **envp)
|
||||
|
||||
/* 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);
|
||||
|
@ -131,6 +131,9 @@ struct eigrp {
|
||||
uint32_t metric;
|
||||
} route_map[ZEBRA_ROUTE_MAX];
|
||||
|
||||
/* distribute_ctx */
|
||||
struct distribute_ctx *distribute_ctx;
|
||||
|
||||
QOBJ_FIELDS
|
||||
};
|
||||
DECLARE_QOBJ_TYPE(eigrp)
|
||||
|
@ -174,7 +174,7 @@ static int config_write_eigrp_distribute(struct vty *vty, struct eigrp *eigrp)
|
||||
int write = 0;
|
||||
|
||||
/* Distribute configuration. */
|
||||
write += config_write_distribute(vty);
|
||||
write += config_write_distribute(vty, eigrp->distribute_ctx);
|
||||
|
||||
return write;
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "keychain.h"
|
||||
#include "libfrr.h"
|
||||
#include "lib_errors.h"
|
||||
#include "distribute.h"
|
||||
|
||||
#include "eigrpd/eigrp_structs.h"
|
||||
#include "eigrpd/eigrpd.h"
|
||||
@ -55,6 +56,7 @@
|
||||
#include "eigrpd/eigrp_network.h"
|
||||
#include "eigrpd/eigrp_topology.h"
|
||||
#include "eigrpd/eigrp_memory.h"
|
||||
#include "eigrpd/eigrp_filter.h"
|
||||
|
||||
DEFINE_QOBJ_TYPE(eigrp)
|
||||
|
||||
@ -197,6 +199,13 @@ static struct eigrp *eigrp_new(const char *AS)
|
||||
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;
|
||||
}
|
||||
@ -279,6 +288,7 @@ void eigrp_finish_final(struct eigrp *eigrp)
|
||||
listnode_delete(eigrp_om->eigrp, eigrp);
|
||||
|
||||
stream_free(eigrp->ibuf);
|
||||
distribute_list_delete(&eigrp->distribute_ctx);
|
||||
XFREE(MTYPE_EIGRP_TOP, eigrp);
|
||||
}
|
||||
|
||||
|
155
lib/distribute.c
155
lib/distribute.c
@ -27,16 +27,12 @@
|
||||
#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)
|
||||
{
|
||||
@ -62,7 +58,8 @@ static void distribute_free(struct distribute *dist)
|
||||
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;
|
||||
|
||||
@ -70,12 +67,13 @@ static void distribute_free_if_empty(struct distribute *dist)
|
||||
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;
|
||||
@ -83,7 +81,7 @@ struct distribute *distribute_lookup(const char *ifname)
|
||||
/* 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);
|
||||
@ -91,14 +89,18 @@ struct distribute *distribute_lookup(const char *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)
|
||||
@ -114,7 +116,8 @@ 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;
|
||||
@ -122,7 +125,7 @@ static struct distribute *distribute_get(const char *ifname)
|
||||
/* 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)
|
||||
@ -152,29 +155,32 @@ static bool distribute_cmp(const struct distribute *dist1,
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
@ -187,39 +193,41 @@ static int distribute_list_unset(const char *ifname, enum distribute_type type,
|
||||
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;
|
||||
|
||||
@ -232,10 +240,10 @@ static int distribute_list_prefix_unset(const char *ifname,
|
||||
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;
|
||||
}
|
||||
|
||||
@ -250,15 +258,17 @@ DEFUN (distribute_list,
|
||||
"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;
|
||||
@ -266,7 +276,7 @@ DEFUN (distribute_list,
|
||||
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;
|
||||
}
|
||||
@ -283,15 +293,16 @@ DEFUN (ipv6_distribute_list,
|
||||
"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;
|
||||
@ -299,7 +310,7 @@ DEFUN (ipv6_distribute_list,
|
||||
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;
|
||||
}
|
||||
@ -316,7 +327,6 @@ DEFUN (no_distribute_list,
|
||||
"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 =
|
||||
@ -324,16 +334,17 @@ DEFUN (no_distribute_list,
|
||||
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");
|
||||
@ -355,16 +366,17 @@ DEFUN (no_ipv6_distribute_list,
|
||||
"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 */
|
||||
@ -373,7 +385,7 @@ DEFUN (no_ipv6_distribute_list,
|
||||
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");
|
||||
@ -393,7 +405,7 @@ static int distribute_print(struct vty *vty, char *tab[], int is_prefix,
|
||||
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;
|
||||
@ -401,7 +413,7 @@ int config_show_distribute(struct vty *vty)
|
||||
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) {
|
||||
@ -419,8 +431,8 @@ int config_show_distribute(struct vty *vty)
|
||||
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",
|
||||
@ -447,7 +459,7 @@ int config_show_distribute(struct vty *vty)
|
||||
|
||||
|
||||
/* 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) {
|
||||
@ -465,8 +477,8 @@ int config_show_distribute(struct vty *vty)
|
||||
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",
|
||||
@ -494,7 +506,8 @@ int config_show_distribute(struct vty *vty)
|
||||
}
|
||||
|
||||
/* 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;
|
||||
@ -502,8 +515,8 @@ int config_write_distribute(struct vty *vty)
|
||||
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;
|
||||
@ -543,19 +556,38 @@ int config_write_distribute(struct vty *vty)
|
||||
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);
|
||||
@ -563,10 +595,7 @@ void distribute_list_init(int node)
|
||||
} 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);
|
||||
}
|
||||
|
@ -45,14 +45,36 @@ struct distribute {
|
||||
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 *);
|
||||
|
31
ripd/ripd.c
31
ripd/ripd.c
@ -68,6 +68,9 @@ static void rip_output_process(struct connected *, struct sockaddr_in *, int,
|
||||
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 };
|
||||
|
||||
@ -328,7 +331,7 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p,
|
||||
}
|
||||
|
||||
/* 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,
|
||||
@ -2702,7 +2705,13 @@ int rip_create(int socket)
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@ -3121,7 +3130,7 @@ DEFUN (show_ip_rip_status,
|
||||
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",
|
||||
@ -3215,7 +3224,8 @@ static int config_write_rip(struct vty *vty)
|
||||
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);
|
||||
@ -3227,7 +3237,8 @@ static int config_write_rip(struct vty *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;
|
||||
@ -3288,9 +3299,11 @@ void rip_distribute_update_interface(struct interface *ifp)
|
||||
{
|
||||
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. */
|
||||
@ -3367,6 +3380,7 @@ void rip_clean(void)
|
||||
route_table_finish(rip->table);
|
||||
route_table_finish(rip->neighbor);
|
||||
|
||||
distribute_list_delete(&rip->distribute_ctx);
|
||||
XFREE(MTYPE_RIP, rip);
|
||||
rip = NULL;
|
||||
}
|
||||
@ -3390,7 +3404,6 @@ static void rip_if_rmap_update(struct if_rmap *if_rmap)
|
||||
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)
|
||||
@ -3472,8 +3485,6 @@ void rip_init(void)
|
||||
|
||||
/* 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();
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "hook.h"
|
||||
#include "nexthop.h"
|
||||
#include "distribute.h"
|
||||
#include "rip_memory.h"
|
||||
|
||||
/* RIP version number. */
|
||||
@ -150,6 +151,9 @@ struct rip {
|
||||
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. */
|
||||
|
@ -52,6 +52,9 @@ enum { ripng_all_route,
|
||||
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);
|
||||
|
||||
@ -619,7 +622,7 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p,
|
||||
}
|
||||
|
||||
/* 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,
|
||||
@ -1806,6 +1809,13 @@ int ripng_create(int socket)
|
||||
/* 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;
|
||||
|
||||
@ -2071,7 +2081,7 @@ DEFUN (show_ipv6_ripng_status,
|
||||
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",
|
||||
@ -2290,7 +2300,8 @@ static int ripng_config_write(struct vty *vty)
|
||||
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);
|
||||
|
||||
@ -2305,7 +2316,8 @@ static struct cmd_node cmd_ripng_node = {
|
||||
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;
|
||||
@ -2366,9 +2378,11 @@ void ripng_distribute_update_interface(struct interface *ifp)
|
||||
{
|
||||
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. */
|
||||
@ -2450,6 +2464,7 @@ void ripng_clean()
|
||||
stream_free(ripng->ibuf);
|
||||
stream_free(ripng->obuf);
|
||||
|
||||
distribute_list_delete(&ripng->distribute_ctx);
|
||||
XFREE(MTYPE_RIPNG, ripng);
|
||||
ripng = NULL;
|
||||
} /* if (ripng) */
|
||||
@ -2563,8 +2578,6 @@ void ripng_init()
|
||||
|
||||
/* 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();
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include <zclient.h>
|
||||
#include <vty.h>
|
||||
#include <distribute.h>
|
||||
|
||||
#include "ripng_memory.h"
|
||||
|
||||
@ -128,6 +129,9 @@ struct ripng {
|
||||
bool metric_config;
|
||||
uint8_t metric;
|
||||
} route_map[ZEBRA_ROUTE_MAX];
|
||||
|
||||
/* For distribute-list container */
|
||||
struct distribute_ctx *distribute_ctx;
|
||||
};
|
||||
|
||||
/* Routing table entry. */
|
||||
|
Loading…
Reference in New Issue
Block a user