summaryrefslogtreecommitdiff
path: root/ospfd/ospfd.c
diff options
context:
space:
mode:
authorpaul <paul>2005-10-29 12:50:09 +0000
committerpaul <paul>2005-10-29 12:50:09 +0000
commit88d6cf37f66c3b7d1abdaa20875418192d5219b8 (patch)
tree4843e77f622d3bf9e5df5c75de381e06e3126d6b /ospfd/ospfd.c
parent92779fe51dd061ab1502a9acdc0cf5241748e0c7 (diff)
2005-10-29 Paul Jakma <paul.jakma@sun.com>
* (general) RFC3137 stub-router support * ospfd.h: Add OSPF_OUTPUT_COST_INFINITE define. (struct ospf_master) Add a OSPF_MASTER_SHUTDOWN flag for options, to allow shutdown to distinguish between complete shutdown and shutdown of a subset of ospf instances. (struct ospf) Add stub_router_{startup,shutdown_}time, configuration of startup and shutdown time for stub-router. Add t_graceful_shutdown struct thread, timer for graceful shutdown, if needed. (struct ospf_area) Add stub_router_state - run time state of stub-router for an area. Add flags for ADMIN, IS and WAS states. Add t_stub_router, timer thread to resend router-lsa for an area. * ospf_lsa.c: (ospf_link_cost) new simple function to spit out either the given lnks cost or infinite cost if stub-router is in effect. (lsa_link_{ptop,broadcast,virtuallink,ptomp}_set) use previous function for transit-links. (ospf_stub_router_timer) timer thread for end of startup stub router. Change state as required for the area and setup re-origination of router-lsa. (ospf_stub_router_check) Check/do whether stub-router should be enabled, and whether it requires timer to be setup. (ospf_router_lsa_new) call previous function at top. (ospf_router_lsa_originate) no external callers, made static. * ospf_lsa.h: (ospf_router_lsa_originate) removed. * ospf_main.c: (sigint) make static. remove call to exit, as ospf_terminate now deals with exiting. * ospf_route.c: (ospf_terminate) removed, now in ospfd.c. * ospf_vty.c: (show_ip_ospf_area) print out state of stub-router, if active. (show_ip_ospf) print out configuration of stub-router support, and details of graceful-shutdown if the timer is active. ((no)?ospf_max_metric_router_lsa_{admin,startup,shutdown}) new commands to (de-)?configure stub-router support. (config_write_stub_router) write out config of stub-router. (ospf_config_write) call previous. (ospf_vty_init) install the new stub-router commands. * ospfd.c: various functions made static. (ospf_new) Set defaults for stub-router. Graceful shutdown is made to default on, just to be adventerous. (ospf_graceful_shutdown_finish) new function, final part of shutdown. (ospf_graceful_shutdown_timer) timer thread wrapper for graceful-shutdown. (ospf_graceful_shutdown_check) check whether to setup timer for shutdown or proceed directly to final shutdown. (ospf_terminate) moved here from ospf_route.c, call ospf_finish for each instance. (ospf_finish) renamed to ospf_finish_final and made static. (ospf_finish) new function, exported wrapper around ospf_graceful_shutdown_check. (ospf_finish_final) complete shutdown of an instance. Add missing TIMER_OFF's of two timer threads. (ospf_area_free) opaque self lsa timer should be turned off.
Diffstat (limited to 'ospfd/ospfd.c')
-rw-r--r--ospfd/ospfd.c140
1 files changed, 130 insertions, 10 deletions
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index bf8ca4dc..69f091d7 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -64,13 +64,14 @@ extern struct zclient *zclient;
extern struct in_addr router_id_zebra;
-void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
-void ospf_network_free (struct ospf *, struct ospf_network *);
-void ospf_area_free (struct ospf_area *);
-void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
+static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);
+static void ospf_network_free (struct ospf *, struct ospf_network *);
+static void ospf_area_free (struct ospf_area *);
+static void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *);
+static void ospf_finish_final (struct ospf *);
#define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1
-
+
void
ospf_router_id_update (struct ospf *ospf)
{
@@ -172,7 +173,10 @@ ospf_new (void)
new->new_external_route = route_table_init ();
new->old_external_route = route_table_init ();
new->external_lsas = route_table_init ();
-
+
+ new->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED;
+ new->stub_router_shutdown_time = OSPF_STUB_ROUTER_SHUTDOWN_DEFAULT;
+
/* Distribute parameter init. */
for (i = 0; i <= ZEBRA_ROUTE_MAX; i++)
{
@@ -263,10 +267,117 @@ ospf_get ()
return ospf;
}
+
+/* Handle the second half of graceful shutdown. This is called either
+ * from the graceful-shutdown timer thread, or directly through
+ * ospf_graceful_shutdown_check.
+ *
+ * Function is to cleanup G-R state, if required then call ospf_finish_final
+ * to complete shutdown of this ospf instance. Possibly exit if the
+ * whole process is being shutdown and this was the last OSPF instance.
+ */
+static void
+ospf_graceful_shutdown_finish (struct ospf *ospf)
+{
+ ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED;
+ OSPF_TIMER_OFF (ospf->t_graceful_shutdown);
+
+ ospf_finish_final (ospf);
+
+ /* *ospf is now invalid */
+
+ /* ospfd being shut-down? If so, was this the last ospf instance? */
+ if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN)
+ && (listcount (om->ospf) == 0))
+ exit (0);
+
+ return;
+}
+
+/* Timer thread for G-R */
+static int
+ospf_graceful_shutdown_timer (struct thread *t)
+{
+ struct ospf *ospf = THREAD_ARG(t);
+
+ ospf_graceful_shutdown_finish (ospf);
+
+ return 0;
+}
+
+/* Check whether graceful-shutdown must be scheduled, otherwise call
+ * down directly into second-half of instance shutdown.
+ */
+static void
+ospf_graceful_shutdown_check (struct ospf *ospf)
+{
+ unsigned long timeout;
+ struct listnode *ln;
+ struct ospf_area *area;
+
+ /* graceful shutdown already running? */
+ if (ospf->t_graceful_shutdown)
+ return;
+
+ /* Should we try push out max-metric LSAs? */
+ if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
+ {
+ for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area))
+ {
+ SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);
+
+ if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED))
+ ospf_router_lsa_timer_add (area);
+ }
+ timeout = ospf->stub_router_shutdown_time;
+ }
+ else
+ /* No timer needed */
+ return ospf_graceful_shutdown_finish (ospf);
+
+ OSPF_TIMER_ON (ospf->t_graceful_shutdown, ospf_graceful_shutdown_timer,
+ timeout);
+ return;
+}
+
+/* Shut down the entire process */
+void
+ospf_terminate (void)
+{
+ struct ospf *ospf;
+ struct listnode *node, *nnode;
+
+ /* shutdown already in progress */
+ if (CHECK_FLAG (om->options, OSPF_MASTER_SHUTDOWN))
+ return;
+
+ SET_FLAG (om->options, OSPF_MASTER_SHUTDOWN);
+
+ for (ALL_LIST_ELEMENTS (om->ospf, node, nnode, ospf))
+ ospf_finish (ospf);
+
+ /* Deliberately go back up, hopefully to thread scheduler, as
+ * One or more ospf_finish()'s may have deferred shutdown to a timer
+ * thread
+ */
+}
void
ospf_finish (struct ospf *ospf)
{
+ /* let graceful shutdown decide */
+ return ospf_graceful_shutdown_check (ospf);
+
+ /* if ospf_graceful_shutdown returns, then ospf_finish_final is
+ * deferred to expiry of G-S timer thread. Return back up, hopefully
+ * to thread scheduler.
+ */
+}
+
+/* Final cleanup of ospf instance */
+static void
+ospf_finish_final (struct ospf *ospf)
+{
struct route_node *rn;
struct ospf_nbr_nbma *nbr_nbma;
struct ospf_lsa *lsa;
@@ -279,8 +390,11 @@ ospf_finish (struct ospf *ospf)
#ifdef HAVE_OPAQUE_LSA
ospf_opaque_type11_lsa_term (ospf);
#endif /* HAVE_OPAQUE_LSA */
-
- /* Unredister redistribution */
+
+ /* be nice if this worked, but it doesn't */
+ /*ospf_flush_self_originated_lsas_now (ospf);*/
+
+ /* Unregister redistribution */
for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
ospf_redistribute_unset (ospf, i);
@@ -347,10 +461,12 @@ ospf_finish (struct ospf *ospf)
OSPF_TIMER_OFF (ospf->t_maxage);
OSPF_TIMER_OFF (ospf->t_maxage_walker);
OSPF_TIMER_OFF (ospf->t_abr_task);
+ OSPF_TIMER_OFF (ospf->t_asbr_check);
OSPF_TIMER_OFF (ospf->t_distribute_update);
OSPF_TIMER_OFF (ospf->t_lsa_refresher);
OSPF_TIMER_OFF (ospf->t_read);
OSPF_TIMER_OFF (ospf->t_write);
+ OSPF_TIMER_OFF (ospf->t_opaque_lsa_self);
close (ospf->fd);
stream_free(ospf->ibuf);
@@ -435,7 +551,7 @@ ospf_area_new (struct ospf *ospf, struct in_addr area_id)
new->external_routing = OSPF_AREA_DEFAULT;
new->default_cost = 1;
new->auth_type = OSPF_AUTH_NULL;
-
+
/* New LSDB init. */
new->lsdb = ospf_lsdb_new ();
@@ -496,7 +612,11 @@ ospf_area_free (struct ospf_area *area)
/* Cancel timer. */
OSPF_TIMER_OFF (area->t_router_lsa_self);
-
+ OSPF_TIMER_OFF (area->t_stub_router);
+#ifdef HAVE_OPAQUE_LSA
+ OSPF_TIMER_OFF (area->t_opaque_lsa_self);
+#endif /* HAVE_OPAQUE_LSA */
+
if (OSPF_IS_AREA_BACKBONE (area))
area->ospf->backbone = NULL;