Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 # Copyright 2020 NXP
0004 
0005 WAIT_TIME=1
0006 NUM_NETIFS=4
0007 STABLE_MAC_ADDRS=yes
0008 lib_dir=$(dirname $0)/../../../net/forwarding
0009 source $lib_dir/tc_common.sh
0010 source $lib_dir/lib.sh
0011 
0012 require_command tcpdump
0013 
0014 h1=${NETIFS[p1]}
0015 swp1=${NETIFS[p2]}
0016 swp2=${NETIFS[p3]}
0017 h2=${NETIFS[p4]}
0018 
0019 # Helpers to map a VCAP IS1 and VCAP IS2 lookup and policy to a chain number
0020 # used by the kernel driver. The numbers are:
0021 # VCAP IS1 lookup 0:            10000
0022 # VCAP IS1 lookup 1:            11000
0023 # VCAP IS1 lookup 2:            12000
0024 # VCAP IS2 lookup 0 policy 0:   20000
0025 # VCAP IS2 lookup 0 policy 1:   20001
0026 # VCAP IS2 lookup 0 policy 255: 20255
0027 # VCAP IS2 lookup 1 policy 0:   21000
0028 # VCAP IS2 lookup 1 policy 1:   21001
0029 # VCAP IS2 lookup 1 policy 255: 21255
0030 IS1()
0031 {
0032         local lookup=$1
0033 
0034         echo $((10000 + 1000 * lookup))
0035 }
0036 
0037 IS2()
0038 {
0039         local lookup=$1
0040         local pag=$2
0041 
0042         echo $((20000 + 1000 * lookup + pag))
0043 }
0044 
0045 ES0()
0046 {
0047         echo 0
0048 }
0049 
0050 # The Ocelot switches have a fixed ingress pipeline composed of:
0051 #
0052 # +----------------------------------------------+      +-----------------------------------------+
0053 # |                   VCAP IS1                   |      |                  VCAP IS2               |
0054 # |                                              |      |                                         |
0055 # | +----------+    +----------+    +----------+ |      |            +----------+    +----------+ |
0056 # | | Lookup 0 |    | Lookup 1 |    | Lookup 2 | | --+------> PAG 0: | Lookup 0 | -> | Lookup 1 | |
0057 # | +----------+ -> +----------+ -> +----------+ |   |  |            +----------+    +----------+ |
0058 # | |key&action|    |key&action|    |key&action| |   |  |            |key&action|    |key&action| |
0059 # | |key&action|    |key&action|    |key&action| |   |  |            |    ..    |    |    ..    | |
0060 # | |    ..    |    |    ..    |    |    ..    | |   |  |            +----------+    +----------+ |
0061 # | +----------+    +----------+    +----------+ |   |  |                                         |
0062 # |                                 selects PAG  |   |  |            +----------+    +----------+ |
0063 # +----------------------------------------------+   +------> PAG 1: | Lookup 0 | -> | Lookup 1 | |
0064 #                                                    |  |            +----------+    +----------+ |
0065 #                                                    |  |            |key&action|    |key&action| |
0066 #                                                    |  |            |    ..    |    |    ..    | |
0067 #                                                    |  |            +----------+    +----------+ |
0068 #                                                    |  |      ...                                |
0069 #                                                    |  |                                         |
0070 #                                                    |  |            +----------+    +----------+ |
0071 #                                                    +----> PAG 254: | Lookup 0 | -> | Lookup 1 | |
0072 #                                                    |  |            +----------+    +----------+ |
0073 #                                                    |  |            |key&action|    |key&action| |
0074 #                                                    |  |            |    ..    |    |    ..    | |
0075 #                                                    |  |            +----------+    +----------+ |
0076 #                                                    |  |                                         |
0077 #                                                    |  |            +----------+    +----------+ |
0078 #                                                    +----> PAG 255: | Lookup 0 | -> | Lookup 1 | |
0079 #                                                       |            +----------+    +----------+ |
0080 #                                                       |            |key&action|    |key&action| |
0081 #                                                       |            |    ..    |    |    ..    | |
0082 #                                                       |            +----------+    +----------+ |
0083 #                                                       +-----------------------------------------+
0084 #
0085 # Both the VCAP IS1 (Ingress Stage 1) and IS2 (Ingress Stage 2) are indexed
0086 # (looked up) multiple times: IS1 3 times, and IS2 2 times. Each filter
0087 # (key and action pair) can be configured to only match during the first, or
0088 # second, etc, lookup.
0089 #
0090 # During one TCAM lookup, the filter processing stops at the first entry that
0091 # matches, then the pipeline jumps to the next lookup.
0092 # The driver maps each individual lookup of each individual ingress TCAM to a
0093 # separate chain number. For correct rule offloading, it is mandatory that each
0094 # filter installed in one TCAM is terminated by a non-optional GOTO action to
0095 # the next lookup from the fixed pipeline.
0096 #
0097 # A chain can only be used if there is a GOTO action correctly set up from the
0098 # prior lookup in the processing pipeline. Setting up all chains is not
0099 # mandatory.
0100 
0101 # NOTE: VCAP IS1 currently uses only S1_NORMAL half keys and VCAP IS2
0102 # dynamically chooses between MAC_ETYPE, ARP, IP4_TCP_UDP, IP4_OTHER, which are
0103 # all half keys as well.
0104 
0105 create_tcam_skeleton()
0106 {
0107         local eth=$1
0108 
0109         tc qdisc add dev $eth clsact
0110 
0111         # VCAP IS1 is the Ingress Classification TCAM and can offload the
0112         # following actions:
0113         # - skbedit priority
0114         # - vlan pop
0115         # - vlan modify
0116         # - goto (only in lookup 2, the last IS1 lookup)
0117         tc filter add dev $eth ingress chain 0 pref 49152 flower \
0118                 skip_sw action goto chain $(IS1 0)
0119         tc filter add dev $eth ingress chain $(IS1 0) pref 49152 \
0120                 flower skip_sw action goto chain $(IS1 1)
0121         tc filter add dev $eth ingress chain $(IS1 1) pref 49152 \
0122                 flower skip_sw action goto chain $(IS1 2)
0123         tc filter add dev $eth ingress chain $(IS1 2) pref 49152 \
0124                 flower skip_sw action goto chain $(IS2 0 0)
0125 
0126         # VCAP IS2 is the Security Enforcement ingress TCAM and can offload the
0127         # following actions:
0128         # - trap
0129         # - drop
0130         # - police
0131         # The two VCAP IS2 lookups can be segmented into up to 256 groups of
0132         # rules, called Policies. A Policy is selected through the Policy
0133         # Association Group (PAG) action of VCAP IS1 (which is the
0134         # GOTO offload).
0135         tc filter add dev $eth ingress chain $(IS2 0 0) pref 49152 \
0136                 flower skip_sw action goto chain $(IS2 1 0)
0137 }
0138 
0139 setup_prepare()
0140 {
0141         ip link set $swp1 up
0142         ip link set $swp2 up
0143         ip link set $h2 up
0144         ip link set $h1 up
0145 
0146         create_tcam_skeleton $swp1
0147 
0148         ip link add br0 type bridge
0149         ip link set $swp1 master br0
0150         ip link set $swp2 master br0
0151         ip link set br0 up
0152 
0153         ip link add link $h1 name $h1.100 type vlan id 100
0154         ip link set $h1.100 up
0155 
0156         ip link add link $h1 name $h1.200 type vlan id 200
0157         ip link set $h1.200 up
0158 
0159         tc filter add dev $swp1 ingress chain $(IS1 1) pref 1 \
0160                 protocol 802.1Q flower skip_sw vlan_id 100 \
0161                 action vlan pop \
0162                 action goto chain $(IS1 2)
0163 
0164         tc filter add dev $swp1 egress chain $(ES0) pref 1 \
0165                 flower skip_sw indev $swp2 \
0166                 action vlan push protocol 802.1Q id 100
0167 
0168         tc filter add dev $swp1 ingress chain $(IS1 0) pref 2 \
0169                 protocol ipv4 flower skip_sw src_ip 10.1.1.2 \
0170                 action skbedit priority 7 \
0171                 action goto chain $(IS1 1)
0172 
0173         tc filter add dev $swp1 ingress chain $(IS2 0 0) pref 1 \
0174                 protocol ipv4 flower skip_sw ip_proto udp dst_port 5201 \
0175                 action police rate 50mbit burst 64k conform-exceed drop/pipe \
0176                 action goto chain $(IS2 1 0)
0177 }
0178 
0179 cleanup()
0180 {
0181         ip link del $h1.200
0182         ip link del $h1.100
0183         tc qdisc del dev $swp1 clsact
0184         ip link del br0
0185 }
0186 
0187 test_vlan_pop()
0188 {
0189         local h1_mac=$(mac_get $h1)
0190         local h2_mac=$(mac_get $h2)
0191 
0192         RET=0
0193 
0194         tcpdump_start $h2
0195 
0196         # Work around Mausezahn VLAN builder bug
0197         # (https://github.com/netsniff-ng/netsniff-ng/issues/225) by using
0198         # an 8021q upper
0199         $MZ $h1.100 -q -c 1 -p 64 -a $h1_mac -b $h2_mac -t ip
0200 
0201         sleep 1
0202 
0203         tcpdump_stop $h2
0204 
0205         tcpdump_show $h2 | grep -q "$h1_mac > $h2_mac, ethertype IPv4"
0206         check_err "$?" "untagged reception"
0207 
0208         tcpdump_cleanup $h2
0209 
0210         log_test "VLAN pop"
0211 }
0212 
0213 test_vlan_push()
0214 {
0215         local h1_mac=$(mac_get $h1)
0216         local h2_mac=$(mac_get $h2)
0217 
0218         RET=0
0219 
0220         tcpdump_start $h1.100
0221 
0222         $MZ $h2 -q -c 1 -p 64 -a $h2_mac -b $h1_mac -t ip
0223 
0224         sleep 1
0225 
0226         tcpdump_stop $h1.100
0227 
0228         tcpdump_show $h1.100 | grep -q "$h2_mac > $h1_mac"
0229         check_err "$?" "tagged reception"
0230 
0231         tcpdump_cleanup $h1.100
0232 
0233         log_test "VLAN push"
0234 }
0235 
0236 test_vlan_ingress_modify()
0237 {
0238         local h1_mac=$(mac_get $h1)
0239         local h2_mac=$(mac_get $h2)
0240 
0241         RET=0
0242 
0243         ip link set br0 type bridge vlan_filtering 1
0244         bridge vlan add dev $swp1 vid 200
0245         bridge vlan add dev $swp1 vid 300
0246         bridge vlan add dev $swp2 vid 300
0247 
0248         tc filter add dev $swp1 ingress chain $(IS1 2) pref 3 \
0249                 protocol 802.1Q flower skip_sw vlan_id 200 \
0250                 action vlan modify id 300 \
0251                 action goto chain $(IS2 0 0)
0252 
0253         tcpdump_start $h2
0254 
0255         $MZ $h1.200 -q -c 1 -p 64 -a $h1_mac -b $h2_mac -t ip
0256 
0257         sleep 1
0258 
0259         tcpdump_stop $h2
0260 
0261         tcpdump_show $h2 | grep -q "$h1_mac > $h2_mac, .* vlan 300"
0262         check_err "$?" "tagged reception"
0263 
0264         tcpdump_cleanup $h2
0265 
0266         tc filter del dev $swp1 ingress chain $(IS1 2) pref 3
0267 
0268         bridge vlan del dev $swp1 vid 200
0269         bridge vlan del dev $swp1 vid 300
0270         bridge vlan del dev $swp2 vid 300
0271         ip link set br0 type bridge vlan_filtering 0
0272 
0273         log_test "Ingress VLAN modification"
0274 }
0275 
0276 test_vlan_egress_modify()
0277 {
0278         local h1_mac=$(mac_get $h1)
0279         local h2_mac=$(mac_get $h2)
0280 
0281         RET=0
0282 
0283         tc qdisc add dev $swp2 clsact
0284 
0285         ip link set br0 type bridge vlan_filtering 1
0286         bridge vlan add dev $swp1 vid 200
0287         bridge vlan add dev $swp2 vid 200
0288 
0289         tc filter add dev $swp2 egress chain $(ES0) pref 3 \
0290                 protocol 802.1Q flower skip_sw vlan_id 200 vlan_prio 0 \
0291                 action vlan modify id 300 priority 7
0292 
0293         tcpdump_start $h2
0294 
0295         $MZ $h1.200 -q -c 1 -p 64 -a $h1_mac -b $h2_mac -t ip
0296 
0297         sleep 1
0298 
0299         tcpdump_stop $h2
0300 
0301         tcpdump_show $h2 | grep -q "$h1_mac > $h2_mac, .* vlan 300"
0302         check_err "$?" "tagged reception"
0303 
0304         tcpdump_cleanup $h2
0305 
0306         tc filter del dev $swp2 egress chain $(ES0) pref 3
0307         tc qdisc del dev $swp2 clsact
0308 
0309         bridge vlan del dev $swp1 vid 200
0310         bridge vlan del dev $swp2 vid 200
0311         ip link set br0 type bridge vlan_filtering 0
0312 
0313         log_test "Egress VLAN modification"
0314 }
0315 
0316 test_skbedit_priority()
0317 {
0318         local h1_mac=$(mac_get $h1)
0319         local h2_mac=$(mac_get $h2)
0320         local num_pkts=100
0321 
0322         before=$(ethtool_stats_get $swp1 'rx_green_prio_7')
0323 
0324         $MZ $h1 -q -c $num_pkts -p 64 -a $h1_mac -b $h2_mac -t ip -A 10.1.1.2
0325 
0326         after=$(ethtool_stats_get $swp1 'rx_green_prio_7')
0327 
0328         if [ $((after - before)) = $num_pkts ]; then
0329                 RET=0
0330         else
0331                 RET=1
0332         fi
0333 
0334         log_test "Frame prioritization"
0335 }
0336 
0337 trap cleanup EXIT
0338 
0339 ALL_TESTS="
0340         test_vlan_pop
0341         test_vlan_push
0342         test_vlan_ingress_modify
0343         test_vlan_egress_modify
0344         test_skbedit_priority
0345 "
0346 
0347 setup_prepare
0348 setup_wait
0349 
0350 tests_run
0351 
0352 exit $EXIT_STATUS