#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# +-----------------------+ +----------------------+
# | H1 (vrf) | | H2 (vrf) |
# | + $h1 | | $h2 + |
# | | 192.0.2.1/28 | | 192.0.2.2/28 | |
# | | 2001:db8:1::1/64 | | 2001:db8:1::2/64 | |
# +----|------------------+ +------------------|---+
# | |
# +----|-------------------------------------------------------------------|---+
# | SW | | |
# | +-|-------------------------------------------------------------------|-+ |
# | | + $swp1 BR $swp2 + | |
# | +-----------------------------------------------------------------------+ |
# +----------------------------------------------------------------------------+
ALL_TESTS="
test_port_range_ipv4_udp
test_port_range_ipv4_tcp
test_port_range_ipv6_udp
test_port_range_ipv6_tcp
"
NUM_NETIFS=4
source lib.sh
source tc_common.sh
h1_create()
{
simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/64
}
h1_destroy()
{
simple_if_fini $h1 192.0.2.1/28 2001:db8:1::1/64
}
h2_create()
{
simple_if_init $h2 192.0.2.2/28 2001:db8:1::2/64
}
h2_destroy()
{
simple_if_fini $h2 192.0.2.2/28 2001:db8:1::2/64
}
switch_create()
{
ip link add name br1 type bridge
ip link set dev $swp1 master br1
ip link set dev $swp1 up
ip link set dev $swp2 master br1
ip link set dev $swp2 up
ip link set dev br1 up
tc qdisc add dev $swp1 clsact
tc qdisc add dev $swp2 clsact
}
switch_destroy()
{
tc qdisc del dev $swp2 clsact
tc qdisc del dev $swp1 clsact
ip link set dev br1 down
ip link set dev $swp2 down
ip link set dev $swp2 nomaster
ip link set dev $swp1 down
ip link set dev $swp1 nomaster
ip link del dev br1
}
__test_port_range()
{
local proto=$1; shift
local ip_proto=$1; shift
local sip=$1; shift
local dip=$1; shift
local mode=$1; shift
local name=$1; shift
local dmac=$(mac_get $h2)
local smac=$(mac_get $h1)
local sport_min=100
local sport_max=200
local sport_mid=$((sport_min + (sport_max - sport_min) / 2))
local dport_min=300
local dport_max=400
local dport_mid=$((dport_min + (dport_max - dport_min) / 2))
RET=0
tc filter add dev $swp1 ingress protocol $proto handle 101 pref 1 \
flower src_ip $sip dst_ip $dip ip_proto $ip_proto \
src_port $sport_min-$sport_max \
dst_port $dport_min-$dport_max \
action pass
tc filter add dev $swp2 egress protocol $proto handle 101 pref 1 \
flower src_ip $sip dst_ip $dip ip_proto $ip_proto \
src_port $sport_min-$sport_max \
dst_port $dport_min-$dport_max \
action drop
$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
-t $ip_proto "sp=$sport_min,dp=$dport_min"
tc_check_packets "dev $swp1 ingress" 101 1
check_err $? "Ingress filter not hit with minimum ports"
tc_check_packets "dev $swp2 egress" 101 1
check_err $? "Egress filter not hit with minimum ports"
$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
-t $ip_proto "sp=$sport_mid,dp=$dport_mid"
tc_check_packets "dev $swp1 ingress" 101 2
check_err $? "Ingress filter not hit with middle ports"
tc_check_packets "dev $swp2 egress" 101 2
check_err $? "Egress filter not hit with middle ports"
$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
-t $ip_proto "sp=$sport_max,dp=$dport_max"
tc_check_packets "dev $swp1 ingress" 101 3
check_err $? "Ingress filter not hit with maximum ports"
tc_check_packets "dev $swp2 egress" 101 3
check_err $? "Egress filter not hit with maximum ports"
# Send traffic when both ports are out of range and when only one port
# is out of range.
$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
-t $ip_proto "sp=$((sport_min - 1)),dp=$dport_min"
$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
-t $ip_proto "sp=$((sport_max + 1)),dp=$dport_min"
$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
-t $ip_proto "sp=$sport_min,dp=$((dport_min - 1))"
$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
-t $ip_proto "sp=$sport_min,dp=$((dport_max + 1))"
$MZ $mode $h1 -c 1 -q -p 100 -a $smac -b $dmac -A $sip -B $dip \
-t $ip_proto "sp=$((sport_max + 1)),dp=$((dport_max + 1))"
tc_check_packets "dev $swp1 ingress" 101 3
check_err $? "Ingress filter was hit when should not"
tc_check_packets "dev $swp2 egress" 101 3
check_err $? "Egress filter was hit when should not"
tc filter del dev $swp2 egress protocol $proto pref 1 handle 101 flower
tc filter del dev $swp1 ingress protocol $proto pref 1 handle 101 flower
log_test "Port range matching - $name"
}
test_port_range_ipv4_udp()
{
local proto=ipv4
local ip_proto=udp
local sip=192.0.2.1
local dip=192.0.2.2
local mode="-4"
local name="IPv4 UDP"
__test_port_range $proto $ip_proto $sip $dip $mode "$name"
}
test_port_range_ipv4_tcp()
{
local proto=ipv4
local ip_proto=tcp
local sip=192.0.2.1
local dip=192.0.2.2
local mode="-4"
local name="IPv4 TCP"
__test_port_range $proto $ip_proto $sip $dip $mode "$name"
}
test_port_range_ipv6_udp()
{
local proto=ipv6
local ip_proto=udp
local sip=2001:db8:1::1
local dip=2001:db8:1::2
local mode="-6"
local name="IPv6 UDP"
__test_port_range $proto $ip_proto $sip $dip $mode "$name"
}
test_port_range_ipv6_tcp()
{
local proto=ipv6
local ip_proto=tcp
local sip=2001:db8:1::1
local dip=2001:db8:1::2
local mode="-6"
local name="IPv6 TCP"
__test_port_range $proto $ip_proto $sip $dip $mode "$name"
}
setup_prepare()
{
h1=${NETIFS[p1]}
swp1=${NETIFS[p2]}
swp2=${NETIFS[p3]}
h2=${NETIFS[p4]}
vrf_prepare
h1_create
h2_create
switch_create
}
cleanup()
{
pre_cleanup
switch_destroy
h2_destroy
h1_destroy
vrf_cleanup
}
trap cleanup EXIT
setup_prepare
setup_wait
tests_run
exit $EXIT_STATUS