summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@opensourcerouting.org>2017-08-23 16:54:15 +0200
committerDavid Lamparter <equinox@opensourcerouting.org>2017-08-24 00:18:53 +0200
commit427f8e61bb711b51891dbaee845215ca228951f1 (patch)
treebafe78de9e9f109c2f840eaf4a357511275695aa
parentlib: fix cosmetic issue with exit race (diff)
downloadfrr-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.c8
-rw-r--r--lib/plist.h1
-rw-r--r--ospf6d/ospf6_abr.c59
-rw-r--r--ospf6d/ospf6_area.c41
-rw-r--r--ospf6d/ospf6_area.h1
-rw-r--r--ospf6d/ospf6d.c18
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);