summaryrefslogtreecommitdiffstats
path: root/ospf6d/ospf6_area.c
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 03:03:39 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2015-05-20 03:03:39 +0200
commitc3c0ac8395502d7e84e94e0281cb72fa37a236c4 (patch)
tree7975560428f010d143f48ad83f7b1099fa471d39 /ospf6d/ospf6_area.c
parentIncrease SO_SNDBUF and SO_RCVBUF to 8MB to avoid drops in large networks. (diff)
downloadfrr-c3c0ac8395502d7e84e94e0281cb72fa37a236c4.tar.xz
frr-c3c0ac8395502d7e84e94e0281cb72fa37a236c4.zip
ospf6d: ospfv3-abr-ecmp-support.patch
OSPFv3: Add ABR support and make ECMP > 4. Signed-off-by: Dinesh G Dutt <ddutt at cumulusnetworks.com> Signed-off-by: Pradosh Mohapatra <pmohapat at cumulusnetworks.com>
Diffstat (limited to 'ospf6d/ospf6_area.c')
-rw-r--r--ospf6d/ospf6_area.c108
1 files changed, 82 insertions, 26 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index 4b4ca1304..12ab7ce03 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -160,6 +160,7 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
oa->range_table = OSPF6_ROUTE_TABLE_CREATE (AREA, PREFIX_RANGES);
oa->range_table->scope = oa;
+ bf_init(oa->range_table->idspace, 32);
oa->summary_prefix = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_PREFIXES);
oa->summary_prefix->scope = oa;
oa->summary_router = OSPF6_ROUTE_TABLE_CREATE (AREA, SUMMARY_ROUTERS);
@@ -182,6 +183,11 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o)
oa->ospf6 = o;
listnode_add_sort (o->area_list, oa);
+ if (area_id == OSPF_AREA_BACKBONE)
+ {
+ 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))
@@ -196,10 +202,6 @@ ospf6_area_delete (struct ospf6_area *oa)
struct listnode *n;
struct ospf6_interface *oi;
- ospf6_route_table_delete (oa->range_table);
- ospf6_route_table_delete (oa->summary_prefix);
- ospf6_route_table_delete (oa->summary_router);
-
/* The ospf6_interface structs store configuration
* information which should not be lost/reset when
* deleting an area.
@@ -217,8 +219,9 @@ ospf6_area_delete (struct ospf6_area *oa)
ospf6_route_table_delete (oa->spf_table);
ospf6_route_table_delete (oa->route_table);
- THREAD_OFF (oa->thread_spf_calculation);
- THREAD_OFF (oa->thread_route_calculation);
+ ospf6_route_table_delete (oa->range_table);
+ ospf6_route_table_delete (oa->summary_prefix);
+ ospf6_route_table_delete (oa->summary_router);
listnode_delete (oa->ospf6->area_list, oa);
oa->ospf6 = NULL;
@@ -281,9 +284,6 @@ ospf6_area_disable (struct ospf6_area *oa)
ospf6_spf_table_finish(oa->spf_table);
ospf6_route_remove_all(oa->route_table);
- THREAD_OFF (oa->thread_spf_calculation);
- THREAD_OFF (oa->thread_route_calculation);
-
THREAD_OFF (oa->thread_router_lsa);
THREAD_OFF (oa->thread_intra_prefix_lsa);
}
@@ -346,20 +346,17 @@ DEFUN (area_range,
int ret;
struct ospf6_area *oa;
struct prefix prefix;
- struct ospf6_route *range;
+ struct ospf6_route *range, *route;
+ u_int32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
OSPF6_CMD_AREA_GET (argv[0], oa);
- argc--;
- argv++;
- ret = str2prefix (argv[0], &prefix);
+ ret = str2prefix (argv[1], &prefix);
if (ret != 1 || prefix.family != AF_INET6)
{
- vty_out (vty, "Malformed argument: %s%s", argv[0], VNL);
+ vty_out (vty, "Malformed argument: %s%s", argv[1], VNL);
return CMD_SUCCESS;
}
- argc--;
- argv++;
range = ospf6_route_lookup (&prefix, oa->range_table);
if (range == NULL)
@@ -367,23 +364,45 @@ DEFUN (area_range,
range = ospf6_route_create ();
range->type = OSPF6_DEST_TYPE_RANGE;
range->prefix = prefix;
+ range->path.area_id = oa->area_id;
+ range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
+ range->linkstate_id =
+ (u_int32_t) htonl(ospf6_new_range_ls_id (oa->range_table));
}
- if (argc)
+ if (argc > 2)
{
- if (! strcmp (argv[0], "not-advertise"))
- SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
- else if (! strcmp (argv[0], "advertise"))
- UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
+ if (strcmp (argv[2], "not-advertise") == 0)
+ {
+ SET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
+ }
+ else if (strcmp (argv[2], "advertise") == 0)
+ {
+ UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
+ }
+ else
+ {
+ VTY_GET_INTEGER_RANGE ("cost", cost, argv[2], 0, OSPF_LS_INFINITY);
+ UNSET_FLAG (range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
+ }
}
- if (range->rnode)
+ range->path.u.cost_config = cost;
+
+ zlog_debug ("%s: for prefix %s, flag = %x\n", __func__, argv[1], range->flag);
+ if (range->rnode == NULL)
{
- vty_out (vty, "Range already defined: %s%s", argv[-1], VNL);
- return CMD_WARNING;
+ ospf6_route_add (range, oa->range_table);
+ }
+
+ 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_route_add (range, oa->range_table);
return CMD_SUCCESS;
}
@@ -396,6 +415,26 @@ ALIAS (area_range,
"Specify IPv6 prefix\n"
)
+ALIAS (area_range,
+ area_range_cost_cmd,
+ "area (A.B.C.D|<0-4294967295>) range X:X::X:X/M cost <0-16777215>",
+ "OSPF area parameters\n"
+ OSPF6_AREA_ID_STR
+ "Summarize routes matching address/mask (border routers only)\n"
+ "Area range prefix\n"
+ "User specified metric for this range\n"
+ "Advertised metric for this range\n")
+
+ALIAS (area_range,
+ area_range_advertise_cost_cmd,
+ "area (A.B.C.D|<0-4294967295>) range X:X::X:X/M advertise cost <0-16777215>",
+ "OSPF area parameters\n"
+ OSPF6_AREA_ID_STR
+ "Summarize routes matching address/mask (border routers only)\n"
+ "Area range prefix\n"
+ "User specified metric for this range\n"
+ "Advertised metric for this range\n")
+
DEFUN (no_area_range,
no_area_range_cmd,
"no area A.B.C.D range X:X::X:X/M",
@@ -408,7 +447,7 @@ DEFUN (no_area_range,
int ret;
struct ospf6_area *oa;
struct prefix prefix;
- struct ospf6_route *range;
+ struct ospf6_route *range, *route;
OSPF6_CMD_AREA_GET (argv[0], oa);
argc--;
@@ -428,6 +467,21 @@ DEFUN (no_area_range,
return CMD_SUCCESS;
}
+ if (ospf6_is_router_abr(oa->ospf6))
+ {
+ /* Blow away the aggregated LSA and route */
+ SET_FLAG (range->flag, OSPF6_ROUTE_REMOVE);
+
+ /* Redo summaries if required */
+ for (route = ospf6_route_head (ospf6->route_table); route;
+ route = ospf6_route_next (route))
+ ospf6_abr_originate_summary(route);
+
+ /* purge the old aggregated summary LSA */
+ ospf6_abr_originate_summary(range);
+ }
+ ospf6_release_range_ls_id(oa->range_table,
+ (u_int32_t) ntohl(range->linkstate_id));
ospf6_route_remove (range, oa->range_table);
return CMD_SUCCESS;
@@ -801,6 +855,8 @@ ospf6_area_init (void)
install_element (OSPF6_NODE, &area_range_cmd);
install_element (OSPF6_NODE, &area_range_advertise_cmd);
+ 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, &area_import_list_cmd);