summaryrefslogtreecommitdiff
path: root/proto/ospf
diff options
context:
space:
mode:
Diffstat (limited to 'proto/ospf')
-rw-r--r--proto/ospf/ospf.c25
-rw-r--r--proto/ospf/topology.c32
2 files changed, 32 insertions, 25 deletions
diff --git a/proto/ospf/ospf.c b/proto/ospf/ospf.c
index df6c452e..0a9efd19 100644
--- a/proto/ospf/ospf.c
+++ b/proto/ospf/ospf.c
@@ -446,34 +446,21 @@ ospf_disp(timer * timer)
* import to the filters.
*/
static int
-ospf_import_control(struct proto *P, rte **new, ea_list **attrs, struct linpool *pool)
+ospf_import_control(struct proto *P, rte **new, ea_list **attrs UNUSED, struct linpool *pool UNUSED)
{
struct ospf_proto *p = (struct ospf_proto *) P;
struct ospf_area *oa = ospf_main_area(p);
rte *e = *new;
+ /* Reject our own routes */
if (e->attrs->src->proto == P)
- return -1; /* Reject our own routes */
+ return -1;
+ /* Do not export routes to stub areas */
if (oa_is_stub(oa))
- return -1; /* Do not export routes to stub areas */
-
- ea_list *ea = e->attrs->eattrs;
- u32 m0 = ea_get_int(ea, EA_GEN_IGP_METRIC, LSINFINITY);
- u32 m1 = MIN(m0, LSINFINITY);
- u32 m2 = 10000;
- u32 tag = 0;
-
- /* Hack for setting attributes directly in static protocol */
- if (e->attrs->source == RTS_STATIC)
- {
- m1 = ea_get_int(ea, EA_OSPF_METRIC1, m1);
- m2 = ea_get_int(ea, EA_OSPF_METRIC2, 10000);
- tag = ea_get_int(ea, EA_OSPF_TAG, 0);
- }
+ return -1;
- *attrs = ospf_build_attrs(*attrs, pool, m1, m2, tag, 0);
- return 0; /* Leave decision to the filters */
+ return 0;
}
static struct ea_list *
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;