From 88d6cf37f66c3b7d1abdaa20875418192d5219b8 Mon Sep 17 00:00:00 2001 From: paul Date: Sat, 29 Oct 2005 12:50:09 +0000 Subject: 2005-10-29 Paul Jakma * (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. --- ospfd/ospf_lsa.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 87 insertions(+), 8 deletions(-) (limited to 'ospfd/ospf_lsa.c') diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index a85667e6..31b9a4f1 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -483,6 +483,19 @@ ospf_nbr_lookup_ptop (struct ospf_interface *oi) return nbr; } +/* Determine cost of link, taking RFC3137 stub-router support into + * consideration + */ +static u_int16_t +ospf_link_cost (struct ospf_interface *oi) +{ + /* RFC3137 stub router support */ + if (!CHECK_FLAG (oi->area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) + return oi->output_cost; + else + return OSPF_OUTPUT_COST_INFINITE; +} + /* Set a link information. */ static void link_info_set (struct stream *s, struct in_addr id, @@ -503,6 +516,7 @@ lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi) int links = 0; struct ospf_neighbor *nbr; struct in_addr id, mask; + u_int16_t cost = ospf_link_cost (oi); if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) zlog_debug ("LSA[Type1]: Set link Point-to-Point"); @@ -513,7 +527,7 @@ lsa_link_ptop_set (struct stream *s, struct ospf_interface *oi) /* For unnumbered point-to-point networks, the Link Data field should specify the interface's MIB-II ifIndex value. */ link_info_set (s, nbr->router_id, oi->address->u.prefix4, - LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost); + LSA_LINK_TYPE_POINTOPOINT, 0, cost); links++; } @@ -548,7 +562,8 @@ lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi) { struct ospf_neighbor *dr; struct in_addr id, mask; - + u_int16_t cost = ospf_link_cost (oi); + /* Describe Type 3 Link. */ if (oi->state == ISM_Waiting) { @@ -565,7 +580,7 @@ lsa_link_broadcast_set (struct stream *s, struct ospf_interface *oi) ospf_nbr_count (oi, NSM_Full) > 0) { link_info_set (s, DR (oi), oi->address->u.prefix4, - LSA_LINK_TYPE_TRANSIT, 0, oi->output_cost); + LSA_LINK_TYPE_TRANSIT, 0, cost); } /* Describe type 3 link. */ else @@ -581,7 +596,7 @@ static int lsa_link_loopback_set (struct stream *s, struct ospf_interface *oi) { struct in_addr id, mask; - + /* Describe Type 3 Link. */ if (oi->state != ISM_Loopback) return 0; @@ -597,13 +612,14 @@ static int lsa_link_virtuallink_set (struct stream *s, struct ospf_interface *oi) { struct ospf_neighbor *nbr; + u_int16_t cost = ospf_link_cost (oi); if (oi->state == ISM_PointToPoint) if ((nbr = ospf_nbr_lookup_ptop (oi))) if (nbr->state == NSM_Full) { link_info_set (s, nbr->router_id, oi->address->u.prefix4, - LSA_LINK_TYPE_VIRTUALLINK, 0, oi->output_cost); + LSA_LINK_TYPE_VIRTUALLINK, 0, cost); return 1; } @@ -623,6 +639,7 @@ lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi) struct route_node *rn; struct ospf_neighbor *nbr = NULL; struct in_addr id, mask; + u_int16_t cost = ospf_link_cost (oi); mask.s_addr = 0xffffffff; id.s_addr = oi->address->u.prefix4.s_addr; @@ -641,7 +658,7 @@ lsa_link_ptomp_set (struct stream *s, struct ospf_interface *oi) { link_info_set (s, nbr->router_id, oi->address->u.prefix4, - LSA_LINK_TYPE_POINTOPOINT, 0, oi->output_cost); + LSA_LINK_TYPE_POINTOPOINT, 0, cost); links++; if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) zlog_debug ("PointToMultipoint: set link to %s", @@ -721,7 +738,64 @@ ospf_router_lsa_body_set (struct stream *s, struct ospf_area *area) /* Set # of links here. */ stream_putw_at (s, putp, cnt); } + +static int +ospf_stub_router_timer (struct thread *t) +{ + struct ospf_area *area = THREAD_ARG (t); + + area->t_stub_router = NULL; + + SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED); + + /* clear stub route state and generate router-lsa refresh, don't + * clobber an administratively set stub-router state though. + */ + if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) + return 0; + + UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); + + ospf_router_lsa_timer_add (area); + + return 0; +} +inline static void +ospf_stub_router_check (struct ospf_area *area) +{ + /* area must either be administratively configured to be stub + * or startup-time stub-router must be configured and we must in a pre-stub + * state. + */ + if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED)) + { + SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); + return; + } + + /* not admin-stubbed, check whether startup stubbing is configured and + * whether it's not been done yet + */ + if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED)) + return; + + if (area->ospf->stub_router_startup_time == OSPF_STUB_ROUTER_UNCONFIGURED) + { + /* stub-router is hence done forever for this area, even if someone + * tries configure it (take effect next restart). + */ + SET_FLAG (area->stub_router_state, OSPF_AREA_WAS_START_STUB_ROUTED); + return; + } + + /* startup stub-router configured and not yet done */ + SET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); + + OSPF_AREA_TIMER_ON (area->t_stub_router, ospf_stub_router_timer, + area->ospf->stub_router_startup_time); +} + /* Create new router-LSA. */ static struct ospf_lsa * ospf_router_lsa_new (struct ospf_area *area) @@ -735,6 +809,11 @@ ospf_router_lsa_new (struct ospf_area *area) if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) zlog_debug ("LSA[Type1]: Create router-LSA instance"); + /* check whether stub-router is desired, and if this is the first + * router LSA. + */ + ospf_stub_router_check (area); + /* Create a stream for LSA. */ s = stream_new (OSPF_MAX_LSA_SIZE); lsah = (struct lsa_header *) STREAM_DATA (s); @@ -764,11 +843,11 @@ ospf_router_lsa_new (struct ospf_area *area) } /* Originate Router-LSA. */ -struct ospf_lsa * +static struct ospf_lsa * ospf_router_lsa_originate (struct ospf_area *area) { struct ospf_lsa *new; - + /* Create new router-LSA instance. */ new = ospf_router_lsa_new (area); -- cgit v1.2.1