aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/ip_output.c
diff options
context:
space:
mode:
authorQing Li <qingli@FreeBSD.org>2010-04-02 05:02:50 +0000
committerQing Li <qingli@FreeBSD.org>2010-04-02 05:02:50 +0000
commitc951da56b4f19a637c7fdf734fc500560a9555de (patch)
treea67d7828eb0348202e91d50a0581743b1596f635 /sys/netinet/ip_output.c
parentca2d42b2a1bb8cefb1c2bf163b67a0f2a062d4b2 (diff)
downloadsrc-c951da56b4f19a637c7fdf734fc500560a9555de.tar.gz
src-c951da56b4f19a637c7fdf734fc500560a9555de.zip
MFC 204902
One of the advantages of enabling ECMP (a.k.a RADIX_MPATH) is to allow for connection load balancing across interfaces. Currently the address alias handling method is colliding with the ECMP code. For example, when two interfaces are configured on the same prefix, only one prefix route is installed. So connection load balancing among the available interfaces is not possible. The other advantage of ECMP is for failover. The issue with the current code, is that the interface link-state is not reflected in the route entry. For example, if there are two interfaces on the same prefix, the cable on one interface is unplugged, new and existing connections should switch over to the other interface. This is not done today and packets go into a black hole. Also, there is a small bug in the kernel where deleting ECMP routes in the userland will always return an error even though the command is successfully executed.
Notes
Notes: svn path=/stable/8/; revision=206067
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r--sys/netinet/ip_output.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index b665bc093302..00c3c3ceacf9 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -208,6 +208,8 @@ again:
*/
rte = ro->ro_rt;
if (rte && ((rte->rt_flags & RTF_UP) == 0 ||
+ rte->rt_ifp == NULL ||
+ !RT_LINK_IS_UP(rte->rt_ifp) ||
dst->sin_family != AF_INET ||
dst->sin_addr.s_addr != ip->ip_dst.s_addr)) {
if (!nortfree)
@@ -279,7 +281,9 @@ again:
#endif
rte = ro->ro_rt;
}
- if (rte == NULL) {
+ if (rte == NULL ||
+ rte->rt_ifp == NULL ||
+ !RT_LINK_IS_UP(rte->rt_ifp)) {
#ifdef IPSEC
/*
* There is no route for this packet, but it is