summaryrefslogtreecommitdiff
path: root/ripd/ripd.c
diff options
context:
space:
mode:
Diffstat (limited to 'ripd/ripd.c')
-rw-r--r--ripd/ripd.c24
1 files changed, 19 insertions, 5 deletions
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 22777e50..dd9427c5 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -387,7 +387,7 @@ rip_rte_process (struct rte *rte, struct sockaddr_in *from,
int ret;
struct prefix_ipv4 p;
struct route_node *rp;
- struct rip_info *rinfo;
+ struct rip_info *rinfo, rinfotmp;
struct rip_interface *ri;
struct in_addr *nexthop;
u_char oldmetric;
@@ -560,13 +560,27 @@ rip_rte_process (struct rte *rte, struct sockaddr_in *from,
if (same)
rip_timeout_update (rinfo);
+
+ /* Fill in a minimaly temporary rip_info structure, for a future
+ rip_distance_apply() use) */
+ memset (&rinfo,0,sizeof(rinfotmp));
+ IPV4_ADDR_COPY (&rinfotmp.from, &from->sin_addr);
+ rinfotmp.rp=rinfo->rp;
+
+
/* 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, or if the tag has been changed; do the following actions: */
- if ((same && rinfo->metric != rte->metric) ||
- (rte->metric < rinfo->metric) ||
- (same && (rinfo->metric == rte->metric) && ntohs(rte->tag) != rinfo->tag))
+ one, or if the tag has been changed; or if there is a route
+ with a lower administrave distance; or an update of the
+ distance on the actual route; do the following actions: */
+ if (( same && rinfo->metric != rte->metric )
+ || ( rte->metric < rinfo->metric )
+ || ( (same)
+ && (rinfo->metric == rte->metric)
+ && ntohs(rte->tag) != rinfo->tag )
+ || ( rinfo->distance > rip_distance_apply (&rinfotmp) )
+ || ( (rinfo->distance != rip_distance_apply (rinfo)) && same ))
{
/* - Adopt the route from the datagram. That is, put the
new metric in, and adjust the next hop address (if