linux/include/net/ip6_checksum.h
<<
>>
Prefs
   1/*
   2 * INET         An implementation of the TCP/IP protocol suite for the LINUX
   3 *              operating system.  INET is implemented using the  BSD Socket
   4 *              interface as the means of communication with the user level.
   5 *
   6 *              Checksumming functions for IPv6
   7 *
   8 * Authors:     Jorge Cwik, <jorge@laser.satlink.net>
   9 *              Arnt Gulbrandsen, <agulbra@nvg.unit.no>
  10 *              Borrows very liberally from tcp.c and ip.c, see those
  11 *              files for more names.
  12 *
  13 *              This program is free software; you can redistribute it and/or
  14 *              modify it under the terms of the GNU General Public License
  15 *              as published by the Free Software Foundation; either version
  16 *              2 of the License, or (at your option) any later version.
  17 */
  18
  19/*
  20 *      Fixes:
  21 *
  22 *      Ralf Baechle                    :       generic ipv6 checksum
  23 *      <ralf@waldorf-gmbh.de>
  24 */
  25
  26#ifndef _CHECKSUM_IPV6_H
  27#define _CHECKSUM_IPV6_H
  28
  29#include <asm/types.h>
  30#include <asm/byteorder.h>
  31#include <net/ip.h>
  32#include <asm/checksum.h>
  33#include <linux/in6.h>
  34
  35#ifndef _HAVE_ARCH_IPV6_CSUM
  36
  37static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
  38                                          const struct in6_addr *daddr,
  39                                          __u32 len, unsigned short proto,
  40                                          __wsum csum)
  41{
  42
  43        int carry;
  44        __u32 ulen;
  45        __u32 uproto;
  46        __u32 sum = (__force u32)csum;
  47
  48        sum += (__force u32)saddr->s6_addr32[0];
  49        carry = (sum < (__force u32)saddr->s6_addr32[0]);
  50        sum += carry;
  51
  52        sum += (__force u32)saddr->s6_addr32[1];
  53        carry = (sum < (__force u32)saddr->s6_addr32[1]);
  54        sum += carry;
  55
  56        sum += (__force u32)saddr->s6_addr32[2];
  57        carry = (sum < (__force u32)saddr->s6_addr32[2]);
  58        sum += carry;
  59
  60        sum += (__force u32)saddr->s6_addr32[3];
  61        carry = (sum < (__force u32)saddr->s6_addr32[3]);
  62        sum += carry;
  63
  64        sum += (__force u32)daddr->s6_addr32[0];
  65        carry = (sum < (__force u32)daddr->s6_addr32[0]);
  66        sum += carry;
  67
  68        sum += (__force u32)daddr->s6_addr32[1];
  69        carry = (sum < (__force u32)daddr->s6_addr32[1]);
  70        sum += carry;
  71
  72        sum += (__force u32)daddr->s6_addr32[2];
  73        carry = (sum < (__force u32)daddr->s6_addr32[2]);
  74        sum += carry;
  75
  76        sum += (__force u32)daddr->s6_addr32[3];
  77        carry = (sum < (__force u32)daddr->s6_addr32[3]);
  78        sum += carry;
  79
  80        ulen = (__force u32)htonl((__u32) len);
  81        sum += ulen;
  82        carry = (sum < ulen);
  83        sum += carry;
  84
  85        uproto = (__force u32)htonl(proto);
  86        sum += uproto;
  87        carry = (sum < uproto);
  88        sum += carry;
  89
  90        return csum_fold((__force __wsum)sum);
  91}
  92
  93#endif
  94#endif
  95