diff options
Diffstat (limited to 'ospf6d')
-rw-r--r-- | ospf6d/ChangeLog | 5 | ||||
-rw-r--r-- | ospf6d/ospf6_abr.c | 96 | ||||
-rw-r--r-- | ospf6d/ospf6_abr.h | 1 | ||||
-rw-r--r-- | ospf6d/ospf6_area.c | 200 | ||||
-rw-r--r-- | ospf6d/ospf6_area.h | 36 |
5 files changed, 338 insertions, 0 deletions
diff --git a/ospf6d/ChangeLog b/ospf6d/ChangeLog index 711e1a89..9e0505ad 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 7eb8f09c..833a1bc9 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 @@ ospf6_abr_originate_summary_to_area (struct ospf6_route *route, } } + /* 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 @@ ospf6_abr_examin_summary (struct ospf6_lsa *lsa, struct ospf6_area *oa) 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 @@ ospf6_abr_examin_brouter (u_int32_t router_id) } } +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 ce3c19a0..84c6fa5e 100644 --- a/ospf6d/ospf6_abr.h +++ b/ospf6d/ospf6_abr.h @@ -62,6 +62,7 @@ void ospf6_abr_originate_summary_to_area (struct ospf6_route *route, 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 57070e16..9368defe 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 @@ ospf6_area_config_write (struct vty *vty) } } +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 @@ ospf6_area_init () 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 0cee6386..dd33ac47 100644 --- a/ospf6d/ospf6_area.h +++ b/ospf6d/ospf6_area.h @@ -61,6 +61,42 @@ struct ospf6_area 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 |