1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0-only
3
4lib_dir=$(dirname $0)/../../../net
5source $lib_dir/lib.sh
6
7NSIM_DEV_1_ID=$((256 + RANDOM % 256))
8NSIM_DEV_1_SYS=/sys/bus/netdevsim/devices/netdevsim$NSIM_DEV_1_ID
9NSIM_DEV_2_ID=$((512 + RANDOM % 256))
10NSIM_DEV_2_SYS=/sys/bus/netdevsim/devices/netdevsim$NSIM_DEV_2_ID
11
12NSIM_DEV_SYS_NEW=/sys/bus/netdevsim/new_device
13NSIM_DEV_SYS_DEL=/sys/bus/netdevsim/del_device
14NSIM_DEV_SYS_LINK=/sys/bus/netdevsim/link_device
15NSIM_DEV_SYS_UNLINK=/sys/bus/netdevsim/unlink_device
16
17socat_check()
18{
19	if [ ! -x "$(command -v socat)" ]; then
20		echo "socat command not found. Skipping test"
21		return 1
22	fi
23
24	return 0
25}
26
27setup_ns()
28{
29	set -e
30	ip netns add nssv
31	ip netns add nscl
32
33	NSIM_DEV_1_NAME=$(find $NSIM_DEV_1_SYS/net -maxdepth 1 -type d ! \
34		-path $NSIM_DEV_1_SYS/net -exec basename {} \;)
35	NSIM_DEV_2_NAME=$(find $NSIM_DEV_2_SYS/net -maxdepth 1 -type d ! \
36		-path $NSIM_DEV_2_SYS/net -exec basename {} \;)
37
38	ip link set $NSIM_DEV_1_NAME netns nssv
39	ip link set $NSIM_DEV_2_NAME netns nscl
40
41	ip netns exec nssv ip addr add '192.168.1.1/24' dev $NSIM_DEV_1_NAME
42	ip netns exec nscl ip addr add '192.168.1.2/24' dev $NSIM_DEV_2_NAME
43
44	ip netns exec nssv ip link set dev $NSIM_DEV_1_NAME up
45	ip netns exec nscl ip link set dev $NSIM_DEV_2_NAME up
46	set +e
47}
48
49cleanup_ns()
50{
51	ip netns del nscl
52	ip netns del nssv
53}
54
55###
56### Code start
57###
58
59socat_check || exit 4
60
61modprobe netdevsim
62
63# linking
64
65echo $NSIM_DEV_1_ID > $NSIM_DEV_SYS_NEW
66echo $NSIM_DEV_2_ID > $NSIM_DEV_SYS_NEW
67udevadm settle
68
69setup_ns
70
71NSIM_DEV_1_FD=$((256 + RANDOM % 256))
72exec {NSIM_DEV_1_FD}</var/run/netns/nssv
73NSIM_DEV_1_IFIDX=$(ip netns exec nssv cat /sys/class/net/$NSIM_DEV_1_NAME/ifindex)
74
75NSIM_DEV_2_FD=$((256 + RANDOM % 256))
76exec {NSIM_DEV_2_FD}</var/run/netns/nscl
77NSIM_DEV_2_IFIDX=$(ip netns exec nscl cat /sys/class/net/$NSIM_DEV_2_NAME/ifindex)
78
79echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:2000" > $NSIM_DEV_SYS_LINK 2>/dev/null
80if [ $? -eq 0 ]; then
81	echo "linking with non-existent netdevsim should fail"
82	cleanup_ns
83	exit 1
84fi
85
86echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX 2000:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK 2>/dev/null
87if [ $? -eq 0 ]; then
88	echo "linking with non-existent netnsid should fail"
89	cleanup_ns
90	exit 1
91fi
92
93echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > $NSIM_DEV_SYS_LINK 2>/dev/null
94if [ $? -eq 0 ]; then
95	echo "linking with self should fail"
96	cleanup_ns
97	exit 1
98fi
99
100echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:$NSIM_DEV_2_IFIDX" > $NSIM_DEV_SYS_LINK
101if [ $? -ne 0 ]; then
102	echo "linking netdevsim1 with netdevsim2 should succeed"
103	cleanup_ns
104	exit 1
105fi
106
107# argument error checking
108
109echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX $NSIM_DEV_2_FD:a" > $NSIM_DEV_SYS_LINK 2>/dev/null
110if [ $? -eq 0 ]; then
111	echo "invalid arg should fail"
112	cleanup_ns
113	exit 1
114fi
115
116# send/recv packets
117
118tmp_file=$(mktemp)
119ip netns exec nssv socat TCP-LISTEN:1234,fork $tmp_file &
120pid=$!
121res=0
122
123wait_local_port_listen nssv 1234 tcp
124
125echo "HI" | ip netns exec nscl socat STDIN TCP:192.168.1.1:1234
126
127count=$(cat $tmp_file | wc -c)
128if [[ $count -ne 3 ]]; then
129	echo "expected 3 bytes, got $count"
130	res=1
131fi
132
133echo "$NSIM_DEV_1_FD:$NSIM_DEV_1_IFIDX" > $NSIM_DEV_SYS_UNLINK
134
135echo $NSIM_DEV_2_ID > $NSIM_DEV_SYS_DEL
136
137kill $pid
138echo $NSIM_DEV_1_ID > $NSIM_DEV_SYS_DEL
139
140cleanup_ns
141
142modprobe -r netdevsim
143
144exit $res
145