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 60f92385dd..1022101eb3 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -1823,6 +1823,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); } }