0001
0002
0003
0004 MY_DIR=$(dirname $0)
0005
0006 BPF_CGRP2_ARRAY_NAME='test_cgrp2_array_pin'
0007 BPF_PROG="$MY_DIR/test_cgrp2_tc_kern.o"
0008 BPF_SECTION='filter'
0009
0010 [ -z "$TC" ] && TC='tc'
0011 [ -z "$IP" ] && IP='ip'
0012
0013
0014 HOST_IFC='ve'
0015 NS_IFC='vens'
0016 NS='ns'
0017
0018 find_mnt() {
0019 cat /proc/mounts | \
0020 awk '{ if ($3 == "'$1'" && mnt == "") { mnt = $2 }} END { print mnt }'
0021 }
0022
0023
0024 init_cgrp2_vars() {
0025 CGRP2_ROOT=$(find_mnt cgroup2)
0026 if [ -z "$CGRP2_ROOT" ]
0027 then
0028 CGRP2_ROOT='/mnt/cgroup2'
0029 MOUNT_CGRP2="yes"
0030 fi
0031 CGRP2_TC="$CGRP2_ROOT/tc"
0032 CGRP2_TC_LEAF="$CGRP2_TC/leaf"
0033 }
0034
0035
0036 init_bpf_fs_vars() {
0037 local bpf_fs_root=$(find_mnt bpf)
0038 [ -n "$bpf_fs_root" ] || return -1
0039 BPF_FS_TC_SHARE="$bpf_fs_root/tc/globals"
0040 }
0041
0042 setup_cgrp2() {
0043 case $1 in
0044 start)
0045 if [ "$MOUNT_CGRP2" == 'yes' ]
0046 then
0047 [ -d $CGRP2_ROOT ] || mkdir -p $CGRP2_ROOT
0048 mount -t cgroup2 none $CGRP2_ROOT || return $?
0049 fi
0050 mkdir -p $CGRP2_TC_LEAF
0051 ;;
0052 *)
0053 rmdir $CGRP2_TC_LEAF && rmdir $CGRP2_TC
0054 [ "$MOUNT_CGRP2" == 'yes' ] && umount $CGRP2_ROOT
0055 ;;
0056 esac
0057 }
0058
0059 setup_bpf_cgrp2_array() {
0060 local bpf_cgrp2_array="$BPF_FS_TC_SHARE/$BPF_CGRP2_ARRAY_NAME"
0061 case $1 in
0062 start)
0063 $MY_DIR/test_cgrp2_array_pin -U $bpf_cgrp2_array -v $CGRP2_TC
0064 ;;
0065 *)
0066 [ -d "$BPF_FS_TC_SHARE" ] && rm -f $bpf_cgrp2_array
0067 ;;
0068 esac
0069 }
0070
0071 setup_net() {
0072 case $1 in
0073 start)
0074 $IP link add $HOST_IFC type veth peer name $NS_IFC || return $?
0075 $IP link set dev $HOST_IFC up || return $?
0076 sysctl -q net.ipv6.conf.$HOST_IFC.accept_dad=0
0077
0078 $IP netns add ns || return $?
0079 $IP link set dev $NS_IFC netns ns || return $?
0080 $IP -n $NS link set dev $NS_IFC up || return $?
0081 $IP netns exec $NS sysctl -q net.ipv6.conf.$NS_IFC.accept_dad=0
0082 $TC qdisc add dev $HOST_IFC clsact || return $?
0083 $TC filter add dev $HOST_IFC egress bpf da obj $BPF_PROG sec $BPF_SECTION || return $?
0084 ;;
0085 *)
0086 $IP netns del $NS
0087 $IP link del $HOST_IFC
0088 ;;
0089 esac
0090 }
0091
0092 run_in_cgrp() {
0093
0094
0095 cmd='echo $$ > '
0096 cmd="$cmd $1/cgroup.procs; exec $2"
0097 bash -c "$cmd"
0098 }
0099
0100 do_test() {
0101 run_in_cgrp $CGRP2_TC_LEAF "ping -6 -c3 ff02::1%$HOST_IFC >& /dev/null"
0102 local dropped=$($TC -s qdisc show dev $HOST_IFC | tail -3 | \
0103 awk '/drop/{print substr($7, 0, index($7, ",")-1)}')
0104 if [[ $dropped -eq 0 ]]
0105 then
0106 echo "FAIL"
0107 return 1
0108 else
0109 echo "Successfully filtered $dropped packets"
0110 return 0
0111 fi
0112 }
0113
0114 do_exit() {
0115 if [ "$DEBUG" == "yes" ] && [ "$MODE" != 'cleanuponly' ]
0116 then
0117 echo "------ DEBUG ------"
0118 echo "mount: "; mount | egrep '(cgroup2|bpf)'; echo
0119 echo "$CGRP2_TC_LEAF: "; ls -l $CGRP2_TC_LEAF; echo
0120 if [ -d "$BPF_FS_TC_SHARE" ]
0121 then
0122 echo "$BPF_FS_TC_SHARE: "; ls -l $BPF_FS_TC_SHARE; echo
0123 fi
0124 echo "Host net:"
0125 $IP netns
0126 $IP link show dev $HOST_IFC
0127 $IP -6 a show dev $HOST_IFC
0128 $TC -s qdisc show dev $HOST_IFC
0129 echo
0130 echo "$NS net:"
0131 $IP -n $NS link show dev $NS_IFC
0132 $IP -n $NS -6 link show dev $NS_IFC
0133 echo "------ DEBUG ------"
0134 echo
0135 fi
0136
0137 if [ "$MODE" != 'nocleanup' ]
0138 then
0139 setup_net stop
0140 setup_bpf_cgrp2_array stop
0141 setup_cgrp2 stop
0142 fi
0143 }
0144
0145 init_cgrp2_vars
0146 init_bpf_fs_vars
0147
0148 while [[ $
0149 do
0150 a="$1"
0151 case $a in
0152 debug)
0153 DEBUG='yes'
0154 shift 1
0155 ;;
0156 cleanup-only)
0157 MODE='cleanuponly'
0158 shift 1
0159 ;;
0160 no-cleanup)
0161 MODE='nocleanup'
0162 shift 1
0163 ;;
0164 *)
0165 echo "test_cgrp2_tc [debug] [cleanup-only | no-cleanup]"
0166 echo " debug: Print cgrp and network setup details at the end of the test"
0167 echo " cleanup-only: Try to cleanup things from last test. No test will be run"
0168 echo " no-cleanup: Run the test but don't do cleanup at the end"
0169 echo "[Note: If no arg is given, it will run the test and do cleanup at the end]"
0170 echo
0171 exit -1
0172 ;;
0173 esac
0174 done
0175
0176 trap do_exit 0
0177
0178 [ "$MODE" == 'cleanuponly' ] && exit
0179
0180 setup_cgrp2 start || exit $?
0181 setup_net start || exit $?
0182 init_bpf_fs_vars || exit $?
0183 setup_bpf_cgrp2_array start || exit $?
0184 do_test
0185 echo