Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 8 Oct 2012 08:03:59 +0000 (UTC)
From:      Gleb Smirnoff <glebius@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r241344 - in head/sys: netgraph netinet netinet6 netpfil/ipfw netpfil/pf
Message-ID:  <201210080803.q9883xrS059506@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: glebius
Date: Mon Oct  8 08:03:58 2012
New Revision: 241344
URL: http://svn.freebsd.org/changeset/base/241344

Log:
    After r241245 it appeared that in_delayed_cksum(), which still expects
  host byte order, was sometimes called with net byte order. Since we are
  moving towards net byte order throughout the stack, the function was
  converted to expect net byte order, and its consumers fixed appropriately:
    - ip_output(), ipfilter(4) not changed, since already call
      in_delayed_cksum() with header in net byte order.
    - divert(4), ng_nat(4), ipfw_nat(4) now don't need to swap byte order
      there and back.
    - mrouting code and IPv6 ipsec now need to switch byte order there and
      back, but I hope, this is temporary solution.
    - In ipsec(4) shifted switch to net byte order prior to in_delayed_cksum().
    - pf_route() catches up on r241245 changes to ip_output().

Modified:
  head/sys/netgraph/ng_nat.c
  head/sys/netinet/ip_divert.c
  head/sys/netinet/ip_ipsec.c
  head/sys/netinet/ip_mroute.c
  head/sys/netinet/ip_output.c
  head/sys/netinet6/ip6_ipsec.c
  head/sys/netpfil/ipfw/ip_fw_nat.c
  head/sys/netpfil/pf/pf.c

Modified: head/sys/netgraph/ng_nat.c
==============================================================================
--- head/sys/netgraph/ng_nat.c	Mon Oct  8 07:33:43 2012	(r241343)
+++ head/sys/netgraph/ng_nat.c	Mon Oct  8 08:03:58 2012	(r241344)
@@ -756,18 +756,18 @@ ng_nat_rcvdata(hook_p hook, item_p item 
 		 */
 
 		if (th->th_x2) {
+			uint16_t ip_len = ntohs(ip->ip_len);
+
 			th->th_x2 = 0;
-			ip->ip_len = ntohs(ip->ip_len);
 			th->th_sum = in_pseudo(ip->ip_src.s_addr,
 			    ip->ip_dst.s_addr, htons(IPPROTO_TCP +
-			    ip->ip_len - (ip->ip_hl << 2)));
+			    ip_len - (ip->ip_hl << 2)));
 	
 			if ((m->m_pkthdr.csum_flags & CSUM_TCP) == 0) {
 				m->m_pkthdr.csum_data = offsetof(struct tcphdr,
 				    th_sum);
 				in_delayed_cksum(m);
 			}
-			ip->ip_len = htons(ip->ip_len);
 		}
 	}
 

Modified: head/sys/netinet/ip_divert.c
==============================================================================
--- head/sys/netinet/ip_divert.c	Mon Oct  8 07:33:43 2012	(r241343)
+++ head/sys/netinet/ip_divert.c	Mon Oct  8 08:03:58 2012	(r241344)
@@ -208,10 +208,8 @@ divert_packet(struct mbuf *m, int incomi
 
 	/* Delayed checksums are currently not compatible with divert. */
 	if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
-		ip->ip_len = ntohs(ip->ip_len);
 		in_delayed_cksum(m);
 		m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
-		ip->ip_len = htons(ip->ip_len);
 	}
 #ifdef SCTP
 	if (m->m_pkthdr.csum_flags & CSUM_SCTP) {

Modified: head/sys/netinet/ip_ipsec.c
==============================================================================
--- head/sys/netinet/ip_ipsec.c	Mon Oct  8 07:33:43 2012	(r241343)
+++ head/sys/netinet/ip_ipsec.c	Mon Oct  8 08:03:58 2012	(r241344)
@@ -332,6 +332,9 @@ ip_ipsec_output(struct mbuf **m, struct 
 			}
 		}
 
+		ip->ip_len = htons(ip->ip_len);
+		ip->ip_off = htons(ip->ip_off);
+
 		/*
 		 * Do delayed checksums now because we send before
 		 * this is done in the normal processing path.
@@ -346,8 +349,6 @@ ip_ipsec_output(struct mbuf **m, struct 
 			(*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP;
 		}
 #endif
-		ip->ip_len = htons(ip->ip_len);
-		ip->ip_off = htons(ip->ip_off);
 
 		/* NB: callee frees mbuf */
 		*error = ipsec4_process_packet(*m, sp->req, *flags, 0);

