3 #include <net/udplite.h>
4 #include <asm/checksum.h>
6 #ifndef _HAVE_ARCH_IPV6_CSUM
7 __sum16
csum_ipv6_magic(const struct in6_addr
*saddr
,
8 const struct in6_addr
*daddr
,
9 __u32 len
, unsigned short proto
,
16 __u32 sum
= (__force u32
)csum
;
18 sum
+= (__force u32
)saddr
->s6_addr32
[0];
19 carry
= (sum
< (__force u32
)saddr
->s6_addr32
[0]);
22 sum
+= (__force u32
)saddr
->s6_addr32
[1];
23 carry
= (sum
< (__force u32
)saddr
->s6_addr32
[1]);
26 sum
+= (__force u32
)saddr
->s6_addr32
[2];
27 carry
= (sum
< (__force u32
)saddr
->s6_addr32
[2]);
30 sum
+= (__force u32
)saddr
->s6_addr32
[3];
31 carry
= (sum
< (__force u32
)saddr
->s6_addr32
[3]);
34 sum
+= (__force u32
)daddr
->s6_addr32
[0];
35 carry
= (sum
< (__force u32
)daddr
->s6_addr32
[0]);
38 sum
+= (__force u32
)daddr
->s6_addr32
[1];
39 carry
= (sum
< (__force u32
)daddr
->s6_addr32
[1]);
42 sum
+= (__force u32
)daddr
->s6_addr32
[2];
43 carry
= (sum
< (__force u32
)daddr
->s6_addr32
[2]);
46 sum
+= (__force u32
)daddr
->s6_addr32
[3];
47 carry
= (sum
< (__force u32
)daddr
->s6_addr32
[3]);
50 ulen
= (__force u32
)htonl((__u32
) len
);
55 uproto
= (__force u32
)htonl(proto
);
57 carry
= (sum
< uproto
);
60 return csum_fold((__force __wsum
)sum
);
62 EXPORT_SYMBOL(csum_ipv6_magic
);
65 int udp6_csum_init(struct sk_buff
*skb
, struct udphdr
*uh
, int proto
)
69 UDP_SKB_CB(skb
)->partial_cov
= 0;
70 UDP_SKB_CB(skb
)->cscov
= skb
->len
;
72 if (proto
== IPPROTO_UDPLITE
) {
73 err
= udplite_checksum_init(skb
, uh
);
79 /* RFC 2460 section 8.1 says that we SHOULD log
80 this error. Well, it is reasonable.
82 LIMIT_NETDEBUG(KERN_INFO
"IPv6: udp checksum is 0\n");
85 if (skb
->ip_summed
== CHECKSUM_COMPLETE
&&
86 !csum_ipv6_magic(&ipv6_hdr(skb
)->saddr
, &ipv6_hdr(skb
)->daddr
,
87 skb
->len
, proto
, skb
->csum
))
88 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
90 if (!skb_csum_unnecessary(skb
))
91 skb
->csum
= ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb
)->saddr
,
92 &ipv6_hdr(skb
)->daddr
,
97 EXPORT_SYMBOL(udp6_csum_init
);