1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4ALL_TESTS="gact_drop_and_ok_test mirred_egress_redirect_test \ 5 mirred_egress_mirror_test matchall_mirred_egress_mirror_test \ 6 gact_trap_test mirred_egress_to_ingress_tcp_test" 7NUM_NETIFS=4 8source tc_common.sh 9source lib.sh 10 11require_command ncat 12 13tcflags="skip_hw" 14 15h1_create() 16{ 17 simple_if_init $h1 192.0.2.1/24 18} 19 20h1_destroy() 21{ 22 simple_if_fini $h1 192.0.2.1/24 23} 24 25h2_create() 26{ 27 simple_if_init $h2 192.0.2.2/24 28 tc qdisc add dev $h2 clsact 29} 30 31h2_destroy() 32{ 33 tc qdisc del dev $h2 clsact 34 simple_if_fini $h2 192.0.2.2/24 35} 36 37switch_create() 38{ 39 simple_if_init $swp1 192.0.2.2/24 40 tc qdisc add dev $swp1 clsact 41 42 simple_if_init $swp2 192.0.2.1/24 43} 44 45switch_destroy() 46{ 47 simple_if_fini $swp2 192.0.2.1/24 48 49 tc qdisc del dev $swp1 clsact 50 simple_if_fini $swp1 192.0.2.2/24 51} 52 53mirred_egress_test() 54{ 55 local action=$1 56 local protocol=$2 57 local classifier=$3 58 local classifier_args=$4 59 60 RET=0 61 62 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 63 $tcflags dst_ip 192.0.2.2 action drop 64 65 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 66 -t ip -q 67 68 tc_check_packets "dev $h2 ingress" 101 1 69 check_fail $? "Matched without redirect rule inserted" 70 71 tc filter add dev $swp1 ingress protocol $protocol pref 1 handle 101 \ 72 $classifier $tcflags $classifier_args \ 73 action mirred egress $action dev $swp2 74 75 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 76 -t ip -q 77 78 tc_check_packets "dev $h2 ingress" 101 1 79 check_err $? "Did not match incoming $action packet" 80 81 tc filter del dev $swp1 ingress protocol $protocol pref 1 handle 101 \ 82 $classifier 83 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 84 85 log_test "mirred egress $classifier $action ($tcflags)" 86} 87 88gact_drop_and_ok_test() 89{ 90 RET=0 91 92 tc filter add dev $swp1 ingress protocol ip pref 2 handle 102 flower \ 93 $tcflags dst_ip 192.0.2.2 action drop 94 95 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 96 -t ip -q 97 98 tc_check_packets "dev $swp1 ingress" 102 1 99 check_err $? "Packet was not dropped" 100 101 tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \ 102 $tcflags dst_ip 192.0.2.2 action ok 103 104 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 105 -t ip -q 106 107 tc_check_packets "dev $swp1 ingress" 101 1 108 check_err $? "Did not see passed packet" 109 110 tc_check_packets "dev $swp1 ingress" 102 2 111 check_fail $? "Packet was dropped and it should not reach here" 112 113 tc filter del dev $swp1 ingress protocol ip pref 2 handle 102 flower 114 tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower 115 116 log_test "gact drop and ok ($tcflags)" 117} 118 119gact_trap_test() 120{ 121 RET=0 122 123 if [[ "$tcflags" != "skip_sw" ]]; then 124 return 0; 125 fi 126 127 tc filter add dev $swp1 ingress protocol ip pref 1 handle 101 flower \ 128 skip_hw dst_ip 192.0.2.2 action drop 129 tc filter add dev $swp1 ingress protocol ip pref 3 handle 103 flower \ 130 $tcflags dst_ip 192.0.2.2 action mirred egress redirect \ 131 dev $swp2 132 133 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 134 -t ip -q 135 136 tc_check_packets "dev $swp1 ingress" 101 1 137 check_fail $? "Saw packet without trap rule inserted" 138 139 tc filter add dev $swp1 ingress protocol ip pref 2 handle 102 flower \ 140 $tcflags dst_ip 192.0.2.2 action trap 141 142 $MZ $h1 -c 1 -p 64 -a $h1mac -b $h2mac -A 192.0.2.1 -B 192.0.2.2 \ 143 -t ip -q 144 145 tc_check_packets "dev $swp1 ingress" 102 1 146 check_err $? "Packet was not trapped" 147 148 tc_check_packets "dev $swp1 ingress" 101 1 149 check_err $? "Did not see trapped packet" 150 151 tc filter del dev $swp1 ingress protocol ip pref 3 handle 103 flower 152 tc filter del dev $swp1 ingress protocol ip pref 2 handle 102 flower 153 tc filter del dev $swp1 ingress protocol ip pref 1 handle 101 flower 154 155 log_test "trap ($tcflags)" 156} 157 158mirred_egress_to_ingress_tcp_test() 159{ 160 mirred_e2i_tf1=$(mktemp) mirred_e2i_tf2=$(mktemp) 161 162 RET=0 163 dd conv=sparse status=none if=/dev/zero bs=1M count=2 of=$mirred_e2i_tf1 164 tc filter add dev $h1 protocol ip pref 100 handle 100 egress flower \ 165 $tcflags ip_proto tcp src_ip 192.0.2.1 dst_ip 192.0.2.2 \ 166 action ct commit nat src addr 192.0.2.2 pipe \ 167 action ct clear pipe \ 168 action ct commit nat dst addr 192.0.2.1 pipe \ 169 action ct clear pipe \ 170 action skbedit ptype host pipe \ 171 action mirred ingress redirect dev $h1 172 tc filter add dev $h1 protocol ip pref 101 handle 101 egress flower \ 173 $tcflags ip_proto icmp \ 174 action mirred ingress redirect dev $h1 175 tc filter add dev $h1 protocol ip pref 102 handle 102 ingress flower \ 176 ip_proto icmp \ 177 action drop 178 179 ip vrf exec v$h1 ncat --recv-only -w10 -l -p 12345 -o $mirred_e2i_tf2 & 180 local rpid=$! 181 ip vrf exec v$h1 ncat -w1 --send-only 192.0.2.2 12345 <$mirred_e2i_tf1 182 wait -n $rpid 183 cmp -s $mirred_e2i_tf1 $mirred_e2i_tf2 184 check_err $? "server output check failed" 185 186 $MZ $h1 -c 10 -p 64 -a $h1mac -b $h1mac -A 192.0.2.1 -B 192.0.2.1 \ 187 -t icmp "ping,id=42,seq=5" -q 188 tc_check_packets "dev $h1 egress" 101 10 189 check_err $? "didn't mirred redirect ICMP" 190 tc_check_packets "dev $h1 ingress" 102 10 191 check_err $? "didn't drop mirred ICMP" 192 local overlimits=$(tc_rule_stats_get ${h1} 101 egress .overlimits) 193 test ${overlimits} = 10 194 check_err $? "wrong overlimits, expected 10 got ${overlimits}" 195 196 tc filter del dev $h1 egress protocol ip pref 100 handle 100 flower 197 tc filter del dev $h1 egress protocol ip pref 101 handle 101 flower 198 tc filter del dev $h1 ingress protocol ip pref 102 handle 102 flower 199 200 rm -f $mirred_e2i_tf1 $mirred_e2i_tf2 201 log_test "mirred_egress_to_ingress_tcp ($tcflags)" 202} 203 204setup_prepare() 205{ 206 h1=${NETIFS[p1]} 207 swp1=${NETIFS[p2]} 208 209 swp2=${NETIFS[p3]} 210 h2=${NETIFS[p4]} 211 212 h1mac=$(mac_get $h1) 213 h2mac=$(mac_get $h2) 214 215 swp1origmac=$(mac_get $swp1) 216 swp2origmac=$(mac_get $swp2) 217 ip link set $swp1 address $h2mac 218 ip link set $swp2 address $h1mac 219 220 vrf_prepare 221 222 h1_create 223 h2_create 224 switch_create 225} 226 227cleanup() 228{ 229 local tf 230 231 pre_cleanup 232 233 switch_destroy 234 h2_destroy 235 h1_destroy 236 237 vrf_cleanup 238 239 ip link set $swp2 address $swp2origmac 240 ip link set $swp1 address $swp1origmac 241 242 for tf in $mirred_e2i_tf1 $mirred_e2i_tf2; do rm -f $tf; done 243} 244 245mirred_egress_redirect_test() 246{ 247 mirred_egress_test "redirect" "ip" "flower" "dst_ip 192.0.2.2" 248} 249 250mirred_egress_mirror_test() 251{ 252 mirred_egress_test "mirror" "ip" "flower" "dst_ip 192.0.2.2" 253} 254 255matchall_mirred_egress_mirror_test() 256{ 257 mirred_egress_test "mirror" "all" "matchall" "" 258} 259 260trap cleanup EXIT 261 262setup_prepare 263setup_wait 264 265tests_run 266 267tc_offload_check 268if [[ $? -ne 0 ]]; then 269 log_info "Could not test offloaded functionality" 270else 271 tcflags="skip_sw" 272 tests_run 273fi 274 275exit $EXIT_STATUS 276