summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAcee Lindem <acee@lindem.com>2025-03-14 16:02:28 +0000
committerMergify <37929162+mergify[bot]@users.noreply.github.com>2025-03-19 06:56:18 +0000
commit7f87f7e5fc922744f5e832afd5c5d25f8d5f1896 (patch)
treedc194097388241c61c9cc0cfa2a97a67161fb2ed
parent187a4b01f88010c553a7f2ac0d9d3bb2909708b8 (diff)
ospf6d: Disable and delete OSPFv3 areas that no longer have interfaces or configuration.
This fix will delete an OSPFv3 area when all the interfaces and configuration (ranges, NSSA ranges, stub area, NSSA area, filter-list, import-list and export-list) have been removed. The changes provides a general solution to https://github.com/FRRouting/frr/issues/18324. Signed-off-by: Acee Lindem <acee@lindem.com> (cherry picked from commit 04994891fe164b4d5a2819d3bc90e5346f94dc53)
-rw-r--r--ospf6d/ospf6_area.c32
-rw-r--r--ospf6d/ospf6_area.h1
-rw-r--r--ospf6d/ospf6_interface.c3
3 files changed, 36 insertions, 0 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c
index cf5479e18c..f512e60ef2 100644
--- a/ospf6d/ospf6_area.c
+++ b/ospf6d/ospf6_area.c
@@ -360,12 +360,25 @@ void ospf6_area_delete(struct ospf6_area *oa)
ospf6_route_table_delete(oa->summary_router);
listnode_delete(oa->ospf6->area_list, oa);
+
+ if (oa->ospf6->backbone == oa)
+ oa->ospf6->backbone = NULL;
oa->ospf6 = NULL;
/* free area */
XFREE(MTYPE_OSPF6_AREA, oa);
}
+void ospf6_area_no_config_delete(struct ospf6_area *oa)
+{
+ if ((oa->if_list->count == 0) && (oa->range_table->count == 0) &&
+ (oa->nssa_range_table->count == 0) && !IS_AREA_STUB(oa) && !IS_AREA_NSSA(oa) &&
+ !PREFIX_NAME_IN(oa) && !PREFIX_NAME_OUT(oa) && !IMPORT_NAME(oa) && !EXPORT_NAME(oa)) {
+ ospf6_area_disable(oa);
+ ospf6_area_delete(oa);
+ }
+}
+
struct ospf6_area *ospf6_area_lookup_by_area_id(uint32_t area_id)
{
struct ospf6_area *oa;
@@ -409,6 +422,7 @@ void ospf6_area_disable(struct ospf6_area *oa)
struct listnode *node, *nnode;
struct ospf6_interface *oi;
+ UNSET_FLAG(oa->flag, OSPF6_AREA_ACTIVE);
UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
for (ALL_LIST_ELEMENTS(oa->if_list, node, nnode, oi))
@@ -646,6 +660,9 @@ DEFUN (no_area_range,
}
ospf6_route_remove(range, oa->range_table);
+ /* Delete area if no interfaces or configuration. */
+ ospf6_area_no_config_delete(oa);
+
return CMD_SUCCESS;
}
@@ -814,6 +831,9 @@ DEFUN (no_area_filter_list,
if (ospf6_check_and_set_router_abr(area->ospf6))
ospf6_schedule_abr_task(ospf6);
+ /* Delete area if no interfaces or configuration. */
+ ospf6_area_no_config_delete(area);
+
return CMD_SUCCESS;
}
@@ -939,6 +959,9 @@ DEFUN (no_area_import_list,
if (ospf6_check_and_set_router_abr(area->ospf6))
ospf6_schedule_abr_task(ospf6);
+ /* Delete area if no interfaces or configuration. */
+ ospf6_area_no_config_delete(area);
+
return CMD_SUCCESS;
}
@@ -1002,6 +1025,9 @@ DEFUN (no_area_export_list,
if (ospf6_check_and_set_router_abr(area->ospf6))
ospf6_schedule_abr_task(ospf6);
+ /* Delete area if no interfaces or configuration. */
+ ospf6_area_no_config_delete(area);
+
return CMD_SUCCESS;
}
@@ -1338,6 +1364,9 @@ DEFUN (no_ospf6_area_stub_no_summary,
ospf6_area_stub_unset(ospf6, area);
ospf6_area_no_summary_unset(ospf6, area);
+ /* Delete area if no interfaces or configuration. */
+ ospf6_area_no_config_delete(area);
+
return CMD_SUCCESS;
}
@@ -1418,6 +1447,9 @@ DEFPY(no_ospf6_area_nssa, no_ospf6_area_nssa_cmd,
ospf6_area_no_summary_unset(ospf6, area);
ospf6_nssa_default_originate_unset(ospf6, area);
+ /* Delete area if no interfaces or configuration. */
+ ospf6_area_no_config_delete(area);
+
return CMD_SUCCESS;
}
diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h
index d9afd65d81..2ed69cc597 100644
--- a/ospf6d/ospf6_area.h
+++ b/ospf6d/ospf6_area.h
@@ -144,6 +144,7 @@ extern int ospf6_area_cmp(void *va, void *vb);
extern struct ospf6_area *ospf6_area_create(uint32_t area_id,
struct ospf6 *ospf6, int df);
extern void ospf6_area_delete(struct ospf6_area *oa);
+extern void ospf6_area_no_config_delete(struct ospf6_area *oa);
extern struct ospf6_area *ospf6_area_lookup(uint32_t area_id,
struct ospf6 *ospf6);
extern struct ospf6_area *ospf6_area_lookup_by_area_id(uint32_t area_id);
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 7f813ce3cc..b578ed1e4c 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -1822,6 +1822,9 @@ void ospf6_interface_stop(struct ospf6_interface *oi)
if (oa->if_list->count == 0) {
UNSET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
ospf6_abr_disable_area(oa);
+
+ /* Delete area if no interfaces or configuration. */
+ ospf6_area_no_config_delete(oa);
}
}