Skip to content

Commit 686830b

Browse files
rveerama1jukkar
authored andcommitted
drivers: native_posix: Add VLAN tag strip feature
This is mainly testing purpose from native_posize ethernet driver. Enable CONFIG_ETH_NATIVE_POSIX_VLAN_TAG_STRIP to have VLAN tag strip feature on ethernet Rx frames. Signed-off-by: Ravi kumar Veeramally <[email protected]>
1 parent 543eecb commit 686830b

File tree

3 files changed

+115
-24
lines changed

3 files changed

+115
-24
lines changed

drivers/ethernet/Kconfig.native_posix

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,14 @@ config ETH_NATIVE_POSIX_RANDOM_MAC
9494
help
9595
Generate a random MAC address dynamically.
9696

97+
config ETH_NATIVE_POSIX_VLAN_TAG_STRIP
98+
bool "Strip VLAN tag from Rx frames"
99+
depends on NET_VLAN
100+
help
101+
Native posix ethernet driver will strip of VLAN tag from
102+
Rx Ethernet frames and sets tag information in net packet
103+
metadata.
104+
97105
if ! ETH_NATIVE_POSIX_RANDOM_MAC
98106

99107
config ETH_NATIVE_POSIX_MAC_ADDR

drivers/ethernet/eth_native_posix.c

Lines changed: 105 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -231,55 +231,133 @@ static inline struct net_if *get_iface(struct eth_context *ctx,
231231
#endif
232232
}
233233

