#!/bin/bash # SPDX-License-Identifier: GPL-2.0 # Test VLAN classification after routing and verify that the order of # configuration does not impact switch behavior. Verify that {RIF, Port}->VID # mapping is added correctly for existing {Port, VID}->FID mapping and that # {RIF, Port}->VID mapping is added correctly for new {Port, VID}->FID mapping. # +-------------------+ +--------------------+ # | H1 | | H2 | # | | | | # | $h1.10 + | | + $h2.10 | # | 192.0.2.1/28 | | | | 192.0.2.3/28 | # | | | | | | # | $h1 + | | + $h2 | # +----------------|--+ +--|-----------------+ # | | # +----------------|-------------------------|-----------------+ # | SW $swp1 + + $swp2 | # | | | | # | +--------------|-------------------------|---------------+ | # | | $swp1.10 + + $swp2.10 | | # | | | | # | | br0 | | # | | 192.0.2.2/28 | | # | +--------------------------------------------------------+ | # | | # | $swp3.20 + | # | 192.0.2.17/28 | | # | | | # | $swp3 + | # +---------------|--------------------------------------------+ # | # +---------------|--+ # | $h3 + | # | | | # | $h3.20 + | # | 192.0.2.18/28 | # | | # | H3 | # +------------------+ lib_dir=$(dirname $0)/../../../net/forwarding ALL_TESTS=" port_vid_map_rif rif_port_vid_map " NUM_NETIFS=6 source $lib_dir/lib.sh source $lib_dir/tc_common.sh source $lib_dir/devlink_lib.sh h1_create() { simple_if_init $h1 vlan_create $h1 10 v$h1 192.0.2.1/28 ip route add 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 } h1_destroy() { ip route del 192.0.2.16/28 vrf v$h1 nexthop via 192.0.2.2 vlan_destroy $h1 10 simple_if_fini $h1 } h2_create() { simple_if_init $h2 vlan_create $h2 10 v$h2 192.0.2.3/28 } h2_destroy() { vlan_destroy $h2 10 simple_if_fini $h2 } h3_create() { simple_if_init $h3 vlan_create $h3 20 v$h3 192.0.2.18/28 ip route add 192.0.2.0/28 vrf v$h3 nexthop via 192.0.2.17 } h3_destroy() { ip route del 192.0.2.0/28 vrf v$h3 nexthop via 192.0.2.17 vlan_destroy $h3 20 simple_if_fini $h3 } switch_create() { ip link set dev $swp1 up tc qdisc add dev $swp1 clsact ip link add dev br0 type bridge mcast_snooping 0 # By default, a link-local address is generated when netdevice becomes # up. Adding an address to the bridge will cause creating a RIF for it. # Prevent generating link-local address to be able to control when the # RIF is added. sysctl_set net.ipv6.conf.br0.addr_gen_mode 1 ip link set dev br0 up ip link set dev $swp2 up vlan_create $swp2 10 ip link set dev $swp2.10 master br0 ip link set dev $swp3 up vlan_create $swp3 20 "" 192.0.2.17/28 # Replace neighbor to avoid 1 packet which is forwarded in software due # to "unresolved neigh". ip neigh replace dev $swp3.20 192.0.2.18 lladdr $(mac_get $h3.20) } switch_destroy() { vlan_destroy $swp3 20 ip link set dev $swp3 down ip link set dev $swp2.10 nomaster vlan_destroy $swp2 10 ip link set dev $swp2 down ip link set dev br0 down sysctl_restore net.ipv6.conf.br0.addr_gen_mode ip link del dev br0 tc qdisc del dev $swp1 clsact ip link set dev $swp1 down } setup_prepare() { h1=${NETIFS[p1]} swp1=${NETIFS[p2]} swp2=${NETIFS[p3]} h2=${NETIFS[p4]} swp3=${NETIFS[p5]} h3=${NETIFS[p6]} vrf_prepare forwarding_enable h1_create h2_create h3_create switch_create } cleanup() { pre_cleanup switch_destroy h3_destroy h2_destroy h1_destroy forwarding_restore vrf_cleanup } bridge_rif_add() { rifs_occ_t0=$(devlink_resource_occ_get rifs) __addr_add_del br0 add 192.0.2.2/28 rifs_occ_t1=$(devlink_resource_occ_get rifs) expected_rifs=$((rifs_occ_t0 + 1)) [[ $expected_rifs -eq $rifs_occ_t1 ]] check_err $? "Expected $expected_rifs RIFs, $rifs_occ_t1 are used" sleep 1 } bridge_rif_del() { __addr_add_del br0 del 192.0.2.2/28 } port_vid_map_rif() { RET=0 # First add {port, VID}->FID for swp1.10, then add a RIF and verify that # packets get the correct VID after routing. vlan_create $swp1 10 ip link set dev $swp1.10 master br0 bridge_rif_add # Replace neighbor to avoid 1 packet which is forwarded in software due # to "unresolved neigh". ip neigh replace dev br0 192.0.2.1 lladdr $(mac_get $h1.10) # The hardware matches on the first ethertype which is not VLAN, # so the protocol should be IP. tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \ flower skip_sw dst_ip 192.0.2.1 action pass ping_do $h1.10 192.0.2.18 check_err $? "Ping failed" tc_check_at_least_x_packets "dev $swp1 egress" 101 10 check_err $? "Packets were not routed in hardware" log_test "Add RIF for existing {port, VID}->FID mapping" tc filter del dev $swp1 egress bridge_rif_del ip link set dev $swp1.10 nomaster vlan_destroy $swp1 10 } rif_port_vid_map() { RET=0 # First add an address to the bridge, which will create a RIF on top of # it, then add a new {port, VID}->FID mapping and verify that packets # get the correct VID after routing. bridge_rif_add vlan_create $swp1 10 ip link set dev $swp1.10 master br0 # Replace neighbor to avoid 1 packet which is forwarded in software due # to "unresolved neigh". ip neigh replace dev br0 192.0.2.1 lladdr $(mac_get $h1.10) # The hardware matches on the first ethertype which is not VLAN, # so the protocol should be IP. tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \ flower skip_sw dst_ip 192.0.2.1 action pass ping_do $h1.10 192.0.2.18 check_err $? "Ping failed" tc_check_at_least_x_packets "dev $swp1 egress" 101 10 check_err $? "Packets were not routed in hardware" log_test "Add {port, VID}->FID mapping for FID with a RIF" tc filter del dev $swp1 egress ip link set dev $swp1.10 nomaster vlan_destroy $swp1 10 bridge_rif_del } trap cleanup EXIT setup_prepare setup_wait tests_run exit $EXIT_STATUS