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>
diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c
index 2876eaa..f5edc99 100644
--- a/ospfd/ospf_abr.c
+++ b/ospfd/ospf_abr.c
@@ -566,12 +566,20 @@
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 @@
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 @@
{
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 @@
"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 @@
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 @@
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 @@
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);
}