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