#!/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 | # | | 2001:db8:1::1/64 | # +----|-------------------+ # | # +----|----------------------------------------------------------------------+ # | SW | | # | +--|--------------------------------------------------------------------+ | # | | + $swp1 BR1 (802.1d) | | # | | | | # | | + vx1 (vxlan) | | # | | local 2001:db8:3::1 | | # | | id 1000 dstport $VXPORT | | # | +-----------------------------------------------------------------------+ | # | | # | + $rp1 | # | | 2001:db8:3::1/64 | # +----|----------------------------------------------------------------------+ # | # +----|--------------------------------------------------------+ # | | VRF2 | # | + $rp2 | # | 2001:db8:3::2/64 | # | | # +-------------------------------------------------------------+ 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 2001:db8:1::1/64 } h1_destroy() { simple_if_fini $h1 2001:db8:1::1/64 } 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 2001:db8:3::1 \ dstport "$VXPORT" nolearning udp6zerocsumrx udp6zerocsumtx \ tos inherit ttl 100 ip link set dev vx1 master br1 ip link set dev vx1 up ip link set dev $rp1 up ip address add dev $rp1 2001:db8:3::1/64 } switch_destroy() { ip address del dev $rp1 2001:db8:3::1/64 ip link set dev $rp1 down 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 2001:db8:3::2/64 } vrf2_destroy() { simple_if_fini $rp2 2001:db8:3::2/64 } 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() { local dest_mac=$(mac_get $h1) local saddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:03" local daddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01" 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 )"86:dd:"$( : ETH type )"6"$( : IP version )"0:0"$( : Traffic class )"0:00:00:"$( : Flow label )"00:08:"$( : Payload length )"3a:"$( : Next header )"04:"$( : Hop limit )"$saddr:"$( : IP saddr )"$daddr:"$( : IP daddr )"80:"$( : ICMPv6.type )"00:"$( : ICMPv6.code )"00:"$( : ICMPv6.checksum ) 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 ipv6 pref 1 handle 101 \ flower src_ip 2001:db8:1::3 dst_ip 2001:db8:1::1 action pass rp1_mac=$(mac_get $rp1) payload=$(ecn_payload_get) ip vrf exec v$rp2 $MZ -6 $rp2 -c 0 -d 1msec -b $rp1_mac \ -B 2001:db8:3::1 -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 ipv6 pref 1 handle 101 flower } reserved_bits_payload_get() { local dest_mac=$(mac_get $h1) local saddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:03" local daddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01" 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 )"86:dd:"$( : ETH type )"6"$( : IP version )"0:0"$( : Traffic class )"0:00:00:"$( : Flow label )"00:08:"$( : Payload length )"3a:"$( : Next header )"04:"$( : Hop limit )"$saddr:"$( : IP saddr )"$daddr:"$( : IP daddr )"80:"$( : ICMPv6.type )"00:"$( : ICMPv6.code )"00:"$( : ICMPv6.checksum ) 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 ipv6 pref 1 handle 101 \ flower skip_hw src_ip 2001:db8:3::1 dst_ip 2001:db8:1::1 \ action pass rp1_mac=$(mac_get $rp1) payload=$($payload_get) ip vrf exec v$rp2 $MZ -6 $rp2 -c 0 -d 1msec -b $rp1_mac \ -B 2001:db8:3::1 -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 ipv6 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() { local dest_mac=$(mac_get $h1) local source_mac="01:02:03:04:05:06" local saddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:03" local daddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01" 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 )"86:dd:"$( : ETH type )"6"$( : IP version )"0:0"$( : Traffic class )"0:00:00:"$( : Flow label )"00:08:"$( : Payload length )"3a:"$( : Next header )"04:"$( : Hop limit )"$saddr:"$( : IP saddr )"$daddr:"$( : IP daddr )"80:"$( : ICMPv6.type )"00:"$( : ICMPv6.code )"00:"$( : ICMPv6.checksum ) 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 ipv6 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 -6 $rp2 -c 0 -d 1msec -b $rp1_mac \ -B 2001:db8:3::1 -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 "ipv6" 1 101 } trap cleanup EXIT setup_prepare setup_wait tests_run exit $EXIT_STATUS