selftests/bpf: Add csum helpers
authorStanislav Fomichev <sdf@google.com>
Mon, 27 Nov 2023 19:03:16 +0000 (11:03 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 29 Nov 2023 22:59:41 +0000 (14:59 -0800)
Checksum helpers will be used to calculate pseudo-header checksum in
AF_XDP metadata selftests.

The helpers are mirroring existing kernel ones:
- csum_tcpudp_magic : IPv4 pseudo header csum
- csum_ipv6_magic : IPv6 pseudo header csum
- csum_fold : fold csum and do one's complement

Signed-off-by: Stanislav Fomichev <sdf@google.com>
Link: https://lore.kernel.org/r/20231127190319.1190813-11-sdf@google.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/network_helpers.h

index 34f1200a781b550df99ec02c700a968221c38323..94b9be24e39bcb6b82fc796ab08e34f53fa8bbbb 100644 (file)
@@ -71,4 +71,47 @@ struct nstoken;
  */
 struct nstoken *open_netns(const char *name);
 void close_netns(struct nstoken *token);
+
+static __u16 csum_fold(__u32 csum)
+{
+       csum = (csum & 0xffff) + (csum >> 16);
+       csum = (csum & 0xffff) + (csum >> 16);
+
+       return (__u16)~csum;
+}
+
+static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+                                       __u32 len, __u8 proto,
+                                       __wsum csum)
+{
+       __u64 s = csum;
+
+       s += (__u32)saddr;
+       s += (__u32)daddr;
+       s += htons(proto + len);
+       s = (s & 0xffffffff) + (s >> 32);
+       s = (s & 0xffffffff) + (s >> 32);
+
+       return csum_fold((__u32)s);
+}
+
+static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
+                                     const struct in6_addr *daddr,
+                                       __u32 len, __u8 proto,
+                                       __wsum csum)
+{
+       __u64 s = csum;
+       int i;
+
+       for (i = 0; i < 4; i++)
+               s += (__u32)saddr->s6_addr32[i];
+       for (i = 0; i < 4; i++)
+               s += (__u32)daddr->s6_addr32[i];
+       s += htons(proto + len);
+       s = (s & 0xffffffff) + (s >> 32);
+       s = (s & 0xffffffff) + (s >> 32);
+
+       return csum_fold((__u32)s);
+}
+
 #endif