1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# Test that blackhole routes are marked as offloaded and that packets hitting
5# them are dropped by the ASIC and not by the kernel.
6#
7# +---------------------------------+
8# | H1 (vrf)                        |
9# |    + $h1                        |
10# |    | 192.0.2.1/24               |
11# |    | 2001:db8:1::1/64           |
12# |    |                            |
13# |    |  default via 192.0.2.2     |
14# |    |  default via 2001:db8:1::2 |
15# +----|----------------------------+
16#      |
17# +----|----------------------------------------------------------------------+
18# | SW |                                                                      |
19# |    + $rp1                                                                 |
20# |        192.0.2.2/24                                                       |
21# |        2001:db8:1::2/64                                                   |
22# |                                                                           |
23# |        2001:db8:2::2/64                                                   |
24# |        198.51.100.2/24                                                    |
25# |    + $rp2                                                                 |
26# |    |                                                                      |
27# +----|----------------------------------------------------------------------+
28#      |
29# +----|----------------------------+
30# |    |  default via 198.51.100.2  |
31# |    |  default via 2001:db8:2::2 |
32# |    |                            |
33# |    | 2001:db8:2::1/64           |
34# |    | 198.51.100.1/24            |
35# |    + $h2                        |
36# | H2 (vrf)                        |
37# +---------------------------------+
38
39lib_dir=$(dirname $0)/../../../net/forwarding
40
41ALL_TESTS="
42	ping_ipv4
43	ping_ipv6
44	blackhole_ipv4
45	blackhole_ipv6
46"
47NUM_NETIFS=4
48: ${TIMEOUT:=20000} # ms
49source $lib_dir/tc_common.sh
50source $lib_dir/lib.sh
51
52h1_create()
53{
54	simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
55
56	ip -4 route add default vrf v$h1 nexthop via 192.0.2.2
57	ip -6 route add default vrf v$h1 nexthop via 2001:db8:1::2
58}
59
60h1_destroy()
61{
62	ip -6 route del default vrf v$h1 nexthop via 2001:db8:1::2
63	ip -4 route del default vrf v$h1 nexthop via 192.0.2.2
64
65	simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
66}
67
68h2_create()
69{
70	simple_if_init $h2 198.51.100.1/24 2001:db8:2::1/64
71
72	ip -4 route add default vrf v$h2 nexthop via 198.51.100.2
73	ip -6 route add default vrf v$h2 nexthop via 2001:db8:2::2
74}
75
76h2_destroy()
77{
78	ip -6 route del default vrf v$h2 nexthop via 2001:db8:2::2
79	ip -4 route del default vrf v$h2 nexthop via 198.51.100.2
80
81	simple_if_fini $h2 198.51.100.1/24 2001:db8:2::1/64
82}
83
84router_create()
85{
86	ip link set dev $rp1 up
87	ip link set dev $rp2 up
88
89	tc qdisc add dev $rp1 clsact
90
91	__addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
92	__addr_add_del $rp2 add 198.51.100.2/24 2001:db8:2::2/64
93}
94
95router_destroy()
96{
97	__addr_add_del $rp2 del 198.51.100.2/24 2001:db8:2::2/64
98	__addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64
99
100	tc qdisc del dev $rp1 clsact
101
102	ip link set dev $rp2 down
103	ip link set dev $rp1 down
104}
105
106ping_ipv4()
107{
108	ping_test $h1 198.51.100.1 ": h1->h2"
109}
110
111ping_ipv6()
112{
113	ping6_test $h1 2001:db8:2::1 ": h1->h2"
114}
115
116blackhole_ipv4()
117{
118	# Transmit packets from H1 to H2 and make sure they are dropped by the
119	# ASIC and not by the kernel
120	RET=0
121
122	ip -4 route add blackhole 198.51.100.0/30
123	tc filter add dev $rp1 ingress protocol ip pref 1 handle 101 flower \
124		skip_hw dst_ip 198.51.100.1 src_ip 192.0.2.1 ip_proto icmp \
125		action pass
126
127	busywait "$TIMEOUT" wait_for_offload ip -4 route show 198.51.100.0/30
128	check_err $? "route not marked as offloaded when should"
129
130	ping_do $h1 198.51.100.1
131	check_fail $? "ping passed when should not"
132
133	tc_check_packets "dev $rp1 ingress" 101 0
134	check_err $? "packets trapped and not dropped by ASIC"
135
136	log_test "IPv4 blackhole route"
137
138	tc filter del dev $rp1 ingress protocol ip pref 1 handle 101 flower
139	ip -4 route del blackhole 198.51.100.0/30
140}
141
142blackhole_ipv6()
143{
144	RET=0
145
146	ip -6 route add blackhole 2001:db8:2::/120
147	tc filter add dev $rp1 ingress protocol ipv6 pref 1 handle 101 flower \
148		skip_hw dst_ip 2001:db8:2::1 src_ip 2001:db8:1::1 \
149		ip_proto icmpv6 action pass
150
151	busywait "$TIMEOUT" wait_for_offload ip -6 route show 2001:db8:2::/120
152	check_err $? "route not marked as offloaded when should"
153
154	ping6_do $h1 2001:db8:2::1
155	check_fail $? "ping passed when should not"
156
157	tc_check_packets "dev $rp1 ingress" 101 0
158	check_err $? "packets trapped and not dropped by ASIC"
159
160	log_test "IPv6 blackhole route"
161
162	tc filter del dev $rp1 ingress protocol ipv6 pref 1 handle 101 flower
163	ip -6 route del blackhole 2001:db8:2::/120
164}
165
166setup_prepare()
167{
168	h1=${NETIFS[p1]}
169	rp1=${NETIFS[p2]}
170
171	rp2=${NETIFS[p3]}
172	h2=${NETIFS[p4]}
173
174	vrf_prepare
175	forwarding_enable
176
177	h1_create
178	h2_create
179	router_create
180}
181
182cleanup()
183{
184	pre_cleanup
185
186	router_destroy
187	h2_destroy
188	h1_destroy
189
190	forwarding_restore
191	vrf_cleanup
192}
193
194trap cleanup EXIT
195
196setup_prepare
197setup_wait
198
199tests_run
200
201exit $EXIT_STATUS
202