Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 20 Oct 2016 13:48:29 +0000 (UTC)
From:      Andrew Gallatin <gallatin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r307673 - head/sys/net
Message-ID:  <201610201348.u9KDmTpE022296@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gallatin
Date: Thu Oct 20 13:48:29 2016
New Revision: 307673
URL: https://svnweb.freebsd.org/changeset/base/307673

Log:
  Clear mbuf hashtype on loopback when RSS is enabled.
  
  The hashtype on an outgoing mbuf reflects the correct hash on the
  transmit side of the connection.  If this hash persists on loopback,
  the receiving RSS/PCBGROUP code will use it to look up the pcbgroup
  for the transmit side, which will often not match the pcbgroup for the
  receive side of the connection.  This leads to TCP connections
  hanging, and dropping the SYN/ACK packet.   This is essentially
  the same as having a hardware network card generate mbufs with an
  incorrect RSS hash.
  
  There are a number of places which can set the hash on transmit,
  so the simplest fix is to simply clear the hash at loopback time.
  Clearing the hash allows a new, correct hash to be calculated in
  software on the receive side.
  
  Reviewed by:	jtl
  Discussed with:	adrian
  Sponsored by:	Netflix

Modified:
  head/sys/net/if_loop.c

Modified: head/sys/net/if_loop.c
==============================================================================
--- head/sys/net/if_loop.c	Thu Oct 20 13:12:19 2016	(r307672)
+++ head/sys/net/if_loop.c	Thu Oct 20 13:48:29 2016	(r307673)
@@ -36,6 +36,7 @@
 
 #include "opt_inet.h"
 #include "opt_inet6.h"
+#include "opt_rss.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -224,6 +225,10 @@ looutput(struct ifnet *ifp, struct mbuf 
 	if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
 	if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len);
 
+#ifdef RSS
+	M_HASHTYPE_CLEAR(m);
+#endif
+
 	/* BPF writes need to be handled specially. */
 	if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
 		bcopy(dst->sa_data, &af, sizeof(af));



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201610201348.u9KDmTpE022296>