Skip to content

Commit f724099

Browse files
idoschPaolo Abeni
authored andcommitted
selftests: traceroute: Add VRF tests
Create versions of the existing test cases where the routers generating the ICMP error messages are using VRFs. Check that the source IPs of these messages do not change in the presence of VRFs. IPv6 always behaved correctly, but IPv4 fails when reverting "ipv4: icmp: Fix source IP derivation in presence of VRFs". Without IPv4 change: # ./traceroute.sh TEST: IPv6 traceroute [ OK ] TEST: IPv6 traceroute with VRF [ OK ] TEST: IPv4 traceroute [ OK ] TEST: IPv4 traceroute with VRF [FAIL] traceroute did not return 1.0.3.1 $ echo $? 1 The test fails because the ICMP error message is sent with the VRF device's IP (1.0.4.1): # traceroute -n -s 1.0.1.3 1.0.2.4 traceroute to 1.0.2.4 (1.0.2.4), 30 hops max, 60 byte packets 1 1.0.4.1 0.165 ms 0.110 ms 0.103 ms 2 1.0.2.4 0.098 ms 0.085 ms 0.078 ms # traceroute -n -s 1.0.3.3 1.0.2.4 traceroute to 1.0.2.4 (1.0.2.4), 30 hops max, 60 byte packets 1 1.0.4.1 0.201 ms 0.138 ms 0.129 ms 2 1.0.2.4 0.123 ms 0.105 ms 0.098 ms With IPv4 change: # ./traceroute.sh TEST: IPv6 traceroute [ OK ] TEST: IPv6 traceroute with VRF [ OK ] TEST: IPv4 traceroute [ OK ] TEST: IPv4 traceroute with VRF [ OK ] $ echo $? 0 Reviewed-by: Petr Machata <[email protected]> Reviewed-by: David Ahern <[email protected]> Signed-off-by: Ido Schimmel <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
1 parent 2e64281 commit f724099

File tree

1 file changed

+178
-0
lines changed

1 file changed

+178
-0
lines changed

tools/testing/selftests/net/traceroute.sh

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,110 @@ run_traceroute6()
193193
cleanup_traceroute6
194194
}
195195

196+
################################################################################
197+
# traceroute6 with VRF test
198+
#
199+
# Verify that in this scenario
200+
#
201+
# ------------------------ N2
202+
# | |
203+
# ------ ------ N3 ----
204+
# | R1 | | R2 |------|H2|
205+
# ------ ------ ----
206+
# | |
207+
# ------------------------ N1
208+
# |
209+
# ----
210+
# |H1|
211+
# ----
212+
#
213+
# Where H1's default route goes through R1 and R1's default route goes through
214+
# R2 over N2, traceroute6 from H1 to H2 reports R2's address on N2 and not N1.
215+
# The interfaces connecting R2 to the different subnets are membmer in a VRF
216+
# and the intention is to check that traceroute6 does not report the VRF's
217+
# address.
218+
#
219+
# Addresses are assigned as follows:
220+
#
221+
# N1: 2000:101::/64
222+
# N2: 2000:102::/64
223+
# N3: 2000:103::/64
224+
#
225+
# R1's host part of address: 1
226+
# R2's host part of address: 2
227+
# H1's host part of address: 3
228+
# H2's host part of address: 4
229+
#
230+
# For example:
231+
# the IPv6 address of R1's interface on N2 is 2000:102::1/64
232+
233+
cleanup_traceroute6_vrf()
234+
{
235+
cleanup_all_ns
236+
}
237+
238+
setup_traceroute6_vrf()
239+
{
240+
# Start clean
241+
cleanup_traceroute6_vrf
242+
243+
setup_ns h1 h2 r1 r2
244+
create_ns "$h1"
245+
create_ns "$h2"
246+
create_ns "$r1"
247+
create_ns "$r2"
248+
249+
ip -n "$r2" link add name vrf100 up type vrf table 100
250+
ip -n "$r2" addr add 2001:db8:100::1/64 dev vrf100
251+
252+
# Setup N3
253+
connect_ns "$r2" eth3 - 2000:103::2/64 "$h2" eth3 - 2000:103::4/64
254+
255+
ip -n "$r2" link set dev eth3 master vrf100
256+
257+
ip -n "$h2" route add default via 2000:103::2
258+
259+
# Setup N2
260+
connect_ns "$r1" eth2 - 2000:102::1/64 "$r2" eth2 - 2000:102::2/64
261+
262+
ip -n "$r1" route add default via 2000:102::2
263+
264+
ip -n "$r2" link set dev eth2 master vrf100
265+
266+
# Setup N1. host-1 and router-2 connect to a bridge in router-1.
267+
ip -n "$r1" link add name br100 up type bridge
268+
ip -n "$r1" addr add 2000:101::1/64 dev br100
269+
270+
connect_ns "$h1" eth0 - 2000:101::3/64 "$r1" eth0 - -
271+
272+
ip -n "$h1" route add default via 2000:101::1
273+
274+
ip -n "$r1" link set dev eth0 master br100
275+
276+
connect_ns "$r2" eth1 - 2000:101::2/64 "$r1" eth1 - -
277+
278+
ip -n "$r2" link set dev eth1 master vrf100
279+
280+
ip -n "$r1" link set dev eth1 master br100
281+
282+
# Prime the network
283+
ip netns exec "$h1" ping6 -c5 2000:103::4 >/dev/null 2>&1
284+
}
285+
286+
run_traceroute6_vrf()
287+
{
288+
setup_traceroute6_vrf
289+
290+
RET=0
291+
292+
# traceroute6 host-2 from host-1 (expects 2000:102::2)
293+
run_cmd "$h1" "traceroute6 2000:103::4 | grep 2000:102::2"
294+
check_err $? "traceroute6 did not return 2000:102::2"
295+
log_test "IPv6 traceroute with VRF"
296+
297+
cleanup_traceroute6_vrf
298+
}
299+
196300
################################################################################
197301
# traceroute test
198302
#
@@ -261,13 +365,87 @@ run_traceroute()
261365
cleanup_traceroute
262366
}
263367

