svn commit: r188066 - in head/sys: dev/xen/netback net netinet

Randall Stewart rrs at FreeBSD.org
Tue Feb 3 03:00:44 PST 2009


Author: rrs
Date: Tue Feb  3 11:00:43 2009
New Revision: 188066
URL: http://svn.freebsd.org/changeset/base/188066

Log:
  Adds support for SCTP checksum offload. This means
  we, like TCP and UDP, move the checksum calculation
  into the IP routines when there is no hardware support
  we call into the normal SCTP checksum routine.
  
  The next round of SCTP updates will use
  this functionality. Of course the IGB driver needs
  a few updates to support the new intel controller set
  that actually does SCTP csum offload too.
  
  Reviewed by:	gnn, rwatson, kmacy

Modified:
  head/sys/dev/xen/netback/netback.c
  head/sys/net/if_ethersubr.c
  head/sys/netinet/ip_divert.c
  head/sys/netinet/ip_ipsec.c
  head/sys/netinet/ip_output.c

Modified: head/sys/dev/xen/netback/netback.c
==============================================================================
--- head/sys/dev/xen/netback/netback.c	Tue Feb  3 09:01:45 2009	(r188065)
+++ head/sys/dev/xen/netback/netback.c	Tue Feb  3 11:00:43 2009	(r188066)
@@ -30,6 +30,7 @@
 
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
+#include "opt_sctp.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -57,6 +58,10 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
+#ifdef SCTP
+#include <netinet/sctp.h>
+#include <netinet/sctp_crc32.h>
+#endif
 
 #include <vm/vm_extern.h>
 #include <vm/vm_kern.h>
@@ -295,6 +300,11 @@ fixup_checksum(struct mbuf *m)
 			htons(IPPROTO_TCP + (iplen - iphlen)));
 		th->th_sum = in_cksum_skip(m, iplen + sizeof(*eh), sizeof(*eh) + iphlen);
 		m->m_pkthdr.csum_flags &= ~CSUM_TCP;
+#ifdef SCTP
+	} else if (sw_csum & CSUM_SCTP) {
+		sctp_delayed_cksum(m);
+		sw_csum &= ~CSUM_SCTP;
+#endif
 	} else {
 		u_short csum;
 		struct udphdr *uh = (struct udphdr *)((caddr_t)ip + iphlen);
@@ -908,7 +918,8 @@ netif_rx(netif_t *netif)
 #ifdef XEN_NETBACK_FIXUP_CSUM
 		/* Check if we need to compute a checksum.  This happens */
 		/* when bridging from one domain to another. */
-		if ((m->m_pkthdr.csum_flags & CSUM_DELAY_DATA))
+		if ((m->m_pkthdr.csum_flags & CSUM_DELAY_DATA) ||
+			(m->m_pkthdr.csum_flags & CSUM_SCTP))
 			fixup_checksum(m);
 #endif
 

Modified: head/sys/net/if_ethersubr.c
==============================================================================
--- head/sys/net/if_ethersubr.c	Tue Feb  3 09:01:45 2009	(r188065)
+++ head/sys/net/if_ethersubr.c	Tue Feb  3 11:00:43 2009	(r188066)
@@ -299,6 +299,8 @@ ether_output(struct ifnet *ifp, struct m
 			csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID);
 		if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA)
 			csum_flags |= (CSUM_DATA_VALID|CSUM_PSEUDO_HDR);
+		if (m->m_pkthdr.csum_flags & CSUM_SCTP)
+			csum_flags |= CSUM_SCTP_VALID;
 		m->m_pkthdr.csum_flags |= csum_flags;
 		m->m_pkthdr.csum_data = 0xffff;
 		return (if_simloop(ifp, m, dst->sa_family, 0));
@@ -339,6 +341,8 @@ ether_output(struct ifnet *ifp, struct m
 			csum_flags |= (CSUM_IP_CHECKED|CSUM_IP_VALID);
 		if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA)
 			csum_flags |= (CSUM_DATA_VALID|CSUM_PSEUDO_HDR);
