linux/samples/bpf/test_cgrp2_tc.sh
<<
>>
Prefs
   1#!/bin/bash
   2# SPDX-License-Identifier: GPL-2.0
   3
   4MY_DIR=$(dirname $0)
   5# Details on the bpf prog
   6BPF_CGRP2_ARRAY_NAME='test_cgrp2_array_pin'
   7BPF_PROG="$MY_DIR/test_cgrp2_tc_kern.o"
   8BPF_SECTION='filter'
   9
  10[ -z "$TC" ] && TC='tc'
  11[ -z "$IP" ] && IP='ip'
  12
  13# Names of the veth interface, net namespace...etc.
  14HOST_IFC='ve'
  15NS_IFC='vens'
  16NS='ns'
  17
  18find_mnt() {
  19    cat /proc/mounts | \
  20        awk '{ if ($3 == "'$1'" && mnt == "") { mnt = $2 }} END { print mnt }'
  21}
  22
  23# Init cgroup2 vars
  24init_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
  36init_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
  42setup_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
  59setup_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
  71setup_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
  92run_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
 100do_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
 114do_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
 145init_cgrp2_vars
 146init_bpf_fs_vars
 147
 148while [[ $# -ge 1 ]]
 149do
 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
 174done
 175
 176trap do_exit 0
 177
 178[ "$MODE" == 'cleanuponly' ] && exit
 179
 180setup_cgrp2 start || exit $?
 181setup_net start || exit $?
 182init_bpf_fs_vars || exit $?
 183setup_bpf_cgrp2_array start || exit $?
 184do_test
 185echo
 186