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
This commit is contained in:
parent
bb471e3315
commit
2f4afd2125
@ -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
|
||||
|
||||
|
@ -299,6 +299,8 @@ ether_output(struct ifnet *ifp, struct mbuf *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 mbuf *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;
|
||||
|
@ -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 incoming)
|
||||
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.
|
||||
|
@ -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 inpcb *inp, int *flags, int *error,
|
||||
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);
|
||||
|
||||
|
@ -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 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
}
|
||||
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 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
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 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user