18cd6b020SVladimir Oltean#!/bin/bash 28cd6b020SVladimir Oltean# SPDX-License-Identifier: GPL-2.0 33c9cfb52SVladimir Oltean# Copyright 2020 NXP 48cd6b020SVladimir Oltean 58cd6b020SVladimir OlteanWAIT_TIME=1 68cd6b020SVladimir OlteanNUM_NETIFS=4 74ea1396aSVladimir OlteanSTABLE_MAC_ADDRS=yes 88cd6b020SVladimir Olteanlib_dir=$(dirname $0)/../../../net/forwarding 98cd6b020SVladimir Olteansource $lib_dir/tc_common.sh 108cd6b020SVladimir Olteansource $lib_dir/lib.sh 118cd6b020SVladimir Oltean 128cd6b020SVladimir Olteanrequire_command tcpdump 138cd6b020SVladimir Oltean 144ea1396aSVladimir Olteanh1=${NETIFS[p1]} 154ea1396aSVladimir Olteanswp1=${NETIFS[p2]} 164ea1396aSVladimir Olteanswp2=${NETIFS[p3]} 174ea1396aSVladimir Olteanh2=${NETIFS[p4]} 188cd6b020SVladimir Oltean 198cd6b020SVladimir Oltean# Helpers to map a VCAP IS1 and VCAP IS2 lookup and policy to a chain number 208cd6b020SVladimir Oltean# used by the kernel driver. The numbers are: 218cd6b020SVladimir Oltean# VCAP IS1 lookup 0: 10000 228cd6b020SVladimir Oltean# VCAP IS1 lookup 1: 11000 238cd6b020SVladimir Oltean# VCAP IS1 lookup 2: 12000 248cd6b020SVladimir Oltean# VCAP IS2 lookup 0 policy 0: 20000 258cd6b020SVladimir Oltean# VCAP IS2 lookup 0 policy 1: 20001 268cd6b020SVladimir Oltean# VCAP IS2 lookup 0 policy 255: 20255 278cd6b020SVladimir Oltean# VCAP IS2 lookup 1 policy 0: 21000 288cd6b020SVladimir Oltean# VCAP IS2 lookup 1 policy 1: 21001 298cd6b020SVladimir Oltean# VCAP IS2 lookup 1 policy 255: 21255 308cd6b020SVladimir OlteanIS1() 318cd6b020SVladimir Oltean{ 328cd6b020SVladimir Oltean local lookup=$1 338cd6b020SVladimir Oltean 348cd6b020SVladimir Oltean echo $((10000 + 1000 * lookup)) 358cd6b020SVladimir Oltean} 368cd6b020SVladimir Oltean 378cd6b020SVladimir OlteanIS2() 388cd6b020SVladimir Oltean{ 398cd6b020SVladimir Oltean local lookup=$1 408cd6b020SVladimir Oltean local pag=$2 418cd6b020SVladimir Oltean 428cd6b020SVladimir Oltean echo $((20000 + 1000 * lookup + pag)) 438cd6b020SVladimir Oltean} 448cd6b020SVladimir Oltean 458cd6b020SVladimir OlteanES0() 468cd6b020SVladimir Oltean{ 478cd6b020SVladimir Oltean echo 0 488cd6b020SVladimir Oltean} 498cd6b020SVladimir Oltean 508cd6b020SVladimir Oltean# The Ocelot switches have a fixed ingress pipeline composed of: 518cd6b020SVladimir Oltean# 528cd6b020SVladimir Oltean# +----------------------------------------------+ +-----------------------------------------+ 538cd6b020SVladimir Oltean# | VCAP IS1 | | VCAP IS2 | 548cd6b020SVladimir Oltean# | | | | 558cd6b020SVladimir Oltean# | +----------+ +----------+ +----------+ | | +----------+ +----------+ | 568cd6b020SVladimir Oltean# | | Lookup 0 | | Lookup 1 | | Lookup 2 | | --+------> PAG 0: | Lookup 0 | -> | Lookup 1 | | 578cd6b020SVladimir Oltean# | +----------+ -> +----------+ -> +----------+ | | | +----------+ +----------+ | 588cd6b020SVladimir Oltean# | |key&action| |key&action| |key&action| | | | |key&action| |key&action| | 598cd6b020SVladimir Oltean# | |key&action| |key&action| |key&action| | | | | .. | | .. | | 608cd6b020SVladimir Oltean# | | .. | | .. | | .. | | | | +----------+ +----------+ | 618cd6b020SVladimir Oltean# | +----------+ +----------+ +----------+ | | | | 628cd6b020SVladimir Oltean# | selects PAG | | | +----------+ +----------+ | 638cd6b020SVladimir Oltean# +----------------------------------------------+ +------> PAG 1: | Lookup 0 | -> | Lookup 1 | | 648cd6b020SVladimir Oltean# | | +----------+ +----------+ | 658cd6b020SVladimir Oltean# | | |key&action| |key&action| | 668cd6b020SVladimir Oltean# | | | .. | | .. | | 678cd6b020SVladimir Oltean# | | +----------+ +----------+ | 688cd6b020SVladimir Oltean# | | ... | 698cd6b020SVladimir Oltean# | | | 708cd6b020SVladimir Oltean# | | +----------+ +----------+ | 718cd6b020SVladimir Oltean# +----> PAG 254: | Lookup 0 | -> | Lookup 1 | | 728cd6b020SVladimir Oltean# | | +----------+ +----------+ | 738cd6b020SVladimir Oltean# | | |key&action| |key&action| | 748cd6b020SVladimir Oltean# | | | .. | | .. | | 758cd6b020SVladimir Oltean# | | +----------+ +----------+ | 768cd6b020SVladimir Oltean# | | | 778cd6b020SVladimir Oltean# | | +----------+ +----------+ | 788cd6b020SVladimir Oltean# +----> PAG 255: | Lookup 0 | -> | Lookup 1 | | 798cd6b020SVladimir Oltean# | +----------+ +----------+ | 808cd6b020SVladimir Oltean# | |key&action| |key&action| | 818cd6b020SVladimir Oltean# | | .. | | .. | | 828cd6b020SVladimir Oltean# | +----------+ +----------+ | 838cd6b020SVladimir Oltean# +-----------------------------------------+ 848cd6b020SVladimir Oltean# 858cd6b020SVladimir Oltean# Both the VCAP IS1 (Ingress Stage 1) and IS2 (Ingress Stage 2) are indexed 868cd6b020SVladimir Oltean# (looked up) multiple times: IS1 3 times, and IS2 2 times. Each filter 878cd6b020SVladimir Oltean# (key and action pair) can be configured to only match during the first, or 888cd6b020SVladimir Oltean# second, etc, lookup. 898cd6b020SVladimir Oltean# 908cd6b020SVladimir Oltean# During one TCAM lookup, the filter processing stops at the first entry that 918cd6b020SVladimir Oltean# matches, then the pipeline jumps to the next lookup. 928cd6b020SVladimir Oltean# The driver maps each individual lookup of each individual ingress TCAM to a 938cd6b020SVladimir Oltean# separate chain number. For correct rule offloading, it is mandatory that each 948cd6b020SVladimir Oltean# filter installed in one TCAM is terminated by a non-optional GOTO action to 958cd6b020SVladimir Oltean# the next lookup from the fixed pipeline. 968cd6b020SVladimir Oltean# 978cd6b020SVladimir Oltean# A chain can only be used if there is a GOTO action correctly set up from the 988cd6b020SVladimir Oltean# prior lookup in the processing pipeline. Setting up all chains is not 998cd6b020SVladimir Oltean# mandatory. 1008cd6b020SVladimir Oltean 1018cd6b020SVladimir Oltean# NOTE: VCAP IS1 currently uses only S1_NORMAL half keys and VCAP IS2 1028cd6b020SVladimir Oltean# dynamically chooses between MAC_ETYPE, ARP, IP4_TCP_UDP, IP4_OTHER, which are 1038cd6b020SVladimir Oltean# all half keys as well. 1048cd6b020SVladimir Oltean 1058cd6b020SVladimir Olteancreate_tcam_skeleton() 1068cd6b020SVladimir Oltean{ 1078cd6b020SVladimir Oltean local eth=$1 1088cd6b020SVladimir Oltean 1098cd6b020SVladimir Oltean tc qdisc add dev $eth clsact 1108cd6b020SVladimir Oltean 1118cd6b020SVladimir Oltean # VCAP IS1 is the Ingress Classification TCAM and can offload the 1128cd6b020SVladimir Oltean # following actions: 1138cd6b020SVladimir Oltean # - skbedit priority 1148cd6b020SVladimir Oltean # - vlan pop 1158cd6b020SVladimir Oltean # - vlan modify 1168cd6b020SVladimir Oltean # - goto (only in lookup 2, the last IS1 lookup) 1178cd6b020SVladimir Oltean tc filter add dev $eth ingress chain 0 pref 49152 flower \ 1188cd6b020SVladimir Oltean skip_sw action goto chain $(IS1 0) 1198cd6b020SVladimir Oltean tc filter add dev $eth ingress chain $(IS1 0) pref 49152 \ 1208cd6b020SVladimir Oltean flower skip_sw action goto chain $(IS1 1) 1218cd6b020SVladimir Oltean tc filter add dev $eth ingress chain $(IS1 1) pref 49152 \ 1228cd6b020SVladimir Oltean flower skip_sw action goto chain $(IS1 2) 1238cd6b020SVladimir Oltean tc filter add dev $eth ingress chain $(IS1 2) pref 49152 \ 1248cd6b020SVladimir Oltean flower skip_sw action goto chain $(IS2 0 0) 1258cd6b020SVladimir Oltean 1268cd6b020SVladimir Oltean # VCAP IS2 is the Security Enforcement ingress TCAM and can offload the 1278cd6b020SVladimir Oltean # following actions: 1288cd6b020SVladimir Oltean # - trap 1298cd6b020SVladimir Oltean # - drop 1308cd6b020SVladimir Oltean # - police 1318cd6b020SVladimir Oltean # The two VCAP IS2 lookups can be segmented into up to 256 groups of 1328cd6b020SVladimir Oltean # rules, called Policies. A Policy is selected through the Policy 1338cd6b020SVladimir Oltean # Association Group (PAG) action of VCAP IS1 (which is the 1348cd6b020SVladimir Oltean # GOTO offload). 1358cd6b020SVladimir Oltean tc filter add dev $eth ingress chain $(IS2 0 0) pref 49152 \ 1368cd6b020SVladimir Oltean flower skip_sw action goto chain $(IS2 1 0) 1378cd6b020SVladimir Oltean} 1388cd6b020SVladimir Oltean 1398cd6b020SVladimir Olteansetup_prepare() 1408cd6b020SVladimir Oltean{ 14193196ef9SVladimir Oltean ip link set $swp1 up 14293196ef9SVladimir Oltean ip link set $swp2 up 14393196ef9SVladimir Oltean ip link set $h2 up 14493196ef9SVladimir Oltean ip link set $h1 up 145239f163cSVladimir Oltean 14693196ef9SVladimir Oltean create_tcam_skeleton $swp1 1478cd6b020SVladimir Oltean 1488cd6b020SVladimir Oltean ip link add br0 type bridge 14993196ef9SVladimir Oltean ip link set $swp1 master br0 15093196ef9SVladimir Oltean ip link set $swp2 master br0 1518cd6b020SVladimir Oltean ip link set br0 up 1528cd6b020SVladimir Oltean 15393196ef9SVladimir Oltean ip link add link $h1 name $h1.100 type vlan id 100 15493196ef9SVladimir Oltean ip link set $h1.100 up 1558cd6b020SVladimir Oltean 15693196ef9SVladimir Oltean ip link add link $h1 name $h1.200 type vlan id 200 15793196ef9SVladimir Oltean ip link set $h1.200 up 15882c200beSVladimir Oltean 15993196ef9SVladimir Oltean tc filter add dev $swp1 ingress chain $(IS1 1) pref 1 \ 1608cd6b020SVladimir Oltean protocol 802.1Q flower skip_sw vlan_id 100 \ 1618cd6b020SVladimir Oltean action vlan pop \ 1628cd6b020SVladimir Oltean action goto chain $(IS1 2) 1638cd6b020SVladimir Oltean 16493196ef9SVladimir Oltean tc filter add dev $swp1 egress chain $(ES0) pref 1 \ 16593196ef9SVladimir Oltean flower skip_sw indev $swp2 \ 1668cd6b020SVladimir Oltean action vlan push protocol 802.1Q id 100 1678cd6b020SVladimir Oltean 16893196ef9SVladimir Oltean tc filter add dev $swp1 ingress chain $(IS1 0) pref 2 \ 1698cd6b020SVladimir Oltean protocol ipv4 flower skip_sw src_ip 10.1.1.2 \ 1708cd6b020SVladimir Oltean action skbedit priority 7 \ 1718cd6b020SVladimir Oltean action goto chain $(IS1 1) 1728cd6b020SVladimir Oltean 17393196ef9SVladimir Oltean tc filter add dev $swp1 ingress chain $(IS2 0 0) pref 1 \ 1748cd6b020SVladimir Oltean protocol ipv4 flower skip_sw ip_proto udp dst_port 5201 \ 1755a7c5f70SVladimir Oltean action police rate 50mbit burst 64k conform-exceed drop/pipe \ 1768cd6b020SVladimir Oltean action goto chain $(IS2 1 0) 1778cd6b020SVladimir Oltean} 1788cd6b020SVladimir Oltean 1798cd6b020SVladimir Olteancleanup() 1808cd6b020SVladimir Oltean{ 18193196ef9SVladimir Oltean ip link del $h1.200 18293196ef9SVladimir Oltean ip link del $h1.100 18393196ef9SVladimir Oltean tc qdisc del dev $swp1 clsact 1848cd6b020SVladimir Oltean ip link del br0 1858cd6b020SVladimir Oltean} 1868cd6b020SVladimir Oltean 1878cd6b020SVladimir Olteantest_vlan_pop() 1888cd6b020SVladimir Oltean{ 1894ea1396aSVladimir Oltean local h1_mac=$(mac_get $h1) 1904ea1396aSVladimir Oltean local h2_mac=$(mac_get $h2) 1914ea1396aSVladimir Oltean 192980e74caSVladimir Oltean RET=0 1938cd6b020SVladimir Oltean 19493196ef9SVladimir Oltean tcpdump_start $h2 1958cd6b020SVladimir Oltean 1968cd6b020SVladimir Oltean # Work around Mausezahn VLAN builder bug 1978cd6b020SVladimir Oltean # (https://github.com/netsniff-ng/netsniff-ng/issues/225) by using 1988cd6b020SVladimir Oltean # an 8021q upper 19993196ef9SVladimir Oltean $MZ $h1.100 -q -c 1 -p 64 -a $h1_mac -b $h2_mac -t ip 2008cd6b020SVladimir Oltean 2018cd6b020SVladimir Oltean sleep 1 2028cd6b020SVladimir Oltean 20393196ef9SVladimir Oltean tcpdump_stop $h2 2048cd6b020SVladimir Oltean 20593196ef9SVladimir Oltean tcpdump_show $h2 | grep -q "$h1_mac > $h2_mac, ethertype IPv4" 206980e74caSVladimir Oltean check_err "$?" "untagged reception" 2078cd6b020SVladimir Oltean 20893196ef9SVladimir Oltean tcpdump_cleanup $h2 209980e74caSVladimir Oltean 210980e74caSVladimir Oltean log_test "VLAN pop" 2118cd6b020SVladimir Oltean} 2128cd6b020SVladimir Oltean 2138cd6b020SVladimir Olteantest_vlan_push() 2148cd6b020SVladimir Oltean{ 2154ea1396aSVladimir Oltean local h1_mac=$(mac_get $h1) 2164ea1396aSVladimir Oltean local h2_mac=$(mac_get $h2) 2174ea1396aSVladimir Oltean 218980e74caSVladimir Oltean RET=0 2198cd6b020SVladimir Oltean 22093196ef9SVladimir Oltean tcpdump_start $h1.100 2218cd6b020SVladimir Oltean 22293196ef9SVladimir Oltean $MZ $h2 -q -c 1 -p 64 -a $h2_mac -b $h1_mac -t ip 2238cd6b020SVladimir Oltean 2248cd6b020SVladimir Oltean sleep 1 2258cd6b020SVladimir Oltean 22693196ef9SVladimir Oltean tcpdump_stop $h1.100 2278cd6b020SVladimir Oltean 22893196ef9SVladimir Oltean tcpdump_show $h1.100 | grep -q "$h2_mac > $h1_mac" 229980e74caSVladimir Oltean check_err "$?" "tagged reception" 2308cd6b020SVladimir Oltean 23193196ef9SVladimir Oltean tcpdump_cleanup $h1.100 232980e74caSVladimir Oltean 233980e74caSVladimir Oltean log_test "VLAN push" 2348cd6b020SVladimir Oltean} 2358cd6b020SVladimir Oltean 2364a907f65SVladimir Olteantest_vlan_ingress_modify() 23782c200beSVladimir Oltean{ 2384ea1396aSVladimir Oltean local h1_mac=$(mac_get $h1) 2394ea1396aSVladimir Oltean local h2_mac=$(mac_get $h2) 2404ea1396aSVladimir Oltean 241980e74caSVladimir Oltean RET=0 24282c200beSVladimir Oltean 24382c200beSVladimir Oltean ip link set br0 type bridge vlan_filtering 1 24493196ef9SVladimir Oltean bridge vlan add dev $swp1 vid 200 24593196ef9SVladimir Oltean bridge vlan add dev $swp1 vid 300 24693196ef9SVladimir Oltean bridge vlan add dev $swp2 vid 300 24782c200beSVladimir Oltean 24893196ef9SVladimir Oltean tc filter add dev $swp1 ingress chain $(IS1 2) pref 3 \ 249*bbb253b2SVladimir Oltean protocol 802.1Q flower skip_sw vlan_id 200 src_mac $h1_mac \ 25082c200beSVladimir Oltean action vlan modify id 300 \ 25182c200beSVladimir Oltean action goto chain $(IS2 0 0) 25282c200beSVladimir Oltean 25393196ef9SVladimir Oltean tcpdump_start $h2 25482c200beSVladimir Oltean 25593196ef9SVladimir Oltean $MZ $h1.200 -q -c 1 -p 64 -a $h1_mac -b $h2_mac -t ip 25682c200beSVladimir Oltean 25782c200beSVladimir Oltean sleep 1 25882c200beSVladimir Oltean 25993196ef9SVladimir Oltean tcpdump_stop $h2 26082c200beSVladimir Oltean 26193196ef9SVladimir Oltean tcpdump_show $h2 | grep -q "$h1_mac > $h2_mac, .* vlan 300" 262980e74caSVladimir Oltean check_err "$?" "tagged reception" 26382c200beSVladimir Oltean 26493196ef9SVladimir Oltean tcpdump_cleanup $h2 26582c200beSVladimir Oltean 26693196ef9SVladimir Oltean tc filter del dev $swp1 ingress chain $(IS1 2) pref 3 26782c200beSVladimir Oltean 26893196ef9SVladimir Oltean bridge vlan del dev $swp1 vid 200 26993196ef9SVladimir Oltean bridge vlan del dev $swp1 vid 300 27093196ef9SVladimir Oltean bridge vlan del dev $swp2 vid 300 27182c200beSVladimir Oltean ip link set br0 type bridge vlan_filtering 0 272980e74caSVladimir Oltean 273980e74caSVladimir Oltean log_test "Ingress VLAN modification" 27482c200beSVladimir Oltean} 27582c200beSVladimir Oltean 276434ef350SVladimir Olteantest_vlan_egress_modify() 277434ef350SVladimir Oltean{ 2784ea1396aSVladimir Oltean local h1_mac=$(mac_get $h1) 2794ea1396aSVladimir Oltean local h2_mac=$(mac_get $h2) 2804ea1396aSVladimir Oltean 281980e74caSVladimir Oltean RET=0 282434ef350SVladimir Oltean 28393196ef9SVladimir Oltean tc qdisc add dev $swp2 clsact 284434ef350SVladimir Oltean 285434ef350SVladimir Oltean ip link set br0 type bridge vlan_filtering 1 28693196ef9SVladimir Oltean bridge vlan add dev $swp1 vid 200 28793196ef9SVladimir Oltean bridge vlan add dev $swp2 vid 200 288434ef350SVladimir Oltean 28993196ef9SVladimir Oltean tc filter add dev $swp2 egress chain $(ES0) pref 3 \ 290434ef350SVladimir Oltean protocol 802.1Q flower skip_sw vlan_id 200 vlan_prio 0 \ 291434ef350SVladimir Oltean action vlan modify id 300 priority 7 292434ef350SVladimir Oltean 29393196ef9SVladimir Oltean tcpdump_start $h2 294434ef350SVladimir Oltean 29593196ef9SVladimir Oltean $MZ $h1.200 -q -c 1 -p 64 -a $h1_mac -b $h2_mac -t ip 296434ef350SVladimir Oltean 297434ef350SVladimir Oltean sleep 1 298434ef350SVladimir Oltean 29993196ef9SVladimir Oltean tcpdump_stop $h2 300434ef350SVladimir Oltean 30193196ef9SVladimir Oltean tcpdump_show $h2 | grep -q "$h1_mac > $h2_mac, .* vlan 300" 302980e74caSVladimir Oltean check_err "$?" "tagged reception" 303434ef350SVladimir Oltean 30493196ef9SVladimir Oltean tcpdump_cleanup $h2 305434ef350SVladimir Oltean 30693196ef9SVladimir Oltean tc filter del dev $swp2 egress chain $(ES0) pref 3 30793196ef9SVladimir Oltean tc qdisc del dev $swp2 clsact 308434ef350SVladimir Oltean 30993196ef9SVladimir Oltean bridge vlan del dev $swp1 vid 200 31093196ef9SVladimir Oltean bridge vlan del dev $swp2 vid 200 311434ef350SVladimir Oltean ip link set br0 type bridge vlan_filtering 0 312980e74caSVladimir Oltean 313980e74caSVladimir Oltean log_test "Egress VLAN modification" 314434ef350SVladimir Oltean} 315434ef350SVladimir Oltean 3168cd6b020SVladimir Olteantest_skbedit_priority() 3178cd6b020SVladimir Oltean{ 3184ea1396aSVladimir Oltean local h1_mac=$(mac_get $h1) 3194ea1396aSVladimir Oltean local h2_mac=$(mac_get $h2) 3208cd6b020SVladimir Oltean local num_pkts=100 3218cd6b020SVladimir Oltean 32293196ef9SVladimir Oltean before=$(ethtool_stats_get $swp1 'rx_green_prio_7') 3238cd6b020SVladimir Oltean 32493196ef9SVladimir Oltean $MZ $h1 -q -c $num_pkts -p 64 -a $h1_mac -b $h2_mac -t ip -A 10.1.1.2 3258cd6b020SVladimir Oltean 32693196ef9SVladimir Oltean after=$(ethtool_stats_get $swp1 'rx_green_prio_7') 3278cd6b020SVladimir Oltean 3288cd6b020SVladimir Oltean if [ $((after - before)) = $num_pkts ]; then 329980e74caSVladimir Oltean RET=0 3308cd6b020SVladimir Oltean else 331980e74caSVladimir Oltean RET=1 3328cd6b020SVladimir Oltean fi 333980e74caSVladimir Oltean 334980e74caSVladimir Oltean log_test "Frame prioritization" 3358cd6b020SVladimir Oltean} 3368cd6b020SVladimir Oltean 3378cd6b020SVladimir Olteantrap cleanup EXIT 3388cd6b020SVladimir Oltean 3398cd6b020SVladimir OlteanALL_TESTS=" 3408cd6b020SVladimir Oltean test_vlan_pop 3418cd6b020SVladimir Oltean test_vlan_push 3424a907f65SVladimir Oltean test_vlan_ingress_modify 343434ef350SVladimir Oltean test_vlan_egress_modify 3448cd6b020SVladimir Oltean test_skbedit_priority 3458cd6b020SVladimir Oltean" 3468cd6b020SVladimir Oltean 3478cd6b020SVladimir Olteansetup_prepare 3488cd6b020SVladimir Olteansetup_wait 3498cd6b020SVladimir Oltean 3508cd6b020SVladimir Olteantests_run 3518cd6b020SVladimir Oltean 3528cd6b020SVladimir Olteanexit $EXIT_STATUS 353