xref: /linux/tools/testing/selftests/net/srv6_iptunnel_cache.sh (revision a55f7f5f29b32c2c53cc291899cf9b0c25a07f7c)
1*32dfd742SAndrea Mayer#!/bin/bash
2*32dfd742SAndrea Mayer# SPDX-License-Identifier: GPL-2.0
3*32dfd742SAndrea Mayer#
4*32dfd742SAndrea Mayer# author: Andrea Mayer <andrea.mayer@uniroma2.it>
5*32dfd742SAndrea Mayer
6*32dfd742SAndrea Mayer# This test verifies that the seg6 lwtunnel does not share the dst_cache
7*32dfd742SAndrea Mayer# between the input (forwarding) and output (locally generated) paths.
8*32dfd742SAndrea Mayer#
9*32dfd742SAndrea Mayer# A shared dst_cache allows a forwarded packet to populate the cache and a
10*32dfd742SAndrea Mayer# subsequent locally generated packet to silently reuse that entry, bypassing
11*32dfd742SAndrea Mayer# its own route lookup. To expose this, the SID is made reachable only for
12*32dfd742SAndrea Mayer# forwarded traffic (via an ip rule matching iif) and blackholed for everything
13*32dfd742SAndrea Mayer# else. A local ping on ns_router must always hit the blackhole;
14*32dfd742SAndrea Mayer# if it succeeds after a forwarded packet has populated the
15*32dfd742SAndrea Mayer# cache, the bug is confirmed.
16*32dfd742SAndrea Mayer#
17*32dfd742SAndrea Mayer# Both forwarded and local packets are pinned to the same CPU with taskset,
18*32dfd742SAndrea Mayer# since dst_cache is per-cpu.
19*32dfd742SAndrea Mayer#
20*32dfd742SAndrea Mayer#
21*32dfd742SAndrea Mayer# +--------------------+                        +--------------------+
22*32dfd742SAndrea Mayer# |      ns_src        |                        |      ns_dst        |
23*32dfd742SAndrea Mayer# |                    |                        |                    |
24*32dfd742SAndrea Mayer# |  veth-s0           |                        |           veth-d0  |
25*32dfd742SAndrea Mayer# |  fd00::1/64        |                        |        fd01::2/64  |
26*32dfd742SAndrea Mayer# +-------+------------+                        +----------+---------+
27*32dfd742SAndrea Mayer#         |                                                |
28*32dfd742SAndrea Mayer#         |            +--------------------+              |
29*32dfd742SAndrea Mayer#         |            |     ns_router      |              |
30*32dfd742SAndrea Mayer#         |            |                    |              |
31*32dfd742SAndrea Mayer#         +------------+ veth-r0    veth-r1 +--------------+
32*32dfd742SAndrea Mayer#                      | fd00::2    fd01::1 |
33*32dfd742SAndrea Mayer#                      +--------------------+
34*32dfd742SAndrea Mayer#
35*32dfd742SAndrea Mayer#
36*32dfd742SAndrea Mayer# ns_router: encap (main table)
37*32dfd742SAndrea Mayer# +---------+---------------------------------------+
38*32dfd742SAndrea Mayer# | dst     | action                                |
39*32dfd742SAndrea Mayer# +---------+---------------------------------------+
40*32dfd742SAndrea Mayer# | cafe::1 | encap seg6 mode encap segs fc00::100  |
41*32dfd742SAndrea Mayer# +---------+---------------------------------------+
42*32dfd742SAndrea Mayer#
43*32dfd742SAndrea Mayer# ns_router: post-encap SID resolution
44*32dfd742SAndrea Mayer# +-------+------------+----------------------------+
45*32dfd742SAndrea Mayer# | table | dst        | action                     |
46*32dfd742SAndrea Mayer# +-------+------------+----------------------------+
47*32dfd742SAndrea Mayer# | 100   | fc00::100  | via fd01::2 dev veth-r1    |
48*32dfd742SAndrea Mayer# +-------+------------+----------------------------+
49*32dfd742SAndrea Mayer# | main  | fc00::100  | blackhole                  |
50*32dfd742SAndrea Mayer# +-------+------------+----------------------------+
51*32dfd742SAndrea Mayer#
52*32dfd742SAndrea Mayer# ns_router: ip rule
53*32dfd742SAndrea Mayer# +------------------+------------------------------+
54*32dfd742SAndrea Mayer# | match            | action                       |
55*32dfd742SAndrea Mayer# +------------------+------------------------------+
56*32dfd742SAndrea Mayer# | iif veth-r0      | lookup 100                   |
57*32dfd742SAndrea Mayer# +------------------+------------------------------+
58*32dfd742SAndrea Mayer#
59*32dfd742SAndrea Mayer# ns_dst: SRv6 decap (main table)
60*32dfd742SAndrea Mayer# +--------------+----------------------------------+
61*32dfd742SAndrea Mayer# | SID          | action                           |
62*32dfd742SAndrea Mayer# +--------------+----------------------------------+
63*32dfd742SAndrea Mayer# | fc00::100    | End.DT6 table 255 (local)        |
64*32dfd742SAndrea Mayer# +--------------+----------------------------------+
65*32dfd742SAndrea Mayer
66*32dfd742SAndrea Mayersource lib.sh
67*32dfd742SAndrea Mayer
68*32dfd742SAndrea Mayerreadonly SID="fc00::100"
69*32dfd742SAndrea Mayerreadonly DEST="cafe::1"
70*32dfd742SAndrea Mayer
71*32dfd742SAndrea Mayerreadonly SRC_MAC="02:00:00:00:00:01"
72*32dfd742SAndrea Mayerreadonly RTR_R0_MAC="02:00:00:00:00:02"
73*32dfd742SAndrea Mayerreadonly RTR_R1_MAC="02:00:00:00:00:03"
74*32dfd742SAndrea Mayerreadonly DST_MAC="02:00:00:00:00:04"
75*32dfd742SAndrea Mayer
76*32dfd742SAndrea Mayercleanup()
77*32dfd742SAndrea Mayer{
78*32dfd742SAndrea Mayer	cleanup_ns "${NS_SRC}" "${NS_RTR}" "${NS_DST}"
79*32dfd742SAndrea Mayer}
80*32dfd742SAndrea Mayer
81*32dfd742SAndrea Mayercheck_prerequisites()
82*32dfd742SAndrea Mayer{
83*32dfd742SAndrea Mayer	if ! command -v ip &>/dev/null; then
84*32dfd742SAndrea Mayer		echo "SKIP: ip tool not found"
85*32dfd742SAndrea Mayer		exit "${ksft_skip}"
86*32dfd742SAndrea Mayer	fi
87*32dfd742SAndrea Mayer
88*32dfd742SAndrea Mayer	if ! command -v ping &>/dev/null; then
89*32dfd742SAndrea Mayer		echo "SKIP: ping not found"
90*32dfd742SAndrea Mayer		exit "${ksft_skip}"
91*32dfd742SAndrea Mayer	fi
92*32dfd742SAndrea Mayer
93*32dfd742SAndrea Mayer	if ! command -v sysctl &>/dev/null; then
94*32dfd742SAndrea Mayer		echo "SKIP: sysctl not found"
95*32dfd742SAndrea Mayer		exit "${ksft_skip}"
96*32dfd742SAndrea Mayer	fi
97*32dfd742SAndrea Mayer
98*32dfd742SAndrea Mayer	if ! command -v taskset &>/dev/null; then
99*32dfd742SAndrea Mayer		echo "SKIP: taskset not found"
100*32dfd742SAndrea Mayer		exit "${ksft_skip}"
101*32dfd742SAndrea Mayer	fi
102*32dfd742SAndrea Mayer}
103*32dfd742SAndrea Mayer
104*32dfd742SAndrea Mayersetup()
105*32dfd742SAndrea Mayer{
106*32dfd742SAndrea Mayer	setup_ns NS_SRC NS_RTR NS_DST
107*32dfd742SAndrea Mayer
108*32dfd742SAndrea Mayer	ip link add veth-s0 netns "${NS_SRC}" type veth \
109*32dfd742SAndrea Mayer		peer name veth-r0 netns "${NS_RTR}"
110*32dfd742SAndrea Mayer	ip link add veth-r1 netns "${NS_RTR}" type veth \
111*32dfd742SAndrea Mayer		peer name veth-d0 netns "${NS_DST}"
112*32dfd742SAndrea Mayer
113*32dfd742SAndrea Mayer	ip -n "${NS_SRC}" link set veth-s0 address "${SRC_MAC}"
114*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" link set veth-r0 address "${RTR_R0_MAC}"
115*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" link set veth-r1 address "${RTR_R1_MAC}"
116*32dfd742SAndrea Mayer	ip -n "${NS_DST}" link set veth-d0 address "${DST_MAC}"
117*32dfd742SAndrea Mayer
118*32dfd742SAndrea Mayer	# ns_src
119*32dfd742SAndrea Mayer	ip -n "${NS_SRC}" link set veth-s0 up
120*32dfd742SAndrea Mayer	ip -n "${NS_SRC}" addr add fd00::1/64 dev veth-s0 nodad
121*32dfd742SAndrea Mayer	ip -n "${NS_SRC}" -6 route add "${DEST}"/128 via fd00::2
122*32dfd742SAndrea Mayer
123*32dfd742SAndrea Mayer	# ns_router
124*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" link set veth-r0 up
125*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" addr add fd00::2/64 dev veth-r0 nodad
126*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" link set veth-r1 up
127*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" addr add fd01::1/64 dev veth-r1 nodad
128*32dfd742SAndrea Mayer	ip netns exec "${NS_RTR}" sysctl -qw net.ipv6.conf.all.forwarding=1
129*32dfd742SAndrea Mayer
130*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" -6 route add "${DEST}"/128 \
131*32dfd742SAndrea Mayer		encap seg6 mode encap segs "${SID}" dev veth-r0
132*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" -6 route add "${SID}"/128 table 100 \
133*32dfd742SAndrea Mayer		via fd01::2 dev veth-r1
134*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" -6 route add blackhole "${SID}"/128
135*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" -6 rule add iif veth-r0 lookup 100
136*32dfd742SAndrea Mayer
137*32dfd742SAndrea Mayer	# ns_dst
138*32dfd742SAndrea Mayer	ip -n "${NS_DST}" link set veth-d0 up
139*32dfd742SAndrea Mayer	ip -n "${NS_DST}" addr add fd01::2/64 dev veth-d0 nodad
140*32dfd742SAndrea Mayer	ip -n "${NS_DST}" addr add "${DEST}"/128 dev lo nodad
141*32dfd742SAndrea Mayer	ip -n "${NS_DST}" -6 route add "${SID}"/128 \
142*32dfd742SAndrea Mayer		encap seg6local action End.DT6 table 255 dev veth-d0
143*32dfd742SAndrea Mayer	ip -n "${NS_DST}" -6 route add fd00::/64 via fd01::1
144*32dfd742SAndrea Mayer
145*32dfd742SAndrea Mayer	# static neighbors
146*32dfd742SAndrea Mayer	ip -n "${NS_SRC}" -6 neigh add fd00::2 dev veth-s0 \
147*32dfd742SAndrea Mayer		lladdr "${RTR_R0_MAC}" nud permanent
148*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" -6 neigh add fd00::1 dev veth-r0 \
149*32dfd742SAndrea Mayer		lladdr "${SRC_MAC}" nud permanent
150*32dfd742SAndrea Mayer	ip -n "${NS_RTR}" -6 neigh add fd01::2 dev veth-r1 \
151*32dfd742SAndrea Mayer		lladdr "${DST_MAC}" nud permanent
152*32dfd742SAndrea Mayer	ip -n "${NS_DST}" -6 neigh add fd01::1 dev veth-d0 \
153*32dfd742SAndrea Mayer		lladdr "${RTR_R1_MAC}" nud permanent
154*32dfd742SAndrea Mayer}
155*32dfd742SAndrea Mayer
156*32dfd742SAndrea Mayertest_cache_isolation()
157*32dfd742SAndrea Mayer{
158*32dfd742SAndrea Mayer	RET=0
159*32dfd742SAndrea Mayer
160*32dfd742SAndrea Mayer	# local ping with empty cache: must fail (SID is blackholed)
161*32dfd742SAndrea Mayer	if ip netns exec "${NS_RTR}" taskset -c 0 \
162*32dfd742SAndrea Mayer			ping -c 1 -W 2 "${DEST}" &>/dev/null; then
163*32dfd742SAndrea Mayer		echo "SKIP: local ping succeeded, topology broken"
164*32dfd742SAndrea Mayer		exit "${ksft_skip}"
165*32dfd742SAndrea Mayer	fi
166*32dfd742SAndrea Mayer
167*32dfd742SAndrea Mayer	# forward from ns_src to populate the input cache
168*32dfd742SAndrea Mayer	if ! ip netns exec "${NS_SRC}" taskset -c 0 \
169*32dfd742SAndrea Mayer			ping -c 1 -W 2 "${DEST}" &>/dev/null; then
170*32dfd742SAndrea Mayer		echo "SKIP: forwarded ping failed, topology broken"
171*32dfd742SAndrea Mayer		exit "${ksft_skip}"
172*32dfd742SAndrea Mayer	fi
173*32dfd742SAndrea Mayer
174*32dfd742SAndrea Mayer	# local ping again: must still fail; if the output path reuses
175*32dfd742SAndrea Mayer	# the input cache, it bypasses the blackhole and the ping succeeds
176*32dfd742SAndrea Mayer	if ip netns exec "${NS_RTR}" taskset -c 0 \
177*32dfd742SAndrea Mayer			ping -c 1 -W 2 "${DEST}" &>/dev/null; then
178*32dfd742SAndrea Mayer		echo "FAIL: output path used dst cached by input path"
179*32dfd742SAndrea Mayer		RET="${ksft_fail}"
180*32dfd742SAndrea Mayer	else
181*32dfd742SAndrea Mayer		echo "PASS: output path dst_cache is independent"
182*32dfd742SAndrea Mayer	fi
183*32dfd742SAndrea Mayer
184*32dfd742SAndrea Mayer	return "${RET}"
185*32dfd742SAndrea Mayer}
186*32dfd742SAndrea Mayer
187*32dfd742SAndrea Mayerif [ "$(id -u)" -ne 0 ]; then
188*32dfd742SAndrea Mayer	echo "SKIP: Need root privileges"
189*32dfd742SAndrea Mayer	exit "${ksft_skip}"
190*32dfd742SAndrea Mayerfi
191*32dfd742SAndrea Mayer
192*32dfd742SAndrea Mayertrap cleanup EXIT
193*32dfd742SAndrea Mayer
194*32dfd742SAndrea Mayercheck_prerequisites
195*32dfd742SAndrea Mayersetup
196*32dfd742SAndrea Mayertest_cache_isolation
197*32dfd742SAndrea Mayerexit "${RET}"
198