aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/ip_output.c
diff options
context:
space:
mode:
authorRandall Stewart <rrs@FreeBSD.org>2009-02-03 11:00:43 +0000
committerRandall Stewart <rrs@FreeBSD.org>2009-02-03 11:00:43 +0000
commit2f4afd21257ea1672763722dae9109bbaced5548 (patch)
tree23b147e1d579bbf8d4eb4845fe7846b01184ffc7 /sys/netinet/ip_output.c
parentbb471e331576bef62eb71ad5fe629aea05d10559 (diff)
downloadsrc-2f4afd21257ea1672763722dae9109bbaced5548.tar.gz
src-2f4afd21257ea1672763722dae9109bbaced5548.zip
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
Notes
Notes: svn path=/head/; revision=188066
Diffstat (limited to 'sys/netinet/ip_output.c')
-rw-r--r--sys/netinet/ip_output.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index 2717d6ec25c8..feacb5169f2c 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -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 **m_frag, int mtu,
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