Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  1// SPDX-License-Identifier: GPL-2.0
  2#include <test_progs.h>
  3#include <network_helpers.h>
  4#include <bpf/btf.h>
  5#include <linux/if_link.h>
  6#include <linux/udp.h>
  7#include <net/if.h>
  8#include <unistd.h>
  9
 10#include "xdp_flowtable.skel.h"
 11
 12#define TX_NETNS_NAME	"ns0"
 13#define RX_NETNS_NAME	"ns1"
 14
 15#define TX_NAME		"v0"
 16#define FORWARD_NAME	"v1"
 17#define RX_NAME		"d0"
 18
 19#define TX_MAC		"00:00:00:00:00:01"
 20#define FORWARD_MAC	"00:00:00:00:00:02"
 21#define RX_MAC		"00:00:00:00:00:03"
 22#define DST_MAC		"00:00:00:00:00:04"
 23
 24#define TX_ADDR		"10.0.0.1"
 25#define FORWARD_ADDR	"10.0.0.2"
 26#define RX_ADDR		"20.0.0.1"
 27#define DST_ADDR	"20.0.0.2"
 28
 29#define PREFIX_LEN	"8"
 30#define N_PACKETS	10
 31#define UDP_PORT	12345
 32#define UDP_PORT_STR	"12345"
 33
 34static int send_udp_traffic(void)
 35{
 36	struct sockaddr_storage addr;
 37	int i, sock;
 38
 39	if (make_sockaddr(AF_INET, DST_ADDR, UDP_PORT, &addr, NULL))
 40		return -EINVAL;
 41
 42	sock = socket(AF_INET, SOCK_DGRAM, 0);
 43	if (sock < 0)
 44		return sock;
 45
 46	for (i = 0; i < N_PACKETS; i++) {
 47		unsigned char buf[] = { 0xaa, 0xbb, 0xcc };
 48		int n;
 49
 50		n = sendto(sock, buf, sizeof(buf), MSG_NOSIGNAL | MSG_CONFIRM,
 51			   (struct sockaddr *)&addr, sizeof(addr));
 52		if (n != sizeof(buf)) {
 53			close(sock);
 54			return -EINVAL;
 55		}
 56
 57		usleep(50000); /* 50ms */
 58	}
 59	close(sock);
 60
 61	return 0;
 62}
 63
 64void test_xdp_flowtable(void)
 65{
 66	struct xdp_flowtable *skel = NULL;
 67	struct nstoken *tok = NULL;
 68	int iifindex, stats_fd;
 69	__u32 value, key = 0;
 70	struct bpf_link *link;
 71
 72	if (SYS_NOFAIL("nft -v")) {
 73		fprintf(stdout, "Missing required nft tool\n");
 74		test__skip();
 75		return;
 76	}
 77
 78	SYS(out, "ip netns add " TX_NETNS_NAME);
 79	SYS(out, "ip netns add " RX_NETNS_NAME);
 80
 81	tok = open_netns(RX_NETNS_NAME);
 82	if (!ASSERT_OK_PTR(tok, "setns"))
 83		goto out;
 84
 85	SYS(out, "sysctl -qw net.ipv4.conf.all.forwarding=1");
 86
 87	SYS(out, "ip link add " TX_NAME " type veth peer " FORWARD_NAME);
 88	SYS(out, "ip link set " TX_NAME " netns " TX_NETNS_NAME);
 89	SYS(out, "ip link set dev " FORWARD_NAME " address " FORWARD_MAC);
 90	SYS(out,
 91	    "ip addr add " FORWARD_ADDR "/" PREFIX_LEN " dev " FORWARD_NAME);
 92	SYS(out, "ip link set dev " FORWARD_NAME " up");
 93
 94	SYS(out, "ip link add " RX_NAME " type dummy");
 95	SYS(out, "ip link set dev " RX_NAME " address " RX_MAC);
 96	SYS(out, "ip addr add " RX_ADDR "/" PREFIX_LEN " dev " RX_NAME);
 97	SYS(out, "ip link set dev " RX_NAME " up");
 98
 99	/* configure the flowtable */
100	SYS(out, "nft add table ip filter");
101	SYS(out,
102	    "nft add flowtable ip filter f { hook ingress priority 0\\; "
103	    "devices = { " FORWARD_NAME ", " RX_NAME " }\\; }");
104	SYS(out,
105	    "nft add chain ip filter forward "
106	    "{ type filter hook forward priority 0\\; }");
107	SYS(out,
108	    "nft add rule ip filter forward ip protocol udp th dport "
109	    UDP_PORT_STR " flow add @f");
110
111	/* Avoid ARP calls */
112	SYS(out,
113	    "ip -4 neigh add " DST_ADDR " lladdr " DST_MAC " dev " RX_NAME);
114
115	close_netns(tok);
116	tok = open_netns(TX_NETNS_NAME);
117	if (!ASSERT_OK_PTR(tok, "setns"))
118		goto out;
119
120	SYS(out, "ip addr add " TX_ADDR "/" PREFIX_LEN " dev " TX_NAME);
121	SYS(out, "ip link set dev " TX_NAME " address " TX_MAC);
122	SYS(out, "ip link set dev " TX_NAME " up");
123	SYS(out, "ip route add default via " FORWARD_ADDR);
124
125	close_netns(tok);
126	tok = open_netns(RX_NETNS_NAME);
127	if (!ASSERT_OK_PTR(tok, "setns"))
128		goto out;
129
130	iifindex = if_nametoindex(FORWARD_NAME);
131	if (!ASSERT_NEQ(iifindex, 0, "iifindex"))
132		goto out;
133
134	skel = xdp_flowtable__open_and_load();
135	if (!ASSERT_OK_PTR(skel, "skel"))
136		goto out;
137
138	link = bpf_program__attach_xdp(skel->progs.xdp_flowtable_do_lookup,
139				       iifindex);
140	if (!ASSERT_OK_PTR(link, "prog_attach"))
141		goto out;
142
143	close_netns(tok);
144	tok = open_netns(TX_NETNS_NAME);
145	if (!ASSERT_OK_PTR(tok, "setns"))
146		goto out;
147
148	if (!ASSERT_OK(send_udp_traffic(), "send udp"))
149		goto out;
150
151	close_netns(tok);
152	tok = open_netns(RX_NETNS_NAME);
153	if (!ASSERT_OK_PTR(tok, "setns"))
154		goto out;
155
156	stats_fd = bpf_map__fd(skel->maps.stats);
157	if (!ASSERT_OK(bpf_map_lookup_elem(stats_fd, &key, &value),
158		       "bpf_map_update_elem stats"))
159		goto out;
160
161	ASSERT_GE(value, N_PACKETS - 2, "bpf_xdp_flow_lookup failed");
162out:
163	xdp_flowtable__destroy(skel);
164	if (tok)
165		close_netns(tok);
166	SYS_NOFAIL("ip netns del " TX_NETNS_NAME);
167	SYS_NOFAIL("ip netns del " RX_NETNS_NAME);
168}