summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJR Rivers <jrrivers@cumulusnetworks.com>2012-09-24 17:26:53 +0000
committerDavid Lamparter <equinox@opensourcerouting.org>2012-10-25 10:15:58 -0700
commitb4154c145a2d1d0679983130413b81d44fbb04ab (patch)
treef46031cc4f632315fd7ebb71737c971faeb635f4
parent821755530e328182c885c98891af799926bd56bd (diff)
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 <area> range <addr/mask> 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 <area> range <addr/mask> cost <cost> the summary LSAs are sent out with <cost> (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 <jrrivers@cumulusnetworks.com> Signed-off-by: Scott Feldman <sfeldma@cumulusnetworks.com> Reviewed-by: Ayan Banerjee <ayan@cumulusnetworks.com> Reviewed-by: Dinesh Dutt <ddutt@cumulusnetworks.com> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
-rw-r--r--ospfd/ospf_abr.c36
-rw-r--r--ospfd/ospfd.h2
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. */