Skip to content

Commit 1058a65

Browse files
jukkarnashif
authored andcommitted
tests: net: af_packet: Add test for binding with multiple interfaces
Add a simple test to verify that the bind() can be called multiple times if AF_PACKET is set and there are multiple network interfaces in the system. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 06cd001 commit 1058a65

File tree

4 files changed

+188
-0
lines changed

4 files changed

+188
-0
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.13.1)
4+
include($ENV{ZEPHYR_BASE}/cmake/app/boilerplate.cmake NO_POLICY_SCOPE)
5+
project(socket_udp)
6+
7+
target_include_directories(app PRIVATE $ENV{ZEPHYR_BASE}/subsys/net/ip)
8+
FILE(GLOB app_sources src/*.c)
9+
target_sources(app PRIVATE ${app_sources})
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Networking config
2+
CONFIG_NETWORKING=y
3+
CONFIG_NET_IPV4=n
4+
CONFIG_NET_IPV6=n
5+
CONFIG_NET_UDP=n
6+
CONFIG_NET_TCP=n
7+
CONFIG_NET_SOCKETS=y
8+
CONFIG_NET_SOCKETS_POSIX_NAMES=y
9+
CONFIG_NET_SOCKETS_PACKET=y
10+
CONFIG_POSIX_MAX_FDS=2
11+
CONFIG_NET_IPV6_DAD=n
12+
CONFIG_NET_IPV6_MLD=n
13+
14+
# Network driver config
15+
CONFIG_NET_L2_ETHERNET=y
16+
CONFIG_TEST_RANDOM_GENERATOR=y
17+
18+
# Network address config
19+
CONFIG_NET_CONFIG_SETTINGS=n
20+
CONFIG_NET_CONFIG_NEED_IPV4=n
21+
CONFIG_NET_CONFIG_NEED_IPV6=n
22+
23+
CONFIG_ZTEST=y
24+
CONFIG_NET_TEST=y
25+
CONFIG_TEST_USERSPACE=y
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Copyright (c) 2020 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <logging/log.h>
8+
LOG_MODULE_REGISTER(net_test, CONFIG_NET_SOCKETS_LOG_LEVEL);
9+
10+
#include <stdio.h>
11+
#include <ztest_assert.h>
12+
13+
#include <net/socket.h>
14+
#include <net/ethernet.h>
15+
16+
#if defined(CONFIG_NET_SOCKETS_LOG_LEVEL_DBG)
17+
#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__)
18+
#else
19+
#define DBG(fmt, ...)
20+
#endif
21+
22+
static u8_t lladdr1[] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 };
23+
static u8_t lladdr2[] = { 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 };
24+
25+
struct eth_fake_context {
26+
struct net_if *iface;
27+
u8_t *mac_address;
28+
};
29+
30+
static struct eth_fake_context eth_fake_data1 = {
31+
.mac_address = lladdr1
32+
};
33+
static struct eth_fake_context eth_fake_data2 = {
34+
.mac_address = lladdr2
35+
};
36+
37+
static int eth_fake_send(struct device *dev, struct net_pkt *pkt)
38+
{
39+
ARG_UNUSED(dev);
40+
ARG_UNUSED(pkt);
41+
42+
return 0;
43+
}
44+
45+
static void eth_fake_iface_init(struct net_if *iface)
46+
{
47+
struct device *dev = net_if_get_device(iface);
48+
struct eth_fake_context *ctx = dev->driver_data;
49+
50+
ctx->iface = iface;
51+
52+
net_if_set_link_addr(iface, ctx->mac_address, 6, NET_LINK_ETHERNET);
53+
54+
ethernet_init(iface);
55+
}
56+
57+
static struct ethernet_api eth_fake_api_funcs = {
58+
.iface_api.init = eth_fake_iface_init,
59+
.send = eth_fake_send,
60+
};
61+
62+
static int eth_fake_init(struct device *dev)
63+
{
64+
ARG_UNUSED(dev);
65+
66+
return 0;
67+
}
68+
69+
ETH_NET_DEVICE_INIT(eth_fake1, "eth_fake1", eth_fake_init, &eth_fake_data1,
70+
NULL, CONFIG_ETH_INIT_PRIORITY, &eth_fake_api_funcs,
71+
NET_ETH_MTU);
72+
73+
ETH_NET_DEVICE_INIT(eth_fake2, "eth_fake2", eth_fake_init, &eth_fake_data2,
74+
NULL, CONFIG_ETH_INIT_PRIORITY, &eth_fake_api_funcs,
75+
NET_ETH_MTU);
76+
77+
static int setup_socket(struct net_if *iface)
78+
{
79+
int sock;
80+
81+
sock = socket(AF_PACKET, SOCK_RAW, ETH_P_ALL);
82+
zassert_true(sock >= 0, "Cannot create packet socket (%d)", sock);
83+
84+
return sock;
85+
}
86+
87+
static int bind_socket(int sock, struct net_if *iface)
88+
{
89+
struct sockaddr_ll addr;
90+
91+
memset(&addr, 0, sizeof(addr));
92+
93+
addr.sll_ifindex = net_if_get_by_iface(iface);
94+
addr.sll_family = AF_PACKET;
95+
96+
return bind(sock, (struct sockaddr *)&addr, sizeof(addr));
97+
}
98+
99+
struct user_data {
100+
struct net_if *first;
101+
struct net_if *second;
102+
};
103+
104+
static void iface_cb(struct net_if *iface, void *user_data)
105+
{
106+
struct user_data *ud = user_data;
107+
108+
if (net_if_l2(iface) != &NET_L2_GET_NAME(ETHERNET)) {
109+
return;
110+
}
111+
112+
if (ud->first == NULL) {
113+
ud->first = iface;
114+
return;
115+
}
116+
117+
ud->second = iface;
118+
}
119+
120+
static void test_packet_sockets(void)
121+
{
122+
struct user_data ud = { 0 };
123+
int ret, sock1, sock2;
124+
125+
net_if_foreach(iface_cb, &ud);
126+
127+
zassert_not_null(ud.first, "1st Ethernet interface not found");
128+
zassert_not_null(ud.second, "2nd Ethernet interface not found");
129+
130+
sock1 = setup_socket(ud.first);
131+
zassert_true(sock1 >= 0, "Cannot create 1st socket (%d)", sock1);
132+
133+
sock2 = setup_socket(ud.second);
134+
zassert_true(sock2 >= 0, "Cannot create 2nd socket (%d)", sock2);
135+
136+
ret = bind_socket(sock1, ud.first);
137+
zassert_equal(ret, 0, "Cannot bind 1st socket (%d)", -errno);
138+
139+
ret = bind_socket(sock2, ud.second);
140+
zassert_equal(ret, 0, "Cannot bind 2nd socket (%d)", -errno);
141+
}
142+
143+
void test_main(void)
144+
{
145+
ztest_test_suite(socket_packet,
146+
ztest_unit_test(test_packet_sockets));
147+
ztest_run_test_suite(socket_packet);
148+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
common:
2+
depends_on: netif
3+
tags: net socket af_packet
4+
tests:
5+
net.socket.packet:
6+
min_ram: 21

0 commit comments

Comments
 (0)