1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# Test tc-police action. 5# 6# +---------------------------------+ 7# | H1 (vrf) | 8# | + $h1 | 9# | | 192.0.2.1/24 | 10# | | | 11# | | default via 192.0.2.2 | 12# +----|----------------------------+ 13# | 14# +----|----------------------------------------------------------------------+ 15# | SW | | 16# | + $rp1 | 17# | 192.0.2.2/24 | 18# | | 19# | 198.51.100.2/24 203.0.113.2/24 | 20# | + $rp2 + $rp3 | 21# | | | | 22# +----|-----------------------------------------|----------------------------+ 23# | | 24# +----|----------------------------+ +----|----------------------------+ 25# | | default via 198.51.100.2 | | | default via 203.0.113.2 | 26# | | | | | | 27# | | 198.51.100.1/24 | | | 203.0.113.1/24 | 28# | + $h2 | | + $h3 | 29# | H2 (vrf) | | H3 (vrf) | 30# +---------------------------------+ +---------------------------------+ 31 32ALL_TESTS=" 33 police_rx_test 34 police_tx_test 35 police_shared_test 36 police_rx_mirror_test 37 police_tx_mirror_test 38 police_pps_rx_test 39 police_pps_tx_test 40 police_mtu_rx_test 41 police_mtu_tx_test 42" 43NUM_NETIFS=6 44source tc_common.sh 45source lib.sh 46 47h1_create() 48{ 49 simple_if_init $h1 192.0.2.1/24 50 51 ip -4 route add default vrf v$h1 nexthop via 192.0.2.2 52} 53 54h1_destroy() 55{ 56 ip -4 route del default vrf v$h1 nexthop via 192.0.2.2 57 58 simple_if_fini $h1 192.0.2.1/24 59} 60 61h2_create() 62{ 63 simple_if_init $h2 198.51.100.1/24 64 65 ip -4 route add default vrf v$h2 nexthop via 198.51.100.2 66 67 tc qdisc add dev $h2 clsact 68} 69 70h2_destroy() 71{ 72 tc qdisc del dev $h2 clsact 73 74 ip -4 route del default vrf v$h2 nexthop via 198.51.100.2 75 76 simple_if_fini $h2 198.51.100.1/24 77} 78 79h3_create() 80{ 81 simple_if_init $h3 203.0.113.1/24 82 83 ip -4 route add default vrf v$h3 nexthop via 203.0.113.2 84 85 tc qdisc add dev $h3 clsact 86} 87 88h3_destroy() 89{ 90 tc qdisc del dev $h3 clsact 91 92 ip -4 route del default vrf v$h3 nexthop via 203.0.113.2 93 94 simple_if_fini $h3 203.0.113.1/24 95} 96 97router_create() 98{ 99 ip link set dev $rp1 up 100 ip link set dev $rp2 up 101 ip link set dev $rp3 up 102 103 __addr_add_del $rp1 add 192.0.2.2/24 104 __addr_add_del $rp2 add 198.51.100.2/24 105 __addr_add_del $rp3 add 203.0.113.2/24 106 107 tc qdisc add dev $rp1 clsact 108 tc qdisc add dev $rp2 clsact 109} 110 111router_destroy() 112{ 113 tc qdisc del dev $rp2 clsact 114 tc qdisc del dev $rp1 clsact 115 116 __addr_add_del $rp3 del 203.0.113.2/24 117 __addr_add_del $rp2 del 198.51.100.2/24 118 __addr_add_del $rp1 del 192.0.2.2/24 119 120 ip link set dev $rp3 down 121 ip link set dev $rp2 down 122 ip link set dev $rp1 down 123} 124 125police_common_test() 126{ 127 local test_name=$1; shift 128 129 RET=0 130 131 # Rule to measure bandwidth on ingress of $h2 132 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 133 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 134 action drop 135 136 mausezahn $h1 -a own -b $(mac_get $rp1) -A 192.0.2.1 -B 198.51.100.1 \ 137 -t udp sp=12345,dp=54321 -p 1000 -c 0 -q & 138 139 local t0=$(tc_rule_stats_get $h2 1 ingress .bytes) 140 sleep 10 141 local t1=$(tc_rule_stats_get $h2 1 ingress .bytes) 142 143 local er=$((10 * 1000 * 1000)) 144 local nr=$(rate $t0 $t1 10) 145 local nr_pct=$((100 * (nr - er) / er)) 146 ((-10 <= nr_pct && nr_pct <= 10)) 147 check_err $? "Expected rate $(humanize $er), got $(humanize $nr), which is $nr_pct% off. Required accuracy is +-10%." 148 149 log_test "$test_name" 150 151 kill_process %% 152 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 153} 154 155police_rx_test() 156{ 157 # Rule to police traffic destined to $h2 on ingress of $rp1 158 tc filter add dev $rp1 ingress protocol ip pref 1 handle 101 flower \ 159 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 160 action police rate 10mbit burst 16k conform-exceed drop/ok 161 162 police_common_test "police on rx" 163 164 tc filter del dev $rp1 ingress protocol ip pref 1 handle 101 flower 165} 166 167police_tx_test() 168{ 169 # Rule to police traffic destined to $h2 on egress of $rp2 170 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 flower \ 171 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 172 action police rate 10mbit burst 16k conform-exceed drop/ok 173 174 police_common_test "police on tx" 175 176 tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower 177} 178 179police_shared_common_test() 180{ 181 local dport=$1; shift 182 local test_name=$1; shift 183 184 RET=0 185 186 mausezahn $h1 -a own -b $(mac_get $rp1) -A 192.0.2.1 -B 198.51.100.1 \ 187 -t udp sp=12345,dp=$dport -p 1000 -c 0 -q & 188 189 local t0=$(tc_rule_stats_get $h2 1 ingress .bytes) 190 sleep 10 191 local t1=$(tc_rule_stats_get $h2 1 ingress .bytes) 192 193 local er=$((10 * 1000 * 1000)) 194 local nr=$(rate $t0 $t1 10) 195 local nr_pct=$((100 * (nr - er) / er)) 196 ((-10 <= nr_pct && nr_pct <= 10)) 197 check_err $? "Expected rate $(humanize $er), got $(humanize $nr), which is $nr_pct% off. Required accuracy is +-10%." 198 199 log_test "$test_name" 200 201 kill_process %% 202} 203 204police_shared_test() 205{ 206 # Rule to measure bandwidth on ingress of $h2 207 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 208 dst_ip 198.51.100.1 ip_proto udp src_port 12345 \ 209 action drop 210 211 # Rule to police traffic destined to $h2 on ingress of $rp1 212 tc filter add dev $rp1 ingress protocol ip pref 1 handle 101 flower \ 213 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 214 action police rate 10mbit burst 16k conform-exceed drop/ok \ 215 index 10 216 217 # Rule to police a different flow destined to $h2 on egress of $rp2 218 # using same policer 219 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 flower \ 220 dst_ip 198.51.100.1 ip_proto udp dst_port 22222 \ 221 action police index 10 222 223 police_shared_common_test 54321 "police with shared policer - rx" 224 225 police_shared_common_test 22222 "police with shared policer - tx" 226 227 tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower 228 tc filter del dev $rp1 ingress protocol ip pref 1 handle 101 flower 229 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 230} 231 232police_mirror_common_test() 233{ 234 local pol_if=$1; shift 235 local dir=$1; shift 236 local test_name=$1; shift 237 238 RET=0 239 240 # Rule to measure bandwidth on ingress of $h2 241 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 242 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 243 action drop 244 245 # Rule to measure bandwidth of mirrored traffic on ingress of $h3 246 tc filter add dev $h3 ingress protocol ip pref 1 handle 101 flower \ 247 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 248 action drop 249 250 # Rule to police traffic destined to $h2 and mirror to $h3 251 tc filter add dev $pol_if $dir protocol ip pref 1 handle 101 flower \ 252 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 253 action police rate 10mbit burst 16k conform-exceed drop/pipe \ 254 action mirred egress mirror dev $rp3 255 256 mausezahn $h1 -a own -b $(mac_get $rp1) -A 192.0.2.1 -B 198.51.100.1 \ 257 -t udp sp=12345,dp=54321 -p 1000 -c 0 -q & 258 259 local t0=$(tc_rule_stats_get $h2 1 ingress .bytes) 260 sleep 10 261 local t1=$(tc_rule_stats_get $h2 1 ingress .bytes) 262 263 local er=$((10 * 1000 * 1000)) 264 local nr=$(rate $t0 $t1 10) 265 local nr_pct=$((100 * (nr - er) / er)) 266 ((-10 <= nr_pct && nr_pct <= 10)) 267 check_err $? "Expected rate $(humanize $er), got $(humanize $nr), which is $nr_pct% off. Required accuracy is +-10%." 268 269 local t0=$(tc_rule_stats_get $h3 1 ingress .bytes) 270 sleep 10 271 local t1=$(tc_rule_stats_get $h3 1 ingress .bytes) 272 273 local er=$((10 * 1000 * 1000)) 274 local nr=$(rate $t0 $t1 10) 275 local nr_pct=$((100 * (nr - er) / er)) 276 ((-10 <= nr_pct && nr_pct <= 10)) 277 check_err $? "Expected rate $(humanize $er), got $(humanize $nr), which is $nr_pct% off. Required accuracy is +-10%." 278 279 log_test "$test_name" 280 281 kill_process %% 282 tc filter del dev $pol_if $dir protocol ip pref 1 handle 101 flower 283 tc filter del dev $h3 ingress protocol ip pref 1 handle 101 flower 284 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 285} 286 287police_rx_mirror_test() 288{ 289 police_mirror_common_test $rp1 ingress "police rx and mirror" 290} 291 292police_tx_mirror_test() 293{ 294 police_mirror_common_test $rp2 egress "police tx and mirror" 295} 296 297police_pps_common_test() 298{ 299 local test_name=$1; shift 300 301 RET=0 302 303 # Rule to measure bandwidth on ingress of $h2 304 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 305 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 306 action drop 307 308 mausezahn $h1 -a own -b $(mac_get $rp1) -A 192.0.2.1 -B 198.51.100.1 \ 309 -t udp sp=12345,dp=54321 -p 1000 -c 0 -q & 310 311 local t0=$(tc_rule_stats_get $h2 1 ingress .packets) 312 sleep 10 313 local t1=$(tc_rule_stats_get $h2 1 ingress .packets) 314 315 local er=$((2000)) 316 local nr=$(packets_rate $t0 $t1 10) 317 local nr_pct=$((100 * (nr - er) / er)) 318 ((-10 <= nr_pct && nr_pct <= 10)) 319 check_err $? "Expected rate $(humanize $er), got $(humanize $nr), which is $nr_pct% off. Required accuracy is +-10%." 320 321 log_test "$test_name" 322 323 kill_process %% 324 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 325} 326 327police_pps_rx_test() 328{ 329 # Rule to police traffic destined to $h2 on ingress of $rp1 330 tc filter add dev $rp1 ingress protocol ip pref 1 handle 101 flower \ 331 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 332 action police pkts_rate 2000 pkts_burst 400 conform-exceed drop/ok 333 334 police_pps_common_test "police pps on rx" 335 336 tc filter del dev $rp1 ingress protocol ip pref 1 handle 101 flower 337} 338 339police_pps_tx_test() 340{ 341 # Rule to police traffic destined to $h2 on egress of $rp2 342 tc filter add dev $rp2 egress protocol ip pref 1 handle 101 flower \ 343 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 344 action police pkts_rate 2000 pkts_burst 400 conform-exceed drop/ok 345 346 police_pps_common_test "police pps on tx" 347 348 tc filter del dev $rp2 egress protocol ip pref 1 handle 101 flower 349} 350 351police_mtu_common_test() { 352 RET=0 353 354 local test_name=$1; shift 355 local dev=$1; shift 356 local direction=$1; shift 357 358 tc filter add dev $dev $direction protocol ip pref 1 handle 101 flower \ 359 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 360 action police mtu 1042 conform-exceed drop/ok 361 362 # to count "conform" packets 363 tc filter add dev $h2 ingress protocol ip pref 1 handle 101 flower \ 364 dst_ip 198.51.100.1 ip_proto udp dst_port 54321 \ 365 action drop 366 367 mausezahn $h1 -a own -b $(mac_get $rp1) -A 192.0.2.1 -B 198.51.100.1 \ 368 -t udp sp=12345,dp=54321 -p 1001 -c 10 -q 369 370 mausezahn $h1 -a own -b $(mac_get $rp1) -A 192.0.2.1 -B 198.51.100.1 \ 371 -t udp sp=12345,dp=54321 -p 1000 -c 3 -q 372 373 tc_check_packets "dev $dev $direction" 101 13 374 check_err $? "wrong packet counter" 375 376 # "exceed" packets 377 local overlimits_t0=$(tc_rule_stats_get ${dev} 1 ${direction} .overlimits) 378 test ${overlimits_t0} = 10 379 check_err $? "wrong overlimits, expected 10 got ${overlimits_t0}" 380 381 # "conform" packets 382 tc_check_packets "dev $h2 ingress" 101 3 383 check_err $? "forwarding error" 384 385 tc filter del dev $h2 ingress protocol ip pref 1 handle 101 flower 386 tc filter del dev $dev $direction protocol ip pref 1 handle 101 flower 387 388 log_test "$test_name" 389} 390 391police_mtu_rx_test() 392{ 393 police_mtu_common_test "police mtu (rx)" $rp1 ingress 394} 395 396police_mtu_tx_test() 397{ 398 police_mtu_common_test "police mtu (tx)" $rp2 egress 399} 400 401setup_prepare() 402{ 403 h1=${NETIFS[p1]} 404 rp1=${NETIFS[p2]} 405 406 rp2=${NETIFS[p3]} 407 h2=${NETIFS[p4]} 408 409 rp3=${NETIFS[p5]} 410 h3=${NETIFS[p6]} 411 412 vrf_prepare 413 forwarding_enable 414 415 h1_create 416 h2_create 417 h3_create 418 router_create 419} 420 421cleanup() 422{ 423 pre_cleanup 424 425 router_destroy 426 h3_destroy 427 h2_destroy 428 h1_destroy 429 430 forwarding_restore 431 vrf_cleanup 432} 433 434trap cleanup EXIT 435 436setup_prepare 437setup_wait 438 439tests_run 440 441exit $EXIT_STATUS 442