Skip to content

Commit a2a0cc8

Browse files
jukkarkartben
authored andcommitted
tests: net: vlan: Add testing of link layer header embedding
Create a special Ethernet interface that supports link layer embedding. Add a test that uses this special Ethernet interface to verify that the L2 header is embedded to the first net_buf. Signed-off-by: Jukka Rissanen <[email protected]>
1 parent 420c4b1 commit a2a0cc8

File tree

3 files changed

+136
-9
lines changed

3 files changed

+136
-9
lines changed

tests/net/vlan/prj.conf

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,18 @@ CONFIG_NET_PKT_TX_COUNT=15
1616
CONFIG_NET_PKT_RX_COUNT=15
1717
CONFIG_NET_BUF_RX_COUNT=15
1818
CONFIG_NET_BUF_TX_COUNT=15
19-
CONFIG_NET_IF_MAX_IPV6_COUNT=8
19+
CONFIG_NET_IF_MAX_IPV6_COUNT=9
2020
CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6
2121
CONFIG_NET_IPV6_ND=n
2222
CONFIG_NET_VLAN=y
23-
CONFIG_NET_VLAN_COUNT=4
23+
CONFIG_NET_VLAN_COUNT=5
2424
CONFIG_NET_CONTEXT_PRIORITY=y
2525
CONFIG_NET_SOCKETS=y
2626
CONFIG_ZTEST=y
2727
CONFIG_NET_CONFIG_SETTINGS=n
2828
CONFIG_NET_SHELL=n
29+
CONFIG_NET_INTERFACE_NAME=y
30+
CONFIG_NET_INTERFACE_NAME_LEN=15
2931

3032
# The address check must be disabled so that packet
3133
# is properly routed via Ethernet L2.

tests/net/vlan/src/main.c

Lines changed: 122 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL);
5151
#define VLAN_TAG_3 300
5252
#define VLAN_TAG_4 400
5353
#define VLAN_TAG_5 500
54+
#define VLAN_TAG_6 600
5455

5556
#define NET_ETH_MAX_COUNT 2
5657

@@ -78,6 +79,7 @@ static struct in6_addr ll_addr = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0,
7879
static struct net_if *eth_interfaces[NET_ETH_MAX_COUNT];
7980
static struct net_if *vlan_interfaces[NET_VLAN_MAX_COUNT];
8081
static struct net_if *dummy_interfaces[2];
82+
static struct net_if *embed_ll_interface;
8183

8284
static bool test_failed;
8385
static bool test_started;
@@ -125,6 +127,13 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt)
125127
struct eth_context *context = dev->data;
126128
int ret;
127129

130+
if (!IS_ENABLED(CONFIG_NET_L2_ETHERNET_RESERVE_HEADER)) {
131+
/* There should be at least two net_buf. The first one should contain
132+
* the link layer header.
133+
*/
134+
zassert_not_equal(pkt->buffer->frags, NULL, "Only one net_buf in chain!");
135+
}
136+
128137
zassert_equal_ptr(&eth_vlan_context, context,
129138
"Context pointers do not match (%p vs %p)",
130139
eth_vlan_context, context);
@@ -159,15 +168,15 @@ static int eth_tx(const struct device *dev, struct net_pkt *pkt)
159168
return ret;
160169
}
161170

162-
static enum ethernet_hw_caps eth_capabilities(const struct device *dev)
171+
static enum ethernet_hw_caps eth_vlan_capabilities(const struct device *dev)
163172
{
164173
return ETHERNET_HW_VLAN;
165174
}
166175

167176
static struct ethernet_api api_funcs = {
168177
.iface_api.init = eth_vlan_iface_init,
169178

170-
.get_capabilities = eth_capabilities,
179+
.get_capabilities = eth_vlan_capabilities,
171180
.send = eth_tx,
172181
};
173182

@@ -209,6 +218,37 @@ ETH_NET_DEVICE_INIT(eth_test, "eth_test", eth_init, NULL,
209218
&eth_vlan_context, NULL, CONFIG_ETH_INIT_PRIORITY,
210219
&api_funcs, NET_ETH_MTU);
211220

221+
static int eth_tx_embed_ll_hdr(const struct device *dev, struct net_pkt *pkt)
222+
{
223+
if (IS_ENABLED(CONFIG_NET_L2_ETHERNET_RESERVE_HEADER)) {
224+
/* There should be only one net_buf */
225+
zassert_equal(pkt->buffer->frags, NULL, "More than one net_buf in chain!");
226+
}
227+
228+
if (test_started) {
229+
k_sleep(K_MSEC(10));
230+
k_sem_give(&wait_data);
231+
}
232+
233+
return 0;
234+
}
235+
236+
static enum ethernet_hw_caps eth_vlan_embed_ll_hdr_capabilities(const struct device *dev)
237+
{
238+
return ETHERNET_HW_VLAN;
239+
}
240+
241+
static struct ethernet_api api_vlan_embed_ll_hdr_funcs = {
242+
.iface_api.init = eth_vlan_iface_init,
243+
244+
.get_capabilities = eth_vlan_embed_ll_hdr_capabilities,
245+
.send = eth_tx_embed_ll_hdr,
246+
};
247+
248+
ETH_NET_DEVICE_INIT(eth_embed_ll_hdr_test, "eth_embed_ll_hdr_test", eth_init, NULL,
249+
&eth_vlan_context, NULL, CONFIG_ETH_INIT_PRIORITY,
250+
&api_vlan_embed_ll_hdr_funcs, NET_ETH_MTU);
251+
212252
struct net_if_test {
213253
uint8_t idx; /* not used for anything, just a dummy value */
214254
uint8_t mac_addr[sizeof(struct net_eth_addr)];
@@ -317,6 +357,16 @@ static void iface_cb(struct net_if *iface, void *user_data)
317357
net_if_get_by_iface(iface));
318358

