From b4154c145a2d1d0679983130413b81d44fbb04ab Mon Sep 17 00:00:00 2001 From: JR Rivers Date: Mon, 24 Sep 2012 17:26:53 +0000 Subject: ospfd: respect max-metric over configured cost for summary LSAs ISSUE When max-metric router-lsa administrative is invoked on an ABR created with... area range the summary LSAs are sent out with 65535 (max-metric) added to the normal cost. When max-metric router-lsa administrative is invoked on an ABR created with... area range cost the summary LSAs are sent out with (the max-metric is ignored). This second behavior effectively incapacitates the max-metric function. PATCH This patch evaluates the state of the router and if it's isolated as a stub router (rfc3137) via `max-metric router-lsa`, we unconditionally uses the value of 0xff0000 when advertising summary LSAs. Signed-off-by: JR Rivers Signed-off-by: Scott Feldman Reviewed-by: Ayan Banerjee Reviewed-by: Dinesh Dutt Signed-off-by: David Lamparter --- ospfd/ospf_abr.c | 36 ++++++++++++++++++++++++++++-------- ospfd/ospfd.h | 2 ++ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index 2876eaa7..f5edc99e 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -566,12 +566,20 @@ ospf_check_abr_status (struct ospf *ospf) static void ospf_abr_update_aggregate (struct ospf_area_range *range, - struct ospf_route *or) + struct ospf_route *or, struct ospf_area *area) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_abr_update_aggregate(): Start"); - if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC) + if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED) && + (range->cost != OSPF_STUB_MAX_METRIC_SUMMARY_COST)) + { + range->cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST; + if (IS_DEBUG_OSPF_EVENT) + zlog_debug ("ospf_abr_update_aggregate(): use summary max-metric 0x%08x", + range->cost); + } + else if (range->cost_config != OSPF_AREA_RANGE_COST_UNSPEC) { if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_abr_update_aggregate(): use configured cost %d", @@ -582,12 +590,18 @@ ospf_abr_update_aggregate (struct ospf_area_range *range, else { if (range->specifics == 0) - range->cost = or->cost; /* 1st time get 1st cost */ + { + if (IS_DEBUG_OSPF_EVENT) + zlog_debug ("ospf_abr_update_aggregate(): use or->cost %d", + or->cost); + + range->cost = or->cost; /* 1st time get 1st cost */ + } if (or->cost > range->cost) { if (IS_DEBUG_OSPF_EVENT) - zlog_debug ("ospf_abr_update_aggregate(): largest cost, update"); + zlog_debug ("ospf_abr_update_aggregate(): update to %d", or->cost); range->cost = or->cost; } @@ -711,10 +725,16 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost, { struct ospf_lsa *lsa, *old = NULL; struct summary_lsa *sl = NULL; + u_int32_t full_cost; if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_abr_announce_network_to_area(): Start"); + if (CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) + full_cost = OSPF_STUB_MAX_METRIC_SUMMARY_COST; + else + full_cost = cost; + old = ospf_lsa_lookup_by_prefix (area->lsdb, OSPF_SUMMARY_LSA, (struct prefix_ipv4 *) p, area->ospf->router_id); @@ -730,7 +750,7 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost, "old metric: %d, new metric: %d", GET_METRIC (sl->metric), cost); - if ((GET_METRIC (sl->metric) == cost) && + if ((GET_METRIC (sl->metric) == full_cost) && ((old->flags & OSPF_LSA_IN_MAXAGE) == 0)) { /* unchanged. simply reapprove it */ @@ -745,7 +765,7 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost, if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_abr_announce_network_to_area(): " "refreshing summary"); - set_metric (old, cost); + set_metric (old, full_cost); lsa = ospf_lsa_refresh (area->ospf, old); if (!lsa) @@ -769,7 +789,7 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost, if (IS_DEBUG_OSPF_EVENT) zlog_debug ("ospf_abr_announce_network_to_area(): " "creating new summary"); - lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, cost, area); + lsa = ospf_summary_lsa_originate ( (struct prefix_ipv4 *)p, full_cost, area); /* This will flood through area. */ if (!lsa) @@ -930,7 +950,7 @@ ospf_abr_announce_network (struct ospf *ospf, inet_ntoa (p->prefix), p->prefixlen); if ((range = ospf_area_range_match (or_area, p)) && !ospf_area_is_transit (area)) - ospf_abr_update_aggregate (range, or); + ospf_abr_update_aggregate (range, or, area); else ospf_abr_announce_network_to_area (p, or->cost, area); } diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 7a56d163..bf825d17 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -196,6 +196,8 @@ struct ospf unsigned int stub_router_shutdown_time; /* seconds */ #define OSPF_STUB_ROUTER_UNCONFIGURED 0 +#define OSPF_STUB_MAX_METRIC_SUMMARY_COST 0x00ff0000 + /* SPF parameters */ unsigned int spf_delay; /* SPF delay time. */ unsigned int spf_holdtime; /* SPF hold time. */ -- cgit v1.2.1