Commit 3eb87b81 authored by Alexei Starovoitov's avatar Alexei Starovoitov
Browse files

Merge branch 'selftests-bpf-migrate-test_flow_dissector-sh-to-test_progs'

Alexis Lothoré says:

====================
This is the revision 3 of test_flow_dissector_migration.sh into
test_progs. This revision addresses comments from Stanislas, especially
about proper reuse of pseudo-header checksuming in new network helpers.

There are 2 "main" parts in test_flow_dissector.sh:
- a set of tests checking flow_dissector programs attachment to either
  root namespace or non-root namespace
- dissection test

The first set is integrated in flow_dissector.c, which already contains
some existing tests for flow_dissector programs. This series uses the
opportunity to update a bit this file (use new assert, re-split tests,
etc)
The second part is migrated into a new file under test_progs,
flow_dissector_classification.c. It uses the same eBPF programs as
flow_dissector.c, but the difference is rather about how those program
are executed:
- flow_dissector.c manually runs programs with BPF_PROG_RUN
- flow_dissector_classification.c sends real packets to be dissected, and
  so it also executes kernel code related to eBPF flow dissector (eg:
__skb_flow_bpf_to_target)

---
Changes in v3:
- Keep new helpers name in sync with kernel ones
- Document some existing network helpers
- Properly reuse pseudo-header csum helper in transport layer csum
  helper
- Drop duplicate assert
- Use const for test structure in the migrated test
- Simplify shutdown callchain for basic test
- collect Acked-by
- Link to v2: https://lore.kernel.org/r/20241114-flow_dissector-v2-0-ee4a3be3de65@bootlin.com

Changes in v2:
- allow tests to run in parallel
- move some generic helpers to network_helpers.h
- define proper function for ASSERT_MEMEQ
- fetch acked-by tags
- Link to v1: https://lore.kernel.org/r/20241113-flow_dissector-v1-0-27c4df0592dc@bootlin.com


====================

Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parents e70140ba 63b37657
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -19,7 +19,6 @@ feature
urandom_read
test_sockmap
test_lirc_mode2_user
test_flow_dissector
flow_dissector_load
test_tcpnotify_user
test_libbpf
+0 −2
Original line number Diff line number Diff line
@@ -133,7 +133,6 @@ TEST_PROGS := test_kmod.sh \
	test_tunnel.sh \
	test_lwt_seg6local.sh \
	test_lirc_mode2.sh \
	test_flow_dissector.sh \
	test_xdp_vlan_mode_generic.sh \
	test_xdp_vlan_mode_native.sh \
	test_lwt_ip_encap.sh \
@@ -161,7 +160,6 @@ TEST_GEN_PROGS_EXTENDED = \
	flow_dissector_load \
	runqslower \
	test_cpp \
	test_flow_dissector \
	test_lirc_mode2_user \
	veristat \
	xdp_features \
+1 −0
Original line number Diff line number Diff line
@@ -58,6 +58,7 @@ CONFIG_MPLS=y
CONFIG_MPLS_IPTUNNEL=y
CONFIG_MPLS_ROUTING=y
CONFIG_MPTCP=y
CONFIG_NET_ACT_GACT=y
CONFIG_NET_ACT_SKBMOD=y
CONFIG_NET_CLS=y
CONFIG_NET_CLS_ACT=y
+1 −1
Original line number Diff line number Diff line
@@ -21,7 +21,7 @@
#include <linux/limits.h>

#include <linux/ip.h>
#include <linux/udp.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <net/if.h>

+96 −0
Original line number Diff line number Diff line
@@ -14,6 +14,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>

@@ -105,6 +106,45 @@ static __u16 csum_fold(__u32 csum)
	return (__u16)~csum;
}

static __wsum csum_partial(const void *buf, int len, __wsum sum)
{
	__u16 *p = (__u16 *)buf;
	int num_u16 = len >> 1;
	int i;

	for (i = 0; i < num_u16; i++)
		sum += p[i];

	return sum;
}

static inline __sum16 build_ip_csum(struct iphdr *iph)
{
	__u32 sum = 0;
	__u16 *p;

	iph->check = 0;
	p = (void *)iph;
	sum = csum_partial(p, iph->ihl << 2, 0);

	return csum_fold(sum);
}

/**
 * csum_tcpudp_magic - compute IP pseudo-header checksum
 *
 * Compute the IPv4 pseudo header checksum. The helper can take a
 * accumulated sum from the transport layer to accumulate it and directly
 * return the transport layer
 *
 * @saddr: IP source address
 * @daddr: IP dest address
 * @len: IP data size
 * @proto: transport layer protocol
 * @csum: The accumulated partial sum to add to the computation
 *
 * Returns the folded sum
 */
static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
					__u32 len, __u8 proto,
					__wsum csum)
@@ -120,6 +160,21 @@ static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
	return csum_fold((__u32)s);
}

/**
 * csum_ipv6_magic - compute IPv6 pseudo-header checksum
 *
 * Compute the ipv6 pseudo header checksum. The helper can take a
 * accumulated sum from the transport layer to accumulate it and directly
 * return the transport layer
 *
 * @saddr: IPv6 source address
 * @daddr: IPv6 dest address
 * @len: IPv6 data size
 * @proto: transport layer protocol
 * @csum: The accumulated partial sum to add to the computation
 *
 * Returns the folded sum
 */
static inline __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
				      const struct in6_addr *daddr,
					__u32 len, __u8 proto,
@@ -139,6 +194,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
Loading