summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2019-01-14 08:58:36 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2019-02-19 21:11:13 +0100
commit4b23867cad558a59e8d315400b82c0453510c9af (patch)
tree659eb4c089bfca4451921697caad11eaa5bc2d18
parentMerge pull request #3823 from opensourcerouting/confd-build-fix (diff)
downloadfrr-4b23867cad558a59e8d315400b82c0453510c9af.tar.xz
frr-4b23867cad558a59e8d315400b82c0453510c9af.zip
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>
-rw-r--r--eigrpd/eigrp_main.c5
-rw-r--r--eigrpd/eigrpd.c7
-rw-r--r--lib/if_rmap.c89
-rw-r--r--lib/if_rmap.h33
-rw-r--r--ripd/ripd.c36
-rw-r--r--ripd/ripd.h6
-rw-r--r--ripngd/ripngd.c32
-rw-r--r--ripngd/ripngd.h3
8 files changed, 155 insertions, 56 deletions
diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c
index b19b383e6..3db59a838 100644
--- a/eigrpd/eigrp_main.c
+++ b/eigrpd/eigrp_main.c
@@ -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);
diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c
index 69d947e59..4f0a5d1b0 100644
--- a/eigrpd/eigrpd.c
+++ b/eigrpd/eigrpd.c
@@ -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;
}
diff --git a/lib/if_rmap.c b/lib/if_rmap.c
index 69da695dc..42d01c873 100644
--- a/lib/if_rmap.c
+++ b/lib/if_rmap.c
@@ -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(ctx->ifrmaphash, (void (*)(void *))if_rmap_free);
+ XFREE(MTYPE_IF_RMAP_CTX, ctx);
+}
+
+struct if_rmap_ctx *if_rmap_ctx_create(struct vrf *vrf)
{
- hash_clean(ifrmaphash, (void (*)(void *))if_rmap_free);
+ 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);
}
diff --git a/lib/if_rmap.h b/lib/if_rmap.h
index 8dded2cb4..21ac35fe1 100644
--- a/lib/if_rmap.h
+++ b/lib/if_rmap.h
@@ -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
}
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 38b4aed5b..b95034e40 100644
--- a/ripd/ripd.c
+++ b/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();
diff --git a/ripd/ripd.h b/ripd/ripd.h
index 7b8fe3a90..383df3707 100644
--- a/ripd/ripd.h
+++ b/ripd/ripd.h
@@ -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 *);
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index 70655beff..3e0982e57 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -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);
}
diff --git a/ripngd/ripngd.h b/ripngd/ripngd.h
index 1db7a83b1..3f0ef13a0 100644
--- a/ripngd/ripngd.h
+++ b/ripngd/ripngd.h
@@ -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. */