12de03b45SFlorian Westphal#!/bin/bash 22de03b45SFlorian Westphal# SPDX-License-Identifier: GPL-2.0 32de03b45SFlorian Westphal# 42de03b45SFlorian Westphal# This tests basic flowtable functionality. 5dd08734dSFabian Frederick# Creates following default topology: 62de03b45SFlorian Westphal# 72de03b45SFlorian Westphal# Originator (MTU 9000) <-Router1-> MTU 1500 <-Router2-> Responder (MTU 2000) 82de03b45SFlorian Westphal# Router1 is the one doing flow offloading, Router2 has no special 92de03b45SFlorian Westphal# purpose other than having a link that is smaller than either Originator 102de03b45SFlorian Westphal# and responder, i.e. TCPMSS announced values are too large and will still 112de03b45SFlorian Westphal# result in fragmentation and/or PMTU discovery. 12dd08734dSFabian Frederick# 13dd08734dSFabian Frederick# You can check with different Orgininator/Link/Responder MTU eg: 14da2f849eSFabian Frederick# nft_flowtable.sh -o8000 -l1500 -r2000 15dd08734dSFabian Frederick# 16dd08734dSFabian Frederick 17b71b7bfeSFlorian Westphalsfx=$(mktemp -u "XXXXXXXX") 18b71b7bfeSFlorian Westphalns1="ns1-$sfx" 19b71b7bfeSFlorian Westphalns2="ns2-$sfx" 20b71b7bfeSFlorian Westphalnsr1="nsr1-$sfx" 21b71b7bfeSFlorian Westphalnsr2="nsr2-$sfx" 222de03b45SFlorian Westphal 232de03b45SFlorian Westphal# Kselftest framework requirement - SKIP code is 4. 242de03b45SFlorian Westphalksft_skip=4 252de03b45SFlorian Westphalret=0 262de03b45SFlorian Westphal 27c8550b90SFlorian Westphalnsin="" 282de03b45SFlorian Westphalns1out="" 292de03b45SFlorian Westphalns2out="" 302de03b45SFlorian Westphal 312de03b45SFlorian Westphallog_netns=$(sysctl -n net.netfilter.nf_log_all_netns) 322de03b45SFlorian Westphal 336d006a4eSFabian Frederickchecktool (){ 342f4bba4eSFabian Frederick if ! $1 > /dev/null 2>&1; then 356d006a4eSFabian Frederick echo "SKIP: Could not $2" 362de03b45SFlorian Westphal exit $ksft_skip 372de03b45SFlorian Westphal fi 386d006a4eSFabian Frederick} 392de03b45SFlorian Westphal 406d006a4eSFabian Frederickchecktool "nft --version" "run test without nft tool" 416d006a4eSFabian Frederickchecktool "ip -Version" "run test without ip tool" 426d006a4eSFabian Frederickchecktool "which nc" "run test without nc (netcat)" 43b71b7bfeSFlorian Westphalchecktool "ip netns add $nsr1" "create net namespace $nsr1" 442de03b45SFlorian Westphal 45b71b7bfeSFlorian Westphalip netns add $ns1 46b71b7bfeSFlorian Westphalip netns add $ns2 47b71b7bfeSFlorian Westphalip netns add $nsr2 482de03b45SFlorian Westphal 492de03b45SFlorian Westphalcleanup() { 50b71b7bfeSFlorian Westphal ip netns del $ns1 51b71b7bfeSFlorian Westphal ip netns del $ns2 52b71b7bfeSFlorian Westphal ip netns del $nsr1 53b71b7bfeSFlorian Westphal ip netns del $nsr2 542de03b45SFlorian Westphal 55c8550b90SFlorian Westphal rm -f "$nsin" "$ns1out" "$ns2out" 562de03b45SFlorian Westphal 572de03b45SFlorian Westphal [ $log_netns -eq 0 ] && sysctl -q net.netfilter.nf_log_all_netns=$log_netns 582de03b45SFlorian Westphal} 592de03b45SFlorian Westphal 602de03b45SFlorian Westphaltrap cleanup EXIT 612de03b45SFlorian Westphal 622de03b45SFlorian Westphalsysctl -q net.netfilter.nf_log_all_netns=1 632de03b45SFlorian Westphal 64b71b7bfeSFlorian Westphalip link add veth0 netns $nsr1 type veth peer name eth0 netns $ns1 65b71b7bfeSFlorian Westphalip link add veth1 netns $nsr1 type veth peer name veth0 netns $nsr2 662de03b45SFlorian Westphal 67b71b7bfeSFlorian Westphalip link add veth1 netns $nsr2 type veth peer name eth0 netns $ns2 682de03b45SFlorian Westphal 692de03b45SFlorian Westphalfor dev in lo veth0 veth1; do 70b71b7bfeSFlorian Westphal ip -net $nsr1 link set $dev up 71b71b7bfeSFlorian Westphal ip -net $nsr2 link set $dev up 722de03b45SFlorian Westphaldone 732de03b45SFlorian Westphal 74b71b7bfeSFlorian Westphalip -net $nsr1 addr add 10.0.1.1/24 dev veth0 75b71b7bfeSFlorian Westphalip -net $nsr1 addr add dead:1::1/64 dev veth0 762de03b45SFlorian Westphal 77b71b7bfeSFlorian Westphalip -net $nsr2 addr add 10.0.2.1/24 dev veth1 78b71b7bfeSFlorian Westphalip -net $nsr2 addr add dead:2::1/64 dev veth1 792de03b45SFlorian Westphal 802de03b45SFlorian Westphal# set different MTUs so we need to push packets coming from ns1 (large MTU) 812de03b45SFlorian Westphal# to ns2 (smaller MTU) to stack either to perform fragmentation (ip_no_pmtu_disc=1), 822de03b45SFlorian Westphal# or to do PTMU discovery (send ICMP error back to originator). 832de03b45SFlorian Westphal# ns2 is going via nsr2 with a smaller mtu, so that TCPMSS announced by both peers 842de03b45SFlorian Westphal# is NOT the lowest link mtu. 852de03b45SFlorian Westphal 86dd08734dSFabian Frederickomtu=9000 87dd08734dSFabian Fredericklmtu=1500 88dd08734dSFabian Frederickrmtu=2000 892de03b45SFlorian Westphal 9067afbda6SFabian Frederickusage(){ 9167afbda6SFabian Frederick echo "nft_flowtable.sh [OPTIONS]" 9267afbda6SFabian Frederick echo 9367afbda6SFabian Frederick echo "MTU options" 9467afbda6SFabian Frederick echo " -o originator" 9567afbda6SFabian Frederick echo " -l link" 9667afbda6SFabian Frederick echo " -r responder" 9767afbda6SFabian Frederick exit 1 9867afbda6SFabian Frederick} 9967afbda6SFabian Frederick 100dd08734dSFabian Frederickwhile getopts "o:l:r:" o 101dd08734dSFabian Frederickdo 102dd08734dSFabian Frederick case $o in 103dd08734dSFabian Frederick o) omtu=$OPTARG;; 104dd08734dSFabian Frederick l) lmtu=$OPTARG;; 105dd08734dSFabian Frederick r) rmtu=$OPTARG;; 10667afbda6SFabian Frederick *) usage;; 107dd08734dSFabian Frederick esac 108dd08734dSFabian Frederickdone 109dd08734dSFabian Frederick 110b71b7bfeSFlorian Westphalif ! ip -net $nsr1 link set veth0 mtu $omtu; then 111a7bf670eSFabian Frederick exit 1 112a7bf670eSFabian Frederickfi 113a7bf670eSFabian Frederick 114b71b7bfeSFlorian Westphalip -net $ns1 link set eth0 mtu $omtu 115dd08734dSFabian Frederick 116b71b7bfeSFlorian Westphalif ! ip -net $nsr2 link set veth1 mtu $rmtu; then 117a7bf670eSFabian Frederick exit 1 118a7bf670eSFabian Frederickfi 119a7bf670eSFabian Frederick 120b71b7bfeSFlorian Westphalip -net $ns2 link set eth0 mtu $rmtu 1212de03b45SFlorian Westphal 1222de03b45SFlorian Westphal# transfer-net between nsr1 and nsr2. 1232de03b45SFlorian Westphal# these addresses are not used for connections. 124b71b7bfeSFlorian Westphalip -net $nsr1 addr add 192.168.10.1/24 dev veth1 125b71b7bfeSFlorian Westphalip -net $nsr1 addr add fee1:2::1/64 dev veth1 1262de03b45SFlorian Westphal 127b71b7bfeSFlorian Westphalip -net $nsr2 addr add 192.168.10.2/24 dev veth0 128b71b7bfeSFlorian Westphalip -net $nsr2 addr add fee1:2::2/64 dev veth0 1292de03b45SFlorian Westphal 130b71b7bfeSFlorian Westphalfor i in 0 1; do 131b71b7bfeSFlorian Westphal ip netns exec $nsr1 sysctl net.ipv4.conf.veth$i.forwarding=1 > /dev/null 132b71b7bfeSFlorian Westphal ip netns exec $nsr2 sysctl net.ipv4.conf.veth$i.forwarding=1 > /dev/null 133b71b7bfeSFlorian Westphaldone 1342de03b45SFlorian Westphal 135b71b7bfeSFlorian Westphalfor ns in $ns1 $ns2;do 136b71b7bfeSFlorian Westphal ip -net $ns link set lo up 137b71b7bfeSFlorian Westphal ip -net $ns link set eth0 up 138b71b7bfeSFlorian Westphal 139b71b7bfeSFlorian Westphal if ! ip netns exec $ns sysctl net.ipv4.tcp_no_metrics_save=1 > /dev/null; then 140a7bf670eSFabian Frederick echo "ERROR: Check Originator/Responder values (problem during address addition)" 141a7bf670eSFabian Frederick exit 1 142a7bf670eSFabian Frederick fi 1432de03b45SFlorian Westphal # don't set ip DF bit for first two tests 144b71b7bfeSFlorian Westphal ip netns exec $ns sysctl net.ipv4.ip_no_pmtu_disc=1 > /dev/null 1452de03b45SFlorian Westphaldone 1462de03b45SFlorian Westphal 147b71b7bfeSFlorian Westphalip -net $ns1 addr add 10.0.1.99/24 dev eth0 148b71b7bfeSFlorian Westphalip -net $ns2 addr add 10.0.2.99/24 dev eth0 149b71b7bfeSFlorian Westphalip -net $ns1 route add default via 10.0.1.1 150b71b7bfeSFlorian Westphalip -net $ns2 route add default via 10.0.2.1 151b71b7bfeSFlorian Westphalip -net $ns1 addr add dead:1::99/64 dev eth0 152b71b7bfeSFlorian Westphalip -net $ns2 addr add dead:2::99/64 dev eth0 153b71b7bfeSFlorian Westphalip -net $ns1 route add default via dead:1::1 154b71b7bfeSFlorian Westphalip -net $ns2 route add default via dead:2::1 1552de03b45SFlorian Westphal 156b71b7bfeSFlorian Westphalip -net $nsr1 route add default via 192.168.10.2 157b71b7bfeSFlorian Westphalip -net $nsr2 route add default via 192.168.10.1 158b71b7bfeSFlorian Westphal 159b71b7bfeSFlorian Westphalip netns exec $nsr1 nft -f - <<EOF 1602de03b45SFlorian Westphaltable inet filter { 1612de03b45SFlorian Westphal flowtable f1 { 1622de03b45SFlorian Westphal hook ingress priority 0 1632de03b45SFlorian Westphal devices = { veth0, veth1 } 1642de03b45SFlorian Westphal } 1652de03b45SFlorian Westphal 166c8550b90SFlorian Westphal counter routed_orig { } 167c8550b90SFlorian Westphal counter routed_repl { } 168c8550b90SFlorian Westphal 1692de03b45SFlorian Westphal chain forward { 1702de03b45SFlorian Westphal type filter hook forward priority 0; policy drop; 1712de03b45SFlorian Westphal 1722de03b45SFlorian Westphal # flow offloaded? Tag ct with mark 1, so we can detect when it fails. 173c8550b90SFlorian Westphal meta oif "veth1" tcp dport 12345 ct mark set 1 flow add @f1 counter name routed_orig accept 1742de03b45SFlorian Westphal 175c8550b90SFlorian Westphal # count packets supposedly offloaded as per direction. 176c8550b90SFlorian Westphal ct mark 1 counter name ct direction map { original : routed_orig, reply : routed_repl } accept 1772de03b45SFlorian Westphal 1782de03b45SFlorian Westphal ct state established,related accept 1792de03b45SFlorian Westphal 1802de03b45SFlorian Westphal meta nfproto ipv4 meta l4proto icmp accept 1812de03b45SFlorian Westphal meta nfproto ipv6 meta l4proto icmpv6 accept 1822de03b45SFlorian Westphal } 1832de03b45SFlorian Westphal} 1842de03b45SFlorian WestphalEOF 1852de03b45SFlorian Westphal 1862de03b45SFlorian Westphalif [ $? -ne 0 ]; then 1872de03b45SFlorian Westphal echo "SKIP: Could not load nft ruleset" 1882de03b45SFlorian Westphal exit $ksft_skip 1892de03b45SFlorian Westphalfi 1902de03b45SFlorian Westphal 191*3acf8f6cSFlorian Westphalip netns exec $ns2 nft -f - <<EOF 192*3acf8f6cSFlorian Westphaltable inet filter { 193*3acf8f6cSFlorian Westphal counter ip4dscp0 { } 194*3acf8f6cSFlorian Westphal counter ip4dscp3 { } 195*3acf8f6cSFlorian Westphal 196*3acf8f6cSFlorian Westphal chain input { 197*3acf8f6cSFlorian Westphal type filter hook input priority 0; policy accept; 198*3acf8f6cSFlorian Westphal meta l4proto tcp goto { 199*3acf8f6cSFlorian Westphal ip dscp cs3 counter name ip4dscp3 accept 200*3acf8f6cSFlorian Westphal ip dscp 0 counter name ip4dscp0 accept 201*3acf8f6cSFlorian Westphal } 202*3acf8f6cSFlorian Westphal } 203*3acf8f6cSFlorian Westphal} 204*3acf8f6cSFlorian WestphalEOF 205*3acf8f6cSFlorian Westphal 206*3acf8f6cSFlorian Westphalif [ $? -ne 0 ]; then 207*3acf8f6cSFlorian Westphal echo "SKIP: Could not load nft ruleset" 208*3acf8f6cSFlorian Westphal exit $ksft_skip 209*3acf8f6cSFlorian Westphalfi 210*3acf8f6cSFlorian Westphal 2112de03b45SFlorian Westphal# test basic connectivity 212b71b7bfeSFlorian Westphalif ! ip netns exec $ns1 ping -c 1 -q 10.0.2.99 > /dev/null; then 213b71b7bfeSFlorian Westphal echo "ERROR: $ns1 cannot reach ns2" 1>&2 2142de03b45SFlorian Westphal exit 1 2152de03b45SFlorian Westphalfi 2162de03b45SFlorian Westphal 217b71b7bfeSFlorian Westphalif ! ip netns exec $ns2 ping -c 1 -q 10.0.1.99 > /dev/null; then 218b71b7bfeSFlorian Westphal echo "ERROR: $ns2 cannot reach $ns1" 1>&2 2192de03b45SFlorian Westphal exit 1 2202de03b45SFlorian Westphalfi 2212de03b45SFlorian Westphal 2222de03b45SFlorian Westphalif [ $ret -eq 0 ];then 223b71b7bfeSFlorian Westphal echo "PASS: netns routing/connectivity: $ns1 can reach $ns2" 2242de03b45SFlorian Westphalfi 2252de03b45SFlorian Westphal 226c8550b90SFlorian Westphalnsin=$(mktemp) 2272de03b45SFlorian Westphalns1out=$(mktemp) 2282de03b45SFlorian Westphalns2out=$(mktemp) 2292de03b45SFlorian Westphal 2302de03b45SFlorian Westphalmake_file() 2312de03b45SFlorian Westphal{ 2322de03b45SFlorian Westphal name=$1 2332de03b45SFlorian Westphal 234c8550b90SFlorian Westphal SIZE=$((RANDOM % (1024 * 128))) 235c8550b90SFlorian Westphal SIZE=$((SIZE + (1024 * 8))) 2362de03b45SFlorian Westphal TSIZE=$((SIZE * 1024)) 2372de03b45SFlorian Westphal 2382de03b45SFlorian Westphal dd if=/dev/urandom of="$name" bs=1024 count=$SIZE 2> /dev/null 2392de03b45SFlorian Westphal 2402de03b45SFlorian Westphal SIZE=$((RANDOM % 1024)) 2412de03b45SFlorian Westphal SIZE=$((SIZE + 128)) 2422de03b45SFlorian Westphal TSIZE=$((TSIZE + SIZE)) 2432de03b45SFlorian Westphal dd if=/dev/urandom conf=notrunc of="$name" bs=1 count=$SIZE 2> /dev/null 2442de03b45SFlorian Westphal} 2452de03b45SFlorian Westphal 246c8550b90SFlorian Westphalcheck_counters() 247c8550b90SFlorian Westphal{ 248c8550b90SFlorian Westphal local what=$1 249c8550b90SFlorian Westphal local ok=1 250c8550b90SFlorian Westphal 251c8550b90SFlorian Westphal local orig=$(ip netns exec $nsr1 nft reset counter inet filter routed_orig | grep packets) 252c8550b90SFlorian Westphal local repl=$(ip netns exec $nsr1 nft reset counter inet filter routed_repl | grep packets) 253c8550b90SFlorian Westphal 254c8550b90SFlorian Westphal local orig_cnt=${orig#*bytes} 255c8550b90SFlorian Westphal local repl_cnt=${repl#*bytes} 256c8550b90SFlorian Westphal 257c8550b90SFlorian Westphal local fs=$(du -sb $nsin) 258c8550b90SFlorian Westphal local max_orig=${fs%%/*} 259c8550b90SFlorian Westphal local max_repl=$((max_orig/4)) 260c8550b90SFlorian Westphal 261c8550b90SFlorian Westphal if [ $orig_cnt -gt $max_orig ];then 262c8550b90SFlorian Westphal echo "FAIL: $what: original counter $orig_cnt exceeds expected value $max_orig" 1>&2 263c8550b90SFlorian Westphal ret=1 264c8550b90SFlorian Westphal ok=0 265c8550b90SFlorian Westphal fi 266c8550b90SFlorian Westphal 267c8550b90SFlorian Westphal if [ $repl_cnt -gt $max_repl ];then 268c8550b90SFlorian Westphal echo "FAIL: $what: reply counter $repl_cnt exceeds expected value $max_repl" 1>&2 269c8550b90SFlorian Westphal ret=1 270c8550b90SFlorian Westphal ok=0 271c8550b90SFlorian Westphal fi 272c8550b90SFlorian Westphal 273c8550b90SFlorian Westphal if [ $ok -eq 1 ]; then 274c8550b90SFlorian Westphal echo "PASS: $what" 275c8550b90SFlorian Westphal fi 276c8550b90SFlorian Westphal} 277c8550b90SFlorian Westphal 278*3acf8f6cSFlorian Westphalcheck_dscp() 279*3acf8f6cSFlorian Westphal{ 280*3acf8f6cSFlorian Westphal local what=$1 281*3acf8f6cSFlorian Westphal local ok=1 282*3acf8f6cSFlorian Westphal 283*3acf8f6cSFlorian Westphal local counter=$(ip netns exec $ns2 nft reset counter inet filter ip4dscp3 | grep packets) 284*3acf8f6cSFlorian Westphal 285*3acf8f6cSFlorian Westphal local pc4=${counter%*bytes*} 286*3acf8f6cSFlorian Westphal local pc4=${pc4#*packets} 287*3acf8f6cSFlorian Westphal 288*3acf8f6cSFlorian Westphal local counter=$(ip netns exec $ns2 nft reset counter inet filter ip4dscp0 | grep packets) 289*3acf8f6cSFlorian Westphal local pc4z=${counter%*bytes*} 290*3acf8f6cSFlorian Westphal local pc4z=${pc4z#*packets} 291*3acf8f6cSFlorian Westphal 292*3acf8f6cSFlorian Westphal case "$what" in 293*3acf8f6cSFlorian Westphal "dscp_none") 294*3acf8f6cSFlorian Westphal if [ $pc4 -gt 0 ] || [ $pc4z -eq 0 ]; then 295*3acf8f6cSFlorian Westphal echo "FAIL: dscp counters do not match, expected dscp3 == 0, dscp0 > 0, but got $pc4,$pc4z" 1>&2 296*3acf8f6cSFlorian Westphal ret=1 297*3acf8f6cSFlorian Westphal ok=0 298*3acf8f6cSFlorian Westphal fi 299*3acf8f6cSFlorian Westphal ;; 300*3acf8f6cSFlorian Westphal "dscp_fwd") 301*3acf8f6cSFlorian Westphal if [ $pc4 -eq 0 ] || [ $pc4z -eq 0 ]; then 302*3acf8f6cSFlorian Westphal echo "FAIL: dscp counters do not match, expected dscp3 and dscp0 > 0 but got $pc4,$pc4z" 1>&2 303*3acf8f6cSFlorian Westphal ret=1 304*3acf8f6cSFlorian Westphal ok=0 305*3acf8f6cSFlorian Westphal fi 306*3acf8f6cSFlorian Westphal ;; 307*3acf8f6cSFlorian Westphal "dscp_ingress") 308*3acf8f6cSFlorian Westphal if [ $pc4 -eq 0 ] || [ $pc4z -gt 0 ]; then 309*3acf8f6cSFlorian Westphal echo "FAIL: dscp counters do not match, expected dscp3 > 0, dscp0 == 0 but got $pc4,$pc4z" 1>&2 310*3acf8f6cSFlorian Westphal ret=1 311*3acf8f6cSFlorian Westphal ok=0 312*3acf8f6cSFlorian Westphal fi 313*3acf8f6cSFlorian Westphal ;; 314*3acf8f6cSFlorian Westphal "dscp_egress") 315*3acf8f6cSFlorian Westphal if [ $pc4 -eq 0 ] || [ $pc4z -gt 0 ]; then 316*3acf8f6cSFlorian Westphal echo "FAIL: dscp counters do not match, expected dscp3 > 0, dscp0 == 0 but got $pc4,$pc4z" 1>&2 317*3acf8f6cSFlorian Westphal ret=1 318*3acf8f6cSFlorian Westphal ok=0 319*3acf8f6cSFlorian Westphal fi 320*3acf8f6cSFlorian Westphal ;; 321*3acf8f6cSFlorian Westphal *) 322*3acf8f6cSFlorian Westphal echo "FAIL: Unknown DSCP check" 1>&2 323*3acf8f6cSFlorian Westphal ret=1 324*3acf8f6cSFlorian Westphal ok=0 325*3acf8f6cSFlorian Westphal esac 326*3acf8f6cSFlorian Westphal 327*3acf8f6cSFlorian Westphal if [ $ok -eq 1 ] ;then 328*3acf8f6cSFlorian Westphal echo "PASS: $what: dscp packet counters match" 329*3acf8f6cSFlorian Westphal fi 330*3acf8f6cSFlorian Westphal} 331*3acf8f6cSFlorian Westphal 3322de03b45SFlorian Westphalcheck_transfer() 3332de03b45SFlorian Westphal{ 3342de03b45SFlorian Westphal in=$1 3352de03b45SFlorian Westphal out=$2 3362de03b45SFlorian Westphal what=$3 3372de03b45SFlorian Westphal 3382f4bba4eSFabian Frederick if ! cmp "$in" "$out" > /dev/null 2>&1; then 3392de03b45SFlorian Westphal echo "FAIL: file mismatch for $what" 1>&2 3402de03b45SFlorian Westphal ls -l "$in" 3412de03b45SFlorian Westphal ls -l "$out" 3422de03b45SFlorian Westphal return 1 3432de03b45SFlorian Westphal fi 3442de03b45SFlorian Westphal 3452de03b45SFlorian Westphal return 0 3462de03b45SFlorian Westphal} 3472de03b45SFlorian Westphal 348d05d5db8SFlorian Westphaltest_tcp_forwarding_ip() 3492de03b45SFlorian Westphal{ 3502de03b45SFlorian Westphal local nsa=$1 3512de03b45SFlorian Westphal local nsb=$2 352d05d5db8SFlorian Westphal local dstip=$3 353d05d5db8SFlorian Westphal local dstport=$4 3542de03b45SFlorian Westphal local lret=0 3552de03b45SFlorian Westphal 356c8550b90SFlorian Westphal ip netns exec $nsb nc -w 5 -l -p 12345 < "$nsin" > "$ns2out" & 3572de03b45SFlorian Westphal lpid=$! 3582de03b45SFlorian Westphal 3592de03b45SFlorian Westphal sleep 1 360c8550b90SFlorian Westphal ip netns exec $nsa nc -w 4 "$dstip" "$dstport" < "$nsin" > "$ns1out" & 3612de03b45SFlorian Westphal cpid=$! 3622de03b45SFlorian Westphal 36390ab5122SBoris Sukholitko sleep 1 36490ab5122SBoris Sukholitko 36590ab5122SBoris Sukholitko prev="$(ls -l $ns1out $ns2out)" 36690ab5122SBoris Sukholitko sleep 1 36790ab5122SBoris Sukholitko 36890ab5122SBoris Sukholitko while [[ "$prev" != "$(ls -l $ns1out $ns2out)" ]]; do 36990ab5122SBoris Sukholitko sleep 1; 37090ab5122SBoris Sukholitko prev="$(ls -l $ns1out $ns2out)" 37190ab5122SBoris Sukholitko done 3722de03b45SFlorian Westphal 3730a11073eSBoris Sukholitko if test -d /proc/"$lpid"/; then 3742de03b45SFlorian Westphal kill $lpid 375d8bb9abeSFabian Frederick fi 376d8bb9abeSFabian Frederick 3770a11073eSBoris Sukholitko if test -d /proc/"$cpid"/; then 3782de03b45SFlorian Westphal kill $cpid 379d8bb9abeSFabian Frederick fi 380d8bb9abeSFabian Frederick 3811114803cSBoris Sukholitko wait $lpid 3821114803cSBoris Sukholitko wait $cpid 3832de03b45SFlorian Westphal 384c8550b90SFlorian Westphal if ! check_transfer "$nsin" "$ns2out" "ns1 -> ns2"; then 3852de03b45SFlorian Westphal lret=1 3862de03b45SFlorian Westphal fi 3872de03b45SFlorian Westphal 388c8550b90SFlorian Westphal if ! check_transfer "$nsin" "$ns1out" "ns1 <- ns2"; then 3892de03b45SFlorian Westphal lret=1 3902de03b45SFlorian Westphal fi 3912de03b45SFlorian Westphal 3922de03b45SFlorian Westphal return $lret 3932de03b45SFlorian Westphal} 3942de03b45SFlorian Westphal 395d05d5db8SFlorian Westphaltest_tcp_forwarding() 396d05d5db8SFlorian Westphal{ 397d05d5db8SFlorian Westphal test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 398d05d5db8SFlorian Westphal 399d05d5db8SFlorian Westphal return $? 400d05d5db8SFlorian Westphal} 401d05d5db8SFlorian Westphal 402*3acf8f6cSFlorian Westphaltest_tcp_forwarding_set_dscp() 403*3acf8f6cSFlorian Westphal{ 404*3acf8f6cSFlorian Westphal check_dscp "dscp_none" 405*3acf8f6cSFlorian Westphal 406*3acf8f6cSFlorian Westphalip netns exec $nsr1 nft -f - <<EOF 407*3acf8f6cSFlorian Westphaltable netdev dscpmangle { 408*3acf8f6cSFlorian Westphal chain setdscp0 { 409*3acf8f6cSFlorian Westphal type filter hook ingress device "veth0" priority 0; policy accept 410*3acf8f6cSFlorian Westphal ip dscp set cs3 411*3acf8f6cSFlorian Westphal } 412*3acf8f6cSFlorian Westphal} 413*3acf8f6cSFlorian WestphalEOF 414*3acf8f6cSFlorian Westphalif [ $? -eq 0 ]; then 415*3acf8f6cSFlorian Westphal test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 416*3acf8f6cSFlorian Westphal check_dscp "dscp_ingress" 417*3acf8f6cSFlorian Westphal 418*3acf8f6cSFlorian Westphal ip netns exec $nsr1 nft delete table netdev dscpmangle 419*3acf8f6cSFlorian Westphalelse 420*3acf8f6cSFlorian Westphal echo "SKIP: Could not load netdev:ingress for veth0" 421*3acf8f6cSFlorian Westphalfi 422*3acf8f6cSFlorian Westphal 423*3acf8f6cSFlorian Westphalip netns exec $nsr1 nft -f - <<EOF 424*3acf8f6cSFlorian Westphaltable netdev dscpmangle { 425*3acf8f6cSFlorian Westphal chain setdscp0 { 426*3acf8f6cSFlorian Westphal type filter hook egress device "veth1" priority 0; policy accept 427*3acf8f6cSFlorian Westphal ip dscp set cs3 428*3acf8f6cSFlorian Westphal } 429*3acf8f6cSFlorian Westphal} 430*3acf8f6cSFlorian WestphalEOF 431*3acf8f6cSFlorian Westphalif [ $? -eq 0 ]; then 432*3acf8f6cSFlorian Westphal test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 433*3acf8f6cSFlorian Westphal check_dscp "dscp_egress" 434*3acf8f6cSFlorian Westphal 435*3acf8f6cSFlorian Westphal ip netns exec $nsr1 nft flush table netdev dscpmangle 436*3acf8f6cSFlorian Westphalelse 437*3acf8f6cSFlorian Westphal echo "SKIP: Could not load netdev:egress for veth1" 438*3acf8f6cSFlorian Westphalfi 439*3acf8f6cSFlorian Westphal 440*3acf8f6cSFlorian Westphal # partial. If flowtable really works, then both dscp-is-0 and dscp-is-cs3 441*3acf8f6cSFlorian Westphal # counters should have seen packets (before and after ft offload kicks in). 442*3acf8f6cSFlorian Westphal ip netns exec $nsr1 nft -a insert rule inet filter forward ip dscp set cs3 443*3acf8f6cSFlorian Westphal test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 444*3acf8f6cSFlorian Westphal check_dscp "dscp_fwd" 445*3acf8f6cSFlorian Westphal} 446*3acf8f6cSFlorian Westphal 447d05d5db8SFlorian Westphaltest_tcp_forwarding_nat() 448d05d5db8SFlorian Westphal{ 449d05d5db8SFlorian Westphal local lret 450c8550b90SFlorian Westphal local pmtu 451d05d5db8SFlorian Westphal 452d05d5db8SFlorian Westphal test_tcp_forwarding_ip "$1" "$2" 10.0.2.99 12345 453d05d5db8SFlorian Westphal lret=$? 454d05d5db8SFlorian Westphal 455c8550b90SFlorian Westphal pmtu=$3 456c8550b90SFlorian Westphal what=$4 457c8550b90SFlorian Westphal 458d05d5db8SFlorian Westphal if [ $lret -eq 0 ] ; then 459c8550b90SFlorian Westphal if [ $pmtu -eq 1 ] ;then 460c8550b90SFlorian Westphal check_counters "flow offload for ns1/ns2 with masquerade and pmtu discovery $what" 461c8550b90SFlorian Westphal else 462c8550b90SFlorian Westphal echo "PASS: flow offload for ns1/ns2 with masquerade $what" 463c8550b90SFlorian Westphal fi 464c8550b90SFlorian Westphal 465d05d5db8SFlorian Westphal test_tcp_forwarding_ip "$1" "$2" 10.6.6.6 1666 466d05d5db8SFlorian Westphal lret=$? 467c8550b90SFlorian Westphal if [ $pmtu -eq 1 ] ;then 468c8550b90SFlorian Westphal check_counters "flow offload for ns1/ns2 with dnat and pmtu discovery $what" 469c8550b90SFlorian Westphal elif [ $lret -eq 0 ] ; then 470c8550b90SFlorian Westphal echo "PASS: flow offload for ns1/ns2 with dnat $what" 471c8550b90SFlorian Westphal fi 472d05d5db8SFlorian Westphal fi 473d05d5db8SFlorian Westphal 474d05d5db8SFlorian Westphal return $lret 475d05d5db8SFlorian Westphal} 476d05d5db8SFlorian Westphal 477c8550b90SFlorian Westphalmake_file "$nsin" 4782de03b45SFlorian Westphal 4792de03b45SFlorian Westphal# First test: 4802de03b45SFlorian Westphal# No PMTU discovery, nsr1 is expected to fragment packets from ns1 to ns2 as needed. 481c8550b90SFlorian Westphal# Due to MTU mismatch in both directions, all packets (except small packets like pure 482c8550b90SFlorian Westphal# acks) have to be handled by normal forwarding path. Therefore, packet counters 483c8550b90SFlorian Westphal# are not checked. 484b71b7bfeSFlorian Westphalif test_tcp_forwarding $ns1 $ns2; then 4852de03b45SFlorian Westphal echo "PASS: flow offloaded for ns1/ns2" 4862de03b45SFlorian Westphalelse 4872de03b45SFlorian Westphal echo "FAIL: flow offload for ns1/ns2:" 1>&2 488b71b7bfeSFlorian Westphal ip netns exec $nsr1 nft list ruleset 4892de03b45SFlorian Westphal ret=1 4902de03b45SFlorian Westphalfi 4912de03b45SFlorian Westphal 4922de03b45SFlorian Westphal# delete default route, i.e. ns2 won't be able to reach ns1 and 4932de03b45SFlorian Westphal# will depend on ns1 being masqueraded in nsr1. 4942de03b45SFlorian Westphal# expect ns1 has nsr1 address. 495b71b7bfeSFlorian Westphalip -net $ns2 route del default via 10.0.2.1 496b71b7bfeSFlorian Westphalip -net $ns2 route del default via dead:2::1 497b71b7bfeSFlorian Westphalip -net $ns2 route add 192.168.10.1 via 10.0.2.1 4982de03b45SFlorian Westphal 4992de03b45SFlorian Westphal# Second test: 500c8550b90SFlorian Westphal# Same, but with NAT enabled. Same as in first test: we expect normal forward path 501c8550b90SFlorian Westphal# to handle most packets. 502b71b7bfeSFlorian Westphalip netns exec $nsr1 nft -f - <<EOF 5032de03b45SFlorian Westphaltable ip nat { 504d05d5db8SFlorian Westphal chain prerouting { 505d05d5db8SFlorian Westphal type nat hook prerouting priority 0; policy accept; 506d05d5db8SFlorian Westphal meta iif "veth0" ip daddr 10.6.6.6 tcp dport 1666 counter dnat ip to 10.0.2.99:12345 507d05d5db8SFlorian Westphal } 508d05d5db8SFlorian Westphal 5092de03b45SFlorian Westphal chain postrouting { 5102de03b45SFlorian Westphal type nat hook postrouting priority 0; policy accept; 511d05d5db8SFlorian Westphal meta oifname "veth1" counter masquerade 5122de03b45SFlorian Westphal } 5132de03b45SFlorian Westphal} 5142de03b45SFlorian WestphalEOF 5152de03b45SFlorian Westphal 516*3acf8f6cSFlorian Westphalif ! test_tcp_forwarding_set_dscp $ns1 $ns2 0 ""; then 517*3acf8f6cSFlorian Westphal echo "FAIL: flow offload for ns1/ns2 with dscp update" 1>&2 518*3acf8f6cSFlorian Westphal exit 0 519*3acf8f6cSFlorian Westphalfi 520*3acf8f6cSFlorian Westphal 521c8550b90SFlorian Westphalif ! test_tcp_forwarding_nat $ns1 $ns2 0 ""; then 5222de03b45SFlorian Westphal echo "FAIL: flow offload for ns1/ns2 with NAT" 1>&2 523b71b7bfeSFlorian Westphal ip netns exec $nsr1 nft list ruleset 5242de03b45SFlorian Westphal ret=1 5252de03b45SFlorian Westphalfi 5262de03b45SFlorian Westphal 5272de03b45SFlorian Westphal# Third test: 528c8550b90SFlorian Westphal# Same as second test, but with PMTU discovery enabled. This 529c8550b90SFlorian Westphal# means that we expect the fastpath to handle packets as soon 530c8550b90SFlorian Westphal# as the endpoints adjust the packet size. 531b71b7bfeSFlorian Westphalip netns exec $ns1 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null 532b71b7bfeSFlorian Westphalip netns exec $ns2 sysctl net.ipv4.ip_no_pmtu_disc=0 > /dev/null 5332de03b45SFlorian Westphal 534c8550b90SFlorian Westphal# reset counters. 535c8550b90SFlorian Westphal# With pmtu in-place we'll also check that nft counters 536c8550b90SFlorian Westphal# are lower than file size and packets were forwarded via flowtable layer. 537c8550b90SFlorian Westphal# For earlier tests (large mtus), packets cannot be handled via flowtable 538c8550b90SFlorian Westphal# (except pure acks and other small packets). 539c8550b90SFlorian Westphalip netns exec $nsr1 nft reset counters table inet filter >/dev/null 540c8550b90SFlorian Westphal 541c8550b90SFlorian Westphalif ! test_tcp_forwarding_nat $ns1 $ns2 1 ""; then 5422de03b45SFlorian Westphal echo "FAIL: flow offload for ns1/ns2 with NAT and pmtu discovery" 1>&2 543b71b7bfeSFlorian Westphal ip netns exec $nsr1 nft list ruleset 5442de03b45SFlorian Westphalfi 5452de03b45SFlorian Westphal 54679d4071eSPablo Neira Ayuso# Another test: 54779d4071eSPablo Neira Ayuso# Add bridge interface br0 to Router1, with NAT enabled. 548b71b7bfeSFlorian Westphalip -net $nsr1 link add name br0 type bridge 549b71b7bfeSFlorian Westphalip -net $nsr1 addr flush dev veth0 550b71b7bfeSFlorian Westphalip -net $nsr1 link set up dev veth0 551b71b7bfeSFlorian Westphalip -net $nsr1 link set veth0 master br0 552b71b7bfeSFlorian Westphalip -net $nsr1 addr add 10.0.1.1/24 dev br0 553b71b7bfeSFlorian Westphalip -net $nsr1 addr add dead:1::1/64 dev br0 554b71b7bfeSFlorian Westphalip -net $nsr1 link set up dev br0 55579d4071eSPablo Neira Ayuso 556b71b7bfeSFlorian Westphalip netns exec $nsr1 sysctl net.ipv4.conf.br0.forwarding=1 > /dev/null 55779d4071eSPablo Neira Ayuso 55879d4071eSPablo Neira Ayuso# br0 with NAT enabled. 559b71b7bfeSFlorian Westphalip netns exec $nsr1 nft -f - <<EOF 56079d4071eSPablo Neira Ayusoflush table ip nat 56179d4071eSPablo Neira Ayusotable ip nat { 56279d4071eSPablo Neira Ayuso chain prerouting { 56379d4071eSPablo Neira Ayuso type nat hook prerouting priority 0; policy accept; 56479d4071eSPablo Neira Ayuso meta iif "br0" ip daddr 10.6.6.6 tcp dport 1666 counter dnat ip to 10.0.2.99:12345 56579d4071eSPablo Neira Ayuso } 56679d4071eSPablo Neira Ayuso 56779d4071eSPablo Neira Ayuso chain postrouting { 56879d4071eSPablo Neira Ayuso type nat hook postrouting priority 0; policy accept; 56979d4071eSPablo Neira Ayuso meta oifname "veth1" counter masquerade 57079d4071eSPablo Neira Ayuso } 57179d4071eSPablo Neira Ayuso} 57279d4071eSPablo Neira AyusoEOF 57379d4071eSPablo Neira Ayuso 574c8550b90SFlorian Westphalif ! test_tcp_forwarding_nat $ns1 $ns2 1 "on bridge"; then 57579d4071eSPablo Neira Ayuso echo "FAIL: flow offload for ns1/ns2 with bridge NAT" 1>&2 576b71b7bfeSFlorian Westphal ip netns exec $nsr1 nft list ruleset 57779d4071eSPablo Neira Ayuso ret=1 57879d4071eSPablo Neira Ayusofi 57979d4071eSPablo Neira Ayuso 580c8550b90SFlorian Westphal 58179d4071eSPablo Neira Ayuso# Another test: 58279d4071eSPablo Neira Ayuso# Add bridge interface br0 to Router1, with NAT and VLAN. 583b71b7bfeSFlorian Westphalip -net $nsr1 link set veth0 nomaster 584b71b7bfeSFlorian Westphalip -net $nsr1 link set down dev veth0 585b71b7bfeSFlorian Westphalip -net $nsr1 link add link veth0 name veth0.10 type vlan id 10 586b71b7bfeSFlorian Westphalip -net $nsr1 link set up dev veth0 587b71b7bfeSFlorian Westphalip -net $nsr1 link set up dev veth0.10 588b71b7bfeSFlorian Westphalip -net $nsr1 link set veth0.10 master br0 58979d4071eSPablo Neira Ayuso 590b71b7bfeSFlorian Westphalip -net $ns1 addr flush dev eth0 591b71b7bfeSFlorian Westphalip -net $ns1 link add link eth0 name eth0.10 type vlan id 10 592b71b7bfeSFlorian Westphalip -net $ns1 link set eth0 up 593b71b7bfeSFlorian Westphalip -net $ns1 link set eth0.10 up 594b71b7bfeSFlorian Westphalip -net $ns1 addr add 10.0.1.99/24 dev eth0.10 595b71b7bfeSFlorian Westphalip -net $ns1 route add default via 10.0.1.1 596b71b7bfeSFlorian Westphalip -net $ns1 addr add dead:1::99/64 dev eth0.10 59779d4071eSPablo Neira Ayuso 598c8550b90SFlorian Westphalif ! test_tcp_forwarding_nat $ns1 $ns2 1 "bridge and VLAN"; then 59979d4071eSPablo Neira Ayuso echo "FAIL: flow offload for ns1/ns2 with bridge NAT and VLAN" 1>&2 600b71b7bfeSFlorian Westphal ip netns exec $nsr1 nft list ruleset 60179d4071eSPablo Neira Ayuso ret=1 60279d4071eSPablo Neira Ayusofi 60379d4071eSPablo Neira Ayuso 60479d4071eSPablo Neira Ayuso# restore test topology (remove bridge and VLAN) 605b71b7bfeSFlorian Westphalip -net $nsr1 link set veth0 nomaster 606b71b7bfeSFlorian Westphalip -net $nsr1 link set veth0 down 607b71b7bfeSFlorian Westphalip -net $nsr1 link set veth0.10 down 608b71b7bfeSFlorian Westphalip -net $nsr1 link delete veth0.10 type vlan 609b71b7bfeSFlorian Westphalip -net $nsr1 link delete br0 type bridge 610b71b7bfeSFlorian Westphalip -net $ns1 addr flush dev eth0.10 611b71b7bfeSFlorian Westphalip -net $ns1 link set eth0.10 down 612b71b7bfeSFlorian Westphalip -net $ns1 link set eth0 down 613b71b7bfeSFlorian Westphalip -net $ns1 link delete eth0.10 type vlan 61479d4071eSPablo Neira Ayuso 61579d4071eSPablo Neira Ayuso# restore address in ns1 and nsr1 616b71b7bfeSFlorian Westphalip -net $ns1 link set eth0 up 617b71b7bfeSFlorian Westphalip -net $ns1 addr add 10.0.1.99/24 dev eth0 618b71b7bfeSFlorian Westphalip -net $ns1 route add default via 10.0.1.1 619b71b7bfeSFlorian Westphalip -net $ns1 addr add dead:1::99/64 dev eth0 620b71b7bfeSFlorian Westphalip -net $ns1 route add default via dead:1::1 621b71b7bfeSFlorian Westphalip -net $nsr1 addr add 10.0.1.1/24 dev veth0 622b71b7bfeSFlorian Westphalip -net $nsr1 addr add dead:1::1/64 dev veth0 623b71b7bfeSFlorian Westphalip -net $nsr1 link set up dev veth0 62479d4071eSPablo Neira Ayuso 6250749d670SBoris SukholitkoKEY_SHA="0x"$(ps -af | sha1sum | cut -d " " -f 1) 6260749d670SBoris SukholitkoKEY_AES="0x"$(ps -af | md5sum | cut -d " " -f 1) 6270ca1bbb7SFlorian WestphalSPI1=$RANDOM 6280ca1bbb7SFlorian WestphalSPI2=$RANDOM 6290ca1bbb7SFlorian Westphal 6300ca1bbb7SFlorian Westphalif [ $SPI1 -eq $SPI2 ]; then 6310ca1bbb7SFlorian Westphal SPI2=$((SPI2+1)) 6320ca1bbb7SFlorian Westphalfi 6330ca1bbb7SFlorian Westphal 6340ca1bbb7SFlorian Westphaldo_esp() { 6350ca1bbb7SFlorian Westphal local ns=$1 6360ca1bbb7SFlorian Westphal local me=$2 6370ca1bbb7SFlorian Westphal local remote=$3 6380ca1bbb7SFlorian Westphal local lnet=$4 6390ca1bbb7SFlorian Westphal local rnet=$5 6400ca1bbb7SFlorian Westphal local spi_out=$6 6410ca1bbb7SFlorian Westphal local spi_in=$7 6420ca1bbb7SFlorian Westphal 6430ca1bbb7SFlorian Westphal ip -net $ns xfrm state add src $remote dst $me proto esp spi $spi_in enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $rnet dst $lnet 6440ca1bbb7SFlorian Westphal ip -net $ns xfrm state add src $me dst $remote proto esp spi $spi_out enc aes $KEY_AES auth sha1 $KEY_SHA mode tunnel sel src $lnet dst $rnet 6450ca1bbb7SFlorian Westphal 6460ca1bbb7SFlorian Westphal # to encrypt packets as they go out (includes forwarded packets that need encapsulation) 6470ca1bbb7SFlorian Westphal ip -net $ns xfrm policy add src $lnet dst $rnet dir out tmpl src $me dst $remote proto esp mode tunnel priority 1 action allow 6480ca1bbb7SFlorian Westphal # to fwd decrypted packets after esp processing: 6490ca1bbb7SFlorian Westphal ip -net $ns xfrm policy add src $rnet dst $lnet dir fwd tmpl src $remote dst $me proto esp mode tunnel priority 1 action allow 6500ca1bbb7SFlorian Westphal 6510ca1bbb7SFlorian Westphal} 6520ca1bbb7SFlorian Westphal 653b71b7bfeSFlorian Westphaldo_esp $nsr1 192.168.10.1 192.168.10.2 10.0.1.0/24 10.0.2.0/24 $SPI1 $SPI2 6540ca1bbb7SFlorian Westphal 655b71b7bfeSFlorian Westphaldo_esp $nsr2 192.168.10.2 192.168.10.1 10.0.2.0/24 10.0.1.0/24 $SPI2 $SPI1 6560ca1bbb7SFlorian Westphal 657b71b7bfeSFlorian Westphalip netns exec $nsr1 nft delete table ip nat 6580ca1bbb7SFlorian Westphal 6590ca1bbb7SFlorian Westphal# restore default routes 660b71b7bfeSFlorian Westphalip -net $ns2 route del 192.168.10.1 via 10.0.2.1 661b71b7bfeSFlorian Westphalip -net $ns2 route add default via 10.0.2.1 662b71b7bfeSFlorian Westphalip -net $ns2 route add default via dead:2::1 6630ca1bbb7SFlorian Westphal 664b71b7bfeSFlorian Westphalif test_tcp_forwarding $ns1 $ns2; then 665c8550b90SFlorian Westphal check_counters "ipsec tunnel mode for ns1/ns2" 6660ca1bbb7SFlorian Westphalelse 6670ca1bbb7SFlorian Westphal echo "FAIL: ipsec tunnel mode for ns1/ns2" 668b71b7bfeSFlorian Westphal ip netns exec $nsr1 nft list ruleset 1>&2 669b71b7bfeSFlorian Westphal ip netns exec $nsr1 cat /proc/net/xfrm_stat 1>&2 6700ca1bbb7SFlorian Westphalfi 6710ca1bbb7SFlorian Westphal 6722de03b45SFlorian Westphalexit $ret 673