diff options
author | Christian Weisgerber <naddy@cvs.openbsd.org> | 2015-11-03 21:11:49 +0000 |
---|---|---|
committer | Christian Weisgerber <naddy@cvs.openbsd.org> | 2015-11-03 21:11:49 +0000 |
commit | 9c0a813bac5b02a9dff34a3393b1702cf1500c59 (patch) | |
tree | 5983b9066379f501bf37fcba16f01e70d5f50d68 /sys | |
parent | 50bed4fc63f774d39185ef88ee15cc1dd6988648 (diff) |
Disable TCP/UDP TX hardware checksumming if an IPv4 packet contains
IP options or if an IPv6 packet contains header extensions.
Required by cnmac(4) and a sensible precautionary measure in general.
ok visa@, mikeb@
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/ip_output.c | 10 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 8 |
2 files changed, 10 insertions, 8 deletions
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 3130e91fd77..7f50c60f638 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.304 2015/10/24 12:33:16 mpi Exp $ */ +/* $OpenBSD: ip_output.c,v 1.305 2015/11/03 21:11:48 naddy Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -1753,13 +1753,13 @@ in_delayed_cksum(struct mbuf *m) void in_proto_cksum_out(struct mbuf *m, struct ifnet *ifp) { + struct ip *ip = mtod(m, struct ip *); + /* some hw and in_delayed_cksum need the pseudo header cksum */ if (m->m_pkthdr.csum_flags & (M_TCP_CSUM_OUT|M_UDP_CSUM_OUT|M_ICMP_CSUM_OUT)) { - struct ip *ip; u_int16_t csum = 0, offset; - ip = mtod(m, struct ip *); offset = ip->ip_hl << 2; if (m->m_pkthdr.csum_flags & (M_TCP_CSUM_OUT|M_UDP_CSUM_OUT)) csum = in_cksum_phdr(ip->ip_src.s_addr, @@ -1779,14 +1779,14 @@ in_proto_cksum_out(struct mbuf *m, struct ifnet *ifp) if (m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT) { if (!ifp || !(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || - ifp->if_bridgeport != NULL) { + ip->ip_hl != 5 || ifp->if_bridgeport != NULL) { tcpstat.tcps_outswcsum++; in_delayed_cksum(m); m->m_pkthdr.csum_flags &= ~M_TCP_CSUM_OUT; /* Clear */ } } else if (m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT) { if (!ifp || !(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || - ifp->if_bridgeport != NULL) { + ip->ip_hl != 5 || ifp->if_bridgeport != NULL) { udpstat.udps_outswcsum++; in_delayed_cksum(m); m->m_pkthdr.csum_flags &= ~M_UDP_CSUM_OUT; /* Clear */ diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index d58b2ee77d9..e86fd528caf 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.196 2015/10/29 16:27:45 tedu Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.197 2015/11/03 21:11:48 naddy Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -2902,14 +2902,14 @@ in6_delayed_cksum(struct mbuf *m, u_int8_t nxt) void in6_proto_cksum_out(struct mbuf *m, struct ifnet *ifp) { + struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); + /* some hw and in6_delayed_cksum need the pseudo header cksum */ if (m->m_pkthdr.csum_flags & (M_TCP_CSUM_OUT|M_UDP_CSUM_OUT|M_ICMP_CSUM_OUT)) { - struct ip6_hdr *ip6; int nxt, offset; u_int16_t csum; - ip6 = mtod(m, struct ip6_hdr *); offset = ip6_lasthdr(m, 0, IPPROTO_IPV6, &nxt); csum = in6_cksum_phdr(&ip6->ip6_src, &ip6->ip6_dst, htonl(m->m_pkthdr.len - offset), htonl(nxt)); @@ -2927,6 +2927,7 @@ in6_proto_cksum_out(struct mbuf *m, struct ifnet *ifp) if (m->m_pkthdr.csum_flags & M_TCP_CSUM_OUT) { if (!ifp || !(ifp->if_capabilities & IFCAP_CSUM_TCPv6) || + ip6->ip6_nxt != IPPROTO_TCP || ifp->if_bridgeport != NULL) { tcpstat.tcps_outswcsum++; in6_delayed_cksum(m, IPPROTO_TCP); @@ -2934,6 +2935,7 @@ in6_proto_cksum_out(struct mbuf *m, struct ifnet *ifp) } } else if (m->m_pkthdr.csum_flags & M_UDP_CSUM_OUT) { if (!ifp || !(ifp->if_capabilities & IFCAP_CSUM_UDPv6) || + ip6->ip6_nxt != IPPROTO_UDP || ifp->if_bridgeport != NULL) { udpstat.udps_outswcsum++; in6_delayed_cksum(m, IPPROTO_UDP); |