Branch data Line data Source code
1 : : #include <net/ip.h>
2 : : #include <net/udp.h>
3 : : #include <net/udplite.h>
4 : : #include <asm/checksum.h>
5 : :
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,
10 : : __wsum csum)
11 : : {
12 : :
13 : : int carry;
14 : : __u32 ulen;
15 : : __u32 uproto;
16 : : __u32 sum = (__force u32)csum;
17 : :
18 : : sum += (__force u32)saddr->s6_addr32[0];
19 : : carry = (sum < (__force u32)saddr->s6_addr32[0]);
20 : : sum += carry;
21 : :
22 : : sum += (__force u32)saddr->s6_addr32[1];
23 : : carry = (sum < (__force u32)saddr->s6_addr32[1]);
24 : : sum += carry;
25 : :
26 : : sum += (__force u32)saddr->s6_addr32[2];
27 : : carry = (sum < (__force u32)saddr->s6_addr32[2]);
28 : : sum += carry;
29 : :
30 : : sum += (__force u32)saddr->s6_addr32[3];
31 : : carry = (sum < (__force u32)saddr->s6_addr32[3]);
32 : : sum += carry;
33 : :
34 : : sum += (__force u32)daddr->s6_addr32[0];
35 : : carry = (sum < (__force u32)daddr->s6_addr32[0]);
36 : : sum += carry;
37 : :
38 : : sum += (__force u32)daddr->s6_addr32[1];
39 : : carry = (sum < (__force u32)daddr->s6_addr32[1]);
40 : : sum += carry;
41 : :
42 : : sum += (__force u32)daddr->s6_addr32[2];
43 : : carry = (sum < (__force u32)daddr->s6_addr32[2]);
44 : : sum += carry;
45 : :
46 : : sum += (__force u32)daddr->s6_addr32[3];
47 : : carry = (sum < (__force u32)daddr->s6_addr32[3]);
48 : : sum += carry;
49 : :
50 : : ulen = (__force u32)htonl((__u32) len);
51 : : sum += ulen;
52 : : carry = (sum < ulen);
53 : : sum += carry;
54 : :
55 : : uproto = (__force u32)htonl(proto);
56 : : sum += uproto;
57 : : carry = (sum < uproto);
58 : : sum += carry;
59 : :
60 : : return csum_fold((__force __wsum)sum);
61 : : }
62 : : EXPORT_SYMBOL(csum_ipv6_magic);
63 : : #endif
64 : :
65 : 0 : int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto)
66 : : {
67 : : int err;
68 : :
69 : 0 : UDP_SKB_CB(skb)->partial_cov = 0;
70 : 0 : UDP_SKB_CB(skb)->cscov = skb->len;
71 : :
72 [ # # ]: 0 : if (proto == IPPROTO_UDPLITE) {
73 : : err = udplite_checksum_init(skb, uh);
74 [ # # ]: 0 : if (err)
75 : : return err;
76 : : }
77 : :
78 [ # # ]: 0 : if (uh->check == 0) {
79 : : /* RFC 2460 section 8.1 says that we SHOULD log
80 : : this error. Well, it is reasonable.
81 : : */
82 [ # # ][ # # ]: 0 : LIMIT_NETDEBUG(KERN_INFO "IPv6: udp checksum is 0\n");
83 : : return 1;
84 : : }
85 [ # # # # ]: 0 : if (skb->ip_summed == CHECKSUM_COMPLETE &&
86 : 0 : !csum_ipv6_magic(&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
87 : : skb->len, proto, skb->csum))
88 : 0 : skb->ip_summed = CHECKSUM_UNNECESSARY;
89 : :
90 [ # # ]: 0 : if (!skb_csum_unnecessary(skb))
91 : 0 : skb->csum = ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
92 : 0 : &ipv6_hdr(skb)->daddr,
93 : : skb->len, proto, 0));
94 : :
95 : : return 0;
96 : : }
97 : : EXPORT_SYMBOL(udp6_csum_init);
|