mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-02 18:44:19 +00:00
lib, rip, ripng, eigrp: rework if_rmap context
so as to handle ri/ripng/eigrp multiple instances, the need is to encapsulate if_rmap hash table into a container context self to each instance. This work then reviews the if_rmap api, mainly by adding a if_rmap_ctx context, that is passed for each exchange between library and the daemon. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
parent
8faeb50fe4
commit
4b23867cad
@ -211,10 +211,7 @@ int main(int argc, char **argv, char **envp)
|
||||
/*eigrp_route_map_init();
|
||||
route_map_add_hook (eigrp_rmap_update);
|
||||
route_map_delete_hook (eigrp_rmap_update);*/
|
||||
/*if_rmap_init (EIGRP_NODE);
|
||||
if_rmap_hook_add (eigrp_if_rmap_update);
|
||||
if_rmap_hook_delete (eigrp_if_rmap_update);*/
|
||||
|
||||
/*if_rmap_init (EIGRP_NODE); */
|
||||
/* Distribute list install. */
|
||||
distribute_list_init(EIGRP_NODE);
|
||||
|
||||
|
@ -206,6 +206,13 @@ static struct eigrp *eigrp_new(const char *AS)
|
||||
eigrp_distribute_update);
|
||||
distribute_list_delete_hook(eigrp->distribute_ctx,
|
||||
eigrp_distribute_update);
|
||||
|
||||
/*
|
||||
eigrp->if_rmap_ctx = if_rmap_ctx_create(
|
||||
vrf_lookup_by_id(VRF_DEFAULT));
|
||||
if_rmap_hook_add (eigrp_if_rmap_update);
|
||||
if_rmap_hook_delete (eigrp_if_rmap_update);
|
||||
*/
|
||||
QOBJ_REG(eigrp, eigrp);
|
||||
return eigrp;
|
||||
}
|
||||
|
@ -26,14 +26,11 @@
|
||||
#include "if.h"
|
||||
#include "if_rmap.h"
|
||||
|
||||
DEFINE_MTYPE_STATIC(LIB, IF_RMAP_CTX, "Interface route map container")
|
||||
DEFINE_MTYPE_STATIC(LIB, IF_RMAP, "Interface route map")
|
||||
DEFINE_MTYPE_STATIC(LIB, IF_RMAP_NAME, "I.f. route map name")
|
||||
|
||||
struct hash *ifrmaphash;
|
||||
|
||||
/* Hook functions. */
|
||||
static void (*if_rmap_add_hook)(struct if_rmap *) = NULL;
|
||||
static void (*if_rmap_delete_hook)(struct if_rmap *) = NULL;
|
||||
struct list *if_rmap_ctx_list;
|
||||
|
||||
static struct if_rmap *if_rmap_new(void)
|
||||
{
|
||||
@ -57,7 +54,7 @@ static void if_rmap_free(struct if_rmap *if_rmap)
|
||||
XFREE(MTYPE_IF_RMAP, if_rmap);
|
||||
}
|
||||
|
||||
struct if_rmap *if_rmap_lookup(const char *ifname)
|
||||
struct if_rmap *if_rmap_lookup(struct if_rmap_ctx *ctx, const char *ifname)
|
||||
{
|
||||
struct if_rmap key;
|
||||
struct if_rmap *if_rmap;
|
||||
@ -65,7 +62,7 @@ struct if_rmap *if_rmap_lookup(const char *ifname)
|
||||
/* temporary copy */
|
||||
key.ifname = (ifname) ? XSTRDUP(MTYPE_IF_RMAP_NAME, ifname) : NULL;
|
||||
|
||||
if_rmap = hash_lookup(ifrmaphash, &key);
|
||||
if_rmap = hash_lookup(ctx->ifrmaphash, &key);
|
||||
|
||||
if (key.ifname)
|
||||
XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
|
||||
@ -73,14 +70,18 @@ struct if_rmap *if_rmap_lookup(const char *ifname)
|
||||
return if_rmap;
|
||||
}
|
||||
|
||||
void if_rmap_hook_add(void (*func)(struct if_rmap *))
|
||||
void if_rmap_hook_add(struct if_rmap_ctx *ctx,
|
||||
void (*func)(struct if_rmap_ctx *ctx,
|
||||
struct if_rmap *))
|
||||
{
|
||||
if_rmap_add_hook = func;
|
||||
ctx->if_rmap_add_hook = func;
|
||||
}
|
||||
|
||||
void if_rmap_hook_delete(void (*func)(struct if_rmap *))
|
||||
void if_rmap_hook_delete(struct if_rmap_ctx *ctx,
|
||||
void (*func)(struct if_rmap_ctx *ctx,
|
||||
struct if_rmap *))
|
||||
{
|
||||
if_rmap_delete_hook = func;
|
||||
ctx->if_rmap_delete_hook = func;
|
||||
}
|
||||
|
||||
static void *if_rmap_hash_alloc(void *arg)
|
||||
@ -94,7 +95,7 @@ static void *if_rmap_hash_alloc(void *arg)
|
||||
return if_rmap;
|
||||
}
|
||||
|
||||
static struct if_rmap *if_rmap_get(const char *ifname)
|
||||
static struct if_rmap *if_rmap_get(struct if_rmap_ctx *ctx, const char *ifname)
|
||||
{
|
||||
struct if_rmap key;
|
||||
struct if_rmap *ret;
|
||||
@ -102,7 +103,7 @@ static struct if_rmap *if_rmap_get(const char *ifname)
|
||||
/* temporary copy */
|
||||
key.ifname = (ifname) ? XSTRDUP(MTYPE_IF_RMAP_NAME, ifname) : NULL;
|
||||
|
||||
ret = hash_get(ifrmaphash, &key, if_rmap_hash_alloc);
|
||||
ret = hash_get(ctx->ifrmaphash, &key, if_rmap_hash_alloc);
|
||||
|
||||
if (key.ifname)
|
||||
XFREE(MTYPE_IF_RMAP_NAME, key.ifname);
|
||||
@ -125,12 +126,13 @@ static bool if_rmap_hash_cmp(const void *arg1, const void *arg2)
|
||||
return strcmp(if_rmap1->ifname, if_rmap2->ifname) == 0;
|
||||
}
|
||||
|
||||
static struct if_rmap *if_rmap_set(const char *ifname, enum if_rmap_type type,
|
||||
static struct if_rmap *if_rmap_set(struct if_rmap_ctx *ctx,
|
||||
const char *ifname, enum if_rmap_type type,
|
||||
const char *routemap_name)
|
||||
{
|
||||
struct if_rmap *if_rmap;
|
||||
|
||||
if_rmap = if_rmap_get(ifname);
|
||||
if_rmap = if_rmap_get(ctx, ifname);
|
||||
|
||||
if (type == IF_RMAP_IN) {
|
||||
if (if_rmap->routemap[IF_RMAP_IN])
|
||||
@ -147,18 +149,19 @@ static struct if_rmap *if_rmap_set(const char *ifname, enum if_rmap_type type,
|
||||
XSTRDUP(MTYPE_IF_RMAP_NAME, routemap_name);
|
||||
}
|
||||
|
||||
if (if_rmap_add_hook)
|
||||
(*if_rmap_add_hook)(if_rmap);
|
||||
if (ctx->if_rmap_add_hook)
|
||||
(ctx->if_rmap_add_hook)(ctx, if_rmap);
|
||||
|
||||
return if_rmap;
|
||||
}
|
||||
|
||||
static int if_rmap_unset(const char *ifname, enum if_rmap_type type,
|
||||
static int if_rmap_unset(struct if_rmap_ctx *ctx,
|
||||
const char *ifname, enum if_rmap_type type,
|
||||
const char *routemap_name)
|
||||
{
|
||||
struct if_rmap *if_rmap;
|
||||
|
||||
if_rmap = if_rmap_lookup(ifname);
|
||||
if_rmap = if_rmap_lookup(ctx, ifname);
|
||||
if (!if_rmap)
|
||||
return 0;
|
||||
|
||||
@ -182,12 +185,12 @@ static int if_rmap_unset(const char *ifname, enum if_rmap_type type,
|
||||
if_rmap->routemap[IF_RMAP_OUT] = NULL;
|
||||
}
|
||||
|
||||
if (if_rmap_delete_hook)
|
||||
(*if_rmap_delete_hook)(if_rmap);
|
||||
if (ctx->if_rmap_delete_hook)
|
||||
ctx->if_rmap_delete_hook(ctx, if_rmap);
|
||||
|
||||
if (if_rmap->routemap[IF_RMAP_IN] == NULL
|
||||
&& if_rmap->routemap[IF_RMAP_OUT] == NULL) {
|
||||
hash_release(ifrmaphash, if_rmap);
|
||||
hash_release(ctx->ifrmaphash, if_rmap);
|
||||
if_rmap_free(if_rmap);
|
||||
}
|
||||
|
||||
@ -207,6 +210,8 @@ DEFUN (if_rmap,
|
||||
int idx_in_out = 2;
|
||||
int idx_ifname = 3;
|
||||
enum if_rmap_type type;
|
||||
struct if_rmap_ctx *ctx =
|
||||
(struct if_rmap_ctx *)listnode_head(if_rmap_ctx_list);
|
||||
|
||||
if (strncmp(argv[idx_in_out]->text, "in", 1) == 0)
|
||||
type = IF_RMAP_IN;
|
||||
@ -217,7 +222,8 @@ DEFUN (if_rmap,
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
if_rmap_set(argv[idx_ifname]->arg, type, argv[idx_rmap_name]->arg);
|
||||
if_rmap_set(ctx, argv[idx_ifname]->arg,
|
||||
type, argv[idx_rmap_name]->arg);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
@ -237,6 +243,8 @@ DEFUN (no_if_rmap,
|
||||
int idx_ifname = 4;
|
||||
int ret;
|
||||
enum if_rmap_type type;
|
||||
struct if_rmap_ctx *ctx =
|
||||
(struct if_rmap_ctx *)listnode_head(if_rmap_ctx_list);
|
||||
|
||||
if (strncmp(argv[idx_in_out]->arg, "i", 1) == 0)
|
||||
type = IF_RMAP_IN;
|
||||
@ -247,7 +255,7 @@ DEFUN (no_if_rmap,
|
||||
return CMD_WARNING_CONFIG_FAILED;
|
||||
}
|
||||
|
||||
ret = if_rmap_unset(argv[idx_ifname]->arg, type,
|
||||
ret = if_rmap_unset(ctx, argv[idx_ifname]->arg, type,
|
||||
argv[idx_routemap_name]->arg);
|
||||
if (!ret) {
|
||||
vty_out(vty, "route-map doesn't exist\n");
|
||||
@ -258,11 +266,13 @@ DEFUN (no_if_rmap,
|
||||
|
||||
|
||||
/* Configuration write function. */
|
||||
int config_write_if_rmap(struct vty *vty)
|
||||
int config_write_if_rmap(struct vty *vty,
|
||||
struct if_rmap_ctx *ctx)
|
||||
{
|
||||
unsigned int i;
|
||||
struct hash_backet *mp;
|
||||
int write = 0;
|
||||
struct hash *ifrmaphash = ctx->ifrmaphash;
|
||||
|
||||
for (i = 0; i < ifrmaphash->size; i++)
|
||||
for (mp = ifrmaphash->index[i]; mp; mp = mp->next) {
|
||||
@ -287,18 +297,39 @@ int config_write_if_rmap(struct vty *vty)
|
||||
return write;
|
||||
}
|
||||
|
||||
void if_rmap_reset(void)
|
||||
void if_rmap_ctx_delete(struct if_rmap_ctx *ctx)
|
||||
{
|
||||
hash_clean(ifrmaphash, (void (*)(void *))if_rmap_free);
|
||||
hash_clean(ctx->ifrmaphash, (void (*)(void *))if_rmap_free);
|
||||
XFREE(MTYPE_IF_RMAP_CTX, ctx);
|
||||
}
|
||||
|
||||
struct if_rmap_ctx *if_rmap_ctx_create(struct vrf *vrf)
|
||||
{
|
||||
struct if_rmap_ctx *ctx;
|
||||
|
||||
ctx = XCALLOC(MTYPE_IF_RMAP_CTX, sizeof(struct if_rmap_ctx));
|
||||
ctx->vrf = vrf;
|
||||
ctx->ifrmaphash = hash_create_size(4, if_rmap_hash_make, if_rmap_hash_cmp,
|
||||
"Interface Route-Map Hash");
|
||||
if (!if_rmap_ctx_list)
|
||||
if_rmap_ctx_list = list_new();
|
||||
listnode_add(if_rmap_ctx_list, ctx);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void if_rmap_init(int node)
|
||||
{
|
||||
ifrmaphash = hash_create_size(4, if_rmap_hash_make, if_rmap_hash_cmp,
|
||||
"Interface Route-Map Hash");
|
||||
if (node == RIPNG_NODE) {
|
||||
} else if (node == RIP_NODE) {
|
||||
install_element(RIP_NODE, &if_rmap_cmd);
|
||||
install_element(RIP_NODE, &no_if_rmap_cmd);
|
||||
}
|
||||
if_rmap_ctx_list = list_new();
|
||||
}
|
||||
|
||||
void if_rmap_terminate(void)
|
||||
{
|
||||
if (!if_rmap_ctx_list)
|
||||
return;
|
||||
list_delete(&if_rmap_ctx_list);
|
||||
}
|
||||
|
@ -34,12 +34,33 @@ struct if_rmap {
|
||||
char *routemap[IF_RMAP_MAX];
|
||||
};
|
||||
|
||||
extern void if_rmap_init(int);
|
||||
extern void if_rmap_reset(void);
|
||||
extern void if_rmap_hook_add(void (*)(struct if_rmap *));
|
||||
extern void if_rmap_hook_delete(void (*)(struct if_rmap *));
|
||||
extern struct if_rmap *if_rmap_lookup(const char *);
|
||||
extern int config_write_if_rmap(struct vty *);
|
||||
struct if_rmap_ctx {
|
||||
/* if_rmap */
|
||||
struct hash *ifrmaphash;
|
||||
|
||||
/* Hook functions. */
|
||||
void (*if_rmap_add_hook)(struct if_rmap_ctx *ctx,
|
||||
struct if_rmap *ifrmap);
|
||||
void (*if_rmap_delete_hook)(struct if_rmap_ctx *ctx,
|
||||
struct if_rmap *ifrmap);
|
||||
|
||||
/* vrf information */
|
||||
struct vrf *vrf;
|
||||
};
|
||||
|
||||
extern struct if_rmap_ctx *if_rmap_ctx_create(struct vrf *vrf);
|
||||
extern void if_rmap_ctx_delete(struct if_rmap_ctx *ctx);
|
||||
extern void if_rmap_init(int node);
|
||||
extern void if_rmap_terminate(void);
|
||||
void if_rmap_hook_add(struct if_rmap_ctx *ctx,
|
||||
void (*func)(struct if_rmap_ctx *ctx,
|
||||
struct if_rmap *));
|
||||
void if_rmap_hook_delete(struct if_rmap_ctx *ctx,
|
||||
void (*func)(struct if_rmap_ctx *ctx,
|
||||
struct if_rmap *));
|
||||
extern struct if_rmap *if_rmap_lookup(struct if_rmap_ctx *ctx,
|
||||
const char *ifname);
|
||||
extern int config_write_if_rmap(struct vty *, struct if_rmap_ctx *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
36
ripd/ripd.c
36
ripd/ripd.c
@ -71,6 +71,9 @@ static int rip_update_jitter(unsigned long);
|
||||
static void rip_distribute_update(struct distribute_ctx *ctx,
|
||||
struct distribute *dist);
|
||||
|
||||
static void rip_if_rmap_update(struct if_rmap_ctx *ctx,
|
||||
struct if_rmap *if_rmap);
|
||||
|
||||
/* RIP output routes type. */
|
||||
enum { rip_all_route, rip_changed_route };
|
||||
|
||||
@ -2712,6 +2715,13 @@ int rip_create(int socket)
|
||||
rip_distribute_update);
|
||||
distribute_list_delete_hook(rip->distribute_ctx,
|
||||
rip_distribute_update);
|
||||
|
||||
/* if rmap install. */
|
||||
rip->if_rmap_ctx = if_rmap_ctx_create(
|
||||
vrf_lookup_by_id(VRF_DEFAULT));
|
||||
if_rmap_hook_add(rip->if_rmap_ctx, rip_if_rmap_update);
|
||||
if_rmap_hook_delete(rip->if_rmap_ctx, rip_if_rmap_update);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3228,7 +3238,7 @@ static int config_write_rip(struct vty *vty)
|
||||
rip->distribute_ctx);
|
||||
|
||||
/* Interface routemap configuration */
|
||||
write += config_write_if_rmap(vty);
|
||||
write += config_write_if_rmap(vty, rip->if_rmap_ctx);
|
||||
}
|
||||
return write;
|
||||
}
|
||||
@ -3381,25 +3391,29 @@ void rip_clean(void)
|
||||
route_table_finish(rip->neighbor);
|
||||
|
||||
distribute_list_delete(&rip->distribute_ctx);
|
||||
|
||||
if_rmap_ctx_delete(rip->if_rmap_ctx);
|
||||
|
||||
XFREE(MTYPE_RIP, rip);
|
||||
rip = NULL;
|
||||
}
|
||||
|
||||
rip_clean_network();
|
||||
rip_passive_nondefault_clean();
|
||||
rip_offset_clean();
|
||||
rip_interfaces_clean();
|
||||
rip_distance_reset();
|
||||
rip_redistribute_clean();
|
||||
if_rmap_terminate();
|
||||
}
|
||||
|
||||
static void rip_if_rmap_update(struct if_rmap *if_rmap)
|
||||
static void rip_if_rmap_update(struct if_rmap_ctx *ctx,
|
||||
struct if_rmap *if_rmap)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct rip_interface *ri;
|
||||
struct route_map *rmap;
|
||||
|
||||
ifp = if_lookup_by_name(if_rmap->ifname, VRF_DEFAULT);
|
||||
ifp = if_lookup_by_name(if_rmap->ifname, ctx->vrf->vrf_id);
|
||||
if (ifp == NULL)
|
||||
return;
|
||||
|
||||
@ -3426,10 +3440,18 @@ static void rip_if_rmap_update(struct if_rmap *if_rmap)
|
||||
void rip_if_rmap_update_interface(struct interface *ifp)
|
||||
{
|
||||
struct if_rmap *if_rmap;
|
||||
struct if_rmap_ctx *ctx;
|
||||
|
||||
if_rmap = if_rmap_lookup(ifp->name);
|
||||
if (!rip)
|
||||
return;
|
||||
if (ifp->vrf_id != VRF_DEFAULT)
|
||||
return;
|
||||
ctx = rip->if_rmap_ctx;
|
||||
if (!ctx)
|
||||
return;
|
||||
if_rmap = if_rmap_lookup(ctx, ifp->name);
|
||||
if (if_rmap)
|
||||
rip_if_rmap_update(if_rmap);
|
||||
rip_if_rmap_update(ctx, if_rmap);
|
||||
}
|
||||
|
||||
static void rip_routemap_update_redistribute(void)
|
||||
@ -3497,8 +3519,6 @@ void rip_init(void)
|
||||
route_map_delete_hook(rip_routemap_update);
|
||||
|
||||
if_rmap_init(RIP_NODE);
|
||||
if_rmap_hook_add(rip_if_rmap_update);
|
||||
if_rmap_hook_delete(rip_if_rmap_update);
|
||||
|
||||
/* Distance control. */
|
||||
rip_distance_table = route_table_init();
|
||||
|
@ -154,6 +154,9 @@ struct rip {
|
||||
|
||||
/* For distribute-list container */
|
||||
struct distribute_ctx *distribute_ctx;
|
||||
|
||||
/* For if_rmap container */
|
||||
struct if_rmap_ctx *if_rmap_ctx;
|
||||
};
|
||||
|
||||
/* RIP routing table entry which belong to rip_packet. */
|
||||
@ -419,8 +422,7 @@ extern void rip_zebra_ipv4_add(struct route_node *);
|
||||
extern void rip_zebra_ipv4_delete(struct route_node *);
|
||||
extern void rip_interface_multicast_set(int, struct connected *);
|
||||
extern void rip_distribute_update_interface(struct interface *);
|
||||
extern void rip_if_rmap_update_interface(struct interface *);
|
||||
|
||||
extern void rip_if_rmap_update_interface(struct interface *ifp);
|
||||
extern int rip_show_network_config(struct vty *);
|
||||
extern void rip_show_redistribute_config(struct vty *);
|
||||
|
||||
|
@ -60,6 +60,9 @@ void ripng_output_process(struct interface *, struct sockaddr_in6 *, int);
|
||||
|
||||
int ripng_triggered_update(struct thread *);
|
||||
|
||||
static void ripng_if_rmap_update(struct if_rmap_ctx *ctx,
|
||||
struct if_rmap *if_rmap);
|
||||
|
||||
/* RIPng next hop specification. */
|
||||
struct ripng_nexthop {
|
||||
enum ripng_nexthop_type {
|
||||
@ -1816,6 +1819,13 @@ int ripng_create(int socket)
|
||||
ripng_distribute_update);
|
||||
distribute_list_delete_hook(ripng->distribute_ctx,
|
||||
ripng_distribute_update);
|
||||
|
||||
/* if rmap install. */
|
||||
ripng->if_rmap_ctx = if_rmap_ctx_create(
|
||||
vrf_lookup_by_id(VRF_DEFAULT));
|
||||
if_rmap_hook_add(ripng->if_rmap_ctx, ripng_if_rmap_update);
|
||||
if_rmap_hook_delete(ripng->if_rmap_ctx, ripng_if_rmap_update);
|
||||
|
||||
/* Make socket. */
|
||||
ripng->sock = socket;
|
||||
|
||||
@ -2303,7 +2313,7 @@ static int ripng_config_write(struct vty *vty)
|
||||
config_write_distribute(vty,
|
||||
ripng->distribute_ctx);
|
||||
|
||||
config_write_if_rmap(vty);
|
||||
config_write_if_rmap(vty, ripng->if_rmap_ctx);
|
||||
|
||||
write = 1;
|
||||
}
|
||||
@ -2474,15 +2484,17 @@ void ripng_clean(void)
|
||||
ripng_offset_clean();
|
||||
ripng_interface_clean();
|
||||
ripng_redistribute_clean();
|
||||
if_rmap_terminate();
|
||||
}
|
||||
|
||||
static void ripng_if_rmap_update(struct if_rmap *if_rmap)
|
||||
static void ripng_if_rmap_update(struct if_rmap_ctx *ctx,
|
||||
struct if_rmap *if_rmap)
|
||||
{
|
||||
struct interface *ifp;
|
||||
struct ripng_interface *ri;
|
||||
struct route_map *rmap;
|
||||
|
||||
ifp = if_lookup_by_name(if_rmap->ifname, VRF_DEFAULT);
|
||||
ifp = if_lookup_by_name(if_rmap->ifname, ctx->vrf->vrf_id);
|
||||
if (ifp == NULL)
|
||||
return;
|
||||
|
||||
@ -2510,10 +2522,18 @@ static void ripng_if_rmap_update(struct if_rmap *if_rmap)
|
||||
void ripng_if_rmap_update_interface(struct interface *ifp)
|
||||
{
|
||||
struct if_rmap *if_rmap;
|
||||
struct if_rmap_ctx *ctx;
|
||||
|
||||
if_rmap = if_rmap_lookup(ifp->name);
|
||||
if (ifp->vrf_id != VRF_DEFAULT)
|
||||
return;
|
||||
if (!ripng)
|
||||
return;
|
||||
ctx = ripng->if_rmap_ctx;
|
||||
if (!ctx)
|
||||
return;
|
||||
if_rmap = if_rmap_lookup(ctx, ifp->name);
|
||||
if (if_rmap)
|
||||
ripng_if_rmap_update(if_rmap);
|
||||
ripng_if_rmap_update(ctx, if_rmap);
|
||||
}
|
||||
|
||||
static void ripng_routemap_update_redistribute(void)
|
||||
@ -2590,6 +2610,4 @@ void ripng_init(void)
|
||||
route_map_delete_hook(ripng_routemap_update);
|
||||
|
||||
if_rmap_init(RIPNG_NODE);
|
||||
if_rmap_hook_add(ripng_if_rmap_update);
|
||||
if_rmap_hook_delete(ripng_if_rmap_update);
|
||||
}
|
||||
|
@ -132,6 +132,9 @@ struct ripng {
|
||||
|
||||
/* For distribute-list container */
|
||||
struct distribute_ctx *distribute_ctx;
|
||||
|
||||
/* For if_rmap container */
|
||||
struct if_rmap_ctx *if_rmap_ctx;
|
||||
};
|
||||
|
||||
/* Routing table entry. */
|
||||
|
Loading…
Reference in New Issue
Block a user