summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2016-11-16 16:14:45 -0200
committerRenato Westphal <renato@opensourcerouting.org>2016-11-25 11:46:06 -0200
commit705e86f06eaea9676099f5a32cbed5599ae474c6 (patch)
treee57d2e3f64ace966f55b7591f90e3609b99e087a
parent8578874d6922538fd7f13dce74db488569446993 (diff)
ripngd: implement optional heuristic suggested by RFC 2080
RFC 2080 - Section 2.4.2: "If the new metric is the same as the old one, examine the timeout for the existing route. If it is at least halfway to the expiration point, switch to the new route. This heuristic is optional, but highly recommended". Implement this optional heuristic only when ECMP is disabled globally ("no allow-ecmp"), otherwise all routes with the same metric should be used. Fixes IxANVL RIPng test 7.21. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
-rw-r--r--ripngd/ripngd.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c
index 2a32b934f2..96206e2b08 100644
--- a/ripngd/ripngd.c
+++ b/ripngd/ripngd.c
@@ -829,8 +829,10 @@ ripng_route_process (struct rte *rte, struct sockaddr_in6 *from,
* with the new one in below. */
break;
- /* Metrics are same. Keep "rinfo" null and the new route
- * is added in the ECMP list in below. */
+ /* Metrics are same. Unless ECMP is disabled, keep "rinfo" null and
+ * the new route is added in the ECMP list in below. */
+ if (! ripng->ecmp)
+ break;
}
}
@@ -874,11 +876,24 @@ ripng_route_process (struct rte *rte, struct sockaddr_in6 *from,
same = (IN6_ARE_ADDR_EQUAL (&rinfo->from, &from->sin6_addr)
&& (rinfo->ifindex == ifp->ifindex));
+ /*
+ * RFC 2080 - Section 2.4.2:
+ * "If the new metric is the same as the old one, examine the timeout
+ * for the existing route. If it is at least halfway to the expiration
+ * point, switch to the new route. This heuristic is optional, but
+ * highly recommended".
+ */
+ if (!ripng->ecmp && !same &&
+ rinfo->metric == rte->metric && rinfo->t_timeout &&
+ (thread_timer_remain_second (rinfo->t_timeout) < (ripng->timeout_time / 2)))
+ {
+ ripng_ecmp_replace (&newinfo);
+ }
/* Next, compare the metrics. If the datagram is from the same
router as the existing route, and the new metric is different
than the old one; or, if the new metric is lower than the old
one; do the following actions: */
- if ((same && rinfo->metric != rte->metric) ||
+ else if ((same && rinfo->metric != rte->metric) ||
rte->metric < rinfo->metric)
{
if (listcount (list) == 1)