patch-2.1.8 linux/include/net/checksum.h

Next file: linux/include/net/if_inet6.h
Previous file: linux/include/net/addrconf.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.7/linux/include/net/checksum.h linux/include/net/checksum.h
@@ -15,11 +15,79 @@
  *		as published by the Free Software Foundation; either version
  *		2 of the License, or (at your option) any later version.
  */
+
+/*
+ *	Fixes:
+ *
+ *	Ralf Baechle			:	generic ipv6 checksum
+ *	<ralf@waldorf-gmbh.de>
+ */
+
 #ifndef _CHECKSUM_H
 #define _CHECKSUM_H
 
 #include <asm/byteorder.h>
 #include <net/ip.h>
 #include <asm/checksum.h>
+
+#ifndef _HAVE_ARCH_IPV6_CSUM
+
+static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
+						     struct in6_addr *daddr,
+						     __u16 len,
+						     unsigned short proto,
+						     unsigned int csum) 
+{
+
+	int carry;
+	__u32 ulen;
+	__u32 uproto;
+
+	csum += saddr->s6_addr32[0];
+	carry = (csum < saddr->s6_addr32[0]);
+	csum += carry;
+
+	csum += saddr->s6_addr32[1];
+	carry = (csum < saddr->s6_addr32[1]);
+	csum += carry;
+
+	csum += saddr->s6_addr32[2];
+	carry = (csum < saddr->s6_addr32[2]);
+	csum += carry;
+
+	csum += saddr->s6_addr32[3];
+	carry = (csum < saddr->s6_addr32[3]);
+	csum += carry;
+
+	csum += daddr->s6_addr32[0];
+	carry = (csum < daddr->s6_addr32[0]);
+	csum += carry;
+
+	csum += daddr->s6_addr32[1];
+	carry = (csum < daddr->s6_addr32[1]);
+	csum += carry;
+
+	csum += daddr->s6_addr32[2];
+	carry = (csum < daddr->s6_addr32[2]);
+	csum += carry;
+
+	csum += daddr->s6_addr32[3];
+	carry = (csum < daddr->s6_addr32[3]);
+	csum += carry;
+
+	ulen = htonl((__u32) len);
+	csum += ulen;
+	carry = (csum < ulen);
+	csum += carry;
+
+	uproto = htonl(proto);
+	csum += proto;
+	carry = (csum < proto);
+	csum += carry;
+
+	return csum_fold(csum);
+}
+
+#endif
 
 #endif

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov