diff options
-rw-r--r-- | doc/bird.sgml | 15 | ||||
-rw-r--r-- | proto/babel/babel.c | 12 | ||||
-rw-r--r-- | proto/ospf/ospf.c | 25 | ||||
-rw-r--r-- | proto/ospf/topology.c | 32 | ||||
-rw-r--r-- | proto/rip/rip.c | 12 |
5 files changed, 46 insertions, 50 deletions
diff --git a/doc/bird.sgml b/doc/bird.sgml index ae308d4c..b4d9ea4e 100644 --- a/doc/bird.sgml +++ b/doc/bird.sgml @@ -1618,9 +1618,7 @@ regarded as empty bgppath/*clist for most purposes. The optional attribute that can be used to specify a distance to the network for routes that do not have a native protocol metric attribute (like <cf/ospf_metric1/ for OSPF routes). It is used mainly by BGP to - compare internal distances to boundary routers (see below). It is also - used when the route is exported to OSPF as a default value for OSPF type - 1 metric. + compare internal distances to boundary routers (see below). </descrip> <p>There also exist protocol-specific attributes which are described in the @@ -3536,8 +3534,15 @@ protocol ospf [v2|v3] <name> { with internal <cf/metric/, a <cf/metric of type 2/ is always longer than any <cf/metric of type 1/ or any <cf/internal metric/. <cf/Internal metric/ or <cf/metric of type 1/ is stored in attribute <cf/ospf_metric1/, <cf/metric type -2/ is stored in attribute <cf/ospf_metric2/. If you specify both metrics only -metric1 is used. +2/ is stored in attribute <cf/ospf_metric2/. + +When both metrics are specified then <cf/metric of type 2/ is used. This is +relevant e.g. when a type 2 external route is propagated from one OSPF domain to +another and <cf/ospf_metric1/ is an internal distance to the original ASBR, +while <cf/ospf_metric2/ stores the type 2 metric. Note that in such cases if +<cf/ospf_metric1/ is non-zero then <cf/ospf_metric2/ is increased by one to +ensure monotonicity of metric, as internal distance is reset to zero when an +external route is announced. <p>Each external route can also carry attribute <cf/ospf_tag/ which is a 32-bit integer which is used when exporting routes to other protocols; otherwise, it diff --git a/proto/babel/babel.c b/proto/babel/babel.c index ce05191c..44c6adb8 100644 --- a/proto/babel/babel.c +++ b/proto/babel/babel.c @@ -2087,20 +2087,14 @@ babel_prepare_attrs(struct linpool *pool, ea_list *next, uint metric, u64 router static int -babel_import_control(struct proto *P, struct rte **new, struct ea_list **attrs, struct linpool *pool) +babel_import_control(struct proto *P, struct rte **new, struct ea_list **attrs UNUSED, struct linpool *pool UNUSED) { - struct babel_proto *p = (void *) P; - rte *rt = *new; + rte *e = *new; /* Reject our own unreachable routes */ - if ((rt->attrs->dest == RTD_UNREACHABLE) && (rt->attrs->src->proto == P)) + if ((e->attrs->dest == RTD_UNREACHABLE) && (e->attrs->src->proto == P)) return -1; - - /* Prepare attributes with initial values */ - if (rt->attrs->source != RTS_BABEL) - *attrs = babel_prepare_attrs(pool, NULL, 0, p->router_id); - return 0; } 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; diff --git a/proto/rip/rip.c b/proto/rip/rip.c index 85e37cea..baf98737 100644 --- a/proto/rip/rip.c +++ b/proto/rip/rip.c @@ -1020,16 +1020,6 @@ rip_prepare_attrs(struct linpool *pool, ea_list *next, u8 metric, u16 tag) return l; } -static int -rip_import_control(struct proto *P UNUSED, struct rte **rt, struct ea_list **attrs, struct linpool *pool) -{ - /* Prepare attributes with initial values */ - if ((*rt)->attrs->source != RTS_RIP) - *attrs = rip_prepare_attrs(pool, *attrs, 1, 0); - - return 0; -} - static void rip_reload_routes(struct channel *C) { @@ -1091,7 +1081,7 @@ rip_init(struct proto_config *CF) P->if_notify = rip_if_notify; P->rt_notify = rip_rt_notify; P->neigh_notify = rip_neigh_notify; - P->import_control = rip_import_control; + // P->import_control = rip_import_control; P->reload_routes = rip_reload_routes; P->make_tmp_attrs = rip_make_tmp_attrs; P->store_tmp_attrs = rip_store_tmp_attrs; |