xref: /openbmc/linux/samples/bpf/test_cgrp2_tc.sh (revision 981ab3f1)
1#!/bin/bash
2
3MY_DIR=$(dirname $0)
4# Details on the bpf prog
5BPF_CGRP2_ARRAY_NAME='test_cgrp2_array_pin'
6BPF_PROG="$MY_DIR/test_cgrp2_tc_kern.o"
7BPF_SECTION='filter'
8
9[ -z "$TC" ] && TC='tc'
10[ -z "$IP" ] && IP='ip'
11
12# Names of the veth interface, net namespace...etc.
13HOST_IFC='ve'
14NS_IFC='vens'
15NS='ns'
16
17find_mnt() {
18    cat /proc/mounts | \
19	awk '{ if ($3 == "'$1'" && mnt == "") { mnt = $2 }} END { print mnt }'
20}
21
22# Init cgroup2 vars
23init_cgrp2_vars() {
24    CGRP2_ROOT=$(find_mnt cgroup2)
25    if [ -z "$CGRP2_ROOT" ]
26    then
27	CGRP2_ROOT='/mnt/cgroup2'
28	MOUNT_CGRP2="yes"
29    fi
30    CGRP2_TC="$CGRP2_ROOT/tc"
31    CGRP2_TC_LEAF="$CGRP2_TC/leaf"
32}
33
34# Init bpf fs vars
35init_bpf_fs_vars() {
36    local bpf_fs_root=$(find_mnt bpf)
37    [ -n "$bpf_fs_root" ] || return -1
38    BPF_FS_TC_SHARE="$bpf_fs_root/tc/globals"
39}
40
41setup_cgrp2() {
42    case $1 in
43	start)
44	    if [ "$MOUNT_CGRP2" == 'yes' ]
45	    then
46		[ -d $CGRP2_ROOT ] || mkdir -p $CGRP2_ROOT
47		mount -t cgroup2 none $CGRP2_ROOT || return $?
48	    fi
49	    mkdir -p $CGRP2_TC_LEAF
50	    ;;
51	*)
52	    rmdir $CGRP2_TC_LEAF && rmdir $CGRP2_TC
53	    [ "$MOUNT_CGRP2" == 'yes' ] && umount $CGRP2_ROOT
54	    ;;
55    esac
56}
57
58setup_bpf_cgrp2_array() {
59    local bpf_cgrp2_array="$BPF_FS_TC_SHARE/$BPF_CGRP2_ARRAY_NAME"
60    case $1 in
61	start)
62	    $MY_DIR/test_cgrp2_array_pin -U $bpf_cgrp2_array -v $CGRP2_TC
63	    ;;
64	*)
65	    [ -d "$BPF_FS_TC_SHARE" ] && rm -f $bpf_cgrp2_array
66	    ;;
67    esac
68}
69
70setup_net() {
71    case $1 in
72	start)
73	    $IP link add $HOST_IFC type veth peer name $NS_IFC || return $?
74	    $IP link set dev $HOST_IFC up || return $?
75	    sysctl -q net.ipv6.conf.$HOST_IFC.accept_dad=0
76
77	    $IP netns add ns || return $?
78	    $IP link set dev $NS_IFC netns ns || return $?
79	    $IP -n $NS link set dev $NS_IFC up || return $?
80	    $IP netns exec $NS sysctl -q net.ipv6.conf.$NS_IFC.accept_dad=0
81	    $TC qdisc add dev $HOST_IFC clsact || return $?
82	    $TC filter add dev $HOST_IFC egress bpf da obj $BPF_PROG sec $BPF_SECTION || return $?
83	    ;;
84	*)
85	    $IP netns del $NS
86	    $IP link del $HOST_IFC
87	    ;;
88    esac
89}
90
91run_in_cgrp() {
92    # Fork another bash and move it under the specified cgroup.
93    # It makes the cgroup cleanup easier at the end of the test.
94    cmd='echo $$ > '
95    cmd="$cmd $1/cgroup.procs; exec $2"
96    bash -c "$cmd"
97}
98
99do_test() {
100    run_in_cgrp $CGRP2_TC_LEAF "ping -6 -c3 ff02::1%$HOST_IFC >& /dev/null"
101    local dropped=$($TC -s qdisc show dev $HOST_IFC | tail -3 | \
102			   awk '/drop/{print substr($7, 0, index($7, ",")-1)}')
103    if [[ $dropped -eq 0 ]]
104    then
105	echo "FAIL"
106	return 1
107    else
108	echo "Successfully filtered $dropped packets"
109	return 0
110    fi
111}
112
113do_exit() {
114    if [ "$DEBUG" == "yes" ] && [ "$MODE" != 'cleanuponly' ]
115    then
116	echo "------ DEBUG ------"
117	echo "mount: "; mount | egrep '(cgroup2|bpf)'; echo
118	echo "$CGRP2_TC_LEAF: "; ls -l $CGRP2_TC_LEAF; echo
119	if [ -d "$BPF_FS_TC_SHARE" ]
120	then
121	    echo "$BPF_FS_TC_SHARE: "; ls -l $BPF_FS_TC_SHARE; echo
122	fi
123	echo "Host net:"
124	$IP netns
125	$IP link show dev $HOST_IFC
126	$IP -6 a show dev $HOST_IFC
127	$TC -s qdisc show dev $HOST_IFC
128	echo
129	echo "$NS net:"
130	$IP -n $NS link show dev $NS_IFC
131	$IP -n $NS -6 link show dev $NS_IFC
132	echo "------ DEBUG ------"
133	echo
134    fi
135
136    if [ "$MODE" != 'nocleanup' ]
137    then
138	setup_net stop
139	setup_bpf_cgrp2_array stop
140	setup_cgrp2 stop
141    fi
142}
143
144init_cgrp2_vars
145init_bpf_fs_vars
146
147while [[ $# -ge 1 ]]
148do
149    a="$1"
150    case $a in
151	debug)
152	    DEBUG='yes'
153	    shift 1
154	    ;;
155	cleanup-only)
156	    MODE='cleanuponly'
157	    shift 1
158	    ;;
159	no-cleanup)
160	    MODE='nocleanup'
161	    shift 1
162	    ;;
163	*)
164	    echo "test_cgrp2_tc [debug] [cleanup-only | no-cleanup]"
165	    echo "  debug: Print cgrp and network setup details at the end of the test"
166	    echo "  cleanup-only: Try to cleanup things from last test.  No test will be run"
167	    echo "  no-cleanup: Run the test but don't do cleanup at the end"
168	    echo "[Note: If no arg is given, it will run the test and do cleanup at the end]"
169	    echo
170	    exit -1
171	    ;;
172    esac
173done
174
175trap do_exit 0
176
177[ "$MODE" == 'cleanuponly' ] && exit
178
179setup_cgrp2 start || exit $?
180setup_net start || exit $?
181init_bpf_fs_vars || exit $?
182setup_bpf_cgrp2_array start || exit $?
183do_test
184echo
185