mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-25 20:38:34 +00:00
Merge pull request #3246 from pguibert6WIND/distribute_vrf_aware
Distribute vrf aware
This commit is contained in:
commit
dd6f112619
@ -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);
|
struct interface *ifp = if_lookup_by_index(ifindex, VRF_DEFAULT);
|
||||||
babel_interface_nfo *babel_ifp = ifp ? babel_get_if_nfo(ifp) : NULL;
|
babel_interface_nfo *babel_ifp = ifp ? babel_get_if_nfo(ifp) : NULL;
|
||||||
struct prefix p;
|
struct prefix p;
|
||||||
struct distribute *dist;
|
struct distribute *dist = NULL;
|
||||||
struct access_list *alist;
|
struct access_list *alist;
|
||||||
struct prefix_list *plist;
|
struct prefix_list *plist;
|
||||||
int distribute;
|
int distribute;
|
||||||
|
struct babel *babel;
|
||||||
|
|
||||||
p.family = v4mapped(prefix) ? AF_INET : AF_INET6;
|
p.family = v4mapped(prefix) ? AF_INET : AF_INET6;
|
||||||
p.prefixlen = v4mapped(prefix) ? plen - 96 : plen;
|
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. */
|
/* All interface filter check. */
|
||||||
dist = distribute_lookup (NULL);
|
babel = babel_lookup();
|
||||||
|
if (babel)
|
||||||
|
dist = distribute_lookup (babel->distribute_ctx, NULL);
|
||||||
if (dist) {
|
if (dist) {
|
||||||
if (dist->list[distribute]) {
|
if (dist->list[distribute]) {
|
||||||
alist = access_list_lookup (p.family, dist->list[distribute]);
|
alist = access_list_lookup (p.family, dist->list[distribute]);
|
||||||
|
@ -1248,11 +1248,16 @@ DEFUN (show_babel_parameters,
|
|||||||
"Babel information\n"
|
"Babel information\n"
|
||||||
"Configuration information\n")
|
"Configuration information\n")
|
||||||
{
|
{
|
||||||
|
struct babel *babel_ctx;
|
||||||
|
|
||||||
vty_out (vty, " -- Babel running configuration --\n");
|
vty_out (vty, " -- Babel running configuration --\n");
|
||||||
show_babel_main_configuration(vty);
|
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;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +53,8 @@ static int babel_read_protocol (struct thread *thread);
|
|||||||
static int babel_main_loop(struct thread *thread);
|
static int babel_main_loop(struct thread *thread);
|
||||||
static void babel_set_timer(struct timeval *timeout);
|
static void babel_set_timer(struct timeval *timeout);
|
||||||
static void babel_fill_with_next_timeout(struct timeval *tv);
|
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. */
|
/* Informations relative to the babel running daemon. */
|
||||||
static struct babel *babel_routing_process = NULL;
|
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;
|
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);
|
thread_add_read(master, &babel_read_protocol, NULL, protocol_socket, &babel_routing_process->t_read);
|
||||||
/* wait a little: zebra will announce interfaces, addresses, routes... */
|
/* 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);
|
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:
|
fail:
|
||||||
XFREE(MTYPE_BABEL, babel_routing_process);
|
XFREE(MTYPE_BABEL, babel_routing_process);
|
||||||
babel_routing_process = NULL;
|
babel_routing_process = NULL;
|
||||||
@ -315,6 +320,7 @@ babel_clean_routing_process()
|
|||||||
thread_cancel(babel_routing_process->t_update);
|
thread_cancel(babel_routing_process->t_update);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
distribute_list_delete(&babel_routing_process->distribute_ctx);
|
||||||
XFREE(MTYPE_BABEL, babel_routing_process);
|
XFREE(MTYPE_BABEL, babel_routing_process);
|
||||||
babel_routing_process = NULL;
|
babel_routing_process = NULL;
|
||||||
}
|
}
|
||||||
@ -539,7 +545,7 @@ resize_receive_buffer(int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
babel_distribute_update (struct distribute *dist)
|
babel_distribute_update (struct distribute_ctx *ctx, struct distribute *dist)
|
||||||
{
|
{
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
babel_interface_nfo *babel_ifp;
|
babel_interface_nfo *babel_ifp;
|
||||||
@ -574,11 +580,12 @@ babel_distribute_update (struct distribute *dist)
|
|||||||
static void
|
static void
|
||||||
babel_distribute_update_interface (struct interface *ifp)
|
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)
|
if (dist)
|
||||||
babel_distribute_update (dist);
|
babel_distribute_update (babel_routing_process->distribute_ctx, dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update all interface's distribute list. */
|
/* Update all interface's distribute list. */
|
||||||
@ -736,9 +743,7 @@ babeld_quagga_init(void)
|
|||||||
prefix_list_delete_hook (babel_distribute_update_all);
|
prefix_list_delete_hook (babel_distribute_update_all);
|
||||||
|
|
||||||
/* Distribute list install. */
|
/* Distribute list install. */
|
||||||
distribute_list_init (BABEL_NODE);
|
distribute_list_init(BABEL_NODE);
|
||||||
distribute_list_add_hook (babel_distribute_update);
|
|
||||||
distribute_list_delete_hook (babel_distribute_update);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Stubs to adapt Babel's filtering calls to Quagga's infrastructure. */
|
/* 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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct babel *babel_lookup(void)
|
||||||
|
{
|
||||||
|
return babel_routing_process;
|
||||||
|
}
|
||||||
|
@ -111,6 +111,8 @@ struct babel
|
|||||||
/* Babel threads. */
|
/* Babel threads. */
|
||||||
struct thread *t_read; /* on Babel protocol's socket */
|
struct thread *t_read; /* on Babel protocol's socket */
|
||||||
struct thread *t_update; /* timers */
|
struct thread *t_update; /* timers */
|
||||||
|
/* distribute_ctx */
|
||||||
|
struct distribute_ctx *distribute_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct zebra_privs_t babeld_privs;
|
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);
|
unsigned int ifindex, int proto);
|
||||||
extern int resize_receive_buffer(int size);
|
extern int resize_receive_buffer(int size);
|
||||||
extern void schedule_neighbours_check(int msecs, int override);
|
extern void schedule_neighbours_check(int msecs, int override);
|
||||||
|
extern struct babel *babel_lookup(void);
|
||||||
|
|
||||||
#endif /* BABEL_BABELD_H */
|
#endif /* BABEL_BABELD_H */
|
||||||
|
@ -62,7 +62,8 @@
|
|||||||
/*
|
/*
|
||||||
* Distribute-list update functions.
|
* 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 interface *ifp;
|
||||||
struct eigrp_interface *ei = NULL;
|
struct eigrp_interface *ei = NULL;
|
||||||
@ -285,10 +286,15 @@ void eigrp_distribute_update(struct distribute *dist)
|
|||||||
void eigrp_distribute_update_interface(struct interface *ifp)
|
void eigrp_distribute_update_interface(struct interface *ifp)
|
||||||
{
|
{
|
||||||
struct distribute *dist;
|
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)
|
if (dist)
|
||||||
eigrp_distribute_update(dist);
|
eigrp_distribute_update(eigrp->distribute_ctx,
|
||||||
|
dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update all interface's distribute list.
|
/* Update all interface's distribute list.
|
||||||
|
@ -33,7 +33,8 @@
|
|||||||
#ifndef EIGRPD_EIGRP_FILTER_H_
|
#ifndef EIGRPD_EIGRP_FILTER_H_
|
||||||
#define 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_interface(struct interface *);
|
||||||
extern void eigrp_distribute_update_all(struct prefix_list *);
|
extern void eigrp_distribute_update_all(struct prefix_list *);
|
||||||
extern void eigrp_distribute_update_all_wrapper(struct access_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 install. */
|
||||||
distribute_list_init(EIGRP_NODE);
|
distribute_list_init(EIGRP_NODE);
|
||||||
distribute_list_add_hook(eigrp_distribute_update);
|
|
||||||
distribute_list_delete_hook(eigrp_distribute_update);
|
|
||||||
|
|
||||||
frr_config_fork();
|
frr_config_fork();
|
||||||
frr_run(master);
|
frr_run(master);
|
||||||
|
@ -131,6 +131,9 @@ struct eigrp {
|
|||||||
uint32_t metric;
|
uint32_t metric;
|
||||||
} route_map[ZEBRA_ROUTE_MAX];
|
} route_map[ZEBRA_ROUTE_MAX];
|
||||||
|
|
||||||
|
/* distribute_ctx */
|
||||||
|
struct distribute_ctx *distribute_ctx;
|
||||||
|
|
||||||
QOBJ_FIELDS
|
QOBJ_FIELDS
|
||||||
};
|
};
|
||||||
DECLARE_QOBJ_TYPE(eigrp)
|
DECLARE_QOBJ_TYPE(eigrp)
|
||||||
|
@ -174,7 +174,7 @@ static int config_write_eigrp_distribute(struct vty *vty, struct eigrp *eigrp)
|
|||||||
int write = 0;
|
int write = 0;
|
||||||
|
|
||||||
/* Distribute configuration. */
|
/* Distribute configuration. */
|
||||||
write += config_write_distribute(vty);
|
write += config_write_distribute(vty, eigrp->distribute_ctx);
|
||||||
|
|
||||||
return write;
|
return write;
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include "keychain.h"
|
#include "keychain.h"
|
||||||
#include "libfrr.h"
|
#include "libfrr.h"
|
||||||
#include "lib_errors.h"
|
#include "lib_errors.h"
|
||||||
|
#include "distribute.h"
|
||||||
|
|
||||||
#include "eigrpd/eigrp_structs.h"
|
#include "eigrpd/eigrp_structs.h"
|
||||||
#include "eigrpd/eigrpd.h"
|
#include "eigrpd/eigrpd.h"
|
||||||
@ -55,6 +56,7 @@
|
|||||||
#include "eigrpd/eigrp_network.h"
|
#include "eigrpd/eigrp_network.h"
|
||||||
#include "eigrpd/eigrp_topology.h"
|
#include "eigrpd/eigrp_topology.h"
|
||||||
#include "eigrpd/eigrp_memory.h"
|
#include "eigrpd/eigrp_memory.h"
|
||||||
|
#include "eigrpd/eigrp_filter.h"
|
||||||
|
|
||||||
DEFINE_QOBJ_TYPE(eigrp)
|
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_IN] = NULL;
|
||||||
eigrp->routemap[EIGRP_FILTER_OUT] = 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);
|
QOBJ_REG(eigrp, eigrp);
|
||||||
return eigrp;
|
return eigrp;
|
||||||
}
|
}
|
||||||
@ -279,6 +288,7 @@ void eigrp_finish_final(struct eigrp *eigrp)
|
|||||||
listnode_delete(eigrp_om->eigrp, eigrp);
|
listnode_delete(eigrp_om->eigrp, eigrp);
|
||||||
|
|
||||||
stream_free(eigrp->ibuf);
|
stream_free(eigrp->ibuf);
|
||||||
|
distribute_list_delete(&eigrp->distribute_ctx);
|
||||||
XFREE(MTYPE_EIGRP_TOP, eigrp);
|
XFREE(MTYPE_EIGRP_TOP, eigrp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
155
lib/distribute.c
155
lib/distribute.c
@ -27,16 +27,12 @@
|
|||||||
#include "distribute.h"
|
#include "distribute.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
|
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_CTX, "Distribute ctx")
|
||||||
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list")
|
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE, "Distribute list")
|
||||||
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname")
|
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_IFNAME, "Dist-list ifname")
|
||||||
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name")
|
DEFINE_MTYPE_STATIC(LIB, DISTRIBUTE_NAME, "Dist-list name")
|
||||||
|
|
||||||
/* Hash of distribute list. */
|
struct list *dist_ctx_list;
|
||||||
struct hash *disthash;
|
|
||||||
|
|
||||||
/* Hook functions. */
|
|
||||||
void (*distribute_add_hook)(struct distribute *);
|
|
||||||
void (*distribute_delete_hook)(struct distribute *);
|
|
||||||
|
|
||||||
static struct distribute *distribute_new(void)
|
static struct distribute *distribute_new(void)
|
||||||
{
|
{
|
||||||
@ -62,7 +58,8 @@ static void distribute_free(struct distribute *dist)
|
|||||||
XFREE(MTYPE_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;
|
int i;
|
||||||
|
|
||||||
@ -70,12 +67,13 @@ static void distribute_free_if_empty(struct distribute *dist)
|
|||||||
if (dist->list[i] != NULL || dist->prefix[i] != NULL)
|
if (dist->list[i] != NULL || dist->prefix[i] != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hash_release(disthash, dist);
|
hash_release(ctx->disthash, dist);
|
||||||
distribute_free(dist);
|
distribute_free(dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup interface's distribute list. */
|
/* 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 key;
|
||||||
struct distribute *dist;
|
struct distribute *dist;
|
||||||
@ -83,7 +81,7 @@ struct distribute *distribute_lookup(const char *ifname)
|
|||||||
/* temporary reference */
|
/* temporary reference */
|
||||||
key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
|
key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
|
||||||
|
|
||||||
dist = hash_lookup(disthash, &key);
|
dist = hash_lookup(ctx->disthash, &key);
|
||||||
|
|
||||||
if (key.ifname)
|
if (key.ifname)
|
||||||
XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
|
XFREE(MTYPE_DISTRIBUTE_IFNAME, key.ifname);
|
||||||
@ -91,14 +89,18 @@ struct distribute *distribute_lookup(const char *ifname)
|
|||||||
return dist;
|
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)
|
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. */
|
/* 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 key;
|
||||||
struct distribute *ret;
|
struct distribute *ret;
|
||||||
@ -122,7 +125,7 @@ static struct distribute *distribute_get(const char *ifname)
|
|||||||
/* temporary reference */
|
/* temporary reference */
|
||||||
key.ifname = (ifname) ? XSTRDUP(MTYPE_DISTRIBUTE_IFNAME, ifname) : NULL;
|
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);
|
(void *(*)(void *))distribute_hash_alloc);
|
||||||
|
|
||||||
if (key.ifname)
|
if (key.ifname)
|
||||||
@ -152,29 +155,32 @@ static bool distribute_cmp(const struct distribute *dist1,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set access-list name to the distribute list. */
|
/* 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)
|
const char *alist_name)
|
||||||
{
|
{
|
||||||
struct distribute *dist;
|
struct distribute *dist;
|
||||||
|
|
||||||
dist = distribute_get(ifname);
|
dist = distribute_get(ctx, ifname);
|
||||||
|
|
||||||
if (dist->list[type])
|
if (dist->list[type])
|
||||||
XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]);
|
XFREE(MTYPE_DISTRIBUTE_NAME, dist->list[type]);
|
||||||
dist->list[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, alist_name);
|
dist->list[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, alist_name);
|
||||||
|
|
||||||
/* Apply this distribute-list to the interface. */
|
/* 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
|
/* Unset distribute-list. If matched distribute-list exist then
|
||||||
return 1. */
|
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)
|
const char *alist_name)
|
||||||
{
|
{
|
||||||
struct distribute *dist;
|
struct distribute *dist;
|
||||||
|
|
||||||
dist = distribute_lookup(ifname);
|
dist = distribute_lookup(ctx, ifname);
|
||||||
if (!dist)
|
if (!dist)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -187,39 +193,41 @@ static int distribute_list_unset(const char *ifname, enum distribute_type type,
|
|||||||
dist->list[type] = NULL;
|
dist->list[type] = NULL;
|
||||||
|
|
||||||
/* Apply this distribute-list to the interface. */
|
/* 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. */
|
/* If all dist are NULL, then free distribute list. */
|
||||||
distribute_free_if_empty(dist);
|
distribute_free_if_empty(ctx, dist);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set access-list name to the distribute list. */
|
/* 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,
|
enum distribute_type type,
|
||||||
const char *plist_name)
|
const char *plist_name)
|
||||||
{
|
{
|
||||||
struct distribute *dist;
|
struct distribute *dist;
|
||||||
|
|
||||||
dist = distribute_get(ifname);
|
dist = distribute_get(ctx, ifname);
|
||||||
|
|
||||||
if (dist->prefix[type])
|
if (dist->prefix[type])
|
||||||
XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]);
|
XFREE(MTYPE_DISTRIBUTE_NAME, dist->prefix[type]);
|
||||||
dist->prefix[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, plist_name);
|
dist->prefix[type] = XSTRDUP(MTYPE_DISTRIBUTE_NAME, plist_name);
|
||||||
|
|
||||||
/* Apply this distribute-list to the interface. */
|
/* 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
|
/* Unset distribute-list. If matched distribute-list exist then
|
||||||
return 1. */
|
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,
|
enum distribute_type type,
|
||||||
const char *plist_name)
|
const char *plist_name)
|
||||||
{
|
{
|
||||||
struct distribute *dist;
|
struct distribute *dist;
|
||||||
|
|
||||||
dist = distribute_lookup(ifname);
|
dist = distribute_lookup(ctx, ifname);
|
||||||
if (!dist)
|
if (!dist)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -232,10 +240,10 @@ static int distribute_list_prefix_unset(const char *ifname,
|
|||||||
dist->prefix[type] = NULL;
|
dist->prefix[type] = NULL;
|
||||||
|
|
||||||
/* Apply this distribute-list to the interface. */
|
/* 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. */
|
/* If all dist are NULL, then free distribute list. */
|
||||||
distribute_free_if_empty(dist);
|
distribute_free_if_empty(ctx, dist);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,15 +258,17 @@ DEFUN (distribute_list,
|
|||||||
"Interface name\n")
|
"Interface name\n")
|
||||||
{
|
{
|
||||||
int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
|
int prefix = (argv[1]->type == WORD_TKN) ? 1 : 0;
|
||||||
|
|
||||||
/* Check of distribute list type. */
|
/* Check of distribute list type. */
|
||||||
enum distribute_type type = argv[2 + prefix]->arg[0] == 'i'
|
enum distribute_type type = argv[2 + prefix]->arg[0] == 'i'
|
||||||
? DISTRIBUTE_V4_IN
|
? DISTRIBUTE_V4_IN
|
||||||
: DISTRIBUTE_V4_OUT;
|
: DISTRIBUTE_V4_OUT;
|
||||||
|
|
||||||
/* Set appropriate function call */
|
/* 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;
|
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 */
|
/* if interface is present, get name */
|
||||||
const char *ifname = NULL;
|
const char *ifname = NULL;
|
||||||
@ -266,7 +276,7 @@ DEFUN (distribute_list,
|
|||||||
ifname = argv[argc - 1]->arg;
|
ifname = argv[argc - 1]->arg;
|
||||||
|
|
||||||
/* Get interface name corresponding distribute list. */
|
/* Get interface name corresponding distribute list. */
|
||||||
distfn(ifname, type, argv[1 + prefix]->arg);
|
distfn(ctx, ifname, type, argv[1 + prefix]->arg);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -283,15 +293,16 @@ DEFUN (ipv6_distribute_list,
|
|||||||
"Interface name\n")
|
"Interface name\n")
|
||||||
{
|
{
|
||||||
int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
|
int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
|
||||||
|
|
||||||
/* Check of distribute list type. */
|
/* Check of distribute list type. */
|
||||||
enum distribute_type type = argv[3 + prefix]->arg[0] == 'i'
|
enum distribute_type type = argv[3 + prefix]->arg[0] == 'i'
|
||||||
? DISTRIBUTE_V6_IN
|
? DISTRIBUTE_V6_IN
|
||||||
: DISTRIBUTE_V6_OUT;
|
: DISTRIBUTE_V6_OUT;
|
||||||
|
|
||||||
/* Set appropriate function call */
|
/* 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;
|
prefix ? &distribute_list_prefix_set : &distribute_list_set;
|
||||||
|
struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
|
||||||
|
|
||||||
/* if interface is present, get name */
|
/* if interface is present, get name */
|
||||||
const char *ifname = NULL;
|
const char *ifname = NULL;
|
||||||
@ -299,7 +310,7 @@ DEFUN (ipv6_distribute_list,
|
|||||||
ifname = argv[argc - 1]->arg;
|
ifname = argv[argc - 1]->arg;
|
||||||
|
|
||||||
/* Get interface name corresponding distribute list. */
|
/* Get interface name corresponding distribute list. */
|
||||||
distfn(ifname, type, argv[2 + prefix]->arg);
|
distfn(ctx, ifname, type, argv[2 + prefix]->arg);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -316,7 +327,6 @@ DEFUN (no_distribute_list,
|
|||||||
"Interface name\n")
|
"Interface name\n")
|
||||||
{
|
{
|
||||||
int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
|
int prefix = (argv[2]->type == WORD_TKN) ? 1 : 0;
|
||||||
|
|
||||||
int idx_alname = 2 + prefix;
|
int idx_alname = 2 + prefix;
|
||||||
int idx_disttype = idx_alname + 1;
|
int idx_disttype = idx_alname + 1;
|
||||||
enum distribute_type type =
|
enum distribute_type type =
|
||||||
@ -324,16 +334,17 @@ DEFUN (no_distribute_list,
|
|||||||
DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT;
|
DISTRIBUTE_V4_IN : DISTRIBUTE_V4_OUT;
|
||||||
|
|
||||||
/* Set appropriate function call */
|
/* Set appropriate function call */
|
||||||
int (*distfn)(const char *, enum distribute_type,
|
int (*distfn)(struct distribute_ctx *, const char *,
|
||||||
const char *) =
|
enum distribute_type, const char *) =
|
||||||
prefix ? &distribute_list_prefix_unset : &distribute_list_unset;
|
prefix ? &distribute_list_prefix_unset : &distribute_list_unset;
|
||||||
|
struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
|
||||||
|
|
||||||
/* if interface is present, get name */
|
/* if interface is present, get name */
|
||||||
const char *ifname = NULL;
|
const char *ifname = NULL;
|
||||||
if (argv[argc - 1]->type == VARIABLE_TKN)
|
if (argv[argc - 1]->type == VARIABLE_TKN)
|
||||||
ifname = argv[argc - 1]->arg;
|
ifname = argv[argc - 1]->arg;
|
||||||
/* Get interface name corresponding distribute list. */
|
/* 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) {
|
if (!ret) {
|
||||||
vty_out(vty, "distribute list doesn't exist\n");
|
vty_out(vty, "distribute list doesn't exist\n");
|
||||||
@ -355,16 +366,17 @@ DEFUN (no_ipv6_distribute_list,
|
|||||||
"Interface name\n")
|
"Interface name\n")
|
||||||
{
|
{
|
||||||
int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
|
int prefix = (argv[3]->type == WORD_TKN) ? 1 : 0;
|
||||||
|
|
||||||
int idx_alname = 3 + prefix;
|
int idx_alname = 3 + prefix;
|
||||||
int idx_disttype = idx_alname + 1;
|
int idx_disttype = idx_alname + 1;
|
||||||
|
|
||||||
enum distribute_type type =
|
enum distribute_type type =
|
||||||
argv[idx_disttype]->arg[0] == 'i' ?
|
argv[idx_disttype]->arg[0] == 'i' ?
|
||||||
DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT;
|
DISTRIBUTE_V6_IN : DISTRIBUTE_V6_OUT;
|
||||||
|
struct distribute_ctx *ctx = listnode_head(dist_ctx_list);
|
||||||
|
|
||||||
/* Set appropriate function call */
|
/* 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;
|
prefix ? &distribute_list_prefix_unset : &distribute_list_unset;
|
||||||
|
|
||||||
/* if interface is present, get name */
|
/* if interface is present, get name */
|
||||||
@ -373,7 +385,7 @@ DEFUN (no_ipv6_distribute_list,
|
|||||||
if (argv[argc - 1]->type == VARIABLE_TKN)
|
if (argv[argc - 1]->type == VARIABLE_TKN)
|
||||||
ifname = argv[argc - 1]->arg;
|
ifname = argv[argc - 1]->arg;
|
||||||
/* Get interface name corresponding distribute list. */
|
/* 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) {
|
if (!ret) {
|
||||||
vty_out(vty, "distribute list doesn't exist\n");
|
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;
|
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;
|
unsigned int i;
|
||||||
int has_print = 0;
|
int has_print = 0;
|
||||||
@ -401,7 +413,7 @@ int config_show_distribute(struct vty *vty)
|
|||||||
struct distribute *dist;
|
struct distribute *dist;
|
||||||
|
|
||||||
/* Output filter configuration. */
|
/* Output filter configuration. */
|
||||||
dist = distribute_lookup(NULL);
|
dist = distribute_lookup(dist_ctxt, NULL);
|
||||||
vty_out(vty, " Outgoing update filter list for all interface is");
|
vty_out(vty, " Outgoing update filter list for all interface is");
|
||||||
has_print = 0;
|
has_print = 0;
|
||||||
if (dist) {
|
if (dist) {
|
||||||
@ -419,8 +431,8 @@ int config_show_distribute(struct vty *vty)
|
|||||||
else
|
else
|
||||||
vty_out(vty, " not set\n");
|
vty_out(vty, " not set\n");
|
||||||
|
|
||||||
for (i = 0; i < disthash->size; i++)
|
for (i = 0; i < dist_ctxt->disthash->size; i++)
|
||||||
for (mp = disthash->index[i]; mp; mp = mp->next) {
|
for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) {
|
||||||
dist = mp->data;
|
dist = mp->data;
|
||||||
if (dist->ifname) {
|
if (dist->ifname) {
|
||||||
vty_out(vty, " %s filtered by",
|
vty_out(vty, " %s filtered by",
|
||||||
@ -447,7 +459,7 @@ int config_show_distribute(struct vty *vty)
|
|||||||
|
|
||||||
|
|
||||||
/* Input filter configuration. */
|
/* Input filter configuration. */
|
||||||
dist = distribute_lookup(NULL);
|
dist = distribute_lookup(dist_ctxt, NULL);
|
||||||
vty_out(vty, " Incoming update filter list for all interface is");
|
vty_out(vty, " Incoming update filter list for all interface is");
|
||||||
has_print = 0;
|
has_print = 0;
|
||||||
if (dist) {
|
if (dist) {
|
||||||
@ -465,8 +477,8 @@ int config_show_distribute(struct vty *vty)
|
|||||||
else
|
else
|
||||||
vty_out(vty, " not set\n");
|
vty_out(vty, " not set\n");
|
||||||
|
|
||||||
for (i = 0; i < disthash->size; i++)
|
for (i = 0; i < dist_ctxt->disthash->size; i++)
|
||||||
for (mp = disthash->index[i]; mp; mp = mp->next) {
|
for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) {
|
||||||
dist = mp->data;
|
dist = mp->data;
|
||||||
if (dist->ifname) {
|
if (dist->ifname) {
|
||||||
vty_out(vty, " %s filtered by",
|
vty_out(vty, " %s filtered by",
|
||||||
@ -494,7 +506,8 @@ int config_show_distribute(struct vty *vty)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Configuration write function. */
|
/* 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;
|
unsigned int i;
|
||||||
int j;
|
int j;
|
||||||
@ -502,8 +515,8 @@ int config_write_distribute(struct vty *vty)
|
|||||||
struct hash_backet *mp;
|
struct hash_backet *mp;
|
||||||
int write = 0;
|
int write = 0;
|
||||||
|
|
||||||
for (i = 0; i < disthash->size; i++)
|
for (i = 0; i < dist_ctxt->disthash->size; i++)
|
||||||
for (mp = disthash->index[i]; mp; mp = mp->next) {
|
for (mp = dist_ctxt->disthash->index[i]; mp; mp = mp->next) {
|
||||||
struct distribute *dist;
|
struct distribute *dist;
|
||||||
|
|
||||||
dist = mp->data;
|
dist = mp->data;
|
||||||
@ -543,19 +556,38 @@ int config_write_distribute(struct vty *vty)
|
|||||||
return write;
|
return write;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear all distribute list. */
|
void distribute_list_delete(struct distribute_ctx **ctx)
|
||||||
void distribute_list_reset()
|
|
||||||
{
|
{
|
||||||
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. */
|
/* Initialize distribute list container */
|
||||||
void distribute_list_init(int node)
|
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,
|
distribute_hash_make,
|
||||||
(bool (*)(const void *, const void *))distribute_cmp, NULL);
|
(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, ) */
|
/* vtysh command-extraction doesn't grok install_element(node, ) */
|
||||||
if (node == RIP_NODE) {
|
if (node == RIP_NODE) {
|
||||||
install_element(RIP_NODE, &distribute_list_cmd);
|
install_element(RIP_NODE, &distribute_list_cmd);
|
||||||
@ -563,10 +595,7 @@ void distribute_list_init(int node)
|
|||||||
} else if (node == RIPNG_NODE) {
|
} else if (node == RIPNG_NODE) {
|
||||||
install_element(RIPNG_NODE, &distribute_list_cmd);
|
install_element(RIPNG_NODE, &distribute_list_cmd);
|
||||||
install_element(RIPNG_NODE, &no_distribute_list_cmd);
|
install_element(RIPNG_NODE, &no_distribute_list_cmd);
|
||||||
}
|
/* install v6 */
|
||||||
|
|
||||||
/* install v6 */
|
|
||||||
if (node == RIPNG_NODE) {
|
|
||||||
install_element(RIPNG_NODE, &ipv6_distribute_list_cmd);
|
install_element(RIPNG_NODE, &ipv6_distribute_list_cmd);
|
||||||
install_element(RIPNG_NODE, &no_ipv6_distribute_list_cmd);
|
install_element(RIPNG_NODE, &no_ipv6_distribute_list_cmd);
|
||||||
}
|
}
|
||||||
|
@ -45,14 +45,36 @@ struct distribute {
|
|||||||
char *prefix[DISTRIBUTE_MAX];
|
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. */
|
/* Prototypes for distribute-list. */
|
||||||
extern void distribute_list_init(int);
|
extern void distribute_list_init(int node);
|
||||||
extern void distribute_list_reset(void);
|
extern struct distribute_ctx *distribute_list_ctx_create(struct vrf *vrf);
|
||||||
extern void distribute_list_add_hook(void (*)(struct distribute *));
|
extern void distribute_list_delete(struct distribute_ctx **ctx);
|
||||||
extern void distribute_list_delete_hook(void (*)(struct distribute *));
|
extern void distribute_list_add_hook(struct distribute_ctx *ctx,
|
||||||
extern struct distribute *distribute_lookup(const char *);
|
void (*)(struct distribute_ctx *ctx,
|
||||||
extern int config_write_distribute(struct vty *);
|
struct distribute *));
|
||||||
extern int config_show_distribute(struct vty *);
|
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 *,
|
extern enum filter_type distribute_apply_in(struct interface *,
|
||||||
struct prefix *);
|
struct prefix *);
|
||||||
|
@ -330,6 +330,8 @@ vrf_id_t vrf_name_to_id(const char *name)
|
|||||||
vrf_id_t vrf_id = VRF_DEFAULT; // Pending: need a way to return invalid
|
vrf_id_t vrf_id = VRF_DEFAULT; // Pending: need a way to return invalid
|
||||||
// id/ routine not used.
|
// id/ routine not used.
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return vrf_id;
|
||||||
vrf = vrf_lookup_by_name(name);
|
vrf = vrf_lookup_by_name(name);
|
||||||
if (vrf)
|
if (vrf)
|
||||||
vrf_id = vrf->vrf_id;
|
vrf_id = vrf->vrf_id;
|
||||||
|
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_triggered_update(struct thread *);
|
||||||
static int rip_update_jitter(unsigned long);
|
static int rip_update_jitter(unsigned long);
|
||||||
|
|
||||||
|
static void rip_distribute_update(struct distribute_ctx *ctx,
|
||||||
|
struct distribute *dist);
|
||||||
|
|
||||||
/* RIP output routes type. */
|
/* RIP output routes type. */
|
||||||
enum { rip_all_route, rip_changed_route };
|
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. */
|
/* All interface filter check. */
|
||||||
dist = distribute_lookup(NULL);
|
dist = distribute_lookup(rip->distribute_ctx, NULL);
|
||||||
if (dist) {
|
if (dist) {
|
||||||
if (dist->list[distribute]) {
|
if (dist->list[distribute]) {
|
||||||
alist = access_list_lookup(AFI_IP,
|
alist = access_list_lookup(AFI_IP,
|
||||||
@ -2702,7 +2705,13 @@ int rip_create(int socket)
|
|||||||
/* Create read and timer thread. */
|
/* Create read and timer thread. */
|
||||||
rip_event(RIP_READ, rip->sock);
|
rip_event(RIP_READ, rip->sock);
|
||||||
rip_event(RIP_UPDATE_EVENT, 1);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3121,7 +3130,7 @@ DEFUN (show_ip_rip_status,
|
|||||||
vty_out(vty, " garbage collect after %u seconds\n", rip->garbage_time);
|
vty_out(vty, " garbage collect after %u seconds\n", rip->garbage_time);
|
||||||
|
|
||||||
/* Filtering status show. */
|
/* Filtering status show. */
|
||||||
config_show_distribute(vty);
|
config_show_distribute(vty, rip->distribute_ctx);
|
||||||
|
|
||||||
/* Default metric information. */
|
/* Default metric information. */
|
||||||
vty_out(vty, " Default redistribution metric is %u\n",
|
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);
|
nb_cli_show_dnode_cmds(vty, dnode, false);
|
||||||
|
|
||||||
/* Distribute configuration. */
|
/* Distribute configuration. */
|
||||||
write += config_write_distribute(vty);
|
write += config_write_distribute(vty,
|
||||||
|
rip->distribute_ctx);
|
||||||
|
|
||||||
/* Interface routemap configuration */
|
/* Interface routemap configuration */
|
||||||
write += config_write_if_rmap(vty);
|
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};
|
static struct cmd_node rip_node = {RIP_NODE, "%s(config-router)# ", 1};
|
||||||
|
|
||||||
/* Distribute-list update functions. */
|
/* 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 interface *ifp;
|
||||||
struct rip_interface *ri;
|
struct rip_interface *ri;
|
||||||
@ -3288,9 +3299,11 @@ void rip_distribute_update_interface(struct interface *ifp)
|
|||||||
{
|
{
|
||||||
struct distribute *dist;
|
struct distribute *dist;
|
||||||
|
|
||||||
dist = distribute_lookup(ifp->name);
|
if (!rip)
|
||||||
|
return;
|
||||||
|
dist = distribute_lookup(rip->distribute_ctx, ifp->name);
|
||||||
if (dist)
|
if (dist)
|
||||||
rip_distribute_update(dist);
|
rip_distribute_update(rip->distribute_ctx, dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update all interface's distribute list. */
|
/* Update all interface's distribute list. */
|
||||||
@ -3367,6 +3380,7 @@ void rip_clean(void)
|
|||||||
route_table_finish(rip->table);
|
route_table_finish(rip->table);
|
||||||
route_table_finish(rip->neighbor);
|
route_table_finish(rip->neighbor);
|
||||||
|
|
||||||
|
distribute_list_delete(&rip->distribute_ctx);
|
||||||
XFREE(MTYPE_RIP, rip);
|
XFREE(MTYPE_RIP, rip);
|
||||||
rip = NULL;
|
rip = NULL;
|
||||||
}
|
}
|
||||||
@ -3390,7 +3404,6 @@ static void rip_if_rmap_update(struct if_rmap *if_rmap)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
ri = ifp->info;
|
ri = ifp->info;
|
||||||
|
|
||||||
if (if_rmap->routemap[IF_RMAP_IN]) {
|
if (if_rmap->routemap[IF_RMAP_IN]) {
|
||||||
rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_IN]);
|
rmap = route_map_lookup_by_name(if_rmap->routemap[IF_RMAP_IN]);
|
||||||
if (rmap)
|
if (rmap)
|
||||||
@ -3472,8 +3485,6 @@ void rip_init(void)
|
|||||||
|
|
||||||
/* Distribute list install. */
|
/* Distribute list install. */
|
||||||
distribute_list_init(RIP_NODE);
|
distribute_list_init(RIP_NODE);
|
||||||
distribute_list_add_hook(rip_distribute_update);
|
|
||||||
distribute_list_delete_hook(rip_distribute_update);
|
|
||||||
|
|
||||||
/* Route-map */
|
/* Route-map */
|
||||||
rip_route_map_init();
|
rip_route_map_init();
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
#include "nexthop.h"
|
#include "nexthop.h"
|
||||||
|
#include "distribute.h"
|
||||||
#include "rip_memory.h"
|
#include "rip_memory.h"
|
||||||
|
|
||||||
/* RIP version number. */
|
/* RIP version number. */
|
||||||
@ -150,6 +151,9 @@ struct rip {
|
|||||||
bool metric_config;
|
bool metric_config;
|
||||||
uint8_t metric;
|
uint8_t metric;
|
||||||
} route_map[ZEBRA_ROUTE_MAX];
|
} route_map[ZEBRA_ROUTE_MAX];
|
||||||
|
|
||||||
|
/* For distribute-list container */
|
||||||
|
struct distribute_ctx *distribute_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* RIP routing table entry which belong to rip_packet. */
|
/* RIP routing table entry which belong to rip_packet. */
|
||||||
|
@ -52,6 +52,9 @@ enum { ripng_all_route,
|
|||||||
ripng_changed_route,
|
ripng_changed_route,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void ripng_distribute_update(struct distribute_ctx *ctx,
|
||||||
|
struct distribute *dist);
|
||||||
|
|
||||||
/* Prototypes. */
|
/* Prototypes. */
|
||||||
void ripng_output_process(struct interface *, struct sockaddr_in6 *, int);
|
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. */
|
/* All interface filter check. */
|
||||||
dist = distribute_lookup(NULL);
|
dist = distribute_lookup(ripng->distribute_ctx, NULL);
|
||||||
if (dist) {
|
if (dist) {
|
||||||
if (dist->list[distribute]) {
|
if (dist->list[distribute]) {
|
||||||
alist = access_list_lookup(AFI_IP6,
|
alist = access_list_lookup(AFI_IP6,
|
||||||
@ -1806,6 +1809,13 @@ int ripng_create(int socket)
|
|||||||
/* Initialize RIPng routig table. */
|
/* Initialize RIPng routig table. */
|
||||||
ripng->table = agg_table_init();
|
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. */
|
/* Make socket. */
|
||||||
ripng->sock = socket;
|
ripng->sock = socket;
|
||||||
|
|
||||||
@ -2071,7 +2081,7 @@ DEFUN (show_ipv6_ripng_status,
|
|||||||
ripng->garbage_time);
|
ripng->garbage_time);
|
||||||
|
|
||||||
/* Filtering status show. */
|
/* Filtering status show. */
|
||||||
config_show_distribute(vty);
|
config_show_distribute(vty, ripng->distribute_ctx);
|
||||||
|
|
||||||
/* Default metric information. */
|
/* Default metric information. */
|
||||||
vty_out(vty, " Default redistribution metric is %d\n",
|
vty_out(vty, " Default redistribution metric is %d\n",
|
||||||
@ -2290,7 +2300,8 @@ static int ripng_config_write(struct vty *vty)
|
|||||||
if (dnode) {
|
if (dnode) {
|
||||||
nb_cli_show_dnode_cmds(vty, dnode, false);
|
nb_cli_show_dnode_cmds(vty, dnode, false);
|
||||||
|
|
||||||
config_write_distribute(vty);
|
config_write_distribute(vty,
|
||||||
|
ripng->distribute_ctx);
|
||||||
|
|
||||||
config_write_if_rmap(vty);
|
config_write_if_rmap(vty);
|
||||||
|
|
||||||
@ -2305,7 +2316,8 @@ static struct cmd_node cmd_ripng_node = {
|
|||||||
RIPNG_NODE, "%s(config-router)# ", 1,
|
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 interface *ifp;
|
||||||
struct ripng_interface *ri;
|
struct ripng_interface *ri;
|
||||||
@ -2366,9 +2378,11 @@ void ripng_distribute_update_interface(struct interface *ifp)
|
|||||||
{
|
{
|
||||||
struct distribute *dist;
|
struct distribute *dist;
|
||||||
|
|
||||||
dist = distribute_lookup(ifp->name);
|
if (!ripng)
|
||||||
|
return;
|
||||||
|
dist = distribute_lookup(ripng->distribute_ctx, ifp->name);
|
||||||
if (dist)
|
if (dist)
|
||||||
ripng_distribute_update(dist);
|
ripng_distribute_update(ripng->distribute_ctx, dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update all interface's distribute list. */
|
/* Update all interface's distribute list. */
|
||||||
@ -2450,6 +2464,7 @@ void ripng_clean()
|
|||||||
stream_free(ripng->ibuf);
|
stream_free(ripng->ibuf);
|
||||||
stream_free(ripng->obuf);
|
stream_free(ripng->obuf);
|
||||||
|
|
||||||
|
distribute_list_delete(&ripng->distribute_ctx);
|
||||||
XFREE(MTYPE_RIPNG, ripng);
|
XFREE(MTYPE_RIPNG, ripng);
|
||||||
ripng = NULL;
|
ripng = NULL;
|
||||||
} /* if (ripng) */
|
} /* if (ripng) */
|
||||||
@ -2563,8 +2578,6 @@ void ripng_init()
|
|||||||
|
|
||||||
/* Distribute list install. */
|
/* Distribute list install. */
|
||||||
distribute_list_init(RIPNG_NODE);
|
distribute_list_init(RIPNG_NODE);
|
||||||
distribute_list_add_hook(ripng_distribute_update);
|
|
||||||
distribute_list_delete_hook(ripng_distribute_update);
|
|
||||||
|
|
||||||
/* Route-map for interface. */
|
/* Route-map for interface. */
|
||||||
ripng_route_map_init();
|
ripng_route_map_init();
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
#include <zclient.h>
|
#include <zclient.h>
|
||||||
#include <vty.h>
|
#include <vty.h>
|
||||||
|
#include <distribute.h>
|
||||||
|
|
||||||
#include "ripng_memory.h"
|
#include "ripng_memory.h"
|
||||||
|
|
||||||
@ -128,6 +129,9 @@ struct ripng {
|
|||||||
bool metric_config;
|
bool metric_config;
|
||||||
uint8_t metric;
|
uint8_t metric;
|
||||||
} route_map[ZEBRA_ROUTE_MAX];
|
} route_map[ZEBRA_ROUTE_MAX];
|
||||||
|
|
||||||
|
/* For distribute-list container */
|
||||||
|
struct distribute_ctx *distribute_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Routing table entry. */
|
/* Routing table entry. */
|
||||||
|
Loading…
Reference in New Issue
Block a user