234-
static int read_data(struct eth_context *ctx, int fd)
234+
#if defined(CONFIG_NET_VLAN)
235+
static struct net_pkt *prepare_vlan_pkt(struct eth_context *ctx,
236+
int count, u16_t *vlan_tag, int *status)
235237
{
236-
u16_t vlan_tag = NET_VLAN_TAG_UNSPEC;
237-
struct net_if *iface;
238+
struct net_eth_vlan_hdr *hdr = (struct net_eth_vlan_hdr *)ctx->recv;
238239
struct net_pkt *pkt;
239-
int count;
240+
u8_t pos;
240241

241-
count = eth_read_data(fd, ctx->recv, sizeof(ctx->recv));
242-
if (count <= 0) {
243-
return 0;
242+
if (IS_ENABLED(CONFIG_ETH_NATIVE_POSIX_VLAN_TAG_STRIP)) {
243+
count -= NET_ETH_VLAN_HDR_SIZE;
244244
}
245245

246246
pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, count,
247247
AF_UNSPEC, 0, NET_BUF_TIMEOUT);
248248
if (!pkt) {
249-
return -ENOMEM;
249+
*status = -ENOMEM;
250+
return NULL;
251+
}
252+
253+
net_pkt_set_vlan_tci(pkt, ntohs(hdr->vlan.tci));
254+
*vlan_tag = net_pkt_vlan_tag(pkt);
255+
256+
pos = 0;
257+
258+
if (IS_ENABLED(CONFIG_ETH_NATIVE_POSIX_VLAN_TAG_STRIP)) {
259+
if (net_pkt_write(pkt, ctx->recv,
260+
2 * sizeof(struct net_eth_addr))) {
261+
goto error;
262+
}
263+
264+
pos = (2 * sizeof(struct net_eth_addr)) + NET_ETH_VLAN_HDR_SIZE;
265+
count -= (2 * sizeof(struct net_eth_addr));
266+
}
267+
268+
if (net_pkt_write(pkt, ctx->recv + pos, count)) {
269+
goto error;
270+
}
271+
272+
#if CONFIG_NET_TC_RX_COUNT > 1
273+
{
274+
enum net_priority prio;
275+
276+
prio = net_vlan2priority(net_pkt_vlan_priority(pkt));
277+
net_pkt_set_priority(pkt, prio);
278+
}
279+
#endif
280+
281+
*status = 0;
282+
283+
LOG_DBG("Recv pkt %p len %d", pkt, count);
284+
285+
return pkt;
286+
287+
error:
288+
net_pkt_unref(pkt);
289+
*status = -ENOBUFS;
290+
return NULL;
291+
}
292+
#endif
293+
294+
static struct net_pkt *prepare_non_vlan_pkt(struct eth_context *ctx,
295+
int count, int *status)
296+
{
297+
struct net_pkt *pkt;
298+
299+
pkt = net_pkt_rx_alloc_with_buffer(ctx->iface, count,
300+
AF_UNSPEC, 0, NET_BUF_TIMEOUT);
301+
if (!pkt) {
302+
*status = -ENOMEM;
303+
return NULL;
250304
}
251305

252306
if (net_pkt_write(pkt, ctx->recv, count)) {
253-
return -ENOBUFS;
307+
net_pkt_unref(pkt);
308+
*status = -ENOBUFS;
309+
return NULL;
310+
}
311+
312+
*status = 0;
313+
314+
LOG_DBG("Recv pkt %p len %d", pkt, count);
315+
316+
return pkt;
317+
}
318+
319+
static int read_data(struct eth_context *ctx, int fd)
320+
{
321+
u16_t vlan_tag = NET_VLAN_TAG_UNSPEC;
322+
struct net_if *iface;
323+
struct net_pkt *pkt = NULL;
324+
int status;
325+
int count;
326+
327+
count = eth_read_data(fd, ctx->recv, sizeof(ctx->recv));
328+
if (count <= 0) {
329+
return 0;
254330
}
255331

256332
#if defined(CONFIG_NET_VLAN)
257333
{
258-
struct net_eth_hdr *hdr = NET_ETH_HDR(pkt);
334+
struct net_eth_hdr *hdr = (struct net_eth_hdr *)(ctx->recv);
259335

260336
if (ntohs(hdr->type) == NET_ETH_PTYPE_VLAN) {
261-
struct net_eth_vlan_hdr *hdr_vlan =
262-
(struct net_eth_vlan_hdr *)NET_ETH_HDR(pkt);
337+
pkt = prepare_vlan_pkt(ctx, count, &vlan_tag, &status);
338+
if (!pkt) {
339+
return status;
340+
}
341+
} else {
342+
pkt = prepare_non_vlan_pkt(ctx, count, &status);
343+
if (!pkt) {
344+
return status;
345+
}
263346

264-
net_pkt_set_vlan_tci(pkt, ntohs(hdr_vlan->vlan.tci));
265-
vlan_tag = net_pkt_vlan_tag(pkt);
347+
net_pkt_set_vlan_tci(pkt, 0);
266348
}
267-
268-
#if CONFIG_NET_TC_RX_COUNT > 1
269-
{
270-
enum net_priority prio;
271-
272-
prio = net_vlan2priority(net_pkt_vlan_priority(pkt));
273-
net_pkt_set_priority(pkt, prio);
349+
}
350+
#else
351+
{
352+
pkt = prepare_non_vlan_pkt(ctx, count, &status);
353+
if (!pkt) {
354+
return status;
274355
}
275-
#endif
276356
}
277357
#endif
278358

279359
iface = get_iface(ctx, vlan_tag);
280360

281-
LOG_DBG("Recv pkt %p len %d", pkt, count);
282-
283361
update_gptp(iface, pkt, false);
284362

285363
if (net_recv_data(iface, pkt) < 0) {
@@ -384,6 +462,9 @@ enum ethernet_hw_caps eth_posix_native_get_capabilities(struct device *dev)
384462
ARG_UNUSED(dev);
385463

386464
return ETHERNET_HW_VLAN
465+
#if defined(CONFIG_ETH_NATIVE_POSIX_VLAN_TAG_STRIP)
466+
| ETHERNET_HW_VLAN_TAG_STRIP
467+
#endif
387468
#if defined(CONFIG_ETH_NATIVE_POSIX_PTP_CLOCK)
388469
| ETHERNET_PTP
389470
#endif

include/net/ethernet.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ struct net_eth_addr {
7575
#define NET_ETH_MTU 1500
7676
#define NET_ETH_MAX_FRAME_SIZE (NET_ETH_MTU + sizeof(struct net_eth_hdr))
7777

78+
#define NET_ETH_VLAN_HDR_SIZE 4
79+
7880
/** @endcond */
7981

8082
/** Ethernet hardware capabilities */

0 commit comments

Comments
 (0)