368+
################################################################################
369+
# traceroute with VRF test
370+
#
371+
# Verify that traceroute from H1 to H2 shows 1.0.3.1 and 1.0.1.1 when
372+
# traceroute uses 1.0.3.3 and 1.0.1.3 as the source IP, respectively. The
373+
# intention is to check that the kernel does not choose an IP assigned to the
374+
# VRF device, but rather an address from the VRF port (eth1) that received the
375+
# packet that generates the ICMP error message.
376+
#
377+
# 1.0.4.1/24 (vrf100)
378+
# 1.0.3.3/24 1.0.3.1/24
379+
# ---- 1.0.1.3/24 1.0.1.1/24 ---- 1.0.2.1/24 1.0.2.4/24 ----
380+
# |H1|--------------------------|R1|--------------------------|H2|
381+
# ---- N1 ---- N2 ----
382+
383+
cleanup_traceroute_vrf()
384+
{
385+
cleanup_all_ns
386+
}
387+
388+
setup_traceroute_vrf()
389+
{
390+
# Start clean
391+
cleanup_traceroute_vrf
392+
393+
setup_ns h1 h2 router
394+
create_ns "$h1"
395+
create_ns "$h2"
396+
create_ns "$router"
397+
398+
ip -n "$router" link add name vrf100 up type vrf table 100
399+
ip -n "$router" addr add 1.0.4.1/24 dev vrf100
400+
401+
connect_ns "$h1" eth0 1.0.1.3/24 - \
402+
"$router" eth1 1.0.1.1/24 -
403+
404+
ip -n "$h1" addr add 1.0.3.3/24 dev eth0
405+
ip -n "$h1" route add default via 1.0.1.1
406+
407+
ip -n "$router" link set dev eth1 master vrf100
408+
ip -n "$router" addr add 1.0.3.1/24 dev eth1
409+
ip netns exec "$router" sysctl -qw \
410+
net.ipv4.icmp_errors_use_inbound_ifaddr=1
411+
412+
connect_ns "$h2" eth0 1.0.2.4/24 - \
413+
"$router" eth2 1.0.2.1/24 -
414+
415+
ip -n "$h2" route add default via 1.0.2.1
416+
417+
ip -n "$router" link set dev eth2 master vrf100
418+
419+
# Prime the network
420+
ip netns exec "$h1" ping -c5 1.0.2.4 >/dev/null 2>&1
421+
}
422+
423+
run_traceroute_vrf()
424+
{
425+
setup_traceroute_vrf
426+
427+
RET=0
428+
429+
# traceroute host-2 from host-1. Expect a source IP that is on the same
430+
# subnet as destination IP of the ICMP error message.
431+
run_cmd "$h1" "traceroute -s 1.0.1.3 1.0.2.4 | grep 1.0.1.1"
432+
check_err $? "traceroute did not return 1.0.1.1"
433+
run_cmd "$h1" "traceroute -s 1.0.3.3 1.0.2.4 | grep 1.0.3.1"
434+
check_err $? "traceroute did not return 1.0.3.1"
435+
log_test "IPv4 traceroute with VRF"
436+
437+
cleanup_traceroute_vrf
438+
}
439+
264440
################################################################################
265441
# Run tests
266442

267443
run_tests()
268444
{
269445
run_traceroute6
446+
run_traceroute6_vrf
270447
run_traceroute
448+
run_traceroute_vrf
271449
}
272450

273451
################################################################################

0 commit comments

Comments
 (0)