selftests: forwarding: Add libs for gretap mirror testing
authorPetr Machata <petrm@mellanox.com>
Thu, 26 Apr 2018 23:17:56 +0000 (01:17 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 27 Apr 2018 18:57:49 +0000 (14:57 -0400)
To simplify implementation of mirror-to-gretap tests, extend lib.sh with
several new functions that might potentially be useful more
broadly (although right now the mirroring tests will be the only
client).

Also add mirror_lib.sh with code useful for mirroring tests,
mirror_gre_lib.sh with code specifically useful for mirror-to-gretap
tests, and mirror_gre_topo.sh that primes a given test with a good
baseline topology that the test can then tweak to its liking.

Signed-off-by: Petr Machata <petrm@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
tools/testing/selftests/net/forwarding/lib.sh
tools/testing/selftests/net/forwarding/mirror_gre_lib.sh [new file with mode: 0644]
tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh [new file with mode: 0644]
tools/testing/selftests/net/forwarding/mirror_lib.sh [new file with mode: 0644]

index 1ac6c62271f352329dbc45407df11b6f238cb07c..a066ca536ac41b72b200a87164febe69ffe32ec5 100644 (file)
@@ -321,6 +321,25 @@ simple_if_fini()
        vrf_destroy $vrf_name
 }
 
+tunnel_create()
+{
+       local name=$1; shift
+       local type=$1; shift
+       local local=$1; shift
+       local remote=$1; shift
+
+       ip link add name $name type $type \
+          local $local remote $remote "$@"
+       ip link set dev $name up
+}
+
+tunnel_destroy()
+{
+       local name=$1; shift
+
+       ip link del dev $name
+}
+
 master_name_get()
 {
        local if_name=$1
@@ -335,6 +354,15 @@ link_stats_tx_packets_get()
        ip -j -s link show dev $if_name | jq '.[]["stats64"]["tx"]["packets"]'
 }
 
+tc_rule_stats_get()
+{
+       local dev=$1; shift
+       local pref=$1; shift
+
+       tc -j -s filter show dev $dev ingress pref $pref |
+       jq '.[1].options.actions[].stats.packets'
+}
+
 mac_get()
 {
        local if_name=$1
@@ -381,6 +409,74 @@ tc_offload_check()
        return 0
 }
 
