summaryrefslogtreecommitdiff
path: root/proto/ospf/topology.c
diff options
context:
space:
mode:
Diffstat (limited to 'proto/ospf/topology.c')
-rw-r--r--proto/ospf/topology.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/proto/ospf/topology.c b/proto/ospf/topology.c
index 717c8280..e909bbe9 100644
--- a/proto/ospf/topology.c
+++ b/proto/ospf/topology.c
@@ -1281,14 +1281,34 @@ ospf_rt_notify(struct proto *P, struct channel *ch UNUSED, net *n, rte *new, rte
/* Get route attributes */
rta *a = new->attrs;
- u32 m1 = ea_get_int(ea, EA_OSPF_METRIC1, LSINFINITY);
- u32 m2 = ea_get_int(ea, EA_OSPF_METRIC2, 10000);
- int ebit = (m1 == LSINFINITY);
- u32 metric = ebit ? m2 : m1;
- u32 tag = ea_get_int(ea, EA_OSPF_TAG, 0);
- ip_addr fwd = IPA_NONE;
+ eattr *m1a = ea_find(ea, EA_OSPF_METRIC1);
+ eattr *m2a = ea_find(ea, EA_OSPF_METRIC2);
+ uint m1 = m1a ? m1a->u.data : 0;
+ uint m2 = m2a ? m2a->u.data : 10000;
+ if (m1 > LSINFINITY)
+ {
+ log(L_WARN "%s: Invalid ospf_metric1 value %u for route %N",
+ p->p.name, m1, n->n.addr);
+ m1 = LSINFINITY;
+ }
+ if (m2 > LSINFINITY)
+ {
+ log(L_WARN "%s: Invalid ospf_metric2 value %u for route %N",
+ p->p.name, m2, n->n.addr);
+ m2 = LSINFINITY;
+ }
+
+ /* Ensure monotonicity of metric if both m1 and m2 are used */
+ if ((m1 > 0) && (m2 < LSINFINITY))
+ m2++;
+
+ uint ebit = m2a || !m1a;
+ uint metric = ebit ? m2 : m1;
+ uint tag = ea_get_int(ea, EA_OSPF_TAG, 0);
+
+ ip_addr fwd = IPA_NONE;
if ((a->dest == RTD_UNICAST) && use_gw_for_fwaddr(p, a->nh.gw, a->nh.iface))
fwd = a->nh.gw;