1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3#
4# ns: h1               | ns: h2
5#   192.168.0.1/24     |
6#            eth0      |
7#                      |       192.168.1.1/32
8#            veth0 <---|---> veth1
9# Validate source address selection for route without gateway
10
11source lib.sh
12PAUSE_ON_FAIL=no
13VERBOSE=0
14ret=0
15
16################################################################################
17# helpers
18
19log_test()
20{
21	local rc=$1
22	local expected=$2
23	local msg="$3"
24
25	if [ ${rc} -eq ${expected} ]; then
26		printf "TEST: %-60s  [ OK ]\n" "${msg}"
27		nsuccess=$((nsuccess+1))
28	else
29		ret=1
30		nfail=$((nfail+1))
31		printf "TEST: %-60s  [FAIL]\n" "${msg}"
32		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
33			echo
34			echo "hit enter to continue, 'q' to quit"
35			read a
36			[ "$a" = "q" ] && exit 1
37		fi
38	fi
39
40	[ "$VERBOSE" = "1" ] && echo
41}
42
43run_cmd()
44{
45	local cmd="$*"
46	local out
47	local rc
48
49	if [ "$VERBOSE" = "1" ]; then
50		echo "COMMAND: $cmd"
51	fi
52
53	out=$(eval $cmd 2>&1)
54	rc=$?
55	if [ "$VERBOSE" = "1" -a -n "$out" ]; then
56		echo "$out"
57	fi
58
59	[ "$VERBOSE" = "1" ] && echo
60
61	return $rc
62}
63
64################################################################################
65# config
66setup()
67{
68	setup_ns h1 h2
69
70	# Add a fake eth0 to support an ip address
71	ip -n $h1 link add name eth0 type dummy
72	ip -n $h1 link set eth0 up
73	ip -n $h1 address add 192.168.0.1/24 dev eth0
74
75	# Configure veths (same @mac, arp off)
76	ip -n $h1 link add name veth0 type veth peer name veth1 netns $h2
77	ip -n $h1 link set veth0 up
78
79	ip -n $h2 link set veth1 up
80
81	# Configure @IP in the peer netns
82	ip -n $h2 address add 192.168.1.1/32 dev veth1
83	ip -n $h2 route add default dev veth1
84
85	# Add a nexthop without @gw and use it in a route
86	ip -n $h1 nexthop add id 1 dev veth0
87	ip -n $h1 route add 192.168.1.1 nhid 1
88}
89
90cleanup()
91{
92	cleanup_ns $h1 $h2
93}
94
95trap cleanup EXIT
96
97################################################################################
98# main
99
100while getopts :pv o
101do
102	case $o in
103		p) PAUSE_ON_FAIL=yes;;
104		v) VERBOSE=1;;
105	esac
106done
107
108setup
109
110run_cmd ip -netns $h1 route get 192.168.1.1
111log_test $? 0 "nexthop: get route with nexthop without gw"
112run_cmd ip netns exec $h1 ping -c1 192.168.1.1
113log_test $? 0 "nexthop: ping through nexthop without gw"
114
115exit $ret
116