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