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