@@ -66,7 +66,8 @@ TEST_PROGS := test_kmod.sh \
test_tc_tunnel.sh \
test_tc_edt.sh \
test_xdping.sh \
- test_bpftool_build.sh
+ test_bpftool_build.sh \
+ test_bpftool_pcap.sh
TEST_PROGS_EXTENDED := with_addr.sh \
with_tunnels.sh \
new file mode 100644
@@ -0,0 +1,41 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. */
+
+#include <stddef.h>
+#include <linux/ptrace.h>
+#include <linux/bpf.h>
+#include <linux/pkt_cls.h>
+
+#include <bpf_helpers.h>
+
+#define KBUILD_MODNAME "foo"
+
+struct bpf_map_def SEC("maps") pcap_data_map = {
+ .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+ .key_size = sizeof(int),
+ .value_size = sizeof(int),
+ .max_entries = 1024,
+};
+
+struct bpf_map_def SEC("maps") pcap_conf_map = {
+ .type = BPF_MAP_TYPE_ARRAY,
+ .key_size = sizeof(int),
+ .value_size = sizeof(struct bpf_pcap_hdr),
+ .max_entries = 1,
+};
+
+SEC("tc_pcap")
+int tc_pcap(struct __sk_buff *skb)
+{
+ struct bpf_pcap_hdr *conf;
+ int key = 0;
+
+ conf = bpf_map_lookup_elem(&pcap_conf_map, &key);
+ if (!conf)
+ return 0;
+
+ bpf_pcap(skb, conf->cap_len, &pcap_data_map, conf->protocol,
+ conf->flags);
+
+ return TC_ACT_OK;
+}
new file mode 100644
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. */
+
+#include <stddef.h>
+#include <linux/bpf.h>
+
+#include <bpf_helpers.h>
+
+#define KBUILD_MODNAME "foo"
+
+struct bpf_map_def SEC("maps") pcap_data_map = {
+ .type = BPF_MAP_TYPE_PERF_EVENT_ARRAY,
+ .key_size = sizeof(int),
+ .value_size = sizeof(int),
+ .max_entries = 1024,
+};
+
+struct bpf_map_def SEC("maps") pcap_conf_map = {
+ .type = BPF_MAP_TYPE_ARRAY,
+ .key_size = sizeof(int),
+ .value_size = sizeof(struct bpf_pcap_hdr),
+ .max_entries = 1,
+};
+
+SEC("xdp_pcap")
+int xdp_pcap(struct xdp_md *ctx)
+{
+ struct bpf_pcap_hdr *conf;
+ int key = 0;
+
+ conf = bpf_map_lookup_elem(&pcap_conf_map, &key);
+ if (!conf)
+ return 0;
+
+ bpf_pcap(ctx, conf->cap_len, &pcap_data_map, conf->protocol,
+ conf->flags);
+
+ return XDP_PASS;
+}
new file mode 100755
@@ -0,0 +1,132 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
+
+readonly src="../../../../"
+readonly bpftool="${src}/tools/bpf/bpftool/bpftool"
+readonly capfile="/tmp/cap.$$"
+readonly ns="ns-$$"
+readonly badport="5555"
+readonly addr1="192.168.1.1"
+readonly addr2="192.168.1.2"
+readonly pinpath="/sys/fs/bpf/"
+readonly veth1="${ns}-veth1"
+readonly veth2="${ns}-veth2"
+# 24 bytes for the pcap header
+readonly cap_minsize=24
+readonly caplens="0 8192"
+readonly addrs="127.0.0.1 ::1"
+readonly devs="none lo"
+
+cleanup() {
+ iptables -D INPUT -p tcp --dport $badport -j DROP
+ ip6tables -D INPUT -p tcp --dport $badport -j DROP
+ ip netns del $ns 2>/dev/null
+ rm -f $capfile
+}
+
+verify_capture() {
+ capsize=$(stat -c '%s' $capfile)
+ if [[ $capsize -le $cap_minsize ]]; then
+ exit 1
+ fi
+ if [[ $no_tcpdump == 0 ]]; then
+ count=$(tcpdump -lnr $capfile $1 2>/dev/null)
+ if [[ -z "$count" ]]; then
+ exit 1
+ fi
+ fi
+}
+
+which tcpdump 2>&1 > /dev/null
+no_tcpdump=$?
+
+pcap_supported=$(bpftool pcap help >/dev/null 2>&1)
+if [[ $? -ne 0 ]]; then
+ echo "no pcap support in bpftool, cannot test feature."
+ exit 0
+fi
+
+set -e
+
+trap cleanup EXIT
+
+iptables -A INPUT -p tcp --dport $badport -j DROP
+ip6tables -A INPUT -p tcp --dport $badport -j DROP
+
+# Test "bpftool pcap trace" - kprobe, tracepoint tracing
+for probe in kprobe tracepoint; do
+ for dev in $devs; do
+ devarg=
+ if [[ $dev != "none" ]]; then
+ devarg="dev $dev"
+ fi
+ args="$probe:kfree_skb proto ip data_out $capfile $devarg"
+ echo "Test trace $args"
+ for caplen in $caplens ; do
+ for progname in none $probe ; do
+ progpath=
+ if [[ $progname != "none" ]]; then
+ progpath=${bpftool}_pcap_${probe}.o
+ fi
+ allargs="$progpath $args len $caplen"
+ for addr in $addrs ; do
+ $bpftool pcap trace $allargs &
+ bpftool_pid=$!
+ set +e
+ timeout 2 nc $addr $badport 2>/dev/null
+ kill -TERM $bpftool_pid
+ set -e
+ sleep 1
+ verify_capture "host $addr and port $badport"
+ rm -f $capfile
+ done
+ done
+ done
+ echo "Test trace $args: PASS"
+ done
+done
+
+# Test "bpftool pcap prog" - skb, xdp program tracing
+ip netns add $ns
+ip link add dev $veth2 netns $ns type veth peer name $veth1
+ip link set $veth1 up
+ip addr add ${addr1}/24 dev $veth1
+ip -netns $ns link set $veth2 up
+ip netns exec $ns ip addr add ${addr2}/24 dev $veth2
+
+for prog in tc xdp ; do
+ if [[ $prog == tc ]]; then
+ ip netns exec $ns tc qdisc add dev $veth2 clsact
+ ip netns exec $ns tc filter add dev $veth2 ingress bpf da \
+ obj bpftool_pcap_${prog}.o sec ${prog}_pcap
+ id=$(ip netns exec $ns tc filter show dev $veth2 ingress | \
+ awk '/direct-action/ { for(i=1;i<=NF;i++)if($i=="id")print $(i+1)}')
+ else
+ ip netns exec $ns ip link set dev $veth2 xdp obj bpftool_pcap_${prog}.o \
+ sec ${prog}_pcap
+ id=$(ip netns exec $ns ip link show $veth2 | awk '/prog\/xdp/ { print $3 }')
+ sleep 5
+ fi
+ args="id $id data_out $capfile"
+ echo "Test prog $args"
+ for caplen in $caplens ; do
+ allargs="$args len $caplen"
+ $bpftool pcap prog $allargs &
+ bpftool_pid=$!
+ set +e
+ ping -q -c 5 $addr2 1>/dev/null
+ kill -TERM $bpftool_pid
+ set -e
+ sleep 1
+ verify_capture "host $addr1"
+ rm -f $capfile
+ done
+ if [[ $prog == tc ]]; then
+ ip netns exec $ns tc qdisc del dev $veth2 clsact
+ sleep 1
+ else
+ ip netns exec $ns ip link set dev $veth2 xdp off
+ fi
+ echo "Test trace $args: PASS"
+done
add tests which verify packet capture works for tracing of kprobes and raw tracepoints, and for capturing packets from existing skb/xdp programs. Signed-off-by: Alan Maguire <alan.maguire@oracle.com> --- tools/testing/selftests/bpf/Makefile | 3 +- .../testing/selftests/bpf/progs/bpftool_pcap_tc.c | 41 +++++++ .../testing/selftests/bpf/progs/bpftool_pcap_xdp.c | 39 ++++++ tools/testing/selftests/bpf/test_bpftool_pcap.sh | 132 +++++++++++++++++++++ 4 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/bpf/progs/bpftool_pcap_tc.c create mode 100644 tools/testing/selftests/bpf/progs/bpftool_pcap_xdp.c create mode 100755 tools/testing/selftests/bpf/test_bpftool_pcap.sh