diff options
author | David Lamparter <equinox@opensourcerouting.org> | 2017-08-23 16:54:15 +0200 |
---|---|---|
committer | David Lamparter <equinox@opensourcerouting.org> | 2017-08-24 00:18:53 +0200 |
commit | 427f8e61bb711b51891dbaee845215ca228951f1 (patch) | |
tree | bafe78de9e9f109c2f840eaf4a357511275695aa | |
parent | lib: fix cosmetic issue with exit race (diff) | |
download | frr-427f8e61bb711b51891dbaee845215ca228951f1.tar.xz frr-427f8e61bb711b51891dbaee845215ca228951f1.zip |
ospf6d: properly update prefix list references
Register add/delete hooks with the prefix list code to properly change
ospf6_area's prefix list in/out pointers.
There are 2 other uncached uses of prefix lists in the ASBR route-map
code and the interface code; these should probably be cached too. (To
be fixed another day...)
Fixes: #453
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
-rw-r--r-- | lib/plist.c | 8 | ||||
-rw-r--r-- | lib/plist.h | 1 | ||||
-rw-r--r-- | ospf6d/ospf6_abr.c | 59 | ||||
-rw-r--r-- | ospf6d/ospf6_area.c | 41 | ||||
-rw-r--r-- | ospf6d/ospf6_area.h | 1 | ||||
-rw-r--r-- | ospf6d/ospf6d.c | 18 |
6 files changed, 75 insertions, 53 deletions
diff --git a/lib/plist.c b/lib/plist.c index b0cf42ca4..ebd628d72 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -122,6 +122,14 @@ const char *prefix_list_name(struct prefix_list *plist) return plist->name; } +afi_t prefix_list_afi(struct prefix_list *plist) +{ + if (plist->master == &prefix_master_ipv4 + || plist->master == &prefix_master_orf_v4) + return AFI_IP; + return AFI_IP6; +} + /* Lookup prefix_list from list of prefix_list by name. */ static struct prefix_list *prefix_list_lookup_do(afi_t afi, int orf, const char *name) diff --git a/lib/plist.h b/lib/plist.h index 73d8da509..3eba3046a 100644 --- a/lib/plist.h +++ b/lib/plist.h @@ -48,6 +48,7 @@ extern void prefix_list_add_hook(void (*func)(struct prefix_list *)); extern void prefix_list_delete_hook(void (*func)(struct prefix_list *)); extern const char *prefix_list_name(struct prefix_list *); +extern afi_t prefix_list_afi(struct prefix_list *); extern struct prefix_list *prefix_list_lookup(afi_t, const char *); extern enum prefix_list_type prefix_list_apply(struct prefix_list *, void *); diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c index f198ac4af..36528d063 100644 --- a/ospf6d/ospf6_abr.c +++ b/ospf6d/ospf6_abr.c @@ -386,27 +386,20 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route, } /* Check filter-list */ - if (PREFIX_NAME_OUT(area)) { - if (PREFIX_LIST_OUT(area) == NULL) - PREFIX_LIST_OUT(area) = prefix_list_lookup( - AFI_IP6, PREFIX_NAME_OUT(area)); - - if (PREFIX_LIST_OUT(area)) - if (prefix_list_apply(PREFIX_LIST_OUT(area), - &route->prefix) - != PREFIX_PERMIT) { - if (is_debug) { - inet_ntop(AF_INET, - &(ADV_ROUTER_IN_PREFIX( - &route->prefix)), - buf, sizeof(buf)); - zlog_debug( - "prefix %s was denied by filter-list out", - buf); - } - return 0; + if (PREFIX_LIST_OUT(area)) + if (prefix_list_apply(PREFIX_LIST_OUT(area), &route->prefix) + != PREFIX_PERMIT) { + if (is_debug) { + inet_ntop(AF_INET, + &(ADV_ROUTER_IN_PREFIX( + &route->prefix)), + buf, sizeof(buf)); + zlog_debug( + "prefix %s was denied by filter-list out", + buf); } - } + return 0; + } /* the route is going to be originated. store it in area's summary_table */ @@ -873,22 +866,16 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa) } /* Check input prefix-list */ - if (PREFIX_NAME_IN(oa)) { - if (PREFIX_LIST_IN(oa) == NULL) - PREFIX_LIST_IN(oa) = - prefix_list_lookup(AFI_IP6, PREFIX_NAME_IN(oa)); - - if (PREFIX_LIST_IN(oa)) - if (prefix_list_apply(PREFIX_LIST_IN(oa), &prefix) - != PREFIX_PERMIT) { - if (is_debug) - zlog_debug( - "Prefix was denied by prefix-list"); - if (old) - ospf6_route_remove(old, table); - return; - } - } + if (PREFIX_LIST_IN(oa)) + if (prefix_list_apply(PREFIX_LIST_IN(oa), &prefix) + != PREFIX_PERMIT) { + if (is_debug) + zlog_debug( + "Prefix was denied by prefix-list"); + if (old) + ospf6_route_remove(old, table); + return; + } /* (5),(6): the path preference is handled by the sorting in the routing table. Always install the path by substituting diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index a4cc0bf42..649d7a100 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -45,6 +45,8 @@ #include "ospf6_asbr.h" #include "ospf6d.h" +DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name") + int ospf6_area_cmp(void *va, void *vb) { struct ospf6_area *oa = (struct ospf6_area *)va; @@ -579,17 +581,15 @@ DEFUN (area_filter_list, plist = prefix_list_lookup(AFI_IP6, plistname); if (strmatch(inout, "in")) { PREFIX_LIST_IN(area) = plist; - if (PREFIX_NAME_IN(area)) - free(PREFIX_NAME_IN(area)); - - PREFIX_NAME_IN(area) = strdup(plistname); + XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_IN(area)); + PREFIX_NAME_IN(area) = XSTRDUP(MTYPE_OSPF6_PLISTNAME, + plistname); ospf6_abr_reimport(area); } else { PREFIX_LIST_OUT(area) = plist; - if (PREFIX_NAME_OUT(area)) - free(PREFIX_NAME_OUT(area)); - - PREFIX_NAME_OUT(area) = strdup(plistname); + XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area)); + PREFIX_NAME_OUT(area) = XSTRDUP(MTYPE_OSPF6_PLISTNAME, + plistname); ospf6_abr_enable_area(area); } @@ -622,27 +622,34 @@ DEFUN (no_area_filter_list, return CMD_SUCCESS; PREFIX_LIST_IN(area) = NULL; - if (PREFIX_NAME_IN(area)) - free(PREFIX_NAME_IN(area)); - - PREFIX_NAME_IN(area) = NULL; + XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_IN(area)); ospf6_abr_reimport(area); } else { if (PREFIX_NAME_OUT(area)) if (!strmatch(PREFIX_NAME_OUT(area), plistname)) return CMD_SUCCESS; - PREFIX_LIST_OUT(area) = NULL; - if (PREFIX_NAME_OUT(area)) - free(PREFIX_NAME_OUT(area)); - - PREFIX_NAME_OUT(area) = NULL; + XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area)); ospf6_abr_enable_area(area); } return CMD_SUCCESS; } +void ospf6_area_plist_update(struct prefix_list *plist, int add) +{ + struct ospf6_area *oa; + struct listnode *n; + const char *name = prefix_list_name(plist); + + for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) { + if (!strcmp(PREFIX_NAME_IN(oa), name)) + PREFIX_LIST_IN(oa) = add ? plist : NULL; + if (!strcmp(PREFIX_NAME_OUT(oa), name)) + PREFIX_LIST_OUT(oa) = add ? plist : NULL; + } +} + DEFUN (area_import_list, area_import_list_cmd, "area A.B.C.D import-list NAME", diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h index 4bc24a6dd..d212d9238 100644 --- a/ospf6d/ospf6_area.h +++ b/ospf6d/ospf6_area.h @@ -122,6 +122,7 @@ extern void ospf6_area_disable(struct ospf6_area *); extern void ospf6_area_show(struct vty *, struct ospf6_area *); +extern void ospf6_area_plist_update(struct prefix_list *plist, int add); extern void ospf6_area_config_write(struct vty *vty); extern void ospf6_area_init(void); diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c index f6b9e0ec1..84a56fb50 100644 --- a/ospf6d/ospf6d.c +++ b/ospf6d/ospf6d.c @@ -24,6 +24,7 @@ #include "linklist.h" #include "vty.h" #include "command.h" +#include "plist.h" #include "ospf6_proto.h" #include "ospf6_network.h" @@ -1139,6 +1140,20 @@ DEFUN (show_ipv6_ospf6_linkstate_detail, return CMD_SUCCESS; } +static void ospf6_plist_add(struct prefix_list *plist) +{ + if (prefix_list_afi(plist) != AFI_IP6) + return; + ospf6_area_plist_update(plist, 1); +} + +static void ospf6_plist_del(struct prefix_list *plist) +{ + if (prefix_list_afi(plist) != AFI_IP6) + return; + ospf6_area_plist_update(plist, 0); +} + /* Install ospf related commands. */ void ospf6_init(void) { @@ -1154,6 +1169,9 @@ void ospf6_init(void) ospf6_asbr_init(); ospf6_abr_init(); + prefix_list_add_hook(ospf6_plist_add); + prefix_list_delete_hook(ospf6_plist_del); + ospf6_bfd_init(); install_node(&debug_node, config_write_ospf6_debug); |