+		if (m->m_pkthdr.csum_flags & CSUM_SCTP)
+			csum_flags |= CSUM_SCTP_VALID;
 
 		if (m->m_flags & M_BCAST) {
 			struct mbuf *n;

Modified: head/sys/netinet/ip_divert.c
==============================================================================
--- head/sys/netinet/ip_divert.c	Tue Feb  3 09:01:45 2009	(r188065)
+++ head/sys/netinet/ip_divert.c	Tue Feb  3 11:00:43 2009	(r188066)
@@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_inet.h"
 #include "opt_ipfw.h"
 #include "opt_mac.h"
+#include "opt_sctp.h"
 #ifndef INET
 #error "IPDIVERT requires INET."
 #endif
@@ -76,6 +77,9 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip_var.h>
 #include <netinet/ip_fw.h>
 #include <netinet/vinet.h>
+#ifdef SCTP
+#include <netinet/sctp_crc32.h>
+#endif
 
 #include <security/mac/mac_framework.h>
 
@@ -222,7 +226,14 @@ divert_packet(struct mbuf *m, int incomi
 		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) {
+		ip->ip_len = ntohs(ip->ip_len);
+		sctp_delayed_cksum(m);
+		m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
+		ip->ip_len = htons(ip->ip_len);
+	}
+#endif
 	/*
 	 * Record receive interface address, if any.
 	 * But only for incoming packets.

Modified: head/sys/netinet/ip_ipsec.c
==============================================================================
--- head/sys/netinet/ip_ipsec.c	Tue Feb  3 09:01:45 2009	(r188065)
+++ head/sys/netinet/ip_ipsec.c	Tue Feb  3 11:00:43 2009	(r188066)
@@ -31,6 +31,7 @@
 __FBSDID("$FreeBSD$");
 
 #include "opt_ipsec.h"
+#include "opt_sctp.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -56,6 +57,9 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip_options.h>
 #include <netinet/ip_ipsec.h>
 #include <netinet/vinet.h>
+#ifdef SCTP
+#include <netinet/sctp_crc32.h>
+#endif
 
 #include <machine/in_cksum.h>
 
@@ -328,7 +332,12 @@ ip_ipsec_output(struct mbuf **m, struct 
 			in_delayed_cksum(*m);
 			(*m)->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
 		}
-
+#ifdef SCTP
+		if ((*m)->m_pkthdr.csum_flags & CSUM_SCTP) {
+			sctp_delayed_cksum(*m);
+			(*m)->m_pkthdr.csum_flags &= ~CSUM_SCTP;
+		}
+#endif
 		ip->ip_len = htons(ip->ip_len);
 		ip->ip_off = htons(ip->ip_off);
 

Modified: head/sys/netinet/ip_output.c
==============================================================================
--- head/sys/netinet/ip_output.c	Tue Feb  3 09:01:45 2009	(r188065)
+++ head/sys/netinet/ip_output.c	Tue Feb  3 11:00:43 2009	(r188066)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include "opt_mac.h"
 #include "opt_mbuf_stress_test.h"
 #include "opt_mpath.h"
+#include "opt_sctp.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -70,6 +71,10 @@ __FBSDID("$FreeBSD$");
 #include <netinet/ip_var.h>
 #include <netinet/ip_options.h>
 #include <netinet/vinet.h>
+#ifdef SCTP
+#include <netinet/sctp.h>
+#include <netinet/sctp_crc32.h>
+#endif
 
 #ifdef IPSEC
 #include <netinet/ip_ipsec.h>
@@ -485,7 +490,10 @@ sendit:
 			}
 			m->m_pkthdr.csum_flags |=
 			    CSUM_IP_CHECKED | CSUM_IP_VALID;
-
+#ifdef SCTP
+			if (m->m_pkthdr.csum_flags & CSUM_SCTP)
+				m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID;
+#endif
 			error = netisr_queue(NETISR_IP, m);
 			goto done;
 		} else
@@ -502,6 +510,10 @@ sendit:
 			    CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
 			m->m_pkthdr.csum_data = 0xffff;
 		}
+#ifdef SCTP
+		if (m->m_pkthdr.csum_flags & CSUM_SCTP)
+			m->m_pkthdr.csum_flags |= CSUM_SCTP_VALID;
+#endif
 		m->m_pkthdr.csum_flags |=
 			    CSUM_IP_CHECKED | CSUM_IP_VALID;
 
@@ -536,6 +548,12 @@ passout:
 		in_delayed_cksum(m);
 		sw_csum &= ~CSUM_DELAY_DATA;
 	}
+#ifdef SCTP
+	if (sw_csum & CSUM_SCTP) {
+		sctp_delayed_cksum(m);
+		sw_csum &= ~CSUM_SCTP;
+	}
+#endif
 	m->m_pkthdr.csum_flags &= ifp->if_hwassist;
 
 	/*
@@ -670,7 +688,13 @@ ip_fragment(struct ip *ip, struct mbuf *
 		in_delayed_cksum(m0);
 		m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
 	}
-
+#ifdef SCTP
+	if (m0->m_pkthdr.csum_flags & CSUM_SCTP &&
+	    (if_hwassist_flags & CSUM_IP_FRAGS) == 0) {
+		sctp_delayed_cksum(m0);
+		m0->m_pkthdr.csum_flags &= ~CSUM_SCTP;
+	}
+#endif
 	if (len > PAGE_SIZE) {
 		/* 
 		 * Fragment large datagrams such that each segment 


More information about the svn-src-all mailing list