1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * INET An implementation of the TCP/IP protocol suite for the LINUX
4 * operating system. INET is implemented using the BSD Socket
5 * interface as the means of communication with the user level.
7 * Checksumming functions for IPv6
9 * Authors: Jorge Cwik, <jorge@laser.satlink.net>
10 * Arnt Gulbrandsen, <agulbra@nvg.unit.no>
11 * Borrows very liberally from tcp.c and ip.c, see those
12 * files for more names.
18 * Ralf Baechle : generic ipv6 checksum
19 * <ralf@waldorf-gmbh.de>
22 #ifndef _CHECKSUM_IPV6_H
23 #define _CHECKSUM_IPV6_H
25 #include <asm/types.h>
26 #include <asm/byteorder.h>
28 #include <asm/checksum.h>
29 #include <linux/in6.h>
30 #include <linux/tcp.h>
31 #include <linux/ipv6.h>
33 #ifndef _HAVE_ARCH_IPV6_CSUM
34 __sum16
csum_ipv6_magic(const struct in6_addr
*saddr
,
35 const struct in6_addr
*daddr
,
36 __u32 len
, __u8 proto
, __wsum csum
);
39 static inline __wsum
ip6_compute_pseudo(struct sk_buff
*skb
, int proto
)
41 return ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb
)->saddr
,
42 &ipv6_hdr(skb
)->daddr
,
46 static __inline__ __sum16
tcp_v6_check(int len
,
47 const struct in6_addr
*saddr
,
48 const struct in6_addr
*daddr
,
51 return csum_ipv6_magic(saddr
, daddr
, len
, IPPROTO_TCP
, base
);
54 static inline void __tcp_v6_send_check(struct sk_buff
*skb
,
55 const struct in6_addr
*saddr
,
56 const struct in6_addr
*daddr
)
58 struct tcphdr
*th
= tcp_hdr(skb
);
60 th
->check
= ~tcp_v6_check(skb
->len
, saddr
, daddr
, 0);
61 skb
->csum_start
= skb_transport_header(skb
) - skb
->head
;
62 skb
->csum_offset
= offsetof(struct tcphdr
, check
);
65 static inline void tcp_v6_gso_csum_prep(struct sk_buff
*skb
)
67 struct ipv6hdr
*ipv6h
= ipv6_hdr(skb
);
68 struct tcphdr
*th
= tcp_hdr(skb
);
70 ipv6h
->payload_len
= 0;
71 th
->check
= ~tcp_v6_check(0, &ipv6h
->saddr
, &ipv6h
->daddr
, 0);
74 static inline __sum16
udp_v6_check(int len
,
75 const struct in6_addr
*saddr
,
76 const struct in6_addr
*daddr
,
79 return csum_ipv6_magic(saddr
, daddr
, len
, IPPROTO_UDP
, base
);
82 void udp6_set_csum(bool nocheck
, struct sk_buff
*skb
,
83 const struct in6_addr
*saddr
,
84 const struct in6_addr
*daddr
, int len
);
86 int udp6_csum_init(struct sk_buff
*skb
, struct udphdr
*uh
, int proto
);