summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ripd/ripd.c33
1 files changed, 28 insertions, 5 deletions
diff --git a/ripd/ripd.c b/ripd/ripd.c
index df6cf6cf..29e70c44 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -2119,9 +2119,20 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,
/* if (split_horizon == rip_split_horizon) */
if (ri->split_horizon == RIP_SPLIT_HORIZON)
{
- /* We perform split horizon for RIP and connected route. */
- if ((rinfo->type == ZEBRA_ROUTE_RIP ||
- rinfo->type == ZEBRA_ROUTE_CONNECT) &&
+ /*
+ * We perform split horizon for RIP and connected route.
+ * For rip routes, we want to suppress the route if we would
+ * end up sending the route back on the interface that we
+ * learned it from, with a higher metric. For connected routes,
+ * we suppress the route if the prefix is a subset of the
+ * source address that we are going to use for the packet
+ * (in order to handle the case when multiple subnets are
+ * configured on the same interface).
+ */
+ if (rinfo->type == ZEBRA_ROUTE_RIP &&
+ rinfo->ifindex == ifp->ifindex)
+ continue;
+ if (rinfo->type == ZEBRA_ROUTE_CONNECT &&
prefix_match((struct prefix *)p, (struct prefix *)saddr))
continue;
}
@@ -2206,10 +2217,22 @@ rip_output_process (struct interface *ifp, struct prefix *ifaddr,
* for RIP and connected routes.
**/
if (ri->split_horizon == RIP_SPLIT_HORIZON_POISONED_REVERSE) {
- if ((rinfo->type == ZEBRA_ROUTE_RIP ||
- rinfo->type == ZEBRA_ROUTE_CONNECT) &&
+ /*
+ * We perform split horizon for RIP and connected route.
+ * For rip routes, we want to suppress the route if we would
+ * end up sending the route back on the interface that we
+ * learned it from, with a higher metric. For connected routes,
+ * we suppress the route if the prefix is a subset of the
+ * source address that we are going to use for the packet
+ * (in order to handle the case when multiple subnets are
+ * configured on the same interface).
+ */
+ if (rinfo->type == ZEBRA_ROUTE_RIP &&
rinfo->ifindex == ifp->ifindex)
rinfo->metric_out = RIP_METRIC_INFINITY;
+ if (rinfo->type == ZEBRA_ROUTE_CONNECT &&
+ prefix_match((struct prefix *)p, (struct prefix *)saddr))
+ rinfo->metric_out = RIP_METRIC_INFINITY;
}
/* Write RTE to the stream. */