Skip to content

Commit 4c996ec

Browse files
committed
[nrf fromlist] tests: net: sockets: misc: Fix SO_BINDTODEVICE test
The test case for SO_BINDTODEVICE socket option was flaky, the client socket always sent the datagram to the IP address of the second interface, so in theory every packet should end up on that interface. In practice though, due to imperfect loopback packet handling, the test worked as the packet ended up on the interface it was sent from. The test should send datagrams to the IP addresses of the interface 1 and 2 alternatively. The server socket binds to ANY address, so w/o interface binding it should receive all datagrams, so it allows to verify if SO_BINDTODEVICE filtering works fine. Upstream PR: zephyrproject-rtos/zephyr#76150 Signed-off-by: Robert Lubos <[email protected]>
1 parent 8587f90 commit 4c996ec

File tree

1 file changed

+34
-28
lines changed
  • tests/net/socket/misc/src

1 file changed

+34
-28
lines changed

tests/net/socket/misc/src/main.c

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,9 @@ NET_DEVICE_INIT(dummy_2, DEV2_NAME, NULL, NULL, &dummy_data2, NULL,
166166
#define DST_PORT 4242
167167
#define BIND_PORT 4240
168168

169-
void test_so_bindtodevice(int sock_c, int sock_s, struct sockaddr *peer_addr,
170-
socklen_t peer_addrlen, struct sockaddr *bind_addr,
171-
socklen_t bind_addrlen)
169+
void test_so_bindtodevice(int sock_c, int sock_s, struct sockaddr *peer_addr_1,
170+
struct sockaddr *peer_addr_2, socklen_t peer_addrlen,
171+
struct sockaddr *bind_addr, socklen_t bind_addrlen)
172172
{
173173
int ret;
174174
struct ifreq ifreq = { 0 };
@@ -203,7 +203,7 @@ void test_so_bindtodevice(int sock_c, int sock_s, struct sockaddr *peer_addr,
203203
zassert_equal(ret, 0, "SO_BINDTODEVICE failed, %d", errno);
204204

205205
ret = zsock_sendto(sock_c, send_buf, strlen(send_buf) + 1, 0,
206-
peer_addr, peer_addrlen);
206+
peer_addr_1, peer_addrlen);
207207
zassert_equal(ret, strlen(send_buf) + 1, "sendto failed, %d", errno);
208208

209209
ret = sys_sem_take(&send_sem, K_MSEC(100));
@@ -228,7 +228,7 @@ void test_so_bindtodevice(int sock_c, int sock_s, struct sockaddr *peer_addr,
228228
zassert_equal(ret, 0, "SO_BINDTODEVICE failed, %d", errno);
229229

230230
ret = zsock_sendto(sock_c, send_buf, strlen(send_buf) + 1, 0,
231-
peer_addr, peer_addrlen);
231+
peer_addr_2, peer_addrlen);
232232
zassert_equal(ret, strlen(send_buf) + 1, "sendto failed, %d", errno);
233233

234234
ret = sys_sem_take(&send_sem, K_MSEC(100));
@@ -266,7 +266,7 @@ void test_so_bindtodevice(int sock_c, int sock_s, struct sockaddr *peer_addr,
266266
zassert_equal(ret, 0, "SO_BINDTODEVICE failed, %d", errno);
267267

268268
ret = zsock_sendto(sock_c, send_buf, strlen(send_buf) + 1, 0,
269-
peer_addr, peer_addrlen);
269+
peer_addr_1, peer_addrlen);
270270
zassert_equal(ret, strlen(send_buf) + 1, "sendto failed, %d", errno);
271271

272272
ret = sys_sem_take(&send_sem, K_MSEC(100));
@@ -295,10 +295,18 @@ void test_so_bindtodevice(int sock_c, int sock_s, struct sockaddr *peer_addr,
295295

296296
void test_ipv4_so_bindtodevice(void)
297297
{
298-
int ret;
299298
int sock_c;
300299
int sock_s;
301-
struct sockaddr_in peer_addr;
300+
struct sockaddr_in peer_addr_1 = {
301+
.sin_family = AF_INET,
302+
.sin_port = htons(DST_PORT),
303+
.sin_addr = { { { 192, 0, 2, 1 } } },
304+
};
305+
struct sockaddr_in peer_addr_2 = {
306+
.sin_family = AF_INET,
307+
.sin_port = htons(DST_PORT),
308+
.sin_addr = { { { 192, 0, 2, 2 } } },
309+
};
302310
struct sockaddr_in bind_addr = {
303311
.sin_family = AF_INET,
304312
.sin_port = htons(DST_PORT),
@@ -310,23 +318,27 @@ void test_ipv4_so_bindtodevice(void)
310318
sock_s = zsock_socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
311319
zassert_true(sock_s >= 0, "socket open failed");
312320

313-
peer_addr.sin_family = AF_INET;
314-
peer_addr.sin_port = htons(DST_PORT);
315-
ret = zsock_inet_pton(AF_INET, TEST_PEER_IPV4_ADDR,
316-
&peer_addr.sin_addr);
317-
zassert_equal(ret, 1, "inet_pton failed");
318-
319-
test_so_bindtodevice(sock_c, sock_s, (struct sockaddr *)&peer_addr,
320-
sizeof(peer_addr), (struct sockaddr *)&bind_addr,
321-
sizeof(bind_addr));
321+
test_so_bindtodevice(sock_c, sock_s, (struct sockaddr *)&peer_addr_1,
322+
(struct sockaddr *)&peer_addr_2, sizeof(peer_addr_1),
323+
(struct sockaddr *)&bind_addr, sizeof(bind_addr));
322324
}
323325

324326
void test_ipv6_so_bindtodevice(void)
325327
{
326-
int ret;
327328
int sock_c;
328329
int sock_s;
329-
struct sockaddr_in6 peer_addr;
330+
struct sockaddr_in6 peer_addr_1 = {
331+
.sin6_family = AF_INET6,
332+
.sin6_port = htons(DST_PORT),
333+
.sin6_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
334+
0, 0, 0, 0, 0, 0, 0, 0x1 } } },
335+
};
336+
struct sockaddr_in6 peer_addr_2 = {
337+
.sin6_family = AF_INET6,
338+
.sin6_port = htons(DST_PORT),
339+
.sin6_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0,
340+
0, 0, 0, 0, 0, 0, 0, 0x2 } } },
341+
};
330342
struct sockaddr_in6 bind_addr = {
331343
.sin6_family = AF_INET6,
332344
.sin6_port = htons(DST_PORT),
@@ -338,15 +350,9 @@ void test_ipv6_so_bindtodevice(void)
338350
sock_s = zsock_socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
339351
zassert_true(sock_s >= 0, "socket open failed");
340352

341-
peer_addr.sin6_family = AF_INET6;
342-
peer_addr.sin6_port = htons(DST_PORT);
343-
ret = zsock_inet_pton(AF_INET6, TEST_PEER_IPV6_ADDR,
344-
&peer_addr.sin6_addr);
345-
zassert_equal(ret, 1, "inet_pton failed");
346-
347-
test_so_bindtodevice(sock_c, sock_s, (struct sockaddr *)&peer_addr,
348-
sizeof(peer_addr), (struct sockaddr *)&bind_addr,
349-
sizeof(bind_addr));
353+
test_so_bindtodevice(sock_c, sock_s, (struct sockaddr *)&peer_addr_1,
354+
(struct sockaddr *)&peer_addr_2, sizeof(peer_addr_1),
355+
(struct sockaddr *)&bind_addr, sizeof(bind_addr));
350356
}
351357

352358
#define ADDR_SIZE(family) ((family == AF_INET) ? \

0 commit comments

Comments
 (0)