xref: /openbmc/linux/include/net/ip6_checksum.h (revision 56649d5d3c4cb0fe6dd34808ca9f9208d84130ab)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  * INET		An implementation of the TCP/IP protocol suite for the LINUX
31da177e4SLinus Torvalds  *		operating system.  INET is implemented using the  BSD Socket
41da177e4SLinus Torvalds  *		interface as the means of communication with the user level.
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  *		Checksumming functions for IPv6
71da177e4SLinus Torvalds  *
81da177e4SLinus Torvalds  * Authors:	Jorge Cwik, <jorge@laser.satlink.net>
91da177e4SLinus Torvalds  *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
101da177e4SLinus Torvalds  *		Borrows very liberally from tcp.c and ip.c, see those
111da177e4SLinus Torvalds  *		files for more names.
121da177e4SLinus Torvalds  *
131da177e4SLinus Torvalds  *		This program is free software; you can redistribute it and/or
141da177e4SLinus Torvalds  *		modify it under the terms of the GNU General Public License
151da177e4SLinus Torvalds  *		as published by the Free Software Foundation; either version
161da177e4SLinus Torvalds  *		2 of the License, or (at your option) any later version.
171da177e4SLinus Torvalds  */
181da177e4SLinus Torvalds 
191da177e4SLinus Torvalds /*
201da177e4SLinus Torvalds  *	Fixes:
211da177e4SLinus Torvalds  *
221da177e4SLinus Torvalds  *	Ralf Baechle			:	generic ipv6 checksum
231da177e4SLinus Torvalds  *	<ralf@waldorf-gmbh.de>
241da177e4SLinus Torvalds  */
251da177e4SLinus Torvalds 
261da177e4SLinus Torvalds #ifndef _CHECKSUM_IPV6_H
271da177e4SLinus Torvalds #define _CHECKSUM_IPV6_H
281da177e4SLinus Torvalds 
291da177e4SLinus Torvalds #include <asm/types.h>
301da177e4SLinus Torvalds #include <asm/byteorder.h>
311da177e4SLinus Torvalds #include <net/ip.h>
321da177e4SLinus Torvalds #include <asm/checksum.h>
331da177e4SLinus Torvalds #include <linux/in6.h>
341da177e4SLinus Torvalds 
351da177e4SLinus Torvalds #ifndef _HAVE_ARCH_IPV6_CSUM
361da177e4SLinus Torvalds 
37*56649d5dSAl Viro static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
38*56649d5dSAl Viro 					  const struct in6_addr *daddr,
39*56649d5dSAl Viro 					  __u32 len, unsigned short proto,
40*56649d5dSAl Viro 					  __wsum csum)
411da177e4SLinus Torvalds {
421da177e4SLinus Torvalds 
431da177e4SLinus Torvalds 	int carry;
441da177e4SLinus Torvalds 	__u32 ulen;
451da177e4SLinus Torvalds 	__u32 uproto;
46*56649d5dSAl Viro 	__u32 sum = (__force u32)csum;
471da177e4SLinus Torvalds 
48*56649d5dSAl Viro 	sum += (__force u32)saddr->s6_addr32[0];
49*56649d5dSAl Viro 	carry = (sum < (__force u32)saddr->s6_addr32[0]);
50*56649d5dSAl Viro 	sum += carry;
511da177e4SLinus Torvalds 
52*56649d5dSAl Viro 	sum += (__force u32)saddr->s6_addr32[1];
53*56649d5dSAl Viro 	carry = (sum < (__force u32)saddr->s6_addr32[1]);
54*56649d5dSAl Viro 	sum += carry;
551da177e4SLinus Torvalds 
56*56649d5dSAl Viro 	sum += (__force u32)saddr->s6_addr32[2];
57*56649d5dSAl Viro 	carry = (sum < (__force u32)saddr->s6_addr32[2]);
58*56649d5dSAl Viro 	sum += carry;
591da177e4SLinus Torvalds 
60*56649d5dSAl Viro 	sum += (__force u32)saddr->s6_addr32[3];
61*56649d5dSAl Viro 	carry = (sum < (__force u32)saddr->s6_addr32[3]);
62*56649d5dSAl Viro 	sum += carry;
631da177e4SLinus Torvalds 
64*56649d5dSAl Viro 	sum += (__force u32)daddr->s6_addr32[0];
65*56649d5dSAl Viro 	carry = (sum < (__force u32)daddr->s6_addr32[0]);
66*56649d5dSAl Viro 	sum += carry;
671da177e4SLinus Torvalds 
68*56649d5dSAl Viro 	sum += (__force u32)daddr->s6_addr32[1];
69*56649d5dSAl Viro 	carry = (sum < (__force u32)daddr->s6_addr32[1]);
70*56649d5dSAl Viro 	sum += carry;
711da177e4SLinus Torvalds 
72*56649d5dSAl Viro 	sum += (__force u32)daddr->s6_addr32[2];
73*56649d5dSAl Viro 	carry = (sum < (__force u32)daddr->s6_addr32[2]);
74*56649d5dSAl Viro 	sum += carry;
751da177e4SLinus Torvalds 
76*56649d5dSAl Viro 	sum += (__force u32)daddr->s6_addr32[3];
77*56649d5dSAl Viro 	carry = (sum < (__force u32)daddr->s6_addr32[3]);
78*56649d5dSAl Viro 	sum += carry;
791da177e4SLinus Torvalds 
80*56649d5dSAl Viro 	ulen = (__force u32)htonl((__u32) len);
81*56649d5dSAl Viro 	sum += ulen;
82*56649d5dSAl Viro 	carry = (sum < ulen);
83*56649d5dSAl Viro 	sum += carry;
841da177e4SLinus Torvalds 
85*56649d5dSAl Viro 	uproto = (__force u32)htonl(proto);
86*56649d5dSAl Viro 	sum += uproto;
87*56649d5dSAl Viro 	carry = (sum < uproto);
88*56649d5dSAl Viro 	sum += carry;
891da177e4SLinus Torvalds 
90*56649d5dSAl Viro 	return csum_fold((__force __wsum)csum);
911da177e4SLinus Torvalds }
921da177e4SLinus Torvalds 
931da177e4SLinus Torvalds #endif
941da177e4SLinus Torvalds #endif
95