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