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:
Philippe Guibert 2019-01-14 08:58:36 +01:00
parent 8faeb50fe4
commit 4b23867cad
8 changed files with 155 additions and 56 deletions

View File

@ -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);

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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
}

View File

@ -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();

View File

@ -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 *);

View File

@ -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);
}

View File

@ -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. */