diff options
-rw-r--r-- | ospf6d/ospf6_area.c | 29 | ||||
-rw-r--r-- | ospf6d/ospf6_asbr.c | 18 | ||||
-rw-r--r-- | ospf6d/ospf6_asbr.h | 1 | ||||
-rw-r--r-- | ospf6d/ospf6_interface.c | 22 | ||||
-rw-r--r-- | ospf6d/ospf6_intra.h | 15 | ||||
-rw-r--r-- | ospf6d/ospf6_main.c | 10 | ||||
-rw-r--r-- | ospf6d/ospf6_message.c | 2 | ||||
-rw-r--r-- | ospf6d/ospf6_top.c | 28 | ||||
-rw-r--r-- | ospf6d/ospf6_zebra.c | 4 |
9 files changed, 94 insertions, 35 deletions
diff --git a/ospf6d/ospf6_area.c b/ospf6d/ospf6_area.c index b09d9613c..9a4e30e14 100644 --- a/ospf6d/ospf6_area.c +++ b/ospf6d/ospf6_area.c @@ -193,18 +193,21 @@ ospf6_area_create (u_int32_t area_id, struct ospf6 *o) void ospf6_area_delete (struct ospf6_area *oa) { - struct listnode *n, *nnode; + 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); - /* ospf6 interface list */ - for (ALL_LIST_ELEMENTS (oa->if_list, n, nnode, oi)) - { - ospf6_interface_delete (oi); - } + /* The ospf6_interface structs store configuration + * information which should not be lost/reset when + * deleting an area. + * So just detach the interface from the area and + * keep it around. */ + for (ALL_LIST_ELEMENTS_RO (oa->if_list, n, oi)) + oi->area = NULL; + list_delete (oa->if_list); ospf6_lsdb_delete (oa->lsdb); @@ -257,6 +260,7 @@ ospf6_area_enable (struct ospf6_area *oa) for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi)) ospf6_interface_enable (oi); + ospf6_abr_enable_area (oa); } void @@ -269,6 +273,19 @@ ospf6_area_disable (struct ospf6_area *oa) for (ALL_LIST_ELEMENTS (oa->if_list, node, nnode, oi)) ospf6_interface_disable (oi); + + ospf6_abr_disable_area (oa); + ospf6_lsdb_remove_all (oa->lsdb); + ospf6_lsdb_remove_all (oa->lsdb_self); + + 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); } diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 60df6e6c9..3605e3f87 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -409,6 +409,8 @@ ospf6_asbr_redistribute_unset (int type) ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex, &route->prefix); } + + ospf6_asbr_routemap_unset (type); } void @@ -636,7 +638,6 @@ DEFUN (ospf6_redistribute, return CMD_WARNING; ospf6_asbr_redistribute_unset (type); - ospf6_asbr_routemap_unset (type); ospf6_asbr_redistribute_set (type); return CMD_SUCCESS; } @@ -677,7 +678,6 @@ DEFUN (no_ospf6_redistribute, return CMD_WARNING; ospf6_asbr_redistribute_unset (type); - ospf6_asbr_routemap_unset (type); return CMD_SUCCESS; } @@ -1313,6 +1313,20 @@ ospf6_asbr_init (void) } void +ospf6_asbr_redistribute_reset (void) +{ + int type; + + for (type = 0; type < ZEBRA_ROUTE_MAX; type++) + { + if (type == ZEBRA_ROUTE_OSPF6) + continue; + if (ospf6_zebra_is_redistribute (type)) + ospf6_asbr_redistribute_unset(type); + } +} + +void ospf6_asbr_terminate (void) { route_map_finish (); diff --git a/ospf6d/ospf6_asbr.h b/ospf6d/ospf6_asbr.h index 72e491432..73770cc00 100644 --- a/ospf6d/ospf6_asbr.h +++ b/ospf6d/ospf6_asbr.h @@ -89,6 +89,7 @@ extern void ospf6_asbr_redistribute_remove (int type, int ifindex, extern int ospf6_redistribute_config_write (struct vty *vty); extern void ospf6_asbr_init (void); +extern void ospf6_asbr_redistribute_reset (void); extern void ospf6_asbr_terminate (void); extern int config_write_ospf6_debug_asbr (struct vty *vty); diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 86c0bf688..d9d2d03b0 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -219,31 +219,28 @@ void ospf6_interface_enable (struct ospf6_interface *oi) { UNSET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE); - - oi->thread_send_hello = - thread_add_event (master, ospf6_hello_send, oi, 0); + ospf6_interface_state_update (oi->interface); } void ospf6_interface_disable (struct ospf6_interface *oi) { - struct listnode *node, *nnode; - struct ospf6_neighbor *on; - SET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE); - for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on)) - ospf6_neighbor_delete (on); - - list_delete_all_node (oi->neighbor_list); + thread_execute (master, interface_down, oi, 0); ospf6_lsdb_remove_all (oi->lsdb); + ospf6_lsdb_remove_all (oi->lsdb_self); ospf6_lsdb_remove_all (oi->lsupdate_list); ospf6_lsdb_remove_all (oi->lsack_list); THREAD_OFF (oi->thread_send_hello); THREAD_OFF (oi->thread_send_lsupdate); THREAD_OFF (oi->thread_send_lsack); + + THREAD_OFF (oi->thread_network_lsa); + THREAD_OFF (oi->thread_link_lsa); + THREAD_OFF (oi->thread_intra_prefix_lsa); } static struct in6_addr * @@ -327,6 +324,8 @@ ospf6_interface_state_update (struct interface *ifp) return; if (oi->area == NULL) return; + if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) + return; if (if_is_operative (ifp)) thread_add_event (master, interface_up, oi, 0); @@ -355,6 +354,9 @@ ospf6_interface_connected_route_update (struct interface *ifp) if (oi->area == NULL) return; + if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE)) + return; + /* update "route to advertise" interface route table */ ospf6_route_remove_all (oi->route_connected); diff --git a/ospf6d/ospf6_intra.h b/ospf6d/ospf6_intra.h index a25efa12c..e909da23d 100644 --- a/ospf6d/ospf6_intra.h +++ b/ospf6d/ospf6_intra.h @@ -156,32 +156,37 @@ struct ospf6_intra_prefix_lsa #define OSPF6_ROUTER_LSA_SCHEDULE(oa) \ do { \ - if (! (oa)->thread_router_lsa) \ + if (! (oa)->thread_router_lsa \ + && CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \ (oa)->thread_router_lsa = \ thread_add_event (master, ospf6_router_lsa_originate, oa, 0); \ } while (0) #define OSPF6_NETWORK_LSA_SCHEDULE(oi) \ do { \ - if (! (oi)->thread_network_lsa) \ + if (! (oi)->thread_network_lsa \ + && ! CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ (oi)->thread_network_lsa = \ thread_add_event (master, ospf6_network_lsa_originate, oi, 0); \ } while (0) #define OSPF6_LINK_LSA_SCHEDULE(oi) \ do { \ - if (! (oi)->thread_link_lsa) \ + if (! (oi)->thread_link_lsa \ + && ! CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ (oi)->thread_link_lsa = \ thread_add_event (master, ospf6_link_lsa_originate, oi, 0); \ } while (0) #define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB(oa) \ do { \ - if (! (oa)->thread_intra_prefix_lsa) \ + if (! (oa)->thread_intra_prefix_lsa \ + && CHECK_FLAG((oa)->flag, OSPF6_AREA_ENABLE)) \ (oa)->thread_intra_prefix_lsa = \ thread_add_event (master, ospf6_intra_prefix_lsa_originate_stub, \ oa, 0); \ } while (0) #define OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT(oi) \ do { \ - if (! (oi)->thread_intra_prefix_lsa) \ + if (! (oi)->thread_intra_prefix_lsa \ + && ! CHECK_FLAG((oi)->flag, OSPF6_INTERFACE_DISABLE)) \ (oi)->thread_intra_prefix_lsa = \ thread_add_event (master, ospf6_intra_prefix_lsa_originate_transit, \ oi, 0); \ diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index 17d7654e9..e9919713b 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -41,6 +41,8 @@ #include "ospf6_message.h" #include "ospf6_asbr.h" #include "ospf6_lsa.h" +#include "ospf6_interface.h" +#include "ospf6_zebra.h" /* Default configuration file name for ospf6d. */ #define OSPF6_DEFAULT_CONFIG "ospf6d.conf" @@ -134,12 +136,16 @@ Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS); static void __attribute__ ((noreturn)) ospf6_exit (int status) { - extern struct ospf6 *ospf6; - extern struct zclient *zclient; + struct listnode *node; + struct interface *ifp; if (ospf6) ospf6_delete (ospf6); + for (ALL_LIST_ELEMENTS_RO(iflist, node, ifp)) + if (ifp->info != NULL) + ospf6_interface_delete(ifp->info); + ospf6_message_terminate (); ospf6_asbr_terminate (); ospf6_lsa_terminate (); diff --git a/ospf6d/ospf6_message.c b/ospf6d/ospf6_message.c index caebf5d6b..5fb5a2164 100644 --- a/ospf6d/ospf6_message.c +++ b/ospf6d/ospf6_message.c @@ -1543,7 +1543,7 @@ ospf6_receive (struct thread *thread) } oi = ospf6_interface_lookup_by_ifindex (ifindex); - if (oi == NULL || oi->area == NULL) + if (oi == NULL || oi->area == NULL || CHECK_FLAG(oi->flag, OSPF6_INTERFACE_DISABLE)) { zlog_debug ("Message received on disabled interface"); return 0; diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c index f83e6ab5e..7c0922a6f 100644 --- a/ospf6d/ospf6_top.c +++ b/ospf6d/ospf6_top.c @@ -161,6 +161,8 @@ ospf6_delete (struct ospf6 *o) for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa)) ospf6_area_delete (oa); + + list_delete (o->area_list); ospf6_lsdb_delete (o->lsdb); @@ -202,9 +204,16 @@ ospf6_disable (struct ospf6 *o) for (ALL_LIST_ELEMENTS (o->area_list, node, nnode, oa)) ospf6_area_disable (oa); + /* XXX: This also changes persistent settings */ + ospf6_asbr_redistribute_reset(); + ospf6_lsdb_remove_all (o->lsdb); ospf6_route_remove_all (o->route_table); ospf6_route_remove_all (o->brouter_table); + + THREAD_OFF(o->maxage_remover); + THREAD_OFF(o->t_spf_calc); + THREAD_OFF(o->t_ase_calc); } } @@ -282,8 +291,6 @@ DEFUN (router_ospf6, { if (ospf6 == NULL) ospf6 = ospf6_create (); - if (CHECK_FLAG (ospf6->flag, OSPF6_DISABLED)) - ospf6_enable (ospf6); /* set current ospf point. */ vty->node = OSPF6_NODE; @@ -299,10 +306,13 @@ DEFUN (no_router_ospf6, NO_STR OSPF6_ROUTER_STR) { - if (ospf6 == NULL || CHECK_FLAG (ospf6->flag, OSPF6_DISABLED)) - vty_out (vty, "OSPFv3 is not running%s", VNL); + if (ospf6 == NULL) + vty_out (vty, "OSPFv3 is not configured%s", VNL); else - ospf6_disable (ospf6); + { + ospf6_delete (ospf6); + ospf6 = NULL; + } /* return to config node . */ vty->node = CONFIG_NODE; @@ -435,8 +445,12 @@ DEFUN (ospf6_interface_area, SET_FLAG (oa->flag, OSPF6_AREA_ENABLE); + /* ospf6 process is currently disabled, not much more to do */ + if (CHECK_FLAG (o->flag, OSPF6_DISABLED)) + return CMD_SUCCESS; + /* start up */ - thread_add_event (master, interface_up, oi, 0); + ospf6_interface_enable (oi); /* If the router is ABR, originate summary routes */ if (ospf6_is_router_abr (o)) @@ -861,8 +875,6 @@ config_write_ospf6 (struct vty *vty) /* OSPFv6 configuration. */ if (ospf6 == NULL) return CMD_SUCCESS; - if (CHECK_FLAG (ospf6->flag, OSPF6_DISABLED)) - return CMD_SUCCESS; inet_ntop (AF_INET, &ospf6->router_id_static, router_id, sizeof (router_id)); vty_out (vty, "router ospf6%s", VNL); diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index f09e9d22c..50ecc1700 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -117,7 +117,9 @@ ospf6_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length) ifp->name, ifp->ifindex, ifp->mtu6); #if 0 - /* Why is this commented out? */ + /* XXX: ospf6_interface_if_del is not the right way to handle this, + * because among other thinkable issues, it will also clear all + * settings as they are contained in the struct ospf6_interface. */ ospf6_interface_if_del (ifp); #endif /*0*/ |