diff --git a/sys/dev/xen/netback/netback.c b/sys/dev/xen/netback/netback.c index 950a68ca74e3..a6111e265f58 100644 --- a/sys/dev/xen/netback/netback.c +++ b/sys/dev/xen/netback/netback.c @@ -30,6 +30,7 @@ #include __FBSDID("$FreeBSD$"); +#include "opt_sctp.h" #include #include @@ -57,6 +58,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef SCTP +#include +#include +#endif #include #include @@ -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 diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 73a08dd51a35..e74bb74c86e6 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -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; diff --git a/sys/netinet/ip_divert.c b/sys/netinet/ip_divert.c index d6eb16f833fe..c2e31916c46b 100644 --- a/sys/netinet/ip_divert.c +++ b/sys/netinet/ip_divert.c @@ -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 #include #include +#ifdef SCTP +#include +#endif #include @@ -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. diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c index a1e082bafa88..77e9aa74e60c 100644 --- a/sys/netinet/ip_ipsec.c +++ b/sys/netinet/ip_ipsec.c @@ -31,6 +31,7 @@ __FBSDID("$FreeBSD$"); #include "opt_ipsec.h" +#include "opt_sctp.h" #include #include @@ -56,6 +57,9 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef SCTP +#include +#endif #include @@ -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); 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 #include @@ -70,6 +71,10 @@ __FBSDID("$FreeBSD$"); #include #include #include +#ifdef SCTP +#include +#include +#endif #ifdef IPSEC #include @@ -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