summaryrefslogtreecommitdiff
path: root/proto/ospf/topology.c
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2018-05-24 14:51:05 +0200
committerOndrej Zajicek (work) <santiago@crfreenet.org>2018-05-24 14:51:05 +0200
commitfeae132e0f9bdc62d2b90bf676d12241af8e794c (patch)
tree2767cf9b23d85fdd7f029e27afe855f758430a60 /proto/ospf/topology.c
parentb24b781117179f301116837f0a39468343e4805b (diff)
Do not initialize route metrics in import_control hook
During route export, the receiving protocol often initialized route metrics to default value in its import_control hook before export filter was executed. This is inconsistent with the expectation that an export filter would process the same route as one in the routing table and it breaks setting these metrics before (e.g. for static routes directly in static protocol). The patch removes the initialization of route metrics in import_control hook, the default values are already handled in rt_notify hook called after export filters. The patch also changed the behavior of OSPF to keep metrics when a route is reannounced between OSPF instances (to be consistent with other protocols) and the behavior when both ospf_metric1 and ospf_metric2 are specified (to have more expected behavior).
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;