+slow_path_trap_install()
+{
+       local dev=$1; shift
+       local direction=$1; shift
+
+       if [ "${tcflags/skip_hw}" != "$tcflags" ]; then
+               # For slow-path testing, we need to install a trap to get to
+               # slow path the packets that would otherwise be switched in HW.
+               tc filter add dev $dev $direction pref 1 \
+                  flower skip_sw action trap
+       fi
+}
+
+slow_path_trap_uninstall()
+{
+       local dev=$1; shift
+       local direction=$1; shift
+
+       if [ "${tcflags/skip_hw}" != "$tcflags" ]; then
+               tc filter del dev $dev $direction pref 1 flower skip_sw
+       fi
+}
+
+__icmp_capture_add_del()
+{
+       local add_del=$1; shift
+       local pref=$1; shift
+       local vsuf=$1; shift
+       local tundev=$1; shift
+       local filter=$1; shift
+
+       tc filter $add_del dev "$tundev" ingress \
+          proto ip$vsuf pref $pref \
+          flower ip_proto icmp$vsuf $filter \
+          action pass
+}
+
+icmp_capture_install()
+{
+       __icmp_capture_add_del add 100 "" "$@"
+}
+
+icmp_capture_uninstall()
+{
+       __icmp_capture_add_del del 100 "" "$@"
+}
+
+icmp6_capture_install()
+{
+       __icmp_capture_add_del add 100 v6 "$@"
+}
+
+icmp6_capture_uninstall()
+{
+       __icmp_capture_add_del del 100 v6 "$@"
+}
+
+matchall_sink_create()
+{
+       local dev=$1; shift
+
+       tc qdisc add dev $dev clsact
+       tc filter add dev $dev ingress \
+          pref 10000 \
+          matchall \
+          action drop
+}
+
 ##############################################################################
 # Tests
 
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_lib.sh b/tools/testing/selftests/net/forwarding/mirror_gre_lib.sh
new file mode 100644 (file)
index 0000000..207ffd1
--- /dev/null
@@ -0,0 +1,85 @@
+# SPDX-License-Identifier: GPL-2.0
+
+do_test_span_gre_dir_ips()
+{
+       local expect=$1; shift
+       local tundev=$1; shift
+       local direction=$1; shift
+       local ip1=$1; shift
+       local ip2=$1; shift
+
+       icmp_capture_install h3-$tundev
+       mirror_test v$h1 $ip1 $ip2 h3-$tundev 100 $expect
+       mirror_test v$h2 $ip2 $ip1 h3-$tundev 100 $expect
+       icmp_capture_uninstall h3-$tundev
+}
+
+quick_test_span_gre_dir_ips()
+{
+       do_test_span_gre_dir_ips 10 "$@"
+}
+
+fail_test_span_gre_dir_ips()
+{
+       do_test_span_gre_dir_ips 0 "$@"
+}
+
+test_span_gre_dir_ips()
+{
+       local tundev=$1; shift
+       local direction=$1; shift
+       local forward_type=$1; shift
+       local backward_type=$1; shift
+       local ip1=$1; shift
+       local ip2=$1; shift
+
+       quick_test_span_gre_dir_ips "$tundev" "$direction" "$ip1" "$ip2"
+
+       icmp_capture_install h3-$tundev "type $forward_type"
+       mirror_test v$h1 $ip1 $ip2 h3-$tundev 100 10
+       icmp_capture_uninstall h3-$tundev
+
+       icmp_capture_install h3-$tundev "type $backward_type"
+       mirror_test v$h2 $ip2 $ip1 h3-$tundev 100 10
+       icmp_capture_uninstall h3-$tundev
+}
+
+full_test_span_gre_dir_ips()
+{
+       local tundev=$1; shift
+       local direction=$1; shift
+       local forward_type=$1; shift
+       local backward_type=$1; shift
+       local what=$1; shift
+       local ip1=$1; shift
+       local ip2=$1; shift
+
+       RET=0
+
+       mirror_install $swp1 $direction $tundev "matchall $tcflags"
+       test_span_gre_dir_ips "$tundev" "$direction" "$forward_type" \
+                             "$backward_type" "$ip1" "$ip2"
+       mirror_uninstall $swp1 $direction
+
+       log_test "$direction $what ($tcflags)"
+}
+
+quick_test_span_gre_dir()
+{
+       quick_test_span_gre_dir_ips "$@" 192.0.2.1 192.0.2.2
+}
+
+fail_test_span_gre_dir()
+{
+       fail_test_span_gre_dir_ips "$@" 192.0.2.1 192.0.2.2
+}
+
+test_span_gre_dir()
+{
+       test_span_gre_dir_ips "$@" 192.0.2.1 192.0.2.2
+}
+
+full_test_span_gre_dir()
+{
+       full_test_span_gre_dir_ips "$@" 192.0.2.1 192.0.2.2
+}
diff --git a/tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh b/tools/testing/selftests/net/forwarding/mirror_gre_topo_lib.sh
new file mode 100644 (file)
index 0000000..b3ceda2
--- /dev/null
@@ -0,0 +1,129 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# This is the standard topology for testing mirroring to gretap and ip6gretap
+# netdevices. The tests that use it tweak it in one way or another--importantly,
+# $swp3 and $h3 need to have addresses set up.
+#
+#   +---------------------+                             +---------------------+
+#   | H1                  |                             |                  H2 |
+#   |     + $h1           |                             |           $h2 +     |
+#   |     | 192.0.2.1/28  |                             |  192.0.2.2/28 |     |
+#   +-----|---------------+                             +---------------|-----+
+#         |                                                             |
+#   +-----|-------------------------------------------------------------|-----+
+#   | SW  o--> mirror                                                   |     |
+#   | +---|-------------------------------------------------------------|---+ |
+#   | |   + $swp1                    BR                           $swp2 +   | |
+#   | +---------------------------------------------------------------------+ |
+#   |                                                                         |
+#   |     + $swp3               + gt6 (ip6gretap)      + gt4 (gretap)         |
+#   |     |                     : loc=2001:db8:2::1    : loc=192.0.2.129      |
+#   |     |                     : rem=2001:db8:2::2    : rem=192.0.2.130      |
+#   |     |                     : ttl=100              : ttl=100              |
+#   |     |                     : tos=inherit          : tos=inherit          |
+#   |     |                     :                      :                      |
+#   +-----|---------------------:----------------------:----------------------+
+#         |                     :                      :
+#   +-----|---------------------:----------------------:----------------------+
+#   | H3  + $h3                 + h3-gt6 (ip6gretap)   + h3-gt4 (gretap)      |
+#   |                             loc=2001:db8:2::2      loc=192.0.2.130      |
+#   |                             rem=2001:db8:2::1      rem=192.0.2.129      |
+#   |                             ttl=100                ttl=100              |
+#   |                             tos=inherit            tos=inherit          |
+#   |                                                                         |
+#   +-------------------------------------------------------------------------+
+
+mirror_gre_topo_h1_create()
+{
+       simple_if_init $h1 192.0.2.1/28
+}
+
+mirror_gre_topo_h1_destroy()
+{
+       simple_if_fini $h1 192.0.2.1/28
+}
+
+mirror_gre_topo_h2_create()
+{
+       simple_if_init $h2 192.0.2.2/28
+}
+
+mirror_gre_topo_h2_destroy()
+{
+       simple_if_fini $h2 192.0.2.2/28
+}
+
+mirror_gre_topo_h3_create()
+{
+       simple_if_init $h3
+
+       tunnel_create h3-gt4 gretap 192.0.2.130 192.0.2.129
+       ip link set h3-gt4 vrf v$h3
+       matchall_sink_create h3-gt4
+
+       tunnel_create h3-gt6 ip6gretap 2001:db8:2::2 2001:db8:2::1
+       ip link set h3-gt6 vrf v$h3
+       matchall_sink_create h3-gt6
+}
+
+mirror_gre_topo_h3_destroy()
+{
+       tunnel_destroy h3-gt6
+       tunnel_destroy h3-gt4
+
+       simple_if_fini $h3
+}
+
+mirror_gre_topo_switch_create()
+{
+       ip link set dev $swp3 up
+
+       ip link add name br1 type bridge vlan_filtering 1
+       ip link set dev br1 up
+
+       ip link set dev $swp1 master br1
+       ip link set dev $swp1 up
+
+       ip link set dev $swp2 master br1
+       ip link set dev $swp2 up
+
+       tunnel_create gt4 gretap 192.0.2.129 192.0.2.130 \
+                     ttl 100 tos inherit
+
+       tunnel_create gt6 ip6gretap 2001:db8:2::1 2001:db8:2::2 \
+                     ttl 100 tos inherit allow-localremote
+
+       tc qdisc add dev $swp1 clsact
+}
+
+mirror_gre_topo_switch_destroy()
+{
+       tc qdisc del dev $swp1 clsact
+
+       tunnel_destroy gt6
+       tunnel_destroy gt4
+
+       ip link set dev $swp1 down
+       ip link set dev $swp2 down
+       ip link del dev br1
+
+       ip link set dev $swp3 down
+}
+
+mirror_gre_topo_create()
+{
+       mirror_gre_topo_h1_create
+       mirror_gre_topo_h2_create
+       mirror_gre_topo_h3_create
+
+       mirror_gre_topo_switch_create
+}
+
+mirror_gre_topo_destroy()
+{
+       mirror_gre_topo_switch_destroy
+
+       mirror_gre_topo_h3_destroy
+       mirror_gre_topo_h2_destroy
+       mirror_gre_topo_h1_destroy
+}
diff --git a/tools/testing/selftests/net/forwarding/mirror_lib.sh b/tools/testing/selftests/net/forwarding/mirror_lib.sh
new file mode 100644 (file)
index 0000000..e5028a5
--- /dev/null
@@ -0,0 +1,40 @@
+# SPDX-License-Identifier: GPL-2.0
+
+mirror_install()
+{
+       local from_dev=$1; shift
+       local direction=$1; shift
+       local to_dev=$1; shift
+       local filter=$1; shift
+
+       tc filter add dev $from_dev $direction \
+          pref 1000 $filter \
+          action mirred egress mirror dev $to_dev
+}
+
+mirror_uninstall()
+{
+       local from_dev=$1; shift
+       local direction=$1; shift
+
+       tc filter del dev $swp1 $direction pref 1000
+}
+
+mirror_test()
+{
+       local vrf_name=$1; shift
+       local sip=$1; shift
+       local dip=$1; shift
+       local dev=$1; shift
+       local pref=$1; shift
+       local expect=$1; shift
+
+       local t0=$(tc_rule_stats_get $dev $pref)
+       ip vrf exec $vrf_name \
+          ${PING} ${sip:+-I $sip} $dip -c 10 -i 0.1 -w 2 &> /dev/null
+       local t1=$(tc_rule_stats_get $dev $pref)
+       local delta=$((t1 - t0))
+       # Tolerate a couple stray extra packets.
+       ((expect <= delta && delta <= expect + 2))
+       check_err $? "Expected to capture $expect packets, got $delta."
+}