#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# Test devlink-trap tunnel drops and exceptions functionality over mlxsw.
# Check all traps to make sure they are triggered under the right
# conditions.
# +--------------------+
# | H1 (vrf) |
# | + $h1 |
# | | 192.0.2.1/28 |
# +----|---------------+
# |
# +----|----------------------------------------------------------------------+
# | SW | |
# | +--|--------------------------------------------------------------------+ |
# | | + $swp1 BR1 (802.1d) | |
# | | | |
# | | + vx1 (vxlan) | |
# | | local 192.0.2.17 | |
# | | id 1000 dstport $VXPORT | |
# | +-----------------------------------------------------------------------+ |
# | |
# | + $rp1 |
# | | 192.0.2.17/28 |
# +----|----------------------------------------------------------------------+
# |
# +----|--------------------------------------------------------+
# | | VRF2 |
# | + $rp2 |
# | 192.0.2.18/28 |
# | |
# +-------------------------------------------------------------+
lib_dir=$(dirname $0)/../../../net/forwarding
ALL_TESTS="
decap_error_test
overlay_smac_is_mc_test
"
NUM_NETIFS=4
source $lib_dir/lib.sh
source $lib_dir/tc_common.sh
source $lib_dir/devlink_lib.sh
: ${VXPORT:=4789}
export VXPORT
h1_create()
{
simple_if_init $h1 192.0.2.1/28
}
h1_destroy()
{
simple_if_fini $h1 192.0.2.1/28
}
switch_create()
{
ip link add name br1 type bridge vlan_filtering 0 mcast_snooping 0
# Make sure the bridge uses the MAC address of the local port and not
# that of the VxLAN's device.
ip link set dev br1 address $(mac_get $swp1)
ip link set dev br1 up
tc qdisc add dev $swp1 clsact
ip link set dev $swp1 master br1
ip link set dev $swp1 up
ip link add name vx1 type vxlan id 1000 local 192.0.2.17 \
dstport "$VXPORT" nolearning noudpcsum tos inherit ttl 100
ip link set dev vx1 master br1
ip link set dev vx1 up
ip address add dev $rp1 192.0.2.17/28
ip link set dev $rp1 up
}
switch_destroy()
{
ip link set dev $rp1 down
ip address del dev $rp1 192.0.2.17/28
ip link set dev vx1 down
ip link set dev vx1 nomaster
ip link del dev vx1
ip link set dev $swp1 down
ip link set dev $swp1 nomaster
tc qdisc del dev $swp1 clsact
ip link set dev br1 down
ip link del dev br1
}
vrf2_create()
{
simple_if_init $rp2 192.0.2.18/28
}
vrf2_destroy()
{
simple_if_fini $rp2 192.0.2.18/28
}
setup_prepare()
{
h1=${NETIFS[p1]}
swp1=${NETIFS[p2]}
rp1=${NETIFS[p3]}
rp2=${NETIFS[p4]}
vrf_prepare
forwarding_enable
h1_create
switch_create
vrf2_create
}
cleanup()
{
pre_cleanup
vrf2_destroy
switch_destroy
h1_destroy
forwarding_restore
vrf_cleanup
}
ecn_payload_get()
{
dest_mac=$(mac_get $h1)
p=$(:
)"08:"$( : VXLAN flags
)"00:00:00:"$( : VXLAN reserved
)"00:03:e8:"$( : VXLAN VNI : 1000
)"00:"$( : VXLAN reserved
)"$dest_mac:"$( : ETH daddr
)"00:00:00:00:00:00:"$( : ETH saddr
)"08:00:"$( : ETH type
)"45:"$( : IP version + IHL
)"00:"$( : IP TOS
)"00:14:"$( : IP total length
)"00:00:"$( : IP identification
)"20:00:"$( : IP flags + frag off
)"40:"$( : IP TTL
)"00:"$( : IP proto
)"D6:E5:"$( : IP header csum
)"c0:00:02:03:"$( : IP saddr: 192.0.2.3
)"c0:00:02:01:"$( : IP daddr: 192.0.2.1
)
echo $p
}
ecn_decap_test()
{
local trap_name="decap_error"
local desc=$1; shift
local ecn_desc=$1; shift
local outer_tos=$1; shift
local mz_pid
RET=0
tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
flower src_ip 192.0.2.3 dst_ip 192.0.2.1 action pass
rp1_mac=$(mac_get $rp1)
payload=$(ecn_payload_get)
ip vrf exec v$rp2 $MZ $rp2 -c 0 -d 1msec -b $rp1_mac -B 192.0.2.17 \
-t udp sp=12345,dp=$VXPORT,tos=$outer_tos,p=$payload -q &
mz_pid=$!
devlink_trap_exception_test $trap_name
tc_check_packets "dev $swp1 egress" 101 0
check_err $? "Packets were not dropped"
log_test "$desc: Inner ECN is not ECT and outer is $ecn_desc"
kill $mz_pid && wait $mz_pid &> /dev/null
tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower
}
reserved_bits_payload_get()
{
dest_mac=$(mac_get $h1)
p=$(:
)"08:"$( : VXLAN flags
)"01:00:00:"$( : VXLAN reserved
)"00:03:e8:"$( : VXLAN VNI : 1000
)"00:"$( : VXLAN reserved
)"$dest_mac:"$( : ETH daddr
)"00:00:00:00:00:00:"$( : ETH saddr
)"08:00:"$( : ETH type
)"45:"$( : IP version + IHL
)"00:"$( : IP TOS
)"00:14:"$( : IP total length
)"00:00:"$( : IP identification
)"20:00:"$( : IP flags + frag off
)"40:"$( : IP TTL
)"00:"$( : IP proto
)"00:00:"$( : IP header csum
)"c0:00:02:03:"$( : IP saddr: 192.0.2.3
)"c0:00:02:01:"$( : IP daddr: 192.0.2.1
)
echo $p
}
short_payload_get()
{
dest_mac=$(mac_get $h1)
p=$(:
)"08:"$( : VXLAN flags
)"00:00:00:"$( : VXLAN reserved
)"00:03:e8:"$( : VXLAN VNI : 1000
)"00:"$( : VXLAN reserved
)"$dest_mac:"$( : ETH daddr
)"00:00:00:00:00:00:"$( : ETH saddr
)
echo $p
}
corrupted_packet_test()
{
local trap_name="decap_error"
local desc=$1; shift
local payload_get=$1; shift
local mz_pid
RET=0
# In case of too short packet, there is no any inner packet,
# so the matching will always succeed
tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
flower skip_hw src_ip 192.0.2.3 dst_ip 192.0.2.1 action pass
rp1_mac=$(mac_get $rp1)
payload=$($payload_get)
ip vrf exec v$rp2 $MZ $rp2 -c 0 -d 1msec -b $rp1_mac \
-B 192.0.2.17 -t udp sp=12345,dp=$VXPORT,p=$payload -q &
mz_pid=$!
devlink_trap_exception_test $trap_name
tc_check_packets "dev $swp1 egress" 101 0
check_err $? "Packets were not dropped"
log_test "$desc"
kill $mz_pid && wait $mz_pid &> /dev/null
tc filter del dev $swp1 egress protocol ip pref 1 handle 101 flower
}
decap_error_test()
{
ecn_decap_test "Decap error" "ECT(1)" 01
ecn_decap_test "Decap error" "ECT(0)" 02
ecn_decap_test "Decap error" "CE" 03
corrupted_packet_test "Decap error: Reserved bits in use" \
"reserved_bits_payload_get"
corrupted_packet_test "Decap error: Too short inner packet" \
"short_payload_get"
}
mc_smac_payload_get()
{
dest_mac=$(mac_get $h1)
source_mac=01:02:03:04:05:06
p=$(:
)"08:"$( : VXLAN flags
)"00:00:00:"$( : VXLAN reserved
)"00:03:e8:"$( : VXLAN VNI : 1000
)"00:"$( : VXLAN reserved
)"$dest_mac:"$( : ETH daddr
)"$source_mac:"$( : ETH saddr
)"08:00:"$( : ETH type
)"45:"$( : IP version + IHL
)"00:"$( : IP TOS
)"00:14:"$( : IP total length
)"00:00:"$( : IP identification
)"20:00:"$( : IP flags + frag off
)"40:"$( : IP TTL
)"00:"$( : IP proto
)"00:00:"$( : IP header csum
)"c0:00:02:03:"$( : IP saddr: 192.0.2.3
)"c0:00:02:01:"$( : IP daddr: 192.0.2.1
)
echo $p
}
overlay_smac_is_mc_test()
{
local trap_name="overlay_smac_is_mc"
local mz_pid
RET=0
# The matching will be checked on devlink_trap_drop_test()
# and the filter will be removed on devlink_trap_drop_cleanup()
tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
flower src_mac 01:02:03:04:05:06 action pass
rp1_mac=$(mac_get $rp1)
payload=$(mc_smac_payload_get)
ip vrf exec v$rp2 $MZ $rp2 -c 0 -d 1msec -b $rp1_mac \
-B 192.0.2.17 -t udp sp=12345,dp=$VXPORT,p=$payload -q &
mz_pid=$!
devlink_trap_drop_test $trap_name $swp1 101
log_test "Overlay source MAC is multicast"
devlink_trap_drop_cleanup $mz_pid $swp1 "ip" 1 101
}
trap cleanup EXIT
setup_prepare
setup_wait
tests_run
exit $EXIT_STATUS