Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 
0004 # +-----------------------+                          +------------------------+
0005 # | H1 (vrf)              |                          | H2 (vrf)               |
0006 # |    + $h1              |                          |    + $h2               |
0007 # |    | 192.0.2.1/28     |                          |    | 192.0.2.2/28      |
0008 # |    | 2001:db8:1::1/64 |                          |    | 2001:db8:1::2/64  |
0009 # +----|------------------+                          +----|-------------------+
0010 #      |                                                  |
0011 # +----|--------------------------------------------------|-------------------+
0012 # | SW |                                                  |                   |
0013 # | +--|--------------------------------------------------|-----------------+ |
0014 # | |  + $swp1                   BR1 (802.1d)             + $swp2           | |
0015 # | |                                                                       | |
0016 # | |  + vx1 (vxlan)                                                        | |
0017 # | |    local 2001:db8:3::1                                                | |
0018 # | |    remote 2001:db8:4::1 2001:db8:5::1                                 | |
0019 # | |    id 1000 dstport $VXPORT                                            | |
0020 # | +-----------------------------------------------------------------------+ |
0021 # |                                                                           |
0022 # |  2001:db8:4::0/64 via 2001:db8:3::2                                       |
0023 # |  2001:db8:5::0/64 via 2001:db8:3::2                                       |
0024 # |                                                                           |
0025 # |    + $rp1                                                                 |
0026 # |    | 2001:db8:3::1/64                                                     |
0027 # +----|----------------------------------------------------------------------+
0028 #      |
0029 # +----|----------------------------------------------------------+
0030 # |    |                                             VRP2 (vrf)   |
0031 # |    + $rp2                                                     |
0032 # |      2001:db8:3::2/64                                         |
0033 # |                                                               |  (maybe) HW
0034 # =============================================================================
0035 # |                                                               |  (likely) SW
0036 # |    + v1 (veth)                             + v3 (veth)        |
0037 # |    | 2001:db8:4::2/64                      | 2001:db8:5::2/64 |
0038 # +----|---------------------------------------|------------------+
0039 #      |                                       |
0040 # +----|--------------------------------+ +----|-------------------------------+
0041 # |    + v2 (veth)        NS1 (netns)   | |    + v4 (veth)        NS2 (netns)  |
0042 # |      2001:db8:4::1/64               | |      2001:db8:5::1/64              |
0043 # |                                     | |                                    |
0044 # | 2001:db8:3::0/64 via 2001:db8:4::2  | | 2001:db8:3::0/64 via 2001:db8:5::2 |
0045 # | 2001:db8:5::1/128 via 2001:db8:4::2 | | 2001:db8:4::1/128 via              |
0046 # |                                     | |         2001:db8:5::2              |
0047 # |                                     | |                                    |
0048 # | +-------------------------------+   | | +-------------------------------+  |
0049 # | |                  BR2 (802.1d) |   | | |                  BR2 (802.1d) |  |
0050 # | |  + vx2 (vxlan)                |   | | |  + vx2 (vxlan)                |  |
0051 # | |    local 2001:db8:4::1        |   | | |    local 2001:db8:5::1        |  |
0052 # | |    remote 2001:db8:3::1       |   | | |    remote 2001:db8:3::1       |  |
0053 # | |    remote 2001:db8:5::1       |   | | |    remote 2001:db8:4::1       |  |
0054 # | |    id 1000 dstport $VXPORT    |   | | |    id 1000 dstport $VXPORT    |  |
0055 # | |                               |   | | |                               |  |
0056 # | |  + w1 (veth)                  |   | | |  + w1 (veth)                  |  |
0057 # | +--|----------------------------+   | | +--|----------------------------+  |
0058 # |    |                                | |    |                               |
0059 # | +--|----------------------------+   | | +--|----------------------------+  |
0060 # | |  + w2 (veth)        VW2 (vrf) |   | | |  + w2 (veth)        VW2 (vrf) |  |
0061 # | |    192.0.2.3/28               |   | | |    192.0.2.4/28               |  |
0062 # | |    2001:db8:1::3/64           |   | | |    2001:db8:1::4/64           |  |
0063 # | +-------------------------------+   | | +-------------------------------+  |
0064 # +-------------------------------------+ +------------------------------------+
0065 
0066 : ${VXPORT:=4789}
0067 export VXPORT
0068 
0069 : ${ALL_TESTS:="
0070         ping_ipv4
0071         ping_ipv6
0072         test_flood
0073         test_unicast
0074         test_ttl
0075         test_tos
0076         test_ecn_encap
0077         test_ecn_decap
0078         reapply_config
0079         ping_ipv4
0080         ping_ipv6
0081         test_flood
0082         test_unicast
0083 "}
0084 
0085 NUM_NETIFS=6
0086 source lib.sh
0087 source tc_common.sh
0088 
0089 h1_create()
0090 {
0091         simple_if_init $h1 192.0.2.1/28 2001:db8:1::1/64
0092         tc qdisc add dev $h1 clsact
0093 }
0094 
0095 h1_destroy()
0096 {
0097         tc qdisc del dev $h1 clsact
0098         simple_if_fini $h1 192.0.2.1/28 2001:db8:1::1/64
0099 }
0100 
0101 h2_create()
0102 {
0103         simple_if_init $h2 192.0.2.2/28 2001:db8:1::2/64
0104         tc qdisc add dev $h2 clsact
0105 }
0106 
0107 h2_destroy()
0108 {
0109         tc qdisc del dev $h2 clsact
0110         simple_if_fini $h2 192.0.2.2/28 2001:db8:1::2/64
0111 }
0112 
0113 rp1_set_addr()
0114 {
0115         ip address add dev $rp1 2001:db8:3::1/64
0116 
0117         ip route add 2001:db8:4::0/64 nexthop via 2001:db8:3::2
0118         ip route add 2001:db8:5::0/64 nexthop via 2001:db8:3::2
0119 }
0120 
0121 rp1_unset_addr()
0122 {
0123         ip route del 2001:db8:5::0/64 nexthop via 2001:db8:3::2
0124         ip route del 2001:db8:4::0/64 nexthop via 2001:db8:3::2
0125 
0126         ip address del dev $rp1 2001:db8:3::1/64
0127 }
0128 
0129 switch_create()
0130 {
0131         ip link add name br1 type bridge vlan_filtering 0 mcast_snooping 0
0132         # Make sure the bridge uses the MAC address of the local port and not
0133         # that of the VxLAN's device.
0134         ip link set dev br1 address $(mac_get $swp1)
0135         ip link set dev br1 up
0136 
0137         ip link set dev $rp1 up
0138         rp1_set_addr
0139         tc qdisc add dev $rp1 clsact
0140 
0141         ip link add name vx1 type vxlan id 1000 local 2001:db8:3::1 \
0142                 dstport "$VXPORT" nolearning udp6zerocsumrx udp6zerocsumtx \
0143                 tos inherit ttl 100
0144         ip link set dev vx1 up
0145 
0146         ip link set dev vx1 master br1
0147         ip link set dev $swp1 master br1
0148         ip link set dev $swp1 up
0149         tc qdisc add dev $swp1 clsact
0150 
0151         ip link set dev $swp2 master br1
0152         ip link set dev $swp2 up
0153 
0154         bridge fdb append dev vx1 00:00:00:00:00:00 dst 2001:db8:4::1 self
0155         bridge fdb append dev vx1 00:00:00:00:00:00 dst 2001:db8:5::1 self
0156 }
0157 
0158 switch_destroy()
0159 {
0160         bridge fdb del dev vx1 00:00:00:00:00:00 dst 2001:db8:5::1 self
0161         bridge fdb del dev vx1 00:00:00:00:00:00 dst 2001:db8:4::1 self
0162 
0163         ip link set dev $swp2 down
0164         ip link set dev $swp2 nomaster
0165 
0166         tc qdisc del dev $swp1 clsact
0167         ip link set dev $swp1 down
0168         ip link set dev $swp1 nomaster
0169 
0170         ip link set dev vx1 nomaster
0171         ip link set dev vx1 down
0172         ip link del dev vx1
0173 
0174         tc qdisc del dev $rp1 clsact
0175         rp1_unset_addr
0176         ip link set dev $rp1 down
0177 
0178         ip link set dev br1 down
0179         ip link del dev br1
0180 }
0181 
0182 vrp2_create()
0183 {
0184         simple_if_init $rp2 2001:db8:3::2/64
0185         __simple_if_init v1 v$rp2 2001:db8:4::2/64
0186         __simple_if_init v3 v$rp2 2001:db8:5::2/64
0187         tc qdisc add dev v1 clsact
0188 }
0189 
0190 vrp2_destroy()
0191 {
0192         tc qdisc del dev v1 clsact
0193         __simple_if_fini v3 2001:db8:5::2/64
0194         __simple_if_fini v1 2001:db8:4::2/64
0195         simple_if_fini $rp2 2001:db8:3::2/64
0196 }
0197 
0198 ns_init_common()
0199 {
0200         local in_if=$1; shift
0201         local in_addr=$1; shift
0202         local other_in_addr=$1; shift
0203         local nh_addr=$1; shift
0204         local host_addr_ipv4=$1; shift
0205         local host_addr_ipv6=$1; shift
0206 
0207         ip link set dev $in_if up
0208         ip address add dev $in_if $in_addr/64
0209         tc qdisc add dev $in_if clsact
0210 
0211         ip link add name br2 type bridge vlan_filtering 0
0212         ip link set dev br2 up
0213 
0214         ip link add name w1 type veth peer name w2
0215 
0216         ip link set dev w1 master br2
0217         ip link set dev w1 up
0218 
0219         ip link add name vx2 type vxlan id 1000 local $in_addr \
0220                 dstport "$VXPORT" udp6zerocsumrx
0221         ip link set dev vx2 up
0222         bridge fdb append dev vx2 00:00:00:00:00:00 dst 2001:db8:3::1 self
0223         bridge fdb append dev vx2 00:00:00:00:00:00 dst $other_in_addr self
0224 
0225         ip link set dev vx2 master br2
0226         tc qdisc add dev vx2 clsact
0227 
0228         simple_if_init w2 $host_addr_ipv4/28 $host_addr_ipv6/64
0229 
0230         ip route add 2001:db8:3::0/64 nexthop via $nh_addr
0231         ip route add $other_in_addr/128 nexthop via $nh_addr
0232 }
0233 export -f ns_init_common
0234 
0235 ns1_create()
0236 {
0237         ip netns add ns1
0238         ip link set dev v2 netns ns1
0239         in_ns ns1 \
0240               ns_init_common v2 2001:db8:4::1 2001:db8:5::1 2001:db8:4::2 \
0241               192.0.2.3 2001:db8:1::3
0242 }
0243 
0244 ns1_destroy()
0245 {
0246         ip netns exec ns1 ip link set dev v2 netns 1
0247         ip netns del ns1
0248 }
0249 
0250 ns2_create()
0251 {
0252         ip netns add ns2
0253         ip link set dev v4 netns ns2
0254         in_ns ns2 \
0255               ns_init_common v4 2001:db8:5::1 2001:db8:4::1 2001:db8:5::2 \
0256               192.0.2.4 2001:db8:1::4
0257 }
0258 
0259 ns2_destroy()
0260 {
0261         ip netns exec ns2 ip link set dev v4 netns 1
0262         ip netns del ns2
0263 }
0264 
0265 setup_prepare()
0266 {
0267         h1=${NETIFS[p1]}
0268         swp1=${NETIFS[p2]}
0269 
0270         swp2=${NETIFS[p3]}
0271         h2=${NETIFS[p4]}
0272 
0273         rp1=${NETIFS[p5]}
0274         rp2=${NETIFS[p6]}
0275 
0276         vrf_prepare
0277         forwarding_enable
0278 
0279         h1_create
0280         h2_create
0281         switch_create
0282 
0283         ip link add name v1 type veth peer name v2
0284         ip link add name v3 type veth peer name v4
0285         vrp2_create
0286         ns1_create
0287         ns2_create
0288 
0289         r1_mac=$(in_ns ns1 mac_get w2)
0290         r2_mac=$(in_ns ns2 mac_get w2)
0291         h2_mac=$(mac_get $h2)
0292 }
0293 
0294 cleanup()
0295 {
0296         pre_cleanup
0297 
0298         ns2_destroy
0299         ns1_destroy
0300         vrp2_destroy
0301         ip link del dev v3
0302         ip link del dev v1
0303 
0304         switch_destroy
0305         h2_destroy
0306         h1_destroy
0307 
0308         forwarding_restore
0309         vrf_cleanup
0310 }
0311 
0312 # For the first round of tests, vx1 is the first device to get
0313 # attached to the bridge, and at that point the local IP is already
0314 # configured. Try the other scenario of attaching the devices to a an
0315 # already-offloaded bridge, and only then assign the local IP.
0316 reapply_config()
0317 {
0318         log_info "Reapplying configuration"
0319 
0320         bridge fdb del dev vx1 00:00:00:00:00:00 dst 2001:db8:5::1 self
0321         bridge fdb del dev vx1 00:00:00:00:00:00 dst 2001:db8:4::1 self
0322         ip link set dev vx1 nomaster
0323         rp1_unset_addr
0324         sleep 5
0325 
0326         ip link set dev vx1 master br1
0327         bridge fdb append dev vx1 00:00:00:00:00:00 dst 2001:db8:4::1 self
0328         bridge fdb append dev vx1 00:00:00:00:00:00 dst 2001:db8:5::1 self
0329         sleep 1
0330         rp1_set_addr
0331         sleep 5
0332 }
0333 
0334 __ping_ipv4()
0335 {
0336         local vxlan_local_ip=$1; shift
0337         local vxlan_remote_ip=$1; shift
0338         local src_ip=$1; shift
0339         local dst_ip=$1; shift
0340         local dev=$1; shift
0341         local info=$1; shift
0342 
0343         RET=0
0344 
0345         tc filter add dev $rp1 egress protocol ipv6 pref 1 handle 101 \
0346                 flower ip_proto udp src_ip $vxlan_local_ip \
0347                 dst_ip $vxlan_remote_ip dst_port $VXPORT $TC_FLAG action pass
0348         # Match ICMP-reply packets after decapsulation, so source IP is
0349         # destination IP of the ping and destination IP is source IP of the
0350         # ping.
0351         tc filter add dev $swp1 egress protocol ip pref 1 handle 101 \
0352                 flower src_ip $dst_ip dst_ip $src_ip \
0353                 $TC_FLAG action pass
0354 
0355         # Send 100 packets and verify that at least 100 packets hit the rule,
0356         # to overcome ARP noise.
0357         PING_COUNT=100 PING_TIMEOUT=11 ping_do $dev $dst_ip
0358         check_err $? "Ping failed"
0359 
0360         tc_check_at_least_x_packets "dev $rp1 egress" 101 10 100
0361         check_err $? "Encapsulated packets did not go through router"
0362 
0363         tc_check_at_least_x_packets "dev $swp1 egress" 101 10 100
0364         check_err $? "Decapsulated packets did not go through switch"
0365 
0366         log_test "ping: $info"
0367 
0368         tc filter del dev $swp1 egress
0369         tc filter del dev $rp1 egress
0370 }
0371 
0372 ping_ipv4()
0373 {
0374         RET=0
0375 
0376         local local_sw_ip=2001:db8:3::1
0377         local remote_ns1_ip=2001:db8:4::1
0378         local remote_ns2_ip=2001:db8:5::1
0379         local h1_ip=192.0.2.1
0380         local w2_ns1_ip=192.0.2.3
0381         local w2_ns2_ip=192.0.2.4
0382 
0383         ping_test $h1 192.0.2.2 ": local->local"
0384 
0385         __ping_ipv4 $local_sw_ip $remote_ns1_ip $h1_ip $w2_ns1_ip $h1 \
0386                 "local->remote 1"
0387         __ping_ipv4 $local_sw_ip $remote_ns2_ip $h1_ip $w2_ns2_ip $h1 \
0388                 "local->remote 2"
0389 }
0390 
0391 __ping_ipv6()
0392 {
0393         local vxlan_local_ip=$1; shift
0394         local vxlan_remote_ip=$1; shift
0395         local src_ip=$1; shift
0396         local dst_ip=$1; shift
0397         local dev=$1; shift
0398         local info=$1; shift
0399 
0400         RET=0
0401 
0402         tc filter add dev $rp1 egress protocol ipv6 pref 1 handle 101 \
0403                 flower ip_proto udp src_ip $vxlan_local_ip \
0404                 dst_ip $vxlan_remote_ip dst_port $VXPORT $TC_FLAG action pass
0405         # Match ICMP-reply packets after decapsulation, so source IP is
0406         # destination IP of the ping and destination IP is source IP of the
0407         # ping.
0408         tc filter add dev $swp1 egress protocol ipv6 pref 1 handle 101 \
0409                 flower src_ip $dst_ip dst_ip $src_ip $TC_FLAG action pass
0410 
0411         # Send 100 packets and verify that at least 100 packets hit the rule,
0412         # to overcome neighbor discovery noise.
0413         PING_COUNT=100 PING_TIMEOUT=11 ping6_do $dev $dst_ip
0414         check_err $? "Ping failed"
0415 
0416         tc_check_at_least_x_packets "dev $rp1 egress" 101 100
0417         check_err $? "Encapsulated packets did not go through router"
0418 
0419         tc_check_at_least_x_packets "dev $swp1 egress" 101 100
0420         check_err $? "Decapsulated packets did not go through switch"
0421 
0422         log_test "ping6: $info"
0423 
0424         tc filter del dev $swp1 egress
0425         tc filter del dev $rp1 egress
0426 }
0427 
0428 ping_ipv6()
0429 {
0430         RET=0
0431 
0432         local local_sw_ip=2001:db8:3::1
0433         local remote_ns1_ip=2001:db8:4::1
0434         local remote_ns2_ip=2001:db8:5::1
0435         local h1_ip=2001:db8:1::1
0436         local w2_ns1_ip=2001:db8:1::3
0437         local w2_ns2_ip=2001:db8:1::4
0438 
0439         ping6_test $h1 2001:db8:1::2 ": local->local"
0440 
0441         __ping_ipv6 $local_sw_ip $remote_ns1_ip $h1_ip $w2_ns1_ip $h1 \
0442                 "local->remote 1"
0443         __ping_ipv6 $local_sw_ip $remote_ns2_ip $h1_ip $w2_ns2_ip $h1 \
0444                 "local->remote 2"
0445 }
0446 
0447 maybe_in_ns()
0448 {
0449         echo ${1:+in_ns} $1
0450 }
0451 
0452 __flood_counter_add_del()
0453 {
0454         local add_del=$1; shift
0455         local dst_ip=$1; shift
0456         local dev=$1; shift
0457         local ns=$1; shift
0458 
0459         # Putting the ICMP capture both to HW and to SW will end up
0460         # double-counting the packets that are trapped to slow path, such as for
0461         # the unicast test. Adding either skip_hw or skip_sw fixes this problem,
0462         # but with skip_hw, the flooded packets are not counted at all, because
0463         # those are dropped due to MAC address mismatch; and skip_sw is a no-go
0464         # for veth-based topologies.
0465         #
0466         # So try to install with skip_sw and fall back to skip_sw if that fails.
0467 
0468         $(maybe_in_ns $ns) tc filter $add_del dev "$dev" ingress \
0469            proto ipv6 pref 100 flower dst_ip $dst_ip ip_proto \
0470            icmpv6 skip_sw action pass 2>/dev/null || \
0471         $(maybe_in_ns $ns) tc filter $add_del dev "$dev" ingress \
0472            proto ipv6 pref 100 flower dst_ip $dst_ip ip_proto \
0473            icmpv6 skip_hw action pass
0474 }
0475 
0476 flood_counter_install()
0477 {
0478         __flood_counter_add_del add "$@"
0479 }
0480 
0481 flood_counter_uninstall()
0482 {
0483         __flood_counter_add_del del "$@"
0484 }
0485 
0486 flood_fetch_stat()
0487 {
0488         local dev=$1; shift
0489         local ns=$1; shift
0490 
0491         $(maybe_in_ns $ns) tc_rule_stats_get $dev 100 ingress
0492 }
0493 
0494 flood_fetch_stats()
0495 {
0496         local counters=("${@}")
0497         local counter
0498 
0499         for counter in "${counters[@]}"; do
0500                 flood_fetch_stat $counter
0501         done
0502 }
0503 
0504 vxlan_flood_test()
0505 {
0506         local mac=$1; shift
0507         local dst=$1; shift
0508         local -a expects=("${@}")
0509 
0510         local -a counters=($h2 "vx2 ns1" "vx2 ns2")
0511         local counter
0512         local key
0513 
0514         for counter in "${counters[@]}"; do
0515                 flood_counter_install $dst $counter
0516         done
0517 
0518         local -a t0s=($(flood_fetch_stats "${counters[@]}"))
0519         $MZ -6 $h1 -c 10 -d 100msec -p 64 -b $mac -B $dst -t icmp6 type=128 -q
0520         sleep 1
0521         local -a t1s=($(flood_fetch_stats "${counters[@]}"))
0522 
0523         for key in ${!t0s[@]}; do
0524                 local delta=$((t1s[$key] - t0s[$key]))
0525                 local expect=${expects[$key]}
0526 
0527                 ((expect == delta))
0528                 check_err $? "${counters[$key]}: Expected to capture $expect packets, got $delta."
0529         done
0530 
0531         for counter in "${counters[@]}"; do
0532                 flood_counter_uninstall $dst $counter
0533         done
0534 }
0535 
0536 __test_flood()
0537 {
0538         local mac=$1; shift
0539         local dst=$1; shift
0540         local what=$1; shift
0541 
0542         RET=0
0543 
0544         vxlan_flood_test $mac $dst 10 10 10
0545 
0546         log_test "VXLAN: $what"
0547 }
0548 
0549 test_flood()
0550 {
0551         __test_flood de:ad:be:ef:13:37 2001:db8:1::100 "flood"
0552 }
0553 
0554 vxlan_fdb_add_del()
0555 {
0556         local add_del=$1; shift
0557         local mac=$1; shift
0558         local dev=$1; shift
0559         local dst=$1; shift
0560 
0561         bridge fdb $add_del dev $dev $mac self static permanent \
0562                 ${dst:+dst} $dst 2>/dev/null
0563         bridge fdb $add_del dev $dev $mac master static 2>/dev/null
0564 }
0565 
0566 __test_unicast()
0567 {
0568         local mac=$1; shift
0569         local dst=$1; shift
0570         local hit_idx=$1; shift
0571         local what=$1; shift
0572 
0573         RET=0
0574 
0575         local -a expects=(0 0 0)
0576         expects[$hit_idx]=10
0577 
0578         vxlan_flood_test $mac $dst "${expects[@]}"
0579 
0580         log_test "VXLAN: $what"
0581 }
0582 
0583 test_unicast()
0584 {
0585         local -a targets=("$h2_mac $h2"
0586                           "$r1_mac vx1 2001:db8:4::1"
0587                           "$r2_mac vx1 2001:db8:5::1")
0588         local target
0589 
0590         for target in "${targets[@]}"; do
0591                 vxlan_fdb_add_del add $target
0592         done
0593 
0594         __test_unicast $h2_mac 2001:db8:1::2 0 "local MAC unicast"
0595         __test_unicast $r1_mac 2001:db8:1::3 1 "remote MAC 1 unicast"
0596         __test_unicast $r2_mac 2001:db8:1::4 2 "remote MAC 2 unicast"
0597 
0598         for target in "${targets[@]}"; do
0599                 vxlan_fdb_add_del del $target
0600         done
0601 }
0602 
0603 vxlan_ping_test()
0604 {
0605         local ping_dev=$1; shift
0606         local ping_dip=$1; shift
0607         local ping_args=$1; shift
0608         local capture_dev=$1; shift
0609         local capture_dir=$1; shift
0610         local capture_pref=$1; shift
0611         local expect=$1; shift
0612 
0613         local t0=$(tc_rule_stats_get $capture_dev $capture_pref $capture_dir)
0614         ping6_do $ping_dev $ping_dip "$ping_args"
0615         local t1=$(tc_rule_stats_get $capture_dev $capture_pref $capture_dir)
0616         local delta=$((t1 - t0))
0617 
0618         # Tolerate a couple stray extra packets.
0619         ((expect <= delta && delta <= expect + 2))
0620         check_err $? "$capture_dev: Expected to capture $expect packets, got $delta."
0621 }
0622 
0623 test_ttl()
0624 {
0625         RET=0
0626 
0627         tc filter add dev v1 egress pref 77 protocol ipv6 \
0628                 flower ip_ttl 99 action pass
0629         vxlan_ping_test $h1 2001:db8:1::3 "" v1 egress 77 10
0630         tc filter del dev v1 egress pref 77 protocol ipv6
0631 
0632         log_test "VXLAN: envelope TTL"
0633 }
0634 
0635 test_tos()
0636 {
0637         RET=0
0638 
0639         tc filter add dev v1 egress pref 77 protocol ipv6 \
0640                 flower ip_tos 0x14 action pass
0641         vxlan_ping_test $h1 2001:db8:1::3 "-Q 0x14" v1 egress 77 10
0642         vxlan_ping_test $h1 2001:db8:1::3 "-Q 0x18" v1 egress 77 0
0643         tc filter del dev v1 egress pref 77 protocol ipv6
0644 
0645         log_test "VXLAN: envelope TOS inheritance"
0646 }
0647 
0648 __test_ecn_encap()
0649 {
0650         local q=$1; shift
0651         local tos=$1; shift
0652 
0653         RET=0
0654 
0655         tc filter add dev v1 egress pref 77 protocol ipv6 \
0656                 flower ip_tos $tos action pass
0657         sleep 1
0658         vxlan_ping_test $h1 2001:db8:1::3 "-Q $q" v1 egress 77 10
0659         tc filter del dev v1 egress pref 77 protocol ipv6
0660 
0661         log_test "VXLAN: ECN encap: $q->$tos"
0662 }
0663 
0664 test_ecn_encap()
0665 {
0666         # In accordance with INET_ECN_encapsulate()
0667         __test_ecn_encap 0x00 0x00
0668         __test_ecn_encap 0x01 0x01
0669         __test_ecn_encap 0x02 0x02
0670         __test_ecn_encap 0x03 0x02
0671 }
0672 
0673 vxlan_encapped_ping_do()
0674 {
0675         local count=$1; shift
0676         local dev=$1; shift
0677         local next_hop_mac=$1; shift
0678         local dest_ip=$1; shift
0679         local dest_mac=$1; shift
0680         local inner_tos=$1; shift
0681         local outer_tos=$1; shift
0682         local saddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:03"
0683         local daddr="20:01:0d:b8:00:01:00:00:00:00:00:00:00:00:00:01"
0684 
0685         $MZ -6 $dev -c $count -d 100msec -q \
0686                 -b $next_hop_mac -B $dest_ip \
0687                 -t udp tos=$outer_tos,sp=23456,dp=$VXPORT,p=$(:
0688                     )"08:"$(                      : VXLAN flags
0689                     )"00:00:00:"$(                : VXLAN reserved
0690                     )"00:03:e8:"$(                : VXLAN VNI
0691                     )"00:"$(                      : VXLAN reserved
0692                     )"$dest_mac:"$(               : ETH daddr
0693                     )"$(mac_get w2):"$(           : ETH saddr
0694                     )"86:dd:"$(                   : ETH type
0695                     )"6"$(                        : IP version
0696                     )"$inner_tos"$(               : Traffic class
0697                     )"0:00:00:"$(                 : Flow label
0698                     )"00:08:"$(                   : Payload length
0699                     )"3a:"$(                      : Next header
0700                     )"04:"$(                      : Hop limit
0701                     )"$saddr:"$(                  : IP saddr
0702                     )"$daddr:"$(                  : IP daddr
0703                     )"80:"$(                      : ICMPv6.type
0704                     )"00:"$(                      : ICMPv6.code
0705                     )"00:"$(                      : ICMPv6.checksum
0706                     )
0707 }
0708 export -f vxlan_encapped_ping_do
0709 
0710 vxlan_encapped_ping_test()
0711 {
0712         local ping_dev=$1; shift
0713         local nh_dev=$1; shift
0714         local ping_dip=$1; shift
0715         local inner_tos=$1; shift
0716         local outer_tos=$1; shift
0717         local stat_get=$1; shift
0718         local expect=$1; shift
0719 
0720         local t0=$($stat_get)
0721 
0722         in_ns ns1 \
0723                 vxlan_encapped_ping_do 10 $ping_dev $(mac_get $nh_dev) \
0724                         $ping_dip $(mac_get $h1) \
0725                         $inner_tos $outer_tos
0726         sleep 1
0727         local t1=$($stat_get)
0728         local delta=$((t1 - t0))
0729 
0730         # Tolerate a couple stray extra packets.
0731         ((expect <= delta && delta <= expect + 2))
0732         check_err $? "Expected to capture $expect packets, got $delta."
0733 }
0734 export -f vxlan_encapped_ping_test
0735 
0736 __test_ecn_decap()
0737 {
0738         local orig_inner_tos=$1; shift
0739         local orig_outer_tos=$1; shift
0740         local decapped_tos=$1; shift
0741 
0742         RET=0
0743 
0744         tc filter add dev $h1 ingress pref 77 protocol ipv6 \
0745                 flower src_ip 2001:db8:1::3 dst_ip 2001:db8:1::1 \
0746                 ip_tos $decapped_tos action drop
0747         sleep 1
0748         vxlan_encapped_ping_test v2 v1 2001:db8:3::1 \
0749                                  $orig_inner_tos $orig_outer_tos \
0750                                  "tc_rule_stats_get $h1 77 ingress" 10
0751         tc filter del dev $h1 ingress pref 77
0752 
0753         log_test "VXLAN: ECN decap: $orig_outer_tos/$orig_inner_tos->$decapped_tos"
0754 }
0755 
0756 test_ecn_decap_error()
0757 {
0758         local orig_inner_tos="0:0"
0759         local orig_outer_tos=03
0760 
0761         RET=0
0762 
0763         vxlan_encapped_ping_test v2 v1 2001:db8:3::1 \
0764                                  $orig_inner_tos $orig_outer_tos \
0765                                  "link_stats_rx_errors_get vx1" 10
0766 
0767         log_test "VXLAN: ECN decap: $orig_outer_tos/$orig_inner_tos->error"
0768 }
0769 
0770 test_ecn_decap()
0771 {
0772         # In accordance with INET_ECN_decapsulate()
0773         __test_ecn_decap "0:0" 00 0x00
0774         __test_ecn_decap "0:0" 01 0x00
0775         __test_ecn_decap "0:0" 02 0x00
0776         # 00 03 is tested in test_ecn_decap_error()
0777         __test_ecn_decap "0:1" 00 0x01
0778         __test_ecn_decap "0:1" 01 0x01
0779         __test_ecn_decap "0:1" 02 0x01
0780         __test_ecn_decap "0:1" 03 0x03
0781         __test_ecn_decap "0:2" 00 0x02
0782         __test_ecn_decap "0:2" 01 0x01
0783         __test_ecn_decap "0:2" 02 0x02
0784         __test_ecn_decap "0:2" 03 0x03
0785         __test_ecn_decap "0:3" 00 0x03
0786         __test_ecn_decap "0:3" 01 0x03
0787         __test_ecn_decap "0:3" 02 0x03
0788         __test_ecn_decap "0:3" 03 0x03
0789         test_ecn_decap_error
0790 }
0791 
0792 test_all()
0793 {
0794         log_info "Running tests with UDP port $VXPORT"
0795         tests_run
0796 }
0797 
0798 trap cleanup EXIT
0799 
0800 setup_prepare
0801 setup_wait
0802 test_all
0803 
0804 exit $EXIT_STATUS