* ospf6_abr.[ch], ospf6_area.[ch]: Add area filter-list (in|out)
support and area import and export lists support.
diff --git a/ospf6d/ChangeLog b/ospf6d/ChangeLog
index 711e1a8..9e0505a 100644
--- a/ospf6d/ChangeLog
+++ b/ospf6d/ChangeLog
@@ -1,3 +1,8 @@
+2005-06-24 Harald Welte <laforge@gnumonks.org>
+
+ * ospf6_abr.[ch], ospf6_area.[ch]: Add area filter-list (in|out)
+ support and area import and export lists support.
+
2005-06-24 Yasuhiro Ohara <yasu@sfc.wide.ad.jp>
* ospf6_message.c: Changed to be insensitive to changes of neighbors'
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c
index 7eb8f09..833a1bc 100644
--- a/ospf6d/ospf6_abr.c
+++ b/ospf6d/ospf6_abr.c
@@ -29,6 +29,8 @@
#include "linklist.h"
#include "command.h"
#include "thread.h"
+#include "plist.h"
+#include "filter.h"
#include "ospf6_proto.h"
#include "ospf6_route.h"
@@ -340,6 +342,48 @@
}
}
+ /* Check export list */
+ if (EXPORT_NAME (area))
+ {
+ if (EXPORT_LIST (area) == NULL)
+ EXPORT_LIST (area) =
+ access_list_lookup (AFI_IP6, EXPORT_NAME (area));
+
+ if (EXPORT_LIST (area))
+ if (access_list_apply (EXPORT_LIST (area),
+ &route->prefix) == FILTER_DENY)
+ {
+ if (is_debug)
+ {
+ inet_ntop (AF_INET, &(ADV_ROUTER_IN_PREFIX (&route->prefix)),
+ buf, sizeof(buf));
+ zlog_debug ("prefix %s was denied by export list", buf);
+ }
+ return;
+ }
+ }
+
+ /* 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;
+ }
+ }
+
/* the route is going to be originated. store it in area's summary_table */
if (summary == NULL)
{
@@ -610,6 +654,40 @@
return;
}
+ /* Check import list */
+ if (IMPORT_NAME (oa))
+ {
+ if (IMPORT_LIST (oa) == NULL)
+ IMPORT_LIST (oa) = access_list_lookup (AFI_IP6, IMPORT_NAME (oa));
+
+ if (IMPORT_LIST (oa))
+ if (access_list_apply (IMPORT_LIST (oa), &prefix) == FILTER_DENY)
+ {
+ if (is_debug)
+ zlog_debug ("Prefix was denied by import-list");
+ if (old)
+ ospf6_route_remove (old, table);
+ return;
+ }
+ }
+
+ /* 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;
+ }
+ }
+
/* (5),(6),(7) the path preference is handled by the sorting
in the routing table. Always install the path by substituting
old route (if any). */
@@ -661,6 +739,24 @@
}
}
+void
+ospf6_abr_reimport (struct ospf6_area *oa)
+{
+ struct ospf6_lsa *lsa;
+ u_int16_t type;
+
+ type = htons (OSPF6_LSTYPE_INTER_ROUTER);
+ for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
+ lsa = ospf6_lsdb_type_next (type, lsa))
+ ospf6_abr_examin_summary (lsa, oa);
+
+ type = htons (OSPF6_LSTYPE_INTER_PREFIX);
+ for (lsa = ospf6_lsdb_type_head (type, oa->lsdb); lsa;
+ lsa = ospf6_lsdb_type_next (type, lsa))
+ ospf6_abr_examin_summary (lsa, oa);
+}
+
+
/* Display functions */
int
diff --git a/ospf6d/ospf6_abr.h b/ospf6d/ospf6_abr.h
index ce3c19a..84c6fa5 100644
--- a/ospf6d/ospf6_abr.h
+++ b/ospf6d/ospf6_abr.h
@@ -62,6 +62,7 @@
void ospf6_abr_originate_summary (struct ospf6_route *route);
void ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa);
void ospf6_abr_examin_brouter (u_int32_t router_id);
+void ospf6_abr_reimport (struct ospf6_area *oa);
int config_write_ospf6_debug_abr (struct vty *vty);
void install_element_ospf6_debug_abr ();
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index 57070e1..9368def 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -30,6 +30,8 @@
#include "if.h"
#include "prefix.h"
#include "table.h"
+#include "plist.h"
+#include "filter.h"
#include "ospf6_proto.h"
#include "ospf6_lsa.h"
@@ -414,6 +416,195 @@
}
}
+DEFUN (area_filter_list,
+ area_filter_list_cmd,
+ "area A.B.C.D filter-list prefix WORD (in|out)",
+ "OSPFv6 area parameters\n"
+ "OSPFv6 area ID in IP address format\n"
+ "Filter networks between OSPFv6 areas\n"
+ "Filter prefixes between OSPFv6 areas\n"
+ "Name of an IPv6 prefix-list\n"
+ "Filter networks sent to this area\n"
+ "Filter networks sent from this area\n")
+{
+ struct ospf6_area *area;
+ struct prefix_list *plist;
+
+ OSPF6_CMD_AREA_GET (argv[0], area);
+ argc--;
+ argv++;
+
+ plist = prefix_list_lookup (AFI_IP6, argv[1]);
+ if (strncmp (argv[2], "in", 2) == 0)
+ {
+ PREFIX_LIST_IN (area) = plist;
+ if (PREFIX_NAME_IN (area))
+ free (PREFIX_NAME_IN (area));
+
+ PREFIX_NAME_IN (area) = strdup (argv[1]);
+ 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 (argv[1]);
+ ospf6_abr_enable_area (area);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_area_filter_list,
+ no_area_filter_list_cmd,
+ "no area A.B.C.D filter-list prefix WORD (in|out)",
+ NO_STR
+ "OSPFv6 area parameters\n"
+ "OSPFv6 area ID in IP address format\n"
+ "Filter networks between OSPFv6 areas\n"
+ "Filter prefixes between OSPFv6 areas\n"
+ "Name of an IPv6 prefix-list\n"
+ "Filter networks sent to this area\n"
+ "Filter networks sent from this area\n")
+{
+ struct ospf6_area *area;
+ struct prefix_list *plist;
+
+ OSPF6_CMD_AREA_GET (argv[0], area);
+ argc--;
+ argv++;
+
+ plist = prefix_list_lookup (AFI_IP6, argv[1]);
+ if (strncmp (argv[2], "in", 2) == 0)
+ {
+ if (PREFIX_NAME_IN (area))
+ if (strcmp (PREFIX_NAME_IN (area), argv[1]) != 0)
+ return CMD_SUCCESS;
+
+ PREFIX_LIST_IN (area) = NULL;
+ if (PREFIX_NAME_IN (area))
+ free (PREFIX_NAME_IN (area));
+
+ PREFIX_NAME_IN (area) = NULL;
+ ospf6_abr_reimport (area);
+ }
+ else
+ {
+ if (PREFIX_NAME_OUT (area))
+ if (strcmp (PREFIX_NAME_OUT (area), argv[1]) != 0)
+ return CMD_SUCCESS;
+
+ PREFIX_LIST_OUT (area) = NULL;
+ if (PREFIX_NAME_OUT (area))
+ free (PREFIX_NAME_OUT (area));
+
+ PREFIX_NAME_OUT (area) = NULL;
+ ospf6_abr_enable_area (area);
+ }
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (area_import_list,
+ area_import_list_cmd,
+ "area A.B.C.D import-list NAME",
+ "OSPFv6 area parameters\n"
+ "OSPFv6 area ID in IP address format\n"
+ "Set the filter for networks from other areas announced to the specified one\n"
+ "Name of the acess-list\n")
+{
+ struct ospf6_area *area;
+ struct access_list *list;
+
+ OSPF6_CMD_AREA_GET(argv[0], area);
+
+ list = access_list_lookup (AFI_IP6, argv[1]);
+
+ IMPORT_LIST (area) = list;
+
+ if (IMPORT_NAME (area))
+ free (IMPORT_NAME (area));
+
+ IMPORT_NAME (area) = strdup (argv[1]);
+ ospf6_abr_reimport (area);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_area_import_list,
+ no_area_import_list_cmd,
+ "no area A.B.C.D import-list NAME",
+ "OSPFv6 area parameters\n"
+ "OSPFv6 area ID in IP address format\n"
+ "Unset the filter for networks announced to other areas\n"
+ "NAme of the access-list\n")
+{
+ struct ospf6_area *area;
+
+ OSPF6_CMD_AREA_GET(argv[0], area);
+
+ IMPORT_LIST (area) = 0;
+
+ if (IMPORT_NAME (area))
+ free (IMPORT_NAME (area));
+
+ IMPORT_NAME (area) = NULL;
+ ospf6_abr_reimport (area);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (area_export_list,
+ area_export_list_cmd,
+ "area A.B.C.D export-list NAME",
+ "OSPFv6 area parameters\n"
+ "OSPFv6 area ID in IP address format\n"
+ "Set the filter for networks announced to other areas\n"
+ "Name of the acess-list\n")
+{
+ struct ospf6_area *area;
+ struct access_list *list;
+
+ OSPF6_CMD_AREA_GET(argv[0], area);
+
+ list = access_list_lookup (AFI_IP6, argv[1]);
+
+ EXPORT_LIST (area) = list;
+
+ if (EXPORT_NAME (area))
+ free (EXPORT_NAME (area));
+
+ EXPORT_NAME (area) = strdup (argv[1]);
+ ospf6_abr_enable_area (area);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_area_export_list,
+ no_area_export_list_cmd,
+ "no area A.B.C.D export-list NAME",
+ "OSPFv6 area parameters\n"
+ "OSPFv6 area ID in IP address format\n"
+ "Unset the filter for networks announced to other areas\n"
+ "Name of the access-list\n")
+{
+ struct ospf6_area *area;
+
+ OSPF6_CMD_AREA_GET(argv[0], area);
+
+ EXPORT_LIST (area) = 0;
+
+ if (EXPORT_NAME (area))
+ free (EXPORT_NAME (area));
+
+ EXPORT_NAME (area) = NULL;
+ ospf6_abr_enable_area (area);
+
+ return CMD_SUCCESS;
+}
+
DEFUN (show_ipv6_ospf6_spf_tree,
show_ipv6_ospf6_spf_tree_cmd,
"show ipv6 ospf6 spf tree",
@@ -563,6 +754,15 @@
install_element (OSPF6_NODE, &area_range_cmd);
install_element (OSPF6_NODE, &area_range_advertise_cmd);
install_element (OSPF6_NODE, &no_area_range_cmd);
+
+ install_element (OSPF6_NODE, &area_import_list_cmd);
+ install_element (OSPF6_NODE, &no_area_import_list_cmd);
+ install_element (OSPF6_NODE, &area_export_list_cmd);
+ install_element (OSPF6_NODE, &no_area_export_list_cmd);
+
+ install_element (OSPF6_NODE, &area_filter_list_cmd);
+ install_element (OSPF6_NODE, &no_area_filter_list_cmd);
+
}
diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h
index 0cee638..dd33ac4 100644
--- a/ospf6d/ospf6_area.h
+++ b/ospf6d/ospf6_area.h
@@ -61,6 +61,42 @@
struct thread *thread_router_lsa;
struct thread *thread_intra_prefix_lsa;
u_int32_t router_lsa_size_limit;
+
+ /* Area announce list */
+ struct
+ {
+ char *name;
+ struct access_list *list;
+ } export;
+#define EXPORT_NAME(A) (A)->export.name
+#define EXPORT_LIST(A) (A)->export.list
+
+ /* Area acceptance list */
+ struct
+ {
+ char *name;
+ struct access_list *list;
+ } import;
+#define IMPORT_NAME(A) (A)->import.name
+#define IMPORT_LIST(A) (A)->import.list
+
+ /* Type 3 LSA Area prefix-list */
+ struct
+ {
+ char *name;
+ struct prefix_list *list;
+ } plist_in;
+#define PREFIX_NAME_IN(A) (A)->plist_in.name
+#define PREFIX_LIST_IN(A) (A)->plist_in.list
+
+ struct
+ {
+ char *name;
+ struct prefix_list *list;
+ } plist_out;
+#define PREFIX_NAME_OUT(A) (A)->plist_out.name
+#define PREFIX_LIST_OUT(A) (A)->plist_out.list
+
};
#define OSPF6_AREA_ENABLE 0x01