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