Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 2 Apr 2015 15:47:37 +0000 (UTC)
From:      Hans Petter Selasky <hselasky@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r280991 - head/sys/netinet
Message-ID:  <201504021547.t32FlbOv036992@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hselasky
Date: Thu Apr  2 15:47:37 2015
New Revision: 280991
URL: https://svnweb.freebsd.org/changeset/base/280991

Log:
  Extend fixes made in r278103 and r38754 by copying the complete packet
  header and not only partial flags and fields. Firewalls can attach
  classification tags to the outgoing mbufs which should be copied to
  all the new fragments. Else only the first fragment will be let
  through by the firewall. This can easily be tested by sending a large
  ping packet through a firewall. It was also discovered that VLAN
  related flags and fields should be copied for packets traversing
  through VLANs. This is all handled by "m_dup_pkthdr()".
  
  Regarding the MAC policy check in ip_fragment(), the tag provided by
  the originating mbuf is copied instead of using the default one
  provided by m_gethdr().
  
  Tested by:		Karim Fodil-Lemelin <fodillemlinkarim at gmail.com>
  MFC after:		2 weeks
  Sponsored by:		Mellanox Technologies
  PR:			7802

Modified:
  head/sys/netinet/ip_output.c

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c	Thu Apr  2 14:43:07 2015	(r280990)
+++ head/sys/netinet/ip_output.c	Thu Apr  2 15:47:37 2015	(r280991)
@@ -774,11 +774,19 @@ smart_frag_failure:
 			IPSTAT_INC(ips_odropped);
 			goto done;
 		}
-		/* make sure the flowid is the same for the fragmented mbufs */
-		M_HASHTYPE_SET(m, M_HASHTYPE_GET(m0));
-		m->m_pkthdr.flowid = m0->m_pkthdr.flowid;
-		/* copy multicast flag, if any */
-		m->m_flags |= (m0->m_flags & M_MCAST);
+		/*
+		 * Make sure the complete packet header gets copied
+		 * from the originating mbuf to the newly created
+		 * mbuf. This also ensures that existing firewall
+		 * classification(s), VLAN tags and so on get copied
+		 * to the resulting fragmented packet(s):
+		 */
+		if (m_dup_pkthdr(m, m0, M_NOWAIT) == 0) {
+			m_free(m);
+			error = ENOBUFS;
+			IPSTAT_INC(ips_odropped);
+			goto done;
+		}
 		/*
 		 * In the first mbuf, leave room for the link header, then
 		 * copy the original IP header including options. The payload
@@ -808,11 +816,9 @@ smart_frag_failure:
 			goto done;
 		}
 		m->m_pkthdr.len = mhlen + len;
-		m->m_pkthdr.rcvif = NULL;
 #ifdef MAC
 		mac_netinet_fragment(m0, m);
 #endif
-		m->m_pkthdr.csum_flags = m0->m_pkthdr.csum_flags;
 		mhip->ip_off = htons(mhip->ip_off);
 		mhip->ip_sum = 0;
 		if (m->m_pkthdr.csum_flags & CSUM_IP & ~if_hwassist_flags) {



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