Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 10 Aug 2014 00:03:40 +0000 (UTC)
From:      Bryan Venteicher <bryanv@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r269768 - projects/vxlan/sys/net
Message-ID:  <53e6b6dc.2dfe.795510cd@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bryanv
Date: Sun Aug 10 00:03:40 2014
New Revision: 269768
URL: http://svnweb.freebsd.org/changeset/base/269768

Log:
  Improve the random source port selection
  
  VXLAN uses a random source port to ensure a reasonable distribution of
  the encapsulated packet flows. If available, use the RSS hash of the
  inner packet. Otherwise, use a constant hash based on the inner frame
  Ethernet header. The previous code would select a different source port
  for each frame, potentially causing out of order processing on the
  destination.

Modified:
  projects/vxlan/sys/net/if_vxlan.c

Modified: projects/vxlan/sys/net/if_vxlan.c
==============================================================================
--- projects/vxlan/sys/net/if_vxlan.c	Sat Aug  9 22:51:26 2014	(r269767)
+++ projects/vxlan/sys/net/if_vxlan.c	Sun Aug 10 00:03:40 2014	(r269768)
@@ -150,7 +150,7 @@ struct vxlan_softc {
 #define VXLAN_FLAG_TEARDOWN	0x0002
 #define VXLAN_FLAG_LEARN	0x0004
 
-	uint32_t			 vxl_last_port_hash;
+	uint32_t			 vxl_port_hash_key;
 	uint16_t			 vxl_min_port;
 	uint16_t			 vxl_max_port;
 	uint8_t				 vxl_ttl;
@@ -310,8 +310,7 @@ static int	vxlan_ioctl_drvspec(struct vx
 static int	vxlan_ioctl_ifflags(struct vxlan_softc *);
 static int	vxlan_ioctl(struct ifnet *, u_long, caddr_t);
 
-static uint16_t vxlan_pick_source_port(struct vxlan_softc *,
-		    const struct ether_header *);
+static uint16_t vxlan_pick_source_port(struct vxlan_softc *, struct mbuf *);
 static void	vxlan_encap_header(struct vxlan_softc *, struct mbuf *,
 		    int, uint16_t, uint16_t);
 static int	vxlan_encap4(struct vxlan_softc *,
@@ -2218,19 +2217,19 @@ vxlan_ioctl(struct ifnet *ifp, u_long cm
 }
 
 static uint16_t
-vxlan_pick_source_port(struct vxlan_softc *sc, const struct ether_header *eh)
+vxlan_pick_source_port(struct vxlan_softc *sc, struct mbuf *m)
 {
-	uint32_t hash;
 	int range;
+	uint32_t hash;
 
 	range = sc->vxl_max_port - sc->vxl_min_port + 1;
 
-	/*
-	 * The specification recommends the source port be based on a hash
-	 * of the inner frame's Ethernet header.
-	 */
-	hash = jenkins_hash(eh, ETHER_HDR_LEN, sc->vxl_last_port_hash);
-	sc->vxl_last_port_hash = hash;
+	if (M_HASHTYPE_GET(m) != M_HASHTYPE_NONE &&
+	    M_HASHTYPE_GET(m) != M_HASHTYPE_OPAQUE)
+		hash = m->m_pkthdr.flowid;
+	else
+		hash = jenkins_hash(m->m_data, ETHER_HDR_LEN,
+		    sc->vxl_port_hash_key);
 
 	return (sc->vxl_min_port + (hash % range));
 }
@@ -2272,7 +2271,7 @@ vxlan_encap4(struct vxlan_softc *sc, con
 
 	ifp = sc->vxl_ifp;
 	srcaddr = sc->vxl_src_addr.in4.sin_addr;
-	srcport = vxlan_pick_source_port(sc, mtod(m, struct ether_header *));
+	srcport = vxlan_pick_source_port(sc, m);
 	dstaddr = fvxlsa->in4.sin_addr;
 	dstport = fvxlsa->in4.sin_port;
 
@@ -2328,7 +2327,7 @@ vxlan_encap6(struct vxlan_softc *sc, con
 
 	ifp = sc->vxl_ifp;
 	srcaddr = &sc->vxl_src_addr.in6.sin6_addr;
-	srcport = vxlan_pick_source_port(sc, mtod(m, struct ether_header *));
+	srcport = vxlan_pick_source_port(sc, m);
 	dstaddr = &fvxlsa->in6.sin6_addr;
 	dstport = fvxlsa->in6.sin6_port;
 
@@ -2639,7 +2638,7 @@ vxlan_clone_create(struct if_clone *ifc,
 	sc->vxl_ifp = ifp;
 	rw_init(&sc->vxl_lock, "vxlanrw");
 	callout_init_rw(&sc->vxl_callout, &sc->vxl_lock, 0);
-	sc->vxl_last_port_hash = arc4random();
+	sc->vxl_port_hash_key = arc4random();
 	vxlan_ftable_init(sc);
 
 	vxlan_sysctl_setup(sc);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?53e6b6dc.2dfe.795510cd>