]> git.puffer.fish Git - mirror/frr.git/commitdiff
ospf6d: properly update prefix list references
authorDavid Lamparter <equinox@opensourcerouting.org>
Wed, 23 Aug 2017 14:54:15 +0000 (16:54 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Wed, 23 Aug 2017 22:18:53 +0000 (00:18 +0200)
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>
lib/plist.c
lib/plist.h
ospf6d/ospf6_abr.c
ospf6d/ospf6_area.c
ospf6d/ospf6_area.h
ospf6d/ospf6d.c

index b0cf42ca49980c38c58aa2103953707d863d8910..ebd628d7249cfcc448b34fadf3b76bb5bab441b7 100644 (file)
@@ -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)
index 73d8da509afdd445b4d97228c7631677856ea40a..3eba3046ae6b269f0a690b1a6c0635ea77b162d5 100644 (file)
@@ -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 *);
 
index f198ac4af695266205e1ad68a1656ff65a01f6cf..36528d063ca52f609df83ba94eaa8b3f2cad29a1 100644 (file)
@@ -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
index a4cc0bf42052cbaf8b7e352b97d9d82f8cfb9770..649d7a100041346fba7cb346fa9a53ddf092f6ba 100644 (file)
@@ -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",
index 4bc24a6dd8327fa4a4c5f6a9cd6210bdb6ff318d..d212d9238726971f2e5f2e533aa21aedd189d99a 100644 (file)
@@ -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);
 
index f6b9e0ec140ed116c1ce49370ea4949b6f7ad75c..84a56fb505a46891e099c09a048ac104a0893423 100644 (file)
@@ -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);