Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 
0004 # Test for DSCP prioritization in the router.
0005 #
0006 # With ip_forward_update_priority disabled, the packets are expected to keep
0007 # their DSCP (which in this test uses only values 0..7) intact as they are
0008 # forwarded by the switch. That is verified at $h2. ICMP responses are formed
0009 # with the same DSCP as the requests, and likewise pass through the switch
0010 # intact, which is verified at $h1.
0011 #
0012 # With ip_forward_update_priority enabled, router reprioritizes the packets
0013 # according to the table in reprioritize(). Thus, say, DSCP 7 maps to priority
0014 # 4, which on egress maps back to DSCP 4. The response packet then gets
0015 # reprioritized to 6, getting DSCP 6 on egress.
0016 #
0017 # +----------------------+                             +----------------------+
0018 # | H1                   |                             |                   H2 |
0019 # |    + $h1             |                             |            $h2 +     |
0020 # |    | 192.0.2.1/28    |                             |  192.0.2.18/28 |     |
0021 # +----|-----------------+                             +----------------|-----+
0022 #      |                                                                |
0023 # +----|----------------------------------------------------------------|-----+
0024 # | SW |                                                                |     |
0025 # |    + $swp1                                                    $swp2 +     |
0026 # |      192.0.2.2/28                                     192.0.2.17/28       |
0027 # |      APP=0,5,0 .. 7,5,7                          APP=0,5,0 .. 7,5,7       |
0028 # +---------------------------------------------------------------------------+
0029 
0030 ALL_TESTS="
0031         ping_ipv4
0032         test_update
0033         test_no_update
0034         test_pedit_norewrite
0035         test_dscp_leftover
0036 "
0037 
0038 lib_dir=$(dirname $0)/../../../net/forwarding
0039 
0040 NUM_NETIFS=4
0041 source $lib_dir/lib.sh
0042 
0043 reprioritize()
0044 {
0045         local in=$1; shift
0046 
0047         # This is based on rt_tos2priority in include/net/route.h. Assuming 1:1
0048         # mapping between priorities and TOS, it yields a new priority for a
0049         # packet with ingress priority of $in.
0050         local -a reprio=(0 0 2 2 6 6 4 4)
0051 
0052         echo ${reprio[$in]}
0053 }
0054 
0055 zero()
0056 {
0057     echo 0
0058 }
0059 
0060 three()
0061 {
0062     echo 3
0063 }
0064 
0065 h1_create()
0066 {
0067         simple_if_init $h1 192.0.2.1/28
0068         tc qdisc add dev $h1 clsact
0069         dscp_capture_install $h1 0
0070         ip route add vrf v$h1 192.0.2.16/28 via 192.0.2.2
0071 }
0072 
0073 h1_destroy()
0074 {
0075         ip route del vrf v$h1 192.0.2.16/28 via 192.0.2.2
0076         dscp_capture_uninstall $h1 0
0077         tc qdisc del dev $h1 clsact
0078         simple_if_fini $h1 192.0.2.1/28
0079 }
0080 
0081 h2_create()
0082 {
0083         simple_if_init $h2 192.0.2.18/28
0084         tc qdisc add dev $h2 clsact
0085         dscp_capture_install $h2 0
0086         ip route add vrf v$h2 192.0.2.0/28 via 192.0.2.17
0087 }
0088 
0089 h2_destroy()
0090 {
0091         ip route del vrf v$h2 192.0.2.0/28 via 192.0.2.17
0092         dscp_capture_uninstall $h2 0
0093         tc qdisc del dev $h2 clsact
0094         simple_if_fini $h2 192.0.2.18/28
0095 }
0096 
0097 dscp_map()
0098 {
0099         local base=$1; shift
0100         local prio
0101 
0102         for prio in {0..7}; do
0103                 echo app=$prio,5,$((base + prio))
0104         done
0105 }
0106 
0107 switch_create()
0108 {
0109         simple_if_init $swp1 192.0.2.2/28
0110         __simple_if_init $swp2 v$swp1 192.0.2.17/28
0111 
0112         tc qdisc add dev $swp1 clsact
0113         tc qdisc add dev $swp2 clsact
0114 
0115         lldptool -T -i $swp1 -V APP $(dscp_map 0) >/dev/null
0116         lldptool -T -i $swp2 -V APP $(dscp_map 0) >/dev/null
0117         lldpad_app_wait_set $swp1
0118         lldpad_app_wait_set $swp2
0119 }
0120 
0121 switch_destroy()
0122 {
0123         lldptool -T -i $swp2 -V APP -d $(dscp_map 0) >/dev/null
0124         lldptool -T -i $swp1 -V APP -d $(dscp_map 0) >/dev/null
0125         lldpad_app_wait_del
0126 
0127         tc qdisc del dev $swp2 clsact
0128         tc qdisc del dev $swp1 clsact
0129 
0130         __simple_if_fini $swp2 192.0.2.17/28
0131         simple_if_fini $swp1 192.0.2.2/28
0132 }
0133 
0134 setup_prepare()
0135 {
0136         h1=${NETIFS[p1]}
0137         swp1=${NETIFS[p2]}
0138 
0139         swp2=${NETIFS[p3]}
0140         h2=${NETIFS[p4]}
0141 
0142         vrf_prepare
0143 
0144         sysctl_set net.ipv4.ip_forward_update_priority 1
0145         h1_create
0146         h2_create
0147         switch_create
0148 }
0149 
0150 cleanup()
0151 {
0152         pre_cleanup
0153 
0154         switch_destroy
0155         h2_destroy
0156         h1_destroy
0157         sysctl_restore net.ipv4.ip_forward_update_priority
0158 
0159         vrf_cleanup
0160 }
0161 
0162 ping_ipv4()
0163 {
0164         ping_test $h1 192.0.2.18
0165 }
0166 
0167 dscp_ping_test()
0168 {
0169         local vrf_name=$1; shift
0170         local sip=$1; shift
0171         local dip=$1; shift
0172         local prio=$1; shift
0173         local reprio=$1; shift
0174         local dev1=$1; shift
0175         local dev2=$1; shift
0176         local i
0177 
0178         local prio2=$($reprio $prio)   # ICMP Request egress prio
0179         local prio3=$($reprio $prio2)  # ICMP Response egress prio
0180 
0181         local dscp=$((prio << 2))     # ICMP Request ingress DSCP
0182         local dscp2=$((prio2 << 2))   # ICMP Request egress DSCP
0183         local dscp3=$((prio3 << 2))   # ICMP Response egress DSCP
0184 
0185         RET=0
0186 
0187         eval "local -A dev1_t0s=($(dscp_fetch_stats $dev1 0))"
0188         eval "local -A dev2_t0s=($(dscp_fetch_stats $dev2 0))"
0189 
0190         local ping_timeout=$((PING_TIMEOUT * 5))
0191         ip vrf exec $vrf_name \
0192            ${PING} -Q $dscp ${sip:+-I $sip} $dip \
0193                    -c 10 -i 0.5 -w $ping_timeout &> /dev/null
0194 
0195         eval "local -A dev1_t1s=($(dscp_fetch_stats $dev1 0))"
0196         eval "local -A dev2_t1s=($(dscp_fetch_stats $dev2 0))"
0197 
0198         for i in {0..7}; do
0199                 local dscpi=$((i << 2))
0200                 local expect2=0
0201                 local expect3=0
0202 
0203                 if ((i == prio2)); then
0204                         expect2=10
0205                 fi
0206                 if ((i == prio3)); then
0207                         expect3=10
0208                 fi
0209 
0210                 local delta=$((dev2_t1s[$i] - dev2_t0s[$i]))
0211                 ((expect2 == delta))
0212                 check_err $? "DSCP $dscpi@$dev2: Expected to capture $expect2 packets, got $delta."
0213 
0214                 delta=$((dev1_t1s[$i] - dev1_t0s[$i]))
0215                 ((expect3 == delta))
0216                 check_err $? "DSCP $dscpi@$dev1: Expected to capture $expect3 packets, got $delta."
0217         done
0218 
0219         log_test "DSCP rewrite: $dscp-(prio $prio2)-$dscp2-(prio $prio3)-$dscp3"
0220 }
0221 
0222 __test_update()
0223 {
0224         local update=$1; shift
0225         local reprio=$1; shift
0226         local prio
0227 
0228         sysctl_restore net.ipv4.ip_forward_update_priority
0229         sysctl_set net.ipv4.ip_forward_update_priority $update
0230 
0231         for prio in {0..7}; do
0232                 dscp_ping_test v$h1 192.0.2.1 192.0.2.18 $prio $reprio $h1 $h2
0233         done
0234 }
0235 
0236 test_update()
0237 {
0238         echo "Test net.ipv4.ip_forward_update_priority=1"
0239         __test_update 1 reprioritize
0240 }
0241 
0242 test_no_update()
0243 {
0244         echo "Test net.ipv4.ip_forward_update_priority=0"
0245         __test_update 0 echo
0246 }
0247 
0248 # Test that when DSCP is updated in pedit, the DSCP rewrite is turned off.
0249 test_pedit_norewrite()
0250 {
0251         echo "Test no DSCP rewrite after DSCP is updated by pedit"
0252 
0253         tc filter add dev $swp1 ingress handle 101 pref 1 prot ip flower \
0254             action pedit ex munge ip dsfield set $((3 << 2)) retain 0xfc \
0255             action skbedit priority 3
0256 
0257         __test_update 0 three
0258 
0259         tc filter del dev $swp1 ingress pref 1
0260 }
0261 
0262 # Test that when the last APP rule is removed, the prio->DSCP map is properly
0263 # set to zeroes, and that the last APP rule does not stay active in the ASIC.
0264 test_dscp_leftover()
0265 {
0266         echo "Test that last removed DSCP rule is deconfigured correctly"
0267 
0268         lldptool -T -i $swp2 -V APP -d $(dscp_map 0) >/dev/null
0269         lldpad_app_wait_del
0270 
0271         __test_update 0 zero
0272 
0273         lldptool -T -i $swp2 -V APP $(dscp_map 0) >/dev/null
0274         lldpad_app_wait_set $swp2
0275 }
0276 
0277 trap cleanup EXIT
0278 
0279 setup_prepare
0280 setup_wait
0281 
0282 tests_run
0283 
0284 exit $EXIT_STATUS