diff options
author | Philippe Guibert <philippe.guibert@6wind.com> | 2019-01-14 08:58:36 +0100 |
---|---|---|
committer | Philippe Guibert <philippe.guibert@6wind.com> | 2019-02-19 21:11:13 +0100 |
commit | 4b23867cad558a59e8d315400b82c0453510c9af (patch) | |
tree | 659eb4c089bfca4451921697caad11eaa5bc2d18 | |
parent | Merge pull request #3823 from opensourcerouting/confd-build-fix (diff) | |
download | frr-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.c | 5 | ||||
-rw-r--r-- | eigrpd/eigrpd.c | 7 | ||||
-rw-r--r-- | lib/if_rmap.c | 89 | ||||
-rw-r--r-- | lib/if_rmap.h | 33 | ||||
-rw-r--r-- | ripd/ripd.c | 36 | ||||
-rw-r--r-- | ripd/ripd.h | 6 | ||||
-rw-r--r-- | ripngd/ripngd.c | 32 | ||||
-rw-r--r-- | ripngd/ripngd.h | 3 |
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. */ |