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

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/bpf/prog_tests/lwt_redirect.c
Extension
.c
Size
8850 bytes
Lines
332
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 OR BSD-3-Clause

/*
 * Test suite of lwt_xmit BPF programs that redirect packets
 *   The file tests focus not only if these programs work as expected normally,
 *   but also if they can handle abnormal situations gracefully.
 *
 * WARNING
 * -------
 *  This test suite may crash the kernel, thus should be run in a VM.
 *
 * Setup:
 * ---------
 *  All tests are performed in a single netns. Two lwt encap routes are setup for
 *  each subtest:
 *
 *    ip route add 10.0.0.0/24 encap bpf xmit <obj> sec "<ingress_sec>" dev link_err
 *    ip route add 20.0.0.0/24 encap bpf xmit <obj> sec "<egress_sec>" dev link_err
 *
 *  Here <obj> is statically defined to test_lwt_redirect.bpf.o, and each section
 *  of this object holds a program entry to test. The BPF object is built from
 *  progs/test_lwt_redirect.c. We didn't use generated BPF skeleton since the
 *  attachment for lwt programs are not supported by libbpf yet.
 *
 *  For testing, ping commands are run in the test netns:
 *
 *    ping 10.0.0.<ifindex> -c 1 -w 1 -s 100
 *    ping 20.0.0.<ifindex> -c 1 -w 1 -s 100
 *
 * Scenarios:
 * --------------------------------
 *  1. Redirect to a running tap/tun device
 *  2. Redirect to a down tap/tun device
 *  3. Redirect to a vlan device with lower layer down
 *
 *  Case 1, ping packets should be received by packet socket on target device
 *  when redirected to ingress, and by tun/tap fd when redirected to egress.
 *
 *  Case 2,3 are considered successful as long as they do not crash the kernel
 *  as a regression.
 *
 *  Case 1,2 use tap device to test redirect to device that requires MAC
 *  header, and tun device to test the case with no MAC header added.
 */
#include <sys/socket.h>
#include <net/if.h>
#include <linux/if_ether.h>
#include <linux/if_packet.h>
#include <linux/if_tun.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>

#define NETNS "ns_lwt_redirect"
#include "lwt_helpers.h"
#include "test_progs.h"
#include "network_helpers.h"

#define BPF_OBJECT            "test_lwt_redirect.bpf.o"
#define INGRESS_SEC(need_mac) ((need_mac) ? "redir_ingress" : "redir_ingress_nomac")
#define EGRESS_SEC(need_mac)  ((need_mac) ? "redir_egress" : "redir_egress_nomac")
#define LOCAL_SRC             "10.0.0.1"
#define CIDR_TO_INGRESS       "10.0.0.0/24"
#define CIDR_TO_EGRESS        "20.0.0.0/24"

/* ping to redirect toward given dev, with last byte of dest IP being the target
 * device index.
 *
 * Note: ping command inside BPF-CI is busybox version, so it does not have certain
 * function, such like -m option to set packet mark.
 */
static void ping_dev(const char *dev, bool is_ingress)
{
	int link_index = if_nametoindex(dev);
	char ip[256];

	if (!ASSERT_GE(link_index, 0, "if_nametoindex"))
		return;

	if (is_ingress)
		snprintf(ip, sizeof(ip), "10.0.0.%d", link_index);
	else
		snprintf(ip, sizeof(ip), "20.0.0.%d", link_index);

	/* We won't get a reply. Don't fail here */
	SYS_NOFAIL("ping %s -c1 -W1 -s %d",
		   ip, ICMP_PAYLOAD_SIZE);
}

Annotation

Implementation Notes