tools/testing/selftests/bpf/prog_tests/ip_check_defrag.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/ip_check_defrag.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/ip_check_defrag.c
Extension
.c
Size
7870 bytes
Lines
284
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0
#include <test_progs.h>
#include <net/if.h>
#include <linux/netfilter.h>
#include <network_helpers.h>
#include "ip_check_defrag.skel.h"
#include "ip_check_defrag_frags.h"

/*
 * This selftest spins up a client and an echo server, each in their own
 * network namespace. The client will send a fragmented message to the server.
 * The prog attached to the server will shoot down any fragments. Thus, if
 * the server is able to correctly echo back the message to the client, we will
 * have verified that netfilter is reassembling packets for us.
 *
 * Topology:
 * =========
 *           NS0         |         NS1
 *                       |
 *         client        |       server
 *       ----------      |     ----------
 *       |  veth0  | --------- |  veth1  |
 *       ----------    peer    ----------
 *                       |
 *                       |       with bpf
 */

#define NS0		"defrag_ns0"
#define NS1		"defrag_ns1"
#define VETH0		"veth0"
#define VETH1		"veth1"
#define VETH0_ADDR	"172.16.1.100"
#define VETH0_ADDR6	"fc00::100"
/* The following constants must stay in sync with `generate_udp_fragments.py` */
#define VETH1_ADDR	"172.16.1.200"
#define VETH1_ADDR6	"fc00::200"
#define CLIENT_PORT	48878
#define SERVER_PORT	48879
#define MAGIC_MESSAGE	"THIS IS THE ORIGINAL MESSAGE, PLEASE REASSEMBLE ME"

static int setup_topology(bool ipv6)
{
	bool up;
	int i;

	SYS(fail, "ip netns add " NS0);
	SYS(fail, "ip netns add " NS1);
	SYS(fail, "ip link add " VETH0 " netns " NS0 " type veth peer name " VETH1 " netns " NS1);
	if (ipv6) {
		SYS(fail, "ip -6 -net " NS0 " addr add " VETH0_ADDR6 "/64 dev " VETH0 " nodad");
		SYS(fail, "ip -6 -net " NS1 " addr add " VETH1_ADDR6 "/64 dev " VETH1 " nodad");
	} else {
		SYS(fail, "ip -net " NS0 " addr add " VETH0_ADDR "/24 dev " VETH0);
		SYS(fail, "ip -net " NS1 " addr add " VETH1_ADDR "/24 dev " VETH1);
	}
	SYS(fail, "ip -net " NS0 " link set dev " VETH0 " up");
	SYS(fail, "ip -net " NS1 " link set dev " VETH1 " up");

	/* Wait for up to 5s for links to come up */
	for (i = 0; i < 5; ++i) {
		if (ipv6)
			up = !SYS_NOFAIL("ip netns exec " NS0 " ping -6 -c 1 -W 1 " VETH1_ADDR6);
		else
			up = !SYS_NOFAIL("ip netns exec " NS0 " ping -c 1 -W 1 " VETH1_ADDR);

		if (up)
			break;
	}

	return 0;
fail:
	return -1;
}

static void cleanup_topology(void)
{
	SYS_NOFAIL("test -f /var/run/netns/" NS0 " && ip netns delete " NS0);
	SYS_NOFAIL("test -f /var/run/netns/" NS1 " && ip netns delete " NS1);
}

static int attach(struct ip_check_defrag *skel, bool ipv6)
{
	LIBBPF_OPTS(bpf_netfilter_opts, opts,
		    .pf = ipv6 ? NFPROTO_IPV6 : NFPROTO_IPV4,
		    .priority = 42,
		    .flags = BPF_F_NETFILTER_IP_DEFRAG);
	struct nstoken *nstoken;
	int err = -1;

	nstoken = open_netns(NS1);

Annotation

Implementation Notes