diff options
author | 2014-01-22 14:27:20 +0000 | |
---|---|---|
committer | 2014-01-22 14:27:20 +0000 | |
commit | 24ce3f58004fc019d4affda9b2bb2810f028dcc0 (patch) | |
tree | d15b345faa6e6a8012d0df9db63511a46b72742a /sys/netinet6/in6.h | |
parent | Do not permit periods in session names (colons are already banned). From (diff) | |
download | wireguard-openbsd-24ce3f58004fc019d4affda9b2bb2810f028dcc0.tar.xz wireguard-openbsd-24ce3f58004fc019d4affda9b2bb2810f028dcc0.zip |
Split the checksum calculation for IPv6 like for IPv4:
Always calculate the pseudo-header checksum.
Complete the checksum if hardware offload is not available.
Parts originally from NetBSD; ok henning@
Diffstat (limited to 'sys/netinet6/in6.h')
-rw-r--r-- | sys/netinet6/in6.h | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h index 83ba26eb5cd..7a17a3e9c8f 100644 --- a/sys/netinet6/in6.h +++ b/sys/netinet6/in6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.h,v 1.69 2013/10/28 21:02:35 deraadt Exp $ */ +/* $OpenBSD: in6.h,v 1.70 2014/01/22 14:27:20 naddy Exp $ */ /* $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $ */ /* @@ -416,6 +416,54 @@ typedef __socklen_t socklen_t; /* length type for network syscalls */ #endif /* __BSD_VISIBLE */ #ifdef _KERNEL +/* + * in6_cksum_phdr: + * + * Compute significant parts of the IPv6 checksum pseudo-header + * for use in a delayed TCP/UDP checksum calculation. + * + * Args: + * + * src Source IPv6 address + * dst Destination IPv6 address + * len htonl(proto-hdr-len) + * nxt htonl(next-proto-number) + * + * NOTE: We expect the src and dst addresses to be 16-bit + * aligned! + */ +static __inline u_int16_t __attribute__((__unused__)) +in6_cksum_phdr(const struct in6_addr *src, const struct in6_addr *dst, + u_int32_t len, u_int32_t nxt) +{ + u_int32_t sum = 0; + const u_int16_t *w; + + w = (const u_int16_t *) src; + sum += w[0]; + if (!IN6_IS_SCOPE_EMBED(src)) + sum += w[1]; + sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5]; + sum += w[6]; sum += w[7]; + + w = (const u_int16_t *) dst; + sum += w[0]; + if (!IN6_IS_SCOPE_EMBED(dst)) + sum += w[1]; + sum += w[2]; sum += w[3]; sum += w[4]; sum += w[5]; + sum += w[6]; sum += w[7]; + + sum += (u_int16_t)(len >> 16) + (u_int16_t)(len /*& 0xffff*/); + + sum += (u_int16_t)(nxt >> 16) + (u_int16_t)(nxt /*& 0xffff*/); + + sum = (u_int16_t)(sum >> 16) + (u_int16_t)(sum /*& 0xffff*/); + + if (sum > 0xffff) + sum -= 0xffff; + + return (sum); +} extern u_char inet6ctlerrmap[]; extern struct ifqueue ip6intrq; /* IP6 packet input queue */ |