How to enable ECMP flow based forwarding ?
Ermal Luçi
eri at freebsd.org
Tue Feb 14 19:52:26 UTC 2017
On Tue, Feb 14, 2017 at 6:13 AM, Andrey V. Elsukov <bu7cher at yandex.ru>
wrote:
> On 14.02.2017 03:23, Olivier Cochard-Labbé wrote:
> > Hi,
> >
> > I'm testing FreeBSD ECMP behavior by adding "options RADIX_MPATH" to my
> > kernel configuration (11-stable).
> > Now I can configure two identical routes toward 2 different next-hop:
> First
> > step achieved :-)
> > But it uses only the first entry and never uses the second one.
> >
> > I've tried to shutdown the first next-hop router (then no more arp-reply
> > from this next-hop): But the ECMP FreeBSD router sticks to its first
> route
> > entry and never try the second entry :-(
> >
> > Is there something else to enable (like RSS?) for having a real ECMP flow
> > based router ?
>
> I think you need to implement some code first. The fastfwd has not
> supported MPATH and tryforward also doesn't support it. For IPv4 you can
> try to add some IPsec security policy to disable ip_tryforward. In this
> case ip_forward() will be used, and it uses rtalloc_mpath_fib(), so,
> probably, it will work.
>
> This seems to be a bug to file and which can quickly be fixed by
presenting same
behaviour that slow path does when RADIX_MPATH is active.
It does not impact performance or any of the problems ip_tryforward() is
trying to
solve.
Try the attached patch it should fix your issues.
--
> WBR, Andrey V. Elsukov
>
> --
> Ermal
>
-------------- next part --------------
diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c
index ea59c10..0a50f62 100644
--- a/sys/netinet/ip_fastfwd.c
+++ b/sys/netinet/ip_fastfwd.c
@@ -108,7 +108,8 @@ __FBSDID("$FreeBSD$");
#include <machine/in_cksum.h>
static struct sockaddr_in *
-ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m)
+ip_findroute(struct route *ro, struct ip *ip, struct in_addr dest,
+ struct mbuf *m)
{
struct sockaddr_in *dst;
struct rtentry *rt;
@@ -121,7 +122,14 @@ ip_findroute(struct route *ro, struct in_addr dest, struct mbuf *m)
dst->sin_family = AF_INET;
dst->sin_len = sizeof(*dst);
dst->sin_addr.s_addr = dest.s_addr;
- in_rtalloc_ign(ro, 0, M_GETFIB(m));
+#ifdef RADIX_MPATH
+ rtalloc_mpath_fib(&ro,
+ ntohl(ip->ip_src.s_addr ^ ip->ip_dst.s_addr),
+ M_GETFIB(m));
+#else
+ in_rtalloc_ign(&ro, 0, M_GETFIB(m));
+#endif
+
/*
* Route there and interface still up?
@@ -305,7 +313,7 @@ passin:
/*
* Find route to destination.
*/
- if ((dst = ip_findroute(&ro, dest, m)) == NULL)
+ if ((dst = ip_findroute(&ro, ip, dest, m)) == NULL)
return NULL; /* icmp unreach already sent */
ifp = ro.ro_rt->rt_ifp;
@@ -366,7 +374,7 @@ forwardlocal:
m->m_flags &= ~M_IP_NEXTHOP;
}
RTFREE(ro.ro_rt);
- if ((dst = ip_findroute(&ro, dest, m)) == NULL)
+ if ((dst = ip_findroute(&ro, ip, dest, m)) == NULL)
return NULL; /* icmp unreach already sent */
ifp = ro.ro_rt->rt_ifp;
}
More information about the freebsd-net
mailing list