Modified: head/sys/netinet/ip_mroute.c
==============================================================================
--- head/sys/netinet/ip_mroute.c	Mon Oct  8 07:33:43 2012	(r241343)
+++ head/sys/netinet/ip_mroute.c	Mon Oct  8 08:03:58 2012	(r241344)
@@ -2376,7 +2376,10 @@ pim_register_prepare(struct ip *ip, stru
 
     /* Take care of delayed checksums */
     if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+	/* XXX: in_delayed_cksum() expects net byte order */
+	ip->ip_len = htons(ip->ip_len);
 	in_delayed_cksum(m);
+	ip->ip_len = ntohs(ip->ip_len);
 	m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
     }
 

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c	Mon Oct  8 07:33:43 2012	(r241343)
+++ head/sys/netinet/ip_output.c	Mon Oct  8 08:03:58 2012	(r241344)
@@ -882,11 +882,12 @@ void
 in_delayed_cksum(struct mbuf *m)
 {
 	struct ip *ip;
-	u_short csum, offset;
+	uint16_t csum, offset, ip_len;
 
 	ip = mtod(m, struct ip *);
 	offset = ip->ip_hl << 2 ;
-	csum = in_cksum_skip(m, ip->ip_len, offset);
+	ip_len = ntohs(ip->ip_len);
+	csum = in_cksum_skip(m, ip_len, offset);
 	if (m->m_pkthdr.csum_flags & CSUM_UDP && csum == 0)
 		csum = 0xffff;
 	offset += m->m_pkthdr.csum_data;	/* checksum offset */

Modified: head/sys/netinet6/ip6_ipsec.c
==============================================================================
--- head/sys/netinet6/ip6_ipsec.c	Mon Oct  8 07:33:43 2012	(r241343)
+++ head/sys/netinet6/ip6_ipsec.c	Mon Oct  8 08:03:58 2012	(r241344)
@@ -295,9 +295,15 @@ ip6_ipsec_output(struct mbuf **m, struct
 		 */
 #ifdef INET
 		if ((*m)->m_pkthdr.csum_flags & CSUM_DELAY_DATA) {
+			struct ip *ip;
+
 			ipseclog((LOG_DEBUG,
 			    "%s: we do not support IPv4 over IPv6", __func__));
+			/* XXX: in_delayed_cksum() expects net byte order */
+			ip = mtod(m, struct ip *);
+			ip->ip_len = htons(ip->ip_len);
 			in_delayed_cksum(*m);
+			ip->ip_len = ntohs(ip->ip_len);
 			(*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
 		}
 #endif

Modified: head/sys/netpfil/ipfw/ip_fw_nat.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_nat.c	Mon Oct  8 07:33:43 2012	(r241343)
+++ head/sys/netpfil/ipfw/ip_fw_nat.c	Mon Oct  8 08:03:58 2012	(r241344)
@@ -336,11 +336,11 @@ ipfw_nat(struct ip_fw_args *args, struct
 	if (ldt) {
 		struct tcphdr 	*th;
 		struct udphdr 	*uh;
-		u_short cksum;
+		uint16_t ip_len, cksum;
 
-		ip->ip_len = ntohs(ip->ip_len);
+		ip_len = ntohs(ip->ip_len);
 		cksum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr,
-		    htons(ip->ip_p + ip->ip_len - (ip->ip_hl << 2)));
+		    htons(ip->ip_p + ip_len - (ip->ip_hl << 2)));
 
 		switch (ip->ip_p) {
 		case IPPROTO_TCP:
@@ -366,7 +366,6 @@ ipfw_nat(struct ip_fw_args *args, struct
 			in_delayed_cksum(mcl);
 			mcl->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
 		}
-		ip->ip_len = htons(ip->ip_len);
 	}
 	args->m = mcl;
 	return (IP_FW_NAT);

Modified: head/sys/netpfil/pf/pf.c
==============================================================================
--- head/sys/netpfil/pf/pf.c	Mon Oct  8 07:33:43 2012	(r241343)
+++ head/sys/netpfil/pf/pf.c	Mon Oct  8 08:03:58 2012	(r241344)
@@ -5149,7 +5149,7 @@ pf_route(struct mbuf **m, struct pf_rule
 	struct pf_addr		 naddr;
 	struct pf_src_node	*sn = NULL;
 	int			 error = 0;
-	int sw_csum;
+	uint16_t		 ip_len, ip_off, sw_csum;
 
 	KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
 	KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
@@ -5244,9 +5244,8 @@ pf_route(struct mbuf **m, struct pf_rule
 	if (ifp->if_flags & IFF_LOOPBACK)
 		m0->m_flags |= M_SKIP_FIREWALL;
 
-	/* Back to host byte order. */
-	ip->ip_len = ntohs(ip->ip_len);
-	ip->ip_off = ntohs(ip->ip_off);
+	ip_len = ntohs(ip->ip_len);
+	ip_off = ntohs(ip->ip_off);
 
 	/* Copied from FreeBSD 10.0-CURRENT ip_output. */
 	m0->m_pkthdr.csum_flags |= CSUM_IP;
@@ -5267,11 +5266,9 @@ pf_route(struct mbuf **m, struct pf_rule
 	 * If small enough for interface, or the interface will take
 	 * care of the fragmentation for us, we can just send directly.
 	 */
-	if (ip->ip_len <= ifp->if_mtu ||
+	if (ip_len <= ifp->if_mtu ||
 	    (m0->m_pkthdr.csum_flags & ifp->if_hwassist & CSUM_TSO) != 0 ||
-	    ((ip->ip_off & IP_DF) == 0 && (ifp->if_hwassist & CSUM_FRAGMENT))) {
-		ip->ip_len = htons(ip->ip_len);
-		ip->ip_off = htons(ip->ip_off);
+	    ((ip_off & IP_DF) == 0 && (ifp->if_hwassist & CSUM_FRAGMENT))) {
 		ip->ip_sum = 0;
 		if (sw_csum & CSUM_DELAY_IP)
 			ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
@@ -5281,7 +5278,7 @@ pf_route(struct mbuf **m, struct pf_rule
 	}
 
 	/* Balk when DF bit is set or the interface didn't support TSO. */
-	if ((ip->ip_off & IP_DF) || (m0->m_pkthdr.csum_flags & CSUM_TSO)) {
+	if ((ip_off & IP_DF) || (m0->m_pkthdr.csum_flags & CSUM_TSO)) {
 		error = EMSGSIZE;
 		KMOD_IPSTAT_INC(ips_cantfrag);
 		if (r->rt != PF_DUPTO) {



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