summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_area.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 03:03:40 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 03:03:40 +0200
commitca1f4309e6dfbbed7823ff76160c0b2401a58115 (patch)
tree8b9d6170e8bf94182517a24c30579eb9cb367105 /ospf6d/ospf6_area.c
parentospf6d: ospfv3-abr-ecmp-support.patch (diff)
downloadfrr-ca1f4309e6dfbbed7823ff76160c0b2401a58115.tar.xz
frr-ca1f4309e6dfbbed7823ff76160c0b2401a58115.zip
ospf6d: ospfv3-stub-area-support.patch
Support stubby and totally stubby areas in OSPFv3 Signed-off-by: Dinesh G Dutt <ddutt at cumulusnetworks.com> Reviewed-by: Pradosh Mohapatra <pmohapat at cumulusnetworks.com>
Diffstat (limited to 'ospf6d/ospf6_area.c')
-rw-r--r--ospf6d/ospf6_area.c221
1 files changed, 209 insertions, 12 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index 12ab7ce03..c3a90df6d 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -43,6 +43,7 @@
#include "ospf6_interface.h"
#include "ospf6_intra.h"
#include "ospf6_abr.h"
+#include "ospf6_asbr.h"
#include "ospf6d.h"
int
@@ -133,12 +134,82 @@ ospf6_area_route_hook_remove (struct ospf6_route *route)
ospf6_route_remove (copy, ospf6->route_table);
}
+static void
+ospf6_area_stub_update (struct ospf6_area *area)
+{
+
+ if (IS_AREA_STUB (area))
+ {
+ if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
+ zlog_debug ("Stubbing out area for if %s\n", area->name);
+ OSPF6_OPT_CLEAR (area->options, OSPF6_OPT_E);
+ }
+ else if (IS_AREA_ENABLED (area))
+ {
+ if (IS_OSPF6_DEBUG_ORIGINATE (ROUTER))
+ zlog_debug ("Normal area for if %s\n", area->name);
+ OSPF6_OPT_SET (area->options, OSPF6_OPT_E);
+ ospf6_asbr_send_externals_to_area (area);
+ }
+
+ OSPF6_ROUTER_LSA_SCHEDULE(area);
+}
+
+static int
+ospf6_area_stub_set (struct ospf6 *ospf6, struct ospf6_area *area)
+{
+ if (!IS_AREA_STUB(area))
+ {
+ SET_FLAG (area->flag, OSPF6_AREA_STUB);
+ ospf6_area_stub_update (area);
+ }
+
+ return (1);
+}
+
+static void
+ospf6_area_stub_unset (struct ospf6 *ospf6, struct ospf6_area *area)
+{
+ if (IS_AREA_STUB (area))
+ {
+ UNSET_FLAG (area->flag, OSPF6_AREA_STUB);
+ ospf6_area_stub_update (area);
+ }
+}
+
+static void
+ospf6_area_no_summary_set (struct ospf6 *ospf6, struct ospf6_area *area)
+{
+ if (area)
+ {
+ if (!area->no_summary)
+ {
+ area->no_summary = 1;
+ ospf6_abr_range_reset_cost (ospf6);
+ ospf6_abr_prefix_resummarize (ospf6);
+ }
+ }
+}
+
+static void
+ospf6_area_no_summary_unset (struct ospf6 *ospf6, struct ospf6_area *area)
+{
+ if (area)
+ {
+ if (area->no_summary)
+ {
+ area->no_summary = 0;
+ ospf6_abr_range_reset_cost (ospf6);
+ ospf6_abr_prefix_resummarize (ospf6);
+ }
+ }
+}
+
/* Make new area structure */
struct ospf6_area *
ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
{
struct ospf6_area *oa;
- struct ospf6_route *route;
oa = XCALLOC (MTYPE_OSPF6_AREA, sizeof (struct ospf6_area));
@@ -180,6 +251,9 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
OSPF6_OPT_SET (oa->options, OSPF6_OPT_E);
+ SET_FLAG (oa->flag, OSPF6_AREA_ACTIVE);
+ SET_FLAG (oa->flag, OSPF6_AREA_ENABLE);
+
oa->ospf6 = o;
listnode_add_sort (o->area_list, oa);
@@ -188,11 +262,6 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
o->backbone = oa;
}
- /* import athoer area's routes as inter-area routes */
- for (route = ospf6_route_head (o->route_table); route;
- route = ospf6_route_next (route))
- ospf6_abr_originate_summary_to_area (route, oa);
-
return oa;
}
@@ -294,16 +363,46 @@ ospf6_area_show (struct vty *vty, struct ospf6_area *oa)
{
struct listnode *i;
struct ospf6_interface *oi;
+ unsigned long result;
- vty_out (vty, " Area %s%s", oa->name, VNL);
+ if (!IS_AREA_STUB (oa))
+ vty_out (vty, " Area %s%s", oa->name, VNL);
+ else
+ {
+ if (oa->no_summary)
+ {
+ vty_out (vty, " Area %s[Stub, No Summary]%s", oa->name, VNL);
+ }
+ else
+ {
+ vty_out (vty, " Area %s[Stub]%s", oa->name, VNL);
+ }
+ }
vty_out (vty, " Number of Area scoped LSAs is %u%s",
oa->lsdb->count, VNL);
vty_out (vty, " Interface attached to this area:");
for (ALL_LIST_ELEMENTS_RO (oa->if_list, i, oi))
vty_out (vty, " %s", oi->interface->name);
-
vty_out (vty, "%s", VNL);
+
+ if (oa->ts_spf.tv_sec || oa->ts_spf.tv_usec)
+ {
+ result = timeval_elapsed (recent_relative_time (), oa->ts_spf);
+ if (result/TIMER_SECOND_MICRO > 0)
+ {
+ vty_out (vty, "SPF last executed %ld.%lds ago%s",
+ result/TIMER_SECOND_MICRO,
+ result%TIMER_SECOND_MICRO, VTY_NEWLINE);
+ }
+ else
+ {
+ vty_out (vty, "SPF last executed %ldus ago%s",
+ result, VTY_NEWLINE);
+ }
+ }
+ else
+ vty_out (vty, "SPF has not been run%s", VTY_NEWLINE);
}
@@ -346,7 +445,7 @@ DEFUN (area_range,
int ret;
struct ospf6_area *oa;
struct prefix prefix;
- struct ospf6_route *range, *route;
+ struct ospf6_route *range;
u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
OSPF6_CMD_AREA_GET (argv[0], oa);
@@ -398,9 +497,7 @@ DEFUN (area_range,
if (ospf6_is_router_abr (ospf6))
{
/* Redo summaries if required */
- for (route = ospf6_route_head (ospf6->route_table); route;
- route = ospf6_route_next (route))
- ospf6_abr_originate_summary(route);
+ ospf6_abr_prefix_resummarize (ospf6);
}
return CMD_SUCCESS;
@@ -503,6 +600,13 @@ ospf6_area_config_write (struct vty *vty)
prefix2str (&range->prefix, buf, sizeof (buf));
vty_out (vty, " area %s range %s%s", oa->name, buf, VNL);
}
+ if (IS_AREA_STUB (oa))
+ {
+ if (oa->no_summary)
+ vty_out (vty, " area %s stub no-summary%s", oa->name, VNL);
+ else
+ vty_out (vty, " area %s stub%s", oa->name, VNL);
+ }
if (PREFIX_NAME_IN (oa))
vty_out (vty, " area %s filter-list prefix %s in%s",
oa->name, PREFIX_NAME_IN (oa), VNL);
@@ -842,6 +946,94 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
return CMD_SUCCESS;
}
+DEFUN (ospf6_area_stub,
+ ospf6_area_stub_cmd,
+ "area (A.B.C.D|<0-4294967295>) stub",
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
+ "OSPF6 area ID as a decimal value\n"
+ "Configure OSPF6 area as stub\n")
+{
+ struct ospf6_area *area;
+
+ OSPF6_CMD_AREA_GET(argv[0], area);
+
+ if (!ospf6_area_stub_set (ospf6, area))
+ {
+ vty_out (vty, "First deconfigure all virtual link through this area%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ospf6_area_no_summary_unset (ospf6, area);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (ospf6_area_stub_no_summary,
+ ospf6_area_stub_no_summary_cmd,
+ "area (A.B.C.D|<0-4294967295>) stub no-summary",
+ "OSPF6 stub parameters\n"
+ "OSPF6 area ID in IP address format\n"
+ "OSPF6 area ID as a decimal value\n"
+ "Configure OSPF6 area as stub\n"
+ "Do not inject inter-area routes into stub\n")
+{
+ struct ospf6_area *area;
+
+ OSPF6_CMD_AREA_GET(argv[0], area);
+
+ if (!ospf6_area_stub_set (ospf6, area))
+ {
+ vty_out (vty, "First deconfigure all virtual link through this area%s",
+ VTY_NEWLINE);
+ return CMD_WARNING;
+ }
+
+ ospf6_area_no_summary_set (ospf6, area);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ospf6_area_stub,
+ no_ospf6_area_stub_cmd,
+ "no area (A.B.C.D|<0-4294967295>) stub",
+ NO_STR
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
+ "OSPF6 area ID as a decimal value\n"
+ "Configure OSPF6 area as stub\n")
+{
+ struct ospf6_area *area;
+
+ OSPF6_CMD_AREA_GET(argv[0], area);
+
+ ospf6_area_stub_unset (ospf6, area);
+ ospf6_area_no_summary_unset (ospf6, area);
+
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_ospf6_area_stub_no_summary,
+ no_ospf6_area_stub_no_summary_cmd,
+ "no area (A.B.C.D|<0-4294967295>) stub no-summary",
+ NO_STR
+ "OSPF6 area parameters\n"
+ "OSPF6 area ID in IP address format\n"
+ "OSPF6 area ID as a decimal value\n"
+ "Configure OSPF6 area as stub\n"
+ "Do not inject inter-area routes into area\n")
+{
+ struct ospf6_area *area;
+
+ OSPF6_CMD_AREA_GET(argv[0], area);
+
+ ospf6_area_stub_unset (ospf6, area);
+ ospf6_area_no_summary_unset (ospf6, area);
+
+ return CMD_SUCCESS;
+}
+
void
ospf6_area_init (void)
{
@@ -858,6 +1050,11 @@ ospf6_area_init (void)
install_element (OSPF6_NODE, &area_range_cost_cmd);
install_element (OSPF6_NODE, &area_range_advertise_cost_cmd);
install_element (OSPF6_NODE, &no_area_range_cmd);
+ install_element (OSPF6_NODE, &ospf6_area_stub_no_summary_cmd);
+ install_element (OSPF6_NODE, &ospf6_area_stub_cmd);
+ install_element (OSPF6_NODE, &no_ospf6_area_stub_no_summary_cmd);
+ install_element (OSPF6_NODE, &no_ospf6_area_stub_cmd);
+
install_element (OSPF6_NODE, &area_import_list_cmd);
install_element (OSPF6_NODE, &no_area_import_list_cmd);