summaryrefslogtreecommitdiff
path: root/ospf6d/ospf6_area.c
diff options
context:
space:
mode:
Diffstat (limited to 'ospf6d/ospf6_area.c')
-rw-r--r--ospf6d/ospf6_area.c230
1 files changed, 177 insertions, 53 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index 355b8441bd..996892c49c 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -43,9 +43,13 @@
#include "ospf6_intra.h"
#include "ospf6_abr.h"
#include "ospf6_asbr.h"
+#include "ospf6_zebra.h"
#include "ospf6d.h"
#include "lib/json.h"
#include "ospf6_nssa.h"
+#ifndef VTYSH_EXTRACT_PL
+#include "ospf6d/ospf6_area_clippy.c"
+#endif
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_AREA, "OSPF6 area");
DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_PLISTNAME, "Prefix list name");
@@ -189,6 +193,9 @@ static void ospf6_area_stub_update(struct ospf6_area *area)
static int ospf6_area_stub_set(struct ospf6 *ospf6, struct ospf6_area *area)
{
if (!IS_AREA_STUB(area)) {
+ /* Disable NSSA first. */
+ ospf6_area_nssa_unset(ospf6, area);
+
SET_FLAG(area->flag, OSPF6_AREA_STUB);
ospf6_area_stub_update(area);
}
@@ -196,7 +203,7 @@ static int ospf6_area_stub_set(struct ospf6 *ospf6, struct ospf6_area *area)
return 1;
}
-static void ospf6_area_stub_unset(struct ospf6 *ospf6, struct ospf6_area *area)
+void ospf6_area_stub_unset(struct ospf6 *ospf6, struct ospf6_area *area)
{
if (IS_AREA_STUB(area)) {
UNSET_FLAG(area->flag, OSPF6_AREA_STUB);
@@ -228,6 +235,36 @@ static void ospf6_area_no_summary_unset(struct ospf6 *ospf6,
}
}
+static void ospf6_nssa_default_originate_set(struct ospf6 *ospf6,
+ struct ospf6_area *area,
+ int metric, int metric_type)
+{
+ if (!area->nssa_default_originate.enabled) {
+ area->nssa_default_originate.enabled = true;
+ if (++ospf6->nssa_default_import_check.refcnt == 1) {
+ ospf6->nssa_default_import_check.status = false;
+ ospf6_zebra_import_default_route(ospf6, false);
+ }
+ }
+
+ area->nssa_default_originate.metric_value = metric;
+ area->nssa_default_originate.metric_type = metric_type;
+}
+
+static void ospf6_nssa_default_originate_unset(struct ospf6 *ospf6,
+ struct ospf6_area *area)
+{
+ if (area->nssa_default_originate.enabled) {
+ area->nssa_default_originate.enabled = false;
+ if (--ospf6->nssa_default_import_check.refcnt == 0) {
+ ospf6->nssa_default_import_check.status = false;
+ ospf6_zebra_import_default_route(ospf6, true);
+ }
+ area->nssa_default_originate.metric_value = -1;
+ area->nssa_default_originate.metric_type = -1;
+ }
+}
+
/**
* Make new area structure.
*
@@ -269,7 +306,8 @@ struct ospf6_area *ospf6_area_create(uint32_t area_id, struct ospf6 *o, int df)
oa->range_table = OSPF6_ROUTE_TABLE_CREATE(AREA, PREFIX_RANGES);
oa->range_table->scope = oa;
- bf_init(oa->range_table->idspace, 32);
+ oa->nssa_range_table = OSPF6_ROUTE_TABLE_CREATE(AREA, PREFIX_RANGES);
+ oa->nssa_range_table->scope = oa;
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);
@@ -324,6 +362,7 @@ void ospf6_area_delete(struct ospf6_area *oa)
ospf6_route_table_delete(oa->route_table);
ospf6_route_table_delete(oa->range_table);
+ ospf6_route_table_delete(oa->nssa_range_table);
ospf6_route_table_delete(oa->summary_prefix);
ospf6_route_table_delete(oa->summary_router);
@@ -504,7 +543,7 @@ DEFUN (area_range,
struct ospf6_area *oa;
struct prefix prefix;
struct ospf6_route *range;
- uint32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
+ uint32_t cost;
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
@@ -519,29 +558,26 @@ DEFUN (area_range,
range = ospf6_route_lookup(&prefix, oa->range_table);
if (range == NULL) {
- range = ospf6_route_create();
+ range = ospf6_route_create(ospf6);
range->type = OSPF6_DEST_TYPE_RANGE;
range->prefix = prefix;
range->path.area_id = oa->area_id;
range->path.cost = OSPF_AREA_RANGE_COST_UNSPEC;
}
+ /* default settings */
+ cost = OSPF_AREA_RANGE_COST_UNSPEC;
+ UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
+
if (argc > idx_type) {
- if (strmatch(argv[idx_type]->text, "not-advertise")) {
+ if (strmatch(argv[idx_type]->text, "not-advertise"))
SET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
- } else if (strmatch(argv[idx_type]->text, "advertise")) {
- UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
- cost = range->path.u.cost_config;
- } else {
+ else if (strmatch(argv[idx_type]->text, "cost"))
cost = strtoul(argv[5]->arg, NULL, 10);
- UNSET_FLAG(range->flag, OSPF6_ROUTE_DO_NOT_ADVERTISE);
- }
}
range->path.u.cost_config = cost;
- zlog_debug("%s: for prefix %s, flag = %x", __func__,
- argv[idx_ipv6_prefixlen]->arg, range->flag);
if (range->rnode == NULL) {
ospf6_route_add(range, oa->range_table);
}
@@ -641,8 +677,39 @@ void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6)
else
vty_out(vty, " area %s stub\n", oa->name);
}
- if (IS_AREA_NSSA(oa))
- vty_out(vty, " area %s nssa\n", oa->name);
+ if (IS_AREA_NSSA(oa)) {
+ vty_out(vty, " area %s nssa", oa->name);
+ if (oa->nssa_default_originate.enabled) {
+ vty_out(vty, " default-information-originate");
+ if (oa->nssa_default_originate.metric_value
+ != -1)
+ vty_out(vty, " metric %d",
+ oa->nssa_default_originate
+ .metric_value);
+ if (oa->nssa_default_originate.metric_type
+ != DEFAULT_METRIC_TYPE)
+ vty_out(vty, " metric-type 1");
+ }
+ if (oa->no_summary)
+ vty_out(vty, " no-summary");
+ vty_out(vty, "\n");
+ }
+ for (range = ospf6_route_head(oa->nssa_range_table); range;
+ range = ospf6_route_next(range)) {
+ vty_out(vty, " area %s nssa range %pFX", oa->name,
+ &range->prefix);
+
+ if (CHECK_FLAG(range->flag,
+ OSPF6_ROUTE_DO_NOT_ADVERTISE)) {
+ vty_out(vty, " not-advertise");
+ } else {
+ if (range->path.u.cost_config
+ != OSPF_AREA_RANGE_COST_UNSPEC)
+ vty_out(vty, " cost %u",
+ range->path.u.cost_config);
+ }
+ vty_out(vty, "\n");
+ }
if (PREFIX_NAME_IN(oa))
vty_out(vty, " area %s filter-list prefix %s in\n",
oa->name, PREFIX_NAME_IN(oa));
@@ -687,17 +754,17 @@ DEFUN (area_filter_list,
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;
XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area));
PREFIX_NAME_OUT(area) =
XSTRDUP(MTYPE_OSPF6_PLISTNAME, plistname);
-
- /* Redo summaries if required */
- ospf6_abr_reexport(area);
}
+ /* Redo summaries if required */
+ if (ospf6_check_and_set_router_abr(area->ospf6))
+ ospf6_schedule_abr_task(ospf6);
+
return CMD_SUCCESS;
}
@@ -730,7 +797,6 @@ DEFUN (no_area_filter_list,
PREFIX_LIST_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))
@@ -738,9 +804,12 @@ DEFUN (no_area_filter_list,
XFREE(MTYPE_OSPF6_PLISTNAME, PREFIX_NAME_OUT(area));
PREFIX_LIST_OUT(area) = NULL;
- ospf6_abr_reexport(area);
}
+ /* Redo summaries if required */
+ if (ospf6_check_and_set_router_abr(area->ospf6))
+ ospf6_schedule_abr_task(ospf6);
+
return CMD_SUCCESS;
}
@@ -751,19 +820,30 @@ void ospf6_filter_update(struct access_list *access)
struct ospf6 *ospf6;
for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
+ bool update = false;
+
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) {
if (IMPORT_NAME(oa)
- && strcmp(IMPORT_NAME(oa), access->name) == 0)
- ospf6_abr_reimport(oa);
+ && strcmp(IMPORT_NAME(oa), access->name) == 0) {
+ IMPORT_LIST(oa) = access_list_lookup(
+ AFI_IP6, IMPORT_NAME(oa));
+ update = true;
+ }
if (EXPORT_NAME(oa)
- && strcmp(EXPORT_NAME(oa), access->name) == 0)
- ospf6_abr_reexport(oa);
+ && strcmp(EXPORT_NAME(oa), access->name) == 0) {
+ EXPORT_LIST(oa) = access_list_lookup(
+ AFI_IP6, EXPORT_NAME(oa));
+ update = true;
+ }
}
+
+ if (update && ospf6_check_and_set_router_abr(ospf6))
+ ospf6_schedule_abr_task(ospf6);
}
}
-void ospf6_area_plist_update(struct prefix_list *plist, int add)
+void ospf6_plist_update(struct prefix_list *plist)
{
struct listnode *node, *nnode;
struct ospf6_area *oa;
@@ -771,23 +851,29 @@ void ospf6_area_plist_update(struct prefix_list *plist, int add)
const char *name = prefix_list_name(plist);
struct ospf6 *ospf6 = NULL;
-
- if (!om6->ospf6)
+ if (prefix_list_afi(plist) != AFI_IP6)
return;
for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
+ bool update = false;
+
for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) {
if (PREFIX_NAME_IN(oa)
&& !strcmp(PREFIX_NAME_IN(oa), name)) {
- PREFIX_LIST_IN(oa) = add ? plist : NULL;
- ospf6_abr_reexport(oa);
+ PREFIX_LIST_IN(oa) = prefix_list_lookup(
+ AFI_IP6, PREFIX_NAME_IN(oa));
+ update = true;
}
if (PREFIX_NAME_OUT(oa)
&& !strcmp(PREFIX_NAME_OUT(oa), name)) {
- PREFIX_LIST_OUT(oa) = add ? plist : NULL;
- ospf6_abr_reexport(oa);
+ PREFIX_LIST_OUT(oa) = prefix_list_lookup(
+ AFI_IP6, PREFIX_NAME_OUT(oa));
+ update = true;
}
}
+
+ if (update && ospf6_check_and_set_router_abr(ospf6))
+ ospf6_schedule_abr_task(ospf6);
}
}
@@ -817,7 +903,8 @@ DEFUN (area_import_list,
free(IMPORT_NAME(area));
IMPORT_NAME(area) = strdup(argv[idx_name]->arg);
- ospf6_abr_reimport(area);
+ if (ospf6_check_and_set_router_abr(area->ospf6))
+ ospf6_schedule_abr_task(ospf6);
return CMD_SUCCESS;
}
@@ -839,13 +926,14 @@ DEFUN (no_area_import_list,
OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6);
- IMPORT_LIST(area) = 0;
+ IMPORT_LIST(area) = NULL;
if (IMPORT_NAME(area))
free(IMPORT_NAME(area));
IMPORT_NAME(area) = NULL;
- ospf6_abr_reimport(area);
+ if (ospf6_check_and_set_router_abr(area->ospf6))
+ ospf6_schedule_abr_task(ospf6);
return CMD_SUCCESS;
}
@@ -878,7 +966,8 @@ DEFUN (area_export_list,
EXPORT_NAME(area) = strdup(argv[idx_name]->arg);
/* Redo summaries if required */
- ospf6_abr_reexport(area);
+ if (ospf6_check_and_set_router_abr(area->ospf6))
+ ospf6_schedule_abr_task(ospf6);
return CMD_SUCCESS;
}
@@ -900,13 +989,14 @@ DEFUN (no_area_export_list,
OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6);
- EXPORT_LIST(area) = 0;
+ EXPORT_LIST(area) = NULL;
if (EXPORT_NAME(area))
free(EXPORT_NAME(area));
EXPORT_NAME(area) = NULL;
- ospf6_abr_reexport(area);
+ if (ospf6_check_and_set_router_abr(area->ospf6))
+ ospf6_schedule_abr_task(ospf6);
return CMD_SUCCESS;
}
@@ -979,7 +1069,6 @@ DEFUN(show_ipv6_ospf6_spf_tree, show_ipv6_ospf6_spf_tree_cmd,
int idx_vrf = 0;
bool uj = use_json(argc, argv);
- OSPF6_CMD_CHECK_RUNNING();
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
for (ALL_LIST_ELEMENTS_RO(om6->ospf6, node, ospf6)) {
@@ -1039,7 +1128,6 @@ DEFUN(show_ipv6_ospf6_area_spf_tree, show_ipv6_ospf6_area_spf_tree_cmd,
bool all_vrf = false;
int idx_vrf = 0;
- OSPF6_CMD_CHECK_RUNNING();
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (idx_vrf > 0)
idx_ipv4 += 2;
@@ -1123,7 +1211,6 @@ DEFUN(show_ipv6_ospf6_simulate_spf_tree_root,
bool all_vrf = false;
int idx_vrf = 0;
- OSPF6_CMD_CHECK_RUNNING();
OSPF6_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
if (idx_vrf > 0) {
idx_ipv4 += 2;
@@ -1248,18 +1335,27 @@ DEFUN (no_ospf6_area_stub_no_summary,
return CMD_SUCCESS;
}
-DEFUN(ospf6_area_nssa, ospf6_area_nssa_cmd,
- "area <A.B.C.D|(0-4294967295)> nssa",
+DEFPY(ospf6_area_nssa, ospf6_area_nssa_cmd,
+ "area <A.B.C.D|(0-4294967295)>$area_str nssa\
+ [{\
+ default-information-originate$dflt_originate [{metric (0-16777214)$mval|metric-type (1-2)$mtype}]\
+ |no-summary$no_summary\
+ }]",
"OSPF6 area parameters\n"
"OSPF6 area ID in IP address format\n"
"OSPF6 area ID as a decimal value\n"
- "Configure OSPF6 area as nssa\n")
+ "Configure OSPF6 area as nssa\n"
+ "Originate Type 7 default into NSSA area\n"
+ "OSPFv3 default metric\n"
+ "OSPFv3 metric\n"
+ "OSPFv3 metric type for default routes\n"
+ "Set OSPFv3 External Type 1/2 metrics\n"
+ "Do not inject inter-area routes into area\n")
{
- int idx_ipv4_number = 1;
struct ospf6_area *area;
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
- OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6);
+ OSPF6_CMD_AREA_GET(area_str, area, ospf6);
if (!ospf6_area_nssa_set(ospf6, area)) {
vty_out(vty,
@@ -1267,24 +1363,54 @@ DEFUN(ospf6_area_nssa, ospf6_area_nssa_cmd,
return CMD_WARNING_CONFIG_FAILED;
}
+ if (dflt_originate) {
+ if (mval_str == NULL)
+ mval = -1;
+ if (mtype_str == NULL)
+ mtype = DEFAULT_METRIC_TYPE;
+ ospf6_nssa_default_originate_set(ospf6, area, mval, mtype);
+ } else
+ ospf6_nssa_default_originate_unset(ospf6, area);
+
+ if (no_summary)
+ ospf6_area_no_summary_set(ospf6, area);
+ else
+ ospf6_area_no_summary_unset(ospf6, area);
+
+ if (ospf6_check_and_set_router_abr(ospf6)) {
+ ospf6_abr_defaults_to_stub(ospf6);
+ ospf6_abr_nssa_type_7_defaults(ospf6);
+ }
+
return CMD_SUCCESS;
}
-DEFUN(no_ospf6_area_nssa, no_ospf6_area_nssa_cmd,
- "no area <A.B.C.D|(0-4294967295)> nssa",
+DEFPY(no_ospf6_area_nssa, no_ospf6_area_nssa_cmd,
+ "no area <A.B.C.D|(0-4294967295)>$area_str nssa\
+ [{\
+ default-information-originate [{metric (0-16777214)|metric-type (1-2)}]\
+ |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 nssa\n")
+ "Configure OSPF6 area as nssa\n"
+ "Originate Type 7 default into NSSA area\n"
+ "OSPFv3 default metric\n"
+ "OSPFv3 metric\n"
+ "OSPFv3 metric type for default routes\n"
+ "Set OSPFv3 External Type 1/2 metrics\n"
+ "Do not inject inter-area routes into area\n")
{
- int idx_ipv4_number = 2;
struct ospf6_area *area;
VTY_DECLVAR_CONTEXT(ospf6, ospf6);
- OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6);
+ OSPF6_CMD_AREA_GET(area_str, area, ospf6);
ospf6_area_nssa_unset(ospf6, area);
+ ospf6_area_no_summary_unset(ospf6, area);
+ ospf6_nssa_default_originate_unset(ospf6, area);
return CMD_SUCCESS;
}
@@ -1323,8 +1449,6 @@ void ospf6_area_interface_delete(struct ospf6_interface *oi)
struct listnode *node, *nnode;
struct ospf6 *ospf6;
- if (!om6->ospf6)
- return;
for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa))
if (listnode_lookup(oa->if_list, oi))