319359
if (net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET)) {
360+
/* Ignore one special interface that is used to validate
361+
* ll header embedding.
362+
*/
363+
if (strncmp(net_if_get_device(iface)->name,
364+
"eth_embed_ll_hdr_test",
365+
sizeof("eth_embed_ll_hdr_test") - 1) == 0) {
366+
embed_ll_interface = iface;
367+
return;
368+
}
369+
320370
eth_interfaces[ud->eth_if_count++] = iface;
321371
}
322372

@@ -836,6 +886,76 @@ ZTEST(net_vlan, test_vlan_ipv6_sendto_recvfrom)
836886
zassert_equal(ret, 0, "close failed");
837887
}
838888

889+
/* This should be the last test to be run so add "zz" to the name */
890+
ZTEST(net_vlan, test_zz_vlan_embed_ll_hdr)
891+
{
892+
struct net_if *iface;
893+
int ret;
894+
int client_sock;
895+
struct sockaddr_in6 client_addr;
896+
struct sockaddr_in6 dest_addr;
897+
struct net_if_addr *ifaddr;
898+
ssize_t sent = 0;
899+
struct ifreq ifreq = { 0 };
900+
char ifname[CONFIG_NET_INTERFACE_NAME_LEN];
901+
902+
/* embed ll interface addresses */
903+
static struct in6_addr my_vlan_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0x90, 0, 0, 0,
904+
0, 0, 0, 0, 0, 0, 0, 0x2 } } };
905+
906+
static struct in6_addr peer_vlan_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 0x90, 0, 0, 0,
907+
0, 0, 0, 0, 0, 0, 0, 0x1 } } };
908+
909+
ret = net_eth_vlan_enable(embed_ll_interface, VLAN_TAG_6);
910+
zassert_equal(ret, 0, "Could not enable %d (%d)", VLAN_TAG_6, ret);
911+
912+
iface = net_eth_get_vlan_iface(embed_ll_interface, VLAN_TAG_6);
913+
ret = net_eth_is_vlan_enabled(NULL, embed_ll_interface);
914+
zassert_equal(ret, true, "VLAN not enabled for interface");
915+
916+
ifaddr = net_if_ipv6_addr_add(iface,
917+
&my_vlan_addr,
918+
NET_ADDR_MANUAL, 0);
919+
if (!ifaddr) {
920+
DBG("Cannot add IPv6 address %s\n",
921+
net_sprint_ipv6_addr(&my_vlan_addr));
922+
zassert_not_null(ifaddr, "vlan addr");
923+
}
924+
925+
net_if_up(embed_ll_interface);
926+
net_if_up(iface);
927+
928+
test_started = true;
929+
930+
prepare_sock_udp_v6("2001:db8:90::2", ANY_PORT, &client_sock, &client_addr);
931+
932+
ret = net_if_get_name(iface, ifname, sizeof(ifname));
933+
zassert_true(ret > 0, "cannot get interface name (%d/%s)", ret, strerror(-ret));
934+
935+
strncpy(ifreq.ifr_name, ifname, sizeof(ifreq.ifr_name));
936+
ret = zsock_setsockopt(client_sock, SOL_SOCKET, SO_BINDTODEVICE, &ifreq,
937+
sizeof(ifreq));
938+
zassert_equal(ret, 0, "SO_BINDTODEVICE failed, %d", -errno);
939+
940+
ret = add_neighbor(iface, &peer_vlan_addr);
941+
zassert_true(ret, "Cannot add neighbor");
942+
943+
net_ipaddr_copy(&dest_addr.sin6_addr, &peer_vlan_addr);
944+
945+
sent = zsock_sendto(client_sock, TEST_STR_SMALL, strlen(TEST_STR_SMALL),
946+
0, (struct sockaddr *)&dest_addr, sizeof(dest_addr));
947+
zassert_equal(sent, strlen(TEST_STR_SMALL), "send (%d) failed %d/%s",
948+
sent, -errno, strerror(errno));
949+
950+
if (k_sem_take(&wait_data, WAIT_TIME)) {
951+
DBG("Timeout while waiting interface data\n");
952+
zassert_false(true, "Timeout");
953+
}
954+
955+
ret = zsock_close(client_sock);
956+
zassert_equal(ret, 0, "close failed");
957+
}
958+
839959
static void *setup(void)
840960
{
841961
test_vlan_setup();

tests/net/vlan/testcase.yaml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
common:
22
depends_on: netif
3+
min_ram: 32
4+
tags:
5+
- net
6+
- vlan
37
tests:
4-
net.vlan:
5-
min_ram: 32
6-
tags:
7-
- net
8-
- vlan
8+
net.vlan.separate_net_buf:
9+
extra_configs:
10+
- CONFIG_NET_L2_ETHERNET_RESERVE_HEADER=n
11+
net.vlan.header_reserved:
12+
extra_configs:
13+
- CONFIG_NET_L2_ETHERNET_RESERVE_HEADER=y

0 commit comments

Comments
 (0)