ip6_checksum.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  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.
  6. *
  7. * Checksumming functions for IPv6
  8. *
  9. * Authors: Jorge Cwik, <[email protected]>
  10. * Arnt Gulbrandsen, <[email protected]>
  11. * Borrows very liberally from tcp.c and ip.c, see those
  12. * files for more names.
  13. */
  14. /*
  15. * Fixes:
  16. *
  17. * Ralf Baechle : generic ipv6 checksum
  18. * <[email protected]>
  19. */
  20. #ifndef _CHECKSUM_IPV6_H
  21. #define _CHECKSUM_IPV6_H
  22. #include <asm/types.h>
  23. #include <asm/byteorder.h>
  24. #include <net/ip.h>
  25. #include <asm/checksum.h>
  26. #include <linux/in6.h>
  27. #include <linux/tcp.h>
  28. #include <linux/ipv6.h>
  29. #ifndef _HAVE_ARCH_IPV6_CSUM
  30. __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
  31. const struct in6_addr *daddr,
  32. __u32 len, __u8 proto, __wsum csum);
  33. #endif
  34. static inline __wsum ip6_compute_pseudo(struct sk_buff *skb, int proto)
  35. {
  36. return ~csum_unfold(csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
  37. &ipv6_hdr(skb)->daddr,
  38. skb->len, proto, 0));
  39. }
  40. static __inline__ __sum16 tcp_v6_check(int len,
  41. const struct in6_addr *saddr,
  42. const struct in6_addr *daddr,
  43. __wsum base)
  44. {
  45. return csum_ipv6_magic(saddr, daddr, len, IPPROTO_TCP, base);
  46. }
  47. static inline void __tcp_v6_send_check(struct sk_buff *skb,
  48. const struct in6_addr *saddr,
  49. const struct in6_addr *daddr)
  50. {
  51. struct tcphdr *th = tcp_hdr(skb);
  52. th->check = ~tcp_v6_check(skb->len, saddr, daddr, 0);
  53. skb->csum_start = skb_transport_header(skb) - skb->head;
  54. skb->csum_offset = offsetof(struct tcphdr, check);
  55. }
  56. static inline void tcp_v6_gso_csum_prep(struct sk_buff *skb)
  57. {
  58. struct ipv6hdr *ipv6h = ipv6_hdr(skb);
  59. struct tcphdr *th = tcp_hdr(skb);
  60. ipv6h->payload_len = 0;
  61. th->check = ~tcp_v6_check(0, &ipv6h->saddr, &ipv6h->daddr, 0);
  62. }
  63. static inline __sum16 udp_v6_check(int len,
  64. const struct in6_addr *saddr,
  65. const struct in6_addr *daddr,
  66. __wsum base)
  67. {
  68. return csum_ipv6_magic(saddr, daddr, len, IPPROTO_UDP, base);
  69. }
  70. void udp6_set_csum(bool nocheck, struct sk_buff *skb,
  71. const struct in6_addr *saddr,
  72. const struct in6_addr *daddr, int len);
  73. int udp6_csum_init(struct sk_buff *skb, struct udphdr *uh, int proto);
  74. #endif