# SPDX-License-Identifier: GPL-2.0 # Test offloading a number of mirrors-to-gretap. The test creates a number of # tunnels. Then it adds one flower mirror for each of the tunnels, matching a # given host IP. Then it generates traffic at each of the host IPs and checks # that the traffic has been mirrored at the appropriate tunnel. # # +--------------------------+ +--------------------------+ # | H1 | | H2 | # | + $h1 | | $h2 + | # | | 2001:db8:1:X::1/64 | | 2001:db8:1:X::2/64 | | # +-----|--------------------+ +--------------------|-----+ # | | # +-----|-------------------------------------------------------------|-----+ # | SW o--> mirrors | | # | +---|-------------------------------------------------------------|---+ | # | | + $swp1 BR $swp2 + | | # | +---------------------------------------------------------------------+ | # | | # | + $swp3 + gt6-<X> (ip6gretap) | # | | 2001:db8:2:X::1/64 : loc=2001:db8:2:X::1 | # | | : rem=2001:db8:2:X::2 | # | | : ttl=100 | # | | : tos=inherit | # | | : | # +-----|--------------------------------:----------------------------------+ # | : # +-----|--------------------------------:----------------------------------+ # | H3 + $h3 + h3-gt6-<X> (ip6gretap) | # | 2001:db8:2:X::2/64 loc=2001:db8:2:X::2 | # | rem=2001:db8:2:X::1 | # | ttl=100 | # | tos=inherit | # | | # +-------------------------------------------------------------------------+ source ../../../../net/forwarding/mirror_lib.sh MIRROR_NUM_NETIFS=6 mirror_gre_ipv6_addr() { local net=$1; shift local num=$1; shift printf "2001:db8:%x:%x" $net $num } mirror_gre_tunnels_create() { local count=$1; shift local should_fail=$1; shift MIRROR_GRE_BATCH_FILE="$(mktemp)" for ((i=0; i < count; ++i)); do local match_dip=$(mirror_gre_ipv6_addr 1 $i)::2 local htun=h3-gt6-$i local tun=gt6-$i ((mirror_gre_tunnels++)) ip address add dev $h1 $(mirror_gre_ipv6_addr 1 $i)::1/64 ip address add dev $h2 $(mirror_gre_ipv6_addr 1 $i)::2/64 ip address add dev $swp3 $(mirror_gre_ipv6_addr 2 $i)::1/64 ip address add dev $h3 $(mirror_gre_ipv6_addr 2 $i)::2/64 tunnel_create $tun ip6gretap \ $(mirror_gre_ipv6_addr 2 $i)::1 \ $(mirror_gre_ipv6_addr 2 $i)::2 \ ttl 100 tos inherit allow-localremote tunnel_create $htun ip6gretap \ $(mirror_gre_ipv6_addr 2 $i)::2 \ $(mirror_gre_ipv6_addr 2 $i)::1 ip link set $htun vrf v$h3 matchall_sink_create $htun cat >> $MIRROR_GRE_BATCH_FILE <<-EOF filter add dev $swp1 ingress pref 1000 \ protocol ipv6 \ flower $tcflags dst_ip $match_dip \ action mirred egress mirror dev $tun EOF done tc -b $MIRROR_GRE_BATCH_FILE check_err_fail $should_fail $? "Mirror rule insertion" } mirror_gre_tunnels_destroy() { local count=$1; shift for ((i=0; i < count; ++i)); do local htun=h3-gt6-$i local tun=gt6-$i ip address del dev $h3 $(mirror_gre_ipv6_addr 2 $i)::2/64 ip address del dev $swp3 $(mirror_gre_ipv6_addr 2 $i)::1/64 ip address del dev $h2 $(mirror_gre_ipv6_addr 1 $i)::2/64 ip address del dev $h1 $(mirror_gre_ipv6_addr 1 $i)::1/64 tunnel_destroy $htun tunnel_destroy $tun done } __mirror_gre_test() { local count=$1; shift local should_fail=$1; shift mirror_gre_tunnels_create $count $should_fail if ((should_fail)); then return fi sleep 5 for ((i = 0; i < count; ++i)); do local sip=$(mirror_gre_ipv6_addr 1 $i)::1 local dip=$(mirror_gre_ipv6_addr 1 $i)::2 local htun=h3-gt6-$i local message icmp6_capture_install $htun mirror_test v$h1 $sip $dip $htun 100 10 icmp6_capture_uninstall $htun done } mirror_gre_test() { local count=$1; shift local should_fail=$1; shift if ! tc_offload_check $TC_FLOWER_NUM_NETIFS; then check_err 1 "Could not test offloaded functionality" return fi tcflags="skip_sw" __mirror_gre_test $count $should_fail } mirror_gre_setup_prepare() { h1=${NETIFS[p1]} swp1=${NETIFS[p2]} swp2=${NETIFS[p3]} h2=${NETIFS[p4]} swp3=${NETIFS[p5]} h3=${NETIFS[p6]} mirror_gre_tunnels=0 vrf_prepare simple_if_init $h1 simple_if_init $h2 simple_if_init $h3 ip link add name br1 type bridge vlan_filtering 1 ip link set dev br1 addrgenmode none ip link set dev br1 up ip link set dev $swp1 master br1 ip link set dev $swp1 up tc qdisc add dev $swp1 clsact ip link set dev $swp2 master br1 ip link set dev $swp2 up ip link set dev $swp3 up } mirror_gre_cleanup() { mirror_gre_tunnels_destroy $mirror_gre_tunnels ip link set dev $swp3 down ip link set dev $swp2 down tc qdisc del dev $swp1 clsact ip link set dev $swp1 down ip link del dev br1 simple_if_fini $h3 simple_if_fini $h2 simple_if_fini $h1 vrf_cleanup }