summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/drivers/net/netdevsim/peer.sh
blob: f4721f7636dd6aaf9a671f2520655d0c88330eba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0-only

lib_dir=$(dirname $0)/../../../net
source $lib_dir/lib.sh

NSIM_DEV_1_ID=$((256 + RANDOM % 256))
NSIM_DEV_1_SYS=/sys/bus/netdevsim/devices/netdevsim$NSIM_DEV_1_ID
NSIM_DEV_2_ID=$((512 + RANDOM % 256))
NSIM_DEV_2_SYS=/sys/bus/netdevsim/devices/netdevsim$NSIM_DEV_2_ID

NSIM_DEV_SYS_NEW=/sys/bus/netdevsim/new_device
NSIM_DEV_SYS_DEL=/sys/bus/netdevsim/del_device
NSIM_DEV_SYS_LINK=/sys/bus/netdevsim/link_device
NSIM_DEV_SYS_UNLINK=/sys/bus/netdevsim/unlink_device

socat_check()
{
	if [ ! -x "$(command -v socat)" ]; then
		echo "socat command not found. Skipping test"
		return 1
	fi

	return 0
}

setup_ns()
{
	set -e
	ip netns add nssv
	ip netns add nscl

	NSIM_DEV_1_NAME=$(find $NSIM_DEV_1_SYS/net -maxdepth 1 -type d ! \
		-path $NSIM_DEV_1_SYS/net -exec basename {} \;)
	NSIM_DEV_2_NAME=$(find $NSIM_DEV_2_SYS/net -maxdepth 1 -type d ! \
		-path $NSIM_DEV_2_SYS/net -exec basename {} \;)

	ip link set $NSIM_DEV_1_NAME netns nssv
	ip link set $NSIM_DEV_2_NAME netns nscl

	ip netns exec nssv ip addr add '192.168.1.1/24' dev $NSIM_DEV_1_NAME
	ip netns exec nscl ip addr add '192.168.1.2/24' dev $NSIM_DEV_2_NAME

	ip netns exec nssv ip link set dev $NSIM_DEV_1_NAME up
	ip netns exec nscl ip link set dev $NSIM_DEV_2_NAME up
	set +e
}

cleanup_ns()
{
	ip netns del nscl
	ip netns del nssv
}

is_carrier_up()
{
	local netns="$1"
	local nsim_dev="$2"

	test "$(ip netns exec "$netns"	\
		cat /sys/class/net/"$nsim_dev"/carrier 2>/dev/null)" -eq 1
}

assert_carrier_up()
{
	local netns="$1"
	local nsim_dev="$2"

	if ! is_carrier_up "$netns" "$nsim_dev"; then
		echo "$nsim_dev's carrier should be UP, but it isn't"
		cleanup_ns
		exit 1
	fi
}

assert_carrier_down()
{
	local netns="$1"
	local nsim_dev="$2"

	if is_carrier_up "$netns" "$nsim_dev"; then
		echo "$nsim_dev's carrier should be DOWN, but it isn't"
		cleanup_ns
		exit 1
	fi
}

###
### Code start
###

socat_check || exit 4

modprobe netdevsim

# linking

echo $NSIM_DEV_1_ID > $NSIM_DEV_SYS_NEW
echo $NSIM_DEV_2_ID > $NSIM_DEV_SYS_NEW
udevadm settle

setup_ns

NSIM_DEV_1_FD=$((256 + RANDOM % 256))
exec {NSIM_DEV_1_FD}</var/run/netns/nssv
NSIM_DEV_1_IFIDX=$(ip netns exec nssv cat /sys/class/net/$NSIM_DEV_1_NAME/ifindex)

NSIM_DEV_2_FD=$((256 + RANDOM % 256))
exec {NSIM_DEV_2_FD}</var/run/netns/nscl
NSIM_DEV_2_IFIDX=$(ip netns exec nscl cat /sys/class/net/$NSIM_DEV_2_NAME/ifindex)

echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:2000" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
	echo "linking with non-existent netdevsim should fail"
	cleanup_ns
	exit 1
fi

echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX 2000:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
	echo "linking with non-existent netnsid should fail"
	cleanup_ns
	exit 1
fi

echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
	echo "linking with self should fail"
	cleanup_ns
	exit 1
fi

echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK
if [ $? -ne 0 ]; then
	echo "linking netdevsim1 with netdevsim2 should succeed"
	cleanup_ns
	exit 1
fi

# argument error checking

echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:a" > $NSIM_DEV_SYS_LINK 2>/dev/null
if [ $? -eq 0 ]; then
	echo "invalid arg should fail"
	cleanup_ns
	exit 1
fi

# netdevsim carrier state consistency checking
assert_carrier_up nssv "$NSIM_DEV_1_NAME"
assert_carrier_up nscl "$NSIM_DEV_2_NAME"

echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > "$NSIM_DEV_SYS_UNLINK"

assert_carrier_down nssv "$NSIM_DEV_1_NAME"
assert_carrier_down nscl "$NSIM_DEV_2_NAME"

ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" down
ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" up

assert_carrier_down nssv "$NSIM_DEV_1_NAME"
assert_carrier_down nscl "$NSIM_DEV_2_NAME"

echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK

assert_carrier_up nssv "$NSIM_DEV_1_NAME"
assert_carrier_up nscl "$NSIM_DEV_2_NAME"

ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" down
ip netns exec nssv ip link set dev "$NSIM_DEV_1_NAME" up

assert_carrier_up nssv "$NSIM_DEV_1_NAME"
assert_carrier_up nscl "$NSIM_DEV_2_NAME"

# send/recv packets

tmp_file=$(mktemp)
ip netns exec nssv socat TCP-LISTEN:1234,fork $tmp_file &
pid=$!
res=0

wait_local_port_listen nssv 1234 tcp

echo "HI" | ip netns exec nscl socat STDIN TCP:192.168.1.1:1234

count=$(cat $tmp_file | wc -c)
if [[ $count -ne 3 ]]; then
	echo "expected 3 bytes, got $count"
	res=1
fi

echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > $NSIM_DEV_SYS_UNLINK

echo $NSIM_DEV_2_ID > $NSIM_DEV_SYS_DEL

kill $pid
echo $NSIM_DEV_1_ID > $NSIM_DEV_SYS_DEL

cleanup_ns

modprobe -r netdevsim

exit $res