Merge branch 'parisc-4.9-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[cascardo/linux.git] / samples / bpf / test_cgrp2_tc.sh
1 #!/bin/bash
2
3 MY_DIR=$(dirname $0)
4 # Details on the bpf prog
5 BPF_CGRP2_ARRAY_NAME='test_cgrp2_array_pin'
6 BPF_PROG="$MY_DIR/test_cgrp2_tc_kern.o"
7 BPF_SECTION='filter'
8
9 [ -z "$TC" ] && TC='tc'
10 [ -z "$IP" ] && IP='ip'
11
12 # Names of the veth interface, net namespace...etc.
13 HOST_IFC='ve'
14 NS_IFC='vens'
15 NS='ns'
16
17 find_mnt() {
18     cat /proc/mounts | \
19         awk '{ if ($3 == "'$1'" && mnt == "") { mnt = $2 }} END { print mnt }'
20 }
21
22 # Init cgroup2 vars
23 init_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
35 init_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
41 setup_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
58 setup_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
70 setup_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
91 run_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
99 do_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
113 do_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
144 init_cgrp2_vars
145 init_bpf_fs_vars
146
147 while [[ $# -ge 1 ]]
148 do
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
173 done
174
175 trap do_exit 0
176
177 [ "$MODE" == 'cleanuponly' ] && exit
178
179 setup_cgrp2 start || exit $?
180 setup_net start || exit $?
181 init_bpf_fs_vars || exit $?
182 setup_bpf_cgrp2_array start || exit $?
183 do_test
184 echo