forked from Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
185 lines
4.2 KiB
185 lines
4.2 KiB
#!/bin/bash |
|
# SPDX-License-Identifier: GPL-2.0 |
|
|
|
MY_DIR=$(dirname $0) |
|
# Details on the bpf prog |
|
BPF_CGRP2_ARRAY_NAME='test_cgrp2_array_pin' |
|
BPF_PROG="$MY_DIR/test_cgrp2_tc_kern.o" |
|
BPF_SECTION='filter' |
|
|
|
[ -z "$TC" ] && TC='tc' |
|
[ -z "$IP" ] && IP='ip' |
|
|
|
# Names of the veth interface, net namespace...etc. |
|
HOST_IFC='ve' |
|
NS_IFC='vens' |
|
NS='ns' |
|
|
|
find_mnt() { |
|
cat /proc/mounts | \ |
|
awk '{ if ($3 == "'$1'" && mnt == "") { mnt = $2 }} END { print mnt }' |
|
} |
|
|
|
# Init cgroup2 vars |
|
init_cgrp2_vars() { |
|
CGRP2_ROOT=$(find_mnt cgroup2) |
|
if [ -z "$CGRP2_ROOT" ] |
|
then |
|
CGRP2_ROOT='/mnt/cgroup2' |
|
MOUNT_CGRP2="yes" |
|
fi |
|
CGRP2_TC="$CGRP2_ROOT/tc" |
|
CGRP2_TC_LEAF="$CGRP2_TC/leaf" |
|
} |
|
|
|
# Init bpf fs vars |
|
init_bpf_fs_vars() { |
|
local bpf_fs_root=$(find_mnt bpf) |
|
[ -n "$bpf_fs_root" ] || return -1 |
|
BPF_FS_TC_SHARE="$bpf_fs_root/tc/globals" |
|
} |
|
|
|
setup_cgrp2() { |
|
case $1 in |
|
start) |
|
if [ "$MOUNT_CGRP2" == 'yes' ] |
|
then |
|
[ -d $CGRP2_ROOT ] || mkdir -p $CGRP2_ROOT |
|
mount -t cgroup2 none $CGRP2_ROOT || return $? |
|
fi |
|
mkdir -p $CGRP2_TC_LEAF |
|
;; |
|
*) |
|
rmdir $CGRP2_TC_LEAF && rmdir $CGRP2_TC |
|
[ "$MOUNT_CGRP2" == 'yes' ] && umount $CGRP2_ROOT |
|
;; |
|
esac |
|
} |
|
|
|
setup_bpf_cgrp2_array() { |
|
local bpf_cgrp2_array="$BPF_FS_TC_SHARE/$BPF_CGRP2_ARRAY_NAME" |
|
case $1 in |
|
start) |
|
$MY_DIR/test_cgrp2_array_pin -U $bpf_cgrp2_array -v $CGRP2_TC |
|
;; |
|
*) |
|
[ -d "$BPF_FS_TC_SHARE" ] && rm -f $bpf_cgrp2_array |
|
;; |
|
esac |
|
} |
|
|
|
setup_net() { |
|
case $1 in |
|
start) |
|
$IP link add $HOST_IFC type veth peer name $NS_IFC || return $? |
|
$IP link set dev $HOST_IFC up || return $? |
|
sysctl -q net.ipv6.conf.$HOST_IFC.accept_dad=0 |
|
|
|
$IP netns add ns || return $? |
|
$IP link set dev $NS_IFC netns ns || return $? |
|
$IP -n $NS link set dev $NS_IFC up || return $? |
|
$IP netns exec $NS sysctl -q net.ipv6.conf.$NS_IFC.accept_dad=0 |
|
$TC qdisc add dev $HOST_IFC clsact || return $? |
|
$TC filter add dev $HOST_IFC egress bpf da obj $BPF_PROG sec $BPF_SECTION || return $? |
|
;; |
|
*) |
|
$IP netns del $NS |
|
$IP link del $HOST_IFC |
|
;; |
|
esac |
|
} |
|
|
|
run_in_cgrp() { |
|
# Fork another bash and move it under the specified cgroup. |
|
# It makes the cgroup cleanup easier at the end of the test. |
|
cmd='echo $$ > ' |
|
cmd="$cmd $1/cgroup.procs; exec $2" |
|
bash -c "$cmd" |
|
} |
|
|
|
do_test() { |
|
run_in_cgrp $CGRP2_TC_LEAF "ping -6 -c3 ff02::1%$HOST_IFC >& /dev/null" |
|
local dropped=$($TC -s qdisc show dev $HOST_IFC | tail -3 | \ |
|
awk '/drop/{print substr($7, 0, index($7, ",")-1)}') |
|
if [[ $dropped -eq 0 ]] |
|
then |
|
echo "FAIL" |
|
return 1 |
|
else |
|
echo "Successfully filtered $dropped packets" |
|
return 0 |
|
fi |
|
} |
|
|
|
do_exit() { |
|
if [ "$DEBUG" == "yes" ] && [ "$MODE" != 'cleanuponly' ] |
|
then |
|
echo "------ DEBUG ------" |
|
echo "mount: "; mount | egrep '(cgroup2|bpf)'; echo |
|
echo "$CGRP2_TC_LEAF: "; ls -l $CGRP2_TC_LEAF; echo |
|
if [ -d "$BPF_FS_TC_SHARE" ] |
|
then |
|
echo "$BPF_FS_TC_SHARE: "; ls -l $BPF_FS_TC_SHARE; echo |
|
fi |
|
echo "Host net:" |
|
$IP netns |
|
$IP link show dev $HOST_IFC |
|
$IP -6 a show dev $HOST_IFC |
|
$TC -s qdisc show dev $HOST_IFC |
|
echo |
|
echo "$NS net:" |
|
$IP -n $NS link show dev $NS_IFC |
|
$IP -n $NS -6 link show dev $NS_IFC |
|
echo "------ DEBUG ------" |
|
echo |
|
fi |
|
|
|
if [ "$MODE" != 'nocleanup' ] |
|
then |
|
setup_net stop |
|
setup_bpf_cgrp2_array stop |
|
setup_cgrp2 stop |
|
fi |
|
} |
|
|
|
init_cgrp2_vars |
|
init_bpf_fs_vars |
|
|
|
while [[ $# -ge 1 ]] |
|
do |
|
a="$1" |
|
case $a in |
|
debug) |
|
DEBUG='yes' |
|
shift 1 |
|
;; |
|
cleanup-only) |
|
MODE='cleanuponly' |
|
shift 1 |
|
;; |
|
no-cleanup) |
|
MODE='nocleanup' |
|
shift 1 |
|
;; |
|
*) |
|
echo "test_cgrp2_tc [debug] [cleanup-only | no-cleanup]" |
|
echo " debug: Print cgrp and network setup details at the end of the test" |
|
echo " cleanup-only: Try to cleanup things from last test. No test will be run" |
|
echo " no-cleanup: Run the test but don't do cleanup at the end" |
|
echo "[Note: If no arg is given, it will run the test and do cleanup at the end]" |
|
echo |
|
exit -1 |
|
;; |
|
esac |
|
done |
|
|
|
trap do_exit 0 |
|
|
|
[ "$MODE" == 'cleanuponly' ] && exit |
|
|
|
setup_cgrp2 start || exit $? |
|
setup_net start || exit $? |
|
init_bpf_fs_vars || exit $? |
|
setup_bpf_cgrp2_array start || exit $? |
|
do_test |
|
echo
|
|
|