svn commit: r269768 - projects/vxlan/sys/net
Bryan Venteicher
bryanv at FreeBSD.org
Sun Aug 10 00:03:41 UTC 2014
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);
More information about the svn-src-projects
mailing list