network_helpers.c provides some helpers to generate ip checksums or ip pseudo-header checksums, but not for upper layers (eg: udp checksums)
Add helpers for udp checksum to allow manually building udp packets.
Signed-off-by: Alexis Lothoré (eBPF Foundation) alexis.lothore@bootlin.com --- Changes in v3: - reuse pseudo-header checksum helper in the new helpers - reduce parameters list (eg: it does not make sense to passe the l4 protocol in a udp-specific helper)
Changes in v2: - new patch --- tools/testing/selftests/bpf/network_helpers.h | 42 +++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)
diff --git a/tools/testing/selftests/bpf/network_helpers.h b/tools/testing/selftests/bpf/network_helpers.h index 6ca636643ea2b77fb5cc459b03bf7f8c4f749377..479f678af191e9fa8a7129e050a25bf9ed0cf37e 100644 --- a/tools/testing/selftests/bpf/network_helpers.h +++ b/tools/testing/selftests/bpf/network_helpers.h @@ -13,6 +13,7 @@ typedef __u16 __sum16; #include <linux/sockios.h> #include <linux/err.h> #include <netinet/tcp.h> +#include <netinet/udp.h> #include <bpf/bpf_endian.h> #include <net/if.h>
@@ -192,6 +193,47 @@ static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr, return csum_fold((__u32)s); }
+/** + * build_udp_v4_csum - compute UDP checksum for UDP over IPv4 + * + * Compute the checksum to embed in UDP header, composed of the sum of IP + * pseudo-header checksum, UDP header checksum and UDP data checksum + * @iph IP header + * @udph UDP header, which must be immediately followed by UDP data + * + * Returns the total checksum + */ + +static inline __sum16 build_udp_v4_csum(const struct iphdr *iph, + const struct udphdr *udph) +{ + unsigned long sum; + + sum = csum_partial(udph, ntohs(udph->len), 0); + return csum_tcpudp_magic(iph->saddr, iph->daddr, ntohs(udph->len), + IPPROTO_UDP, sum); +} + +/** + * build_udp_v6_csum - compute UDP checksum for UDP over IPv6 + * + * Compute the checksum to embed in UDP header, composed of the sum of IPv6 + * pseudo-header checksum, UDP header checksum and UDP data checksum + * @ip6h IPv6 header + * @udph UDP header, which must be immediately followed by UDP data + * + * Returns the total checksum + */ +static inline __sum16 build_udp_v6_csum(const struct ipv6hdr *ip6h, + const struct udphdr *udph) +{ + unsigned long sum; + + sum = csum_partial(udph, ntohs(udph->len), 0); + return csum_ipv6_magic(&ip6h->saddr, &ip6h->daddr, ntohs(udph->len), + IPPROTO_UDP, sum); +} + struct tmonitor_ctx;
#ifdef TRAFFIC_MONITOR