Branch data Line data Source code
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 : : #include <linux/tcp.h>
35 : : #include <linux/ipv6.h>
36 : :
37 : : #ifndef _HAVE_ARCH_IPV6_CSUM
38 : : __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
39 : : const struct in6_addr *daddr,
40 : : __u32 len, unsigned short proto,
41 : : __wsum csum);
42 : : #endif
43 : :
44 : : static __inline__ __sum16 tcp_v6_check(int len,
45 : : const struct in6_addr *saddr,
46 : : const struct in6_addr *daddr,
47 : : __wsum base)
48 : : {
49 : : return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base);
50 : : }
51 : :
52 : 0 : static inline void __tcp_v6_send_check(struct sk_buff *skb,
53 : : const struct in6_addr *saddr,
54 : : const struct in6_addr *daddr)
55 : : {
56 : : struct tcphdr *th = tcp_hdr(skb);
57 : :
58 [ # # ][ # # ]: 0 : if (skb->ip_summed == CHECKSUM_PARTIAL) {
59 : 0 : th->check = ~tcp_v6_check(skb->len, saddr, daddr, 0);
60 : 0 : skb->csum_start = skb_transport_header(skb) - skb->head;
61 : 0 : skb->csum_offset = offsetof(struct tcphdr, check);
62 : : } else {
63 : 0 : th->check = tcp_v6_check(skb->len, saddr, daddr,
64 : 0 : csum_partial(th, th->doff << 2,
65 : : skb->csum));
66 : : }
67 : : }
68 : :
69 : : #if IS_ENABLED(CONFIG_IPV6)
70 : 0 : static inline void tcp_v6_send_check(struct sock *sk, struct sk_buff *skb)
71 : : {
72 : : struct ipv6_pinfo *np = inet6_sk(sk);
73 : :
74 : 0 : __tcp_v6_send_check(skb, &np->saddr, &sk->sk_v6_daddr);
75 : 0 : }
76 : : #endif
77 : :
78 : : int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto);
79 : : #endif
|