diff options
author | Rafael Zalamena <rzalamena@users.noreply.github.com> | 2020-12-10 13:01:12 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-10 13:01:12 +0100 |
commit | 551e30a5ff1065a989e70d4d7681657624639b79 (patch) | |
tree | 7c34371581b10a75556c6d9cd87907778a0d8cf6 /ospf6d | |
parent | Merge pull request #7649 from qlyoung/fix-doc-comment-hashcmp (diff) | |
parent | ospf6d : Code refactoring for route redistribution. (diff) | |
download | frr-551e30a5ff1065a989e70d4d7681657624639b79.tar.xz frr-551e30a5ff1065a989e70d4d7681657624639b79.zip |
Merge pull request #7492 from Niral-Networks/niral_ospfv3_fix_redist
ospf6d : Code refactoring for route redistribution.
Diffstat (limited to 'ospf6d')
-rw-r--r-- | ospf6d/ospf6_asbr.c | 243 | ||||
-rw-r--r-- | ospf6d/ospf6_asbr.h | 5 | ||||
-rw-r--r-- | ospf6d/ospf6_memory.c | 1 | ||||
-rw-r--r-- | ospf6d/ospf6_memory.h | 1 | ||||
-rw-r--r-- | ospf6d/ospf6_top.c | 3 | ||||
-rw-r--r-- | ospf6d/ospf6_top.h | 18 |
6 files changed, 180 insertions, 91 deletions
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index a9fc80252..0e419cbff 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -50,7 +50,8 @@ #include "lib/json.h" static void ospf6_asbr_redistribute_set(int type, vrf_id_t vrf_id); -static void ospf6_asbr_redistribute_unset(int type, vrf_id_t vrf_id); +static void ospf6_asbr_redistribute_unset(struct ospf6 *ospf6, + struct ospf6_redist *red, int type); unsigned char conf_debug_ospf6_asbr = 0; @@ -844,35 +845,28 @@ void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry, /* redistribute function */ - -static void ospf6_asbr_routemap_set(int type, const char *mapname, - uint32_t vrf_id) +static void ospf6_asbr_routemap_set(struct ospf6_redist *red, + const char *mapname) { - struct ospf6 *ospf6 = NULL; - - ospf6 = ospf6_lookup_by_vrf_id(vrf_id); - - if (ospf6 == NULL) - return; - - if (ospf6->rmap[type].name) { - route_map_counter_decrement(ospf6->rmap[type].map); - free(ospf6->rmap[type].name); + if (ROUTEMAP_NAME(red)) { + route_map_counter_decrement(ROUTEMAP(red)); + free(ROUTEMAP_NAME(red)); } - ospf6->rmap[type].name = strdup(mapname); - ospf6->rmap[type].map = route_map_lookup_by_name(mapname); - route_map_counter_increment(ospf6->rmap[type].map); + + ROUTEMAP_NAME(red) = strdup(mapname); + ROUTEMAP(red) = route_map_lookup_by_name(mapname); + route_map_counter_increment(ROUTEMAP(red)); } -static void ospf6_asbr_routemap_unset(int type, struct ospf6 *ospf6) +static void ospf6_asbr_routemap_unset(struct ospf6_redist *red) { - if (ospf6->rmap[type].name) - free(ospf6->rmap[type].name); + if (ROUTEMAP_NAME(red)) + free(ROUTEMAP_NAME(red)); - route_map_counter_decrement(ospf6->rmap[type].map); + route_map_counter_decrement(ROUTEMAP(red)); - ospf6->rmap[type].name = NULL; - ospf6->rmap[type].map = NULL; + ROUTEMAP_NAME(red) = NULL; + ROUTEMAP(red) = NULL; } static int ospf6_asbr_routemap_update_timer(struct thread *thread) @@ -880,6 +874,7 @@ static int ospf6_asbr_routemap_update_timer(struct thread *thread) void **arg; int arg_type; struct ospf6 *ospf6; + struct ospf6_redist *red; arg = THREAD_ARG(thread); ospf6 = (struct ospf6 *)arg[0]; @@ -887,13 +882,14 @@ static int ospf6_asbr_routemap_update_timer(struct thread *thread) ospf6->t_distribute_update = NULL; - if (ospf6->rmap[arg_type].name) - ospf6->rmap[arg_type].map = - route_map_lookup_by_name(ospf6->rmap[arg_type].name); - if (ospf6->rmap[arg_type].map) { + red = ospf6_redist_lookup(ospf6, arg_type, 0); + + if (red && ROUTEMAP_NAME(red)) + ROUTEMAP(red) = route_map_lookup_by_name(ROUTEMAP_NAME(red)); + if (red && ROUTEMAP(red)) { if (IS_OSPF6_DEBUG_ASBR) zlog_debug("%s: route-map %s update, reset redist %s", - __func__, ospf6->rmap[arg_type].name, + __func__, ROUTEMAP_NAME(red), ZROUTE_NAME(arg_type)); ospf6_zebra_no_redistribute(arg_type, ospf6->vrf_id); @@ -931,20 +927,23 @@ static void ospf6_asbr_routemap_update(const char *mapname) int type; struct listnode *node, *nnode; struct ospf6 *ospf6 = NULL; + struct ospf6_redist *red; if (om6 == NULL) return; for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { - if (ospf6->rmap[type].name == NULL) + red = ospf6_redist_lookup(ospf6, type, 0); + if (!red || (ROUTEMAP_NAME(red) == NULL)) continue; - ospf6->rmap[type].map = route_map_lookup_by_name( - ospf6->rmap[type].name); + ROUTEMAP(red) = + route_map_lookup_by_name(ROUTEMAP_NAME(red)); - if (mapname == NULL || strcmp(ospf6->rmap[type].name, mapname)) + if (mapname == NULL + || strcmp(ROUTEMAP_NAME(red), mapname)) continue; - if (ospf6->rmap[type].map) { + if (ROUTEMAP(red)) { if (IS_OSPF6_DEBUG_ASBR) zlog_debug( "%s: route-map %s update, reset redist %s", @@ -953,11 +952,9 @@ static void ospf6_asbr_routemap_update(const char *mapname) ZROUTE_NAME( type)); - route_map_counter_increment( - ospf6->rmap[type].map); + route_map_counter_increment(ROUTEMAP(red)); - ospf6_asbr_distribute_list_update( - type, ospf6); + ospf6_asbr_distribute_list_update(type, ospf6); } else { /* * if the mapname matches a @@ -973,11 +970,8 @@ static void ospf6_asbr_routemap_update(const char *mapname) mapname, ZROUTE_NAME( type)); - ospf6_asbr_redistribute_unset( - type, ospf6->vrf_id); - ospf6_asbr_routemap_set( - type, mapname, - ospf6->vrf_id); + ospf6_asbr_redistribute_unset(ospf6, red, type); + ospf6_asbr_routemap_set(red, mapname); ospf6_asbr_redistribute_set( type, ospf6->vrf_id); } @@ -990,13 +984,15 @@ static void ospf6_asbr_routemap_event(const char *name) int type; struct listnode *node, *nnode; struct ospf6 *ospf6; + struct ospf6_redist *red; if (om6 == NULL) return; for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) { for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { - if ((ospf6->rmap[type].name) - && (strcmp(ospf6->rmap[type].name, name) == 0)) + red = ospf6_redist_lookup(ospf6, type, 0); + if (red && ROUTEMAP_NAME(red) + && (strcmp(ROUTEMAP_NAME(red), name) == 0)) ospf6_asbr_distribute_list_update(type, ospf6); } } @@ -1007,23 +1003,70 @@ int ospf6_asbr_is_asbr(struct ospf6 *o) return o->external_table->count; } +struct ospf6_redist *ospf6_redist_lookup(struct ospf6 *ospf6, int type, + unsigned short instance) +{ + struct list *red_list; + struct listnode *node; + struct ospf6_redist *red; + + red_list = ospf6->redist[type]; + if (!red_list) + return (NULL); + + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) + if (red->instance == instance) + return red; + + return NULL; +} + +static struct ospf6_redist *ospf6_redist_add(struct ospf6 *ospf6, int type, + uint8_t instance) +{ + struct ospf6_redist *red; + + red = ospf6_redist_lookup(ospf6, type, instance); + if (red) + return red; + + if (!ospf6->redist[type]) + ospf6->redist[type] = list_new(); + + red = XCALLOC(MTYPE_OSPF6_REDISTRIBUTE, sizeof(struct ospf6_redist)); + red->instance = instance; + ROUTEMAP_NAME(red) = NULL; + ROUTEMAP(red) = NULL; + + listnode_add(ospf6->redist[type], red); + + return red; +} + +static void ospf6_redist_del(struct ospf6 *ospf6, struct ospf6_redist *red, + int type) +{ + if (red) { + listnode_delete(ospf6->redist[type], red); + if (!ospf6->redist[type]->count) { + list_delete(&ospf6->redist[type]); + } + XFREE(MTYPE_OSPF6_REDISTRIBUTE, red); + } +} + static void ospf6_asbr_redistribute_set(int type, vrf_id_t vrf_id) { ospf6_zebra_redistribute(type, vrf_id); } -static void ospf6_asbr_redistribute_unset(int type, vrf_id_t vrf_id) +static void ospf6_asbr_redistribute_unset(struct ospf6 *ospf6, + struct ospf6_redist *red, int type) { struct ospf6_route *route; struct ospf6_external_info *info; - struct ospf6 *ospf6 = NULL; - ospf6 = ospf6_lookup_by_vrf_id(vrf_id); - - if (ospf6 == NULL) - return; - - ospf6_zebra_no_redistribute(type, vrf_id); + ospf6_zebra_no_redistribute(type, ospf6->vrf_id); for (route = ospf6_route_head(ospf6->external_table); route; route = ospf6_route_next(route)) { @@ -1035,7 +1078,7 @@ static void ospf6_asbr_redistribute_unset(int type, vrf_id_t vrf_id) ospf6); } - ospf6_asbr_routemap_unset(type, ospf6); + ospf6_asbr_routemap_unset(red); } /* When an area is unstubified, flood all the external LSAs in the area */ @@ -1068,6 +1111,12 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, char ibuf[16]; struct listnode *lnode, *lnnode; struct ospf6_area *oa; + struct ospf6_redist *red; + + red = ospf6_redist_lookup(ospf6, type, 0); + + if (!red) + return; if (!ospf6_zebra_is_redistribute(type, ospf6->vrf_id)) return; @@ -1079,28 +1128,28 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, zlog_debug("Redistribute %pFX (%s)", prefix, ZROUTE_NAME(type)); /* if route-map was specified but not found, do not advertise */ - if (ospf6->rmap[type].name) { - if (ospf6->rmap[type].map == NULL) + if (ROUTEMAP_NAME(red)) { + if (ROUTEMAP(red) == NULL) ospf6_asbr_routemap_update(NULL); - if (ospf6->rmap[type].map == NULL) { + if (ROUTEMAP(red) == NULL) { zlog_warn( "route-map \"%s\" not found, suppress redistributing", - ospf6->rmap[type].name); + ROUTEMAP_NAME(red)); return; } } /* apply route-map */ - if (ospf6->rmap[type].map) { + if (ROUTEMAP(red)) { troute.route_option = &tinfo; tinfo.ifindex = ifindex; tinfo.tag = tag; - ret = route_map_apply(ospf6->rmap[type].map, prefix, &troute); + ret = route_map_apply(ROUTEMAP(red), prefix, &troute); if (ret == RMAP_DENYMATCH) { if (IS_OSPF6_DEBUG_ASBR) zlog_debug("Denied by route-map \"%s\"", - ospf6->rmap[type].name); + ROUTEMAP_NAME(red)); ospf6_asbr_redistribute_remove(type, ifindex, prefix, ospf6); return; @@ -1111,7 +1160,7 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, if (match) { info = match->route_option; /* copy result of route-map */ - if (ospf6->rmap[type].map) { + if (ROUTEMAP(red)) { if (troute.path.metric_type) match->path.metric_type = troute.path.metric_type; @@ -1164,7 +1213,7 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex, info->id = ospf6->external_id++; /* copy result of route-map */ - if (ospf6->rmap[type].map) { + if (ROUTEMAP(red)) { if (troute.path.metric_type) route->path.metric_type = troute.path.metric_type; if (troute.path.cost) @@ -1272,6 +1321,7 @@ DEFUN (ospf6_redistribute, FRR_REDIST_HELP_STR_OSPF6D) { int type; + struct ospf6_redist *red; VTY_DECLVAR_CONTEXT(ospf6, ospf6); OSPF6_CMD_CHECK_RUNNING(ospf6); @@ -1280,8 +1330,13 @@ DEFUN (ospf6_redistribute, if (type < 0) return CMD_WARNING_CONFIG_FAILED; - ospf6_asbr_redistribute_unset(type, ospf6->vrf_id); + red = ospf6_redist_add(ospf6, type, 0); + if (!red) + return CMD_SUCCESS; + + ospf6_asbr_redistribute_unset(ospf6, red, type); ospf6_asbr_redistribute_set(type, ospf6->vrf_id); + return CMD_SUCCESS; } @@ -1296,6 +1351,7 @@ DEFUN (ospf6_redistribute_routemap, int idx_protocol = 1; int idx_word = 3; int type; + struct ospf6_redist *red; VTY_DECLVAR_CONTEXT(ospf6, ospf6); OSPF6_CMD_CHECK_RUNNING(ospf6); @@ -1305,9 +1361,14 @@ DEFUN (ospf6_redistribute_routemap, if (type < 0) return CMD_WARNING_CONFIG_FAILED; - ospf6_asbr_redistribute_unset(type, ospf6->vrf_id); - ospf6_asbr_routemap_set(type, argv[idx_word]->arg, ospf6->vrf_id); + red = ospf6_redist_add(ospf6, type, 0); + if (!red) + return CMD_SUCCESS; + + ospf6_asbr_redistribute_unset(ospf6, red, type); + ospf6_asbr_routemap_set(red, argv[idx_word]->arg); ospf6_asbr_redistribute_set(type, ospf6->vrf_id); + return CMD_SUCCESS; } @@ -1322,6 +1383,7 @@ DEFUN (no_ospf6_redistribute, { int idx_protocol = 2; int type; + struct ospf6_redist *red; VTY_DECLVAR_CONTEXT(ospf6, ospf6); @@ -1332,7 +1394,12 @@ DEFUN (no_ospf6_redistribute, if (type < 0) return CMD_WARNING_CONFIG_FAILED; - ospf6_asbr_redistribute_unset(type, ospf6->vrf_id); + red = ospf6_redist_lookup(ospf6, type, 0); + if (!red) + return CMD_SUCCESS; + + ospf6_asbr_redistribute_unset(ospf6, red, type); + ospf6_redist_del(ospf6, red, type); return CMD_SUCCESS; } @@ -1340,16 +1407,18 @@ DEFUN (no_ospf6_redistribute, int ospf6_redistribute_config_write(struct vty *vty, struct ospf6 *ospf6) { int type; + struct ospf6_redist *red; for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { - if (type == ZEBRA_ROUTE_OSPF6) + red = ospf6_redist_lookup(ospf6, type, 0); + if (!red) continue; - if (!ospf6_zebra_is_redistribute(type, ospf6->vrf_id)) + if (type == ZEBRA_ROUTE_OSPF6) continue; - if (ospf6->rmap[type].name) + if (ROUTEMAP_NAME(red)) vty_out(vty, " redistribute %s route-map %s\n", - ZROUTE_NAME(type), ospf6->rmap[type].name); + ZROUTE_NAME(type), ROUTEMAP_NAME(red)); else vty_out(vty, " redistribute %s\n", ZROUTE_NAME(type)); } @@ -1367,6 +1436,7 @@ static void ospf6_redistribute_show_config(struct vty *vty, struct ospf6 *ospf6, struct ospf6_route *route; struct ospf6_external_info *info; json_object *json_route; + struct ospf6_redist *red; total = 0; for (type = 0; type < ZEBRA_ROUTE_MAX; type++) @@ -1384,9 +1454,11 @@ static void ospf6_redistribute_show_config(struct vty *vty, struct ospf6 *ospf6, vty_out(vty, "Redistributing External Routes from:\n"); for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { - if (type == ZEBRA_ROUTE_OSPF6) + red = ospf6_redist_lookup(ospf6, type, 0); + + if (!red) continue; - if (!ospf6_zebra_is_redistribute(type, ospf6->vrf_id)) + if (type == ZEBRA_ROUTE_OSPF6) continue; if (use_json) { @@ -1396,25 +1468,24 @@ static void ospf6_redistribute_show_config(struct vty *vty, struct ospf6 *ospf6, nroute[type]); json_object_boolean_add(json_route, "routeMapNamePresent", - ospf6->rmap[type].name); + ROUTEMAP_NAME(red)); } - if (ospf6->rmap[type].name) { + if (ROUTEMAP_NAME(red)) { if (use_json) { json_object_string_add(json_route, "routeMapName", - ospf6->rmap[type].name); + ROUTEMAP_NAME(red)); json_object_boolean_add(json_route, "routeMapFound", - ospf6->rmap[type].map); + ROUTEMAP(red)); } else vty_out(vty, " %d: %s with route-map \"%s\"%s\n", nroute[type], ZROUTE_NAME(type), - ospf6->rmap[type].name, - (ospf6->rmap[type].map - ? "" - : " (not found !)")); + ROUTEMAP_NAME(red), + (ROUTEMAP(red) ? "" + : " (not found !)")); } else { if (!use_json) vty_out(vty, " %d: %s\n", nroute[type], @@ -1980,15 +2051,21 @@ void ospf6_asbr_init(void) install_element(OSPF6_NODE, &no_ospf6_redistribute_cmd); } -void ospf6_asbr_redistribute_reset(vrf_id_t vrf_id) +void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6) { int type; + struct ospf6_redist *red; for (type = 0; type < ZEBRA_ROUTE_MAX; type++) { + red = ospf6_redist_lookup(ospf6, type, 0); + if (!red) + continue; if (type == ZEBRA_ROUTE_OSPF6) continue; - if (ospf6_zebra_is_redistribute(type, vrf_id)) - ospf6_asbr_redistribute_unset(type, vrf_id); + if (ospf6_zebra_is_redistribute(type, ospf6->vrf_id)) { + ospf6_asbr_redistribute_unset(ospf6, red, type); + ospf6_redist_del(ospf6, red, type); + } } } diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index 24cc6a07b..fd1461004 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -92,7 +92,7 @@ extern int ospf6_redistribute_config_write(struct vty *vty, struct ospf6 *ospf6); extern void ospf6_asbr_init(void); -extern void ospf6_asbr_redistribute_reset(vrf_id_t vrf_id); +extern void ospf6_asbr_redistribute_reset(struct ospf6 *ospf6); extern void ospf6_asbr_terminate(void); extern void ospf6_asbr_send_externals_to_area(struct ospf6_area *); @@ -102,5 +102,6 @@ extern void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old, struct ospf6_route *route, struct ospf6 *ospf6); extern void ospf6_asbr_distribute_list_update(int type, struct ospf6 *ospf6); - +struct ospf6_redist *ospf6_redist_lookup(struct ospf6 *ospf6, int type, + unsigned short instance); #endif /* OSPF6_ASBR_H */ diff --git a/ospf6d/ospf6_memory.c b/ospf6d/ospf6_memory.c index c008b54ce..6585fc158 100644 --- a/ospf6d/ospf6_memory.c +++ b/ospf6d/ospf6_memory.c @@ -44,3 +44,4 @@ DEFINE_MTYPE(OSPF6D, OSPF6_EXTERNAL_INFO, "OSPF6 ext. info") DEFINE_MTYPE(OSPF6D, OSPF6_PATH, "OSPF6 Path") DEFINE_MTYPE(OSPF6D, OSPF6_DIST_ARGS, "OSPF6 Distribute arguments") DEFINE_MTYPE(OSPF6D, OSPF6_OTHER, "OSPF6 other") +DEFINE_MTYPE(OSPF6D, OSPF6_REDISTRIBUTE, "OSPF6 Redistribute arguments") diff --git a/ospf6d/ospf6_memory.h b/ospf6d/ospf6_memory.h index a97d67754..57f0abd9a 100644 --- a/ospf6d/ospf6_memory.h +++ b/ospf6d/ospf6_memory.h @@ -42,6 +42,7 @@ DECLARE_MTYPE(OSPF6_NEXTHOP) DECLARE_MTYPE(OSPF6_EXTERNAL_INFO) DECLARE_MTYPE(OSPF6_PATH) DECLARE_MTYPE(OSPF6_DIST_ARGS) +DECLARE_MTYPE(OSPF6_REDISTRIBUTE) DECLARE_MTYPE(OSPF6_OTHER) #endif /* _QUAGGA_OSPF6_MEMORY_H */ diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index 908cda43d..e461a3792 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -338,7 +338,8 @@ static void ospf6_disable(struct ospf6 *o) ospf6_area_disable(oa); /* XXX: This also changes persistent settings */ - ospf6_asbr_redistribute_reset(o->vrf_id); + /* Unregister redistribution */ + ospf6_asbr_redistribute_reset(o); ospf6_lsdb_remove_all(o->lsdb); ospf6_route_remove_all(o->route_table); diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h index 52e1d7ee2..93e25d759 100644 --- a/ospf6d/ospf6_top.h +++ b/ospf6d/ospf6_top.h @@ -38,6 +38,17 @@ enum { OSPF6_LOG_ADJACENCY_DETAIL = (1 << 1), }; +struct ospf6_redist { + uint8_t instance; + /* For redistribute route map. */ + struct { + char *name; + struct route_map *map; + } route_map; +#define ROUTEMAP_NAME(R) (R->route_map.name) +#define ROUTEMAP(R) (R->route_map.map) +}; + /* OSPFv3 top level data structure */ struct ospf6 { /* The relevant vrf_id */ @@ -71,11 +82,8 @@ struct ospf6 { struct route_table *external_id_table; uint32_t external_id; - /* redistribute route-map */ - struct { - char *name; - struct route_map *map; - } rmap[ZEBRA_ROUTE_MAX]; + /* OSPF6 redistribute configuration */ + struct list *redist[ZEBRA_ROUTE_MAX]; uint8_t flag; |