2 # SPDX-License-Identifier: GPL-2.0
7 lib_dir=$(dirname $0)/../../../net/forwarding
8 source $lib_dir/tc_common.sh
11 require_command tcpdump
14 # +---------------------------------------------+
15 # | DUT ports Generator ports |
16 # | +--------+ +--------+ +--------+ +--------+ |
18 # | | eth0 | | eth1 | | eth2 | | eth3 | |
20 # +-+--------+-+--------+-+--------+-+--------+-+
25 # +--------------------------------+
32 eth0_mac="de:ad:be:ef:00:00"
33 eth1_mac="de:ad:be:ef:00:01"
34 eth2_mac="de:ad:be:ef:00:02"
35 eth3_mac="de:ad:be:ef:00:03"
37 # Helpers to map a VCAP IS1 and VCAP IS2 lookup and policy to a chain number
38 # used by the kernel driver. The numbers are:
39 # VCAP IS1 lookup 0: 10000
40 # VCAP IS1 lookup 1: 11000
41 # VCAP IS1 lookup 2: 12000
42 # VCAP IS2 lookup 0 policy 0: 20000
43 # VCAP IS2 lookup 0 policy 1: 20001
44 # VCAP IS2 lookup 0 policy 255: 20255
45 # VCAP IS2 lookup 1 policy 0: 21000
46 # VCAP IS2 lookup 1 policy 1: 21001
47 # VCAP IS2 lookup 1 policy 255: 21255
52 echo $((10000 + 1000 * lookup))
60 echo $((20000 + 1000 * lookup + pag))
68 # The Ocelot switches have a fixed ingress pipeline composed of:
70 # +----------------------------------------------+ +-----------------------------------------+
71 # | VCAP IS1 | | VCAP IS2 |
73 # | +----------+ +----------+ +----------+ | | +----------+ +----------+ |
74 # | | Lookup 0 | | Lookup 1 | | Lookup 2 | | --+------> PAG 0: | Lookup 0 | -> | Lookup 1 | |
75 # | +----------+ -> +----------+ -> +----------+ | | | +----------+ +----------+ |
76 # | |key&action| |key&action| |key&action| | | | |key&action| |key&action| |
77 # | |key&action| |key&action| |key&action| | | | | .. | | .. | |
78 # | | .. | | .. | | .. | | | | +----------+ +----------+ |
79 # | +----------+ +----------+ +----------+ | | | |
80 # | selects PAG | | | +----------+ +----------+ |
81 # +----------------------------------------------+ +------> PAG 1: | Lookup 0 | -> | Lookup 1 | |
82 # | | +----------+ +----------+ |
83 # | | |key&action| |key&action| |
85 # | | +----------+ +----------+ |
88 # | | +----------+ +----------+ |
89 # +----> PAG 254: | Lookup 0 | -> | Lookup 1 | |
90 # | | +----------+ +----------+ |
91 # | | |key&action| |key&action| |
93 # | | +----------+ +----------+ |
95 # | | +----------+ +----------+ |
96 # +----> PAG 255: | Lookup 0 | -> | Lookup 1 | |
97 # | +----------+ +----------+ |
98 # | |key&action| |key&action| |
100 # | +----------+ +----------+ |
101 # +-----------------------------------------+
103 # Both the VCAP IS1 (Ingress Stage 1) and IS2 (Ingress Stage 2) are indexed
104 # (looked up) multiple times: IS1 3 times, and IS2 2 times. Each filter
105 # (key and action pair) can be configured to only match during the first, or
106 # second, etc, lookup.
108 # During one TCAM lookup, the filter processing stops at the first entry that
109 # matches, then the pipeline jumps to the next lookup.
110 # The driver maps each individual lookup of each individual ingress TCAM to a
111 # separate chain number. For correct rule offloading, it is mandatory that each
112 # filter installed in one TCAM is terminated by a non-optional GOTO action to
113 # the next lookup from the fixed pipeline.
115 # A chain can only be used if there is a GOTO action correctly set up from the
116 # prior lookup in the processing pipeline. Setting up all chains is not
119 # NOTE: VCAP IS1 currently uses only S1_NORMAL half keys and VCAP IS2
120 # dynamically chooses between MAC_ETYPE, ARP, IP4_TCP_UDP, IP4_OTHER, which are
121 # all half keys as well.
123 create_tcam_skeleton()
127 tc qdisc add dev $eth clsact
129 # VCAP IS1 is the Ingress Classification TCAM and can offload the
134 # - goto (only in lookup 2, the last IS1 lookup)
135 tc filter add dev $eth ingress chain 0 pref 49152 flower \
136 skip_sw action goto chain $(IS1 0)
137 tc filter add dev $eth ingress chain $(IS1 0) pref 49152 \
138 flower skip_sw action goto chain $(IS1 1)
139 tc filter add dev $eth ingress chain $(IS1 1) pref 49152 \
140 flower skip_sw action goto chain $(IS1 2)
141 tc filter add dev $eth ingress chain $(IS1 2) pref 49152 \
142 flower skip_sw action goto chain $(IS2 0 0)
144 # VCAP IS2 is the Security Enforcement ingress TCAM and can offload the
149 # The two VCAP IS2 lookups can be segmented into up to 256 groups of
150 # rules, called Policies. A Policy is selected through the Policy
151 # Association Group (PAG) action of VCAP IS1 (which is the
153 tc filter add dev $eth ingress chain $(IS2 0 0) pref 49152 \
154 flower skip_sw action goto chain $(IS2 1 0)
164 create_tcam_skeleton $eth0
166 ip link add br0 type bridge
167 ip link set $eth0 master br0
168 ip link set $eth1 master br0
171 ip link add link $eth3 name $eth3.100 type vlan id 100
172 ip link set $eth3.100 up
174 ip link add link $eth3 name $eth3.200 type vlan id 200
175 ip link set $eth3.200 up
177 tc filter add dev $eth0 ingress chain $(IS1 1) pref 1 \
178 protocol 802.1Q flower skip_sw vlan_id 100 \
180 action goto chain $(IS1 2)
182 tc filter add dev $eth0 egress chain $(ES0) pref 1 \
183 flower skip_sw indev $eth1 \
184 action vlan push protocol 802.1Q id 100
186 tc filter add dev $eth0 ingress chain $(IS1 0) pref 2 \
187 protocol ipv4 flower skip_sw src_ip 10.1.1.2 \
188 action skbedit priority 7 \
189 action goto chain $(IS1 1)
191 tc filter add dev $eth0 ingress chain $(IS2 0 0) pref 1 \
192 protocol ipv4 flower skip_sw ip_proto udp dst_port 5201 \
193 action police rate 50mbit burst 64k conform-exceed drop/pipe \
194 action goto chain $(IS2 1 0)
199 ip link del $eth3.200
200 ip link del $eth3.100
201 tc qdisc del dev $eth0 clsact
207 printf "Testing VLAN pop.. "
211 # Work around Mausezahn VLAN builder bug
212 # (https://github.com/netsniff-ng/netsniff-ng/issues/225) by using
214 $MZ $eth3.100 -q -c 1 -p 64 -a $eth3_mac -b $eth2_mac -t ip
220 if tcpdump_show | grep -q "$eth3_mac > $eth2_mac, ethertype IPv4"; then
231 printf "Testing VLAN push.. "
233 tcpdump_start $eth3.100
235 $MZ $eth2 -q -c 1 -p 64 -a $eth2_mac -b $eth3_mac -t ip
241 if tcpdump_show | grep -q "$eth2_mac > $eth3_mac"; then
250 test_vlan_ingress_modify()
252 printf "Testing ingress VLAN modification.. "
254 ip link set br0 type bridge vlan_filtering 1
255 bridge vlan add dev $eth0 vid 200
256 bridge vlan add dev $eth0 vid 300
257 bridge vlan add dev $eth1 vid 300
259 tc filter add dev $eth0 ingress chain $(IS1 2) pref 3 \
260 protocol 802.1Q flower skip_sw vlan_id 200 \
261 action vlan modify id 300 \
262 action goto chain $(IS2 0 0)
266 $MZ $eth3.200 -q -c 1 -p 64 -a $eth3_mac -b $eth2_mac -t ip
272 if tcpdump_show | grep -q "$eth3_mac > $eth2_mac, .* vlan 300"; then
280 tc filter del dev $eth0 ingress chain $(IS1 2) pref 3
282 bridge vlan del dev $eth0 vid 200
283 bridge vlan del dev $eth0 vid 300
284 bridge vlan del dev $eth1 vid 300
285 ip link set br0 type bridge vlan_filtering 0
288 test_vlan_egress_modify()
290 printf "Testing egress VLAN modification.. "
292 tc qdisc add dev $eth1 clsact
294 ip link set br0 type bridge vlan_filtering 1
295 bridge vlan add dev $eth0 vid 200
296 bridge vlan add dev $eth1 vid 200
298 tc filter add dev $eth1 egress chain $(ES0) pref 3 \
299 protocol 802.1Q flower skip_sw vlan_id 200 vlan_prio 0 \
300 action vlan modify id 300 priority 7
304 $MZ $eth3.200 -q -c 1 -p 64 -a $eth3_mac -b $eth2_mac -t ip
310 if tcpdump_show | grep -q "$eth3_mac > $eth2_mac, .* vlan 300"; then
318 tc filter del dev $eth1 egress chain $(ES0) pref 3
319 tc qdisc del dev $eth1 clsact
321 bridge vlan del dev $eth0 vid 200
322 bridge vlan del dev $eth1 vid 200
323 ip link set br0 type bridge vlan_filtering 0
326 test_skbedit_priority()
330 printf "Testing frame prioritization.. "
332 before=$(ethtool_stats_get $eth0 'rx_green_prio_7')
334 $MZ $eth3 -q -c $num_pkts -p 64 -a $eth3_mac -b $eth2_mac -t ip -A 10.1.1.2
336 after=$(ethtool_stats_get $eth0 'rx_green_prio_7')
338 if [ $((after - before)) = $num_pkts ]; then
350 test_vlan_ingress_modify
351 test_vlan_egress_modify
352 test_skbedit_priority