forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drivers: net: loopback: Network loopback interface driver
Loopback is a networking interface which doesn't actually transfer any data via link layer externally, and instead just mirrors back (i.e. any packet send to the loopback interface will be received from it). This interface very useful for testing. Signed-off-by: Paul Sokolovsky <[email protected]>
- Loading branch information
Showing
3 changed files
with
113 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
obj-$(CONFIG_SLIP) = slip.o | ||
obj-$(CONFIG_NET_LOOPBACK) = loopback.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
/* | ||
* Copyright (c) 2015 Intel Corporation | ||
* Copyright (c) 2017 Linaro Limited | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
/** | ||
* @file | ||
* | ||
* Network loopback interface implementation. | ||
*/ | ||
|
||
#define SYS_LOG_DOMAIN "netlo" | ||
#define SYS_LOG_LEVEL CONFIG_SYS_LOG_NETLO_LEVEL | ||
#include <logging/sys_log.h> | ||
|
||
#include <misc/printk.h> | ||
|
||
#include <net/net_pkt.h> | ||
#include <net/buf.h> | ||
#include <net/net_ip.h> | ||
#include <net/net_if.h> | ||
|
||
int loopback_dev_init(struct device *dev) | ||
{ | ||
return 0; | ||
} | ||
|
||
static void loopback_init(struct net_if *iface) | ||
{ | ||
/* RFC 7042, s.2.1.1. address to use in documentation */ | ||
net_if_set_link_addr(iface, "\x00\x00\x5e\x00\x53\xff", 6, | ||
NET_LINK_DUMMY); | ||
} | ||
|
||
static int loopback_send(struct net_if *iface, struct net_pkt *pkt) | ||
{ | ||
int res; | ||
|
||
if (!pkt->frags) { | ||
SYS_LOG_ERR("No data to send"); | ||
return -ENODATA; | ||
} | ||
|
||
/* We need to swap the IP addresses because otherwise | ||
* the packet will be dropped. | ||
*/ | ||
|
||
if (net_pkt_family(pkt) == AF_INET6) { | ||
struct in6_addr addr; | ||
|
||
net_ipaddr_copy(&addr, &NET_IPV6_HDR(pkt)->src); | ||
net_ipaddr_copy(&NET_IPV6_HDR(pkt)->src, | ||
&NET_IPV6_HDR(pkt)->dst); | ||
net_ipaddr_copy(&NET_IPV6_HDR(pkt)->dst, &addr); | ||
} else { | ||
struct in_addr addr; | ||
|
||
net_ipaddr_copy(&addr, &NET_IPV4_HDR(pkt)->src); | ||
net_ipaddr_copy(&NET_IPV4_HDR(pkt)->src, | ||
&NET_IPV4_HDR(pkt)->dst); | ||
net_ipaddr_copy(&NET_IPV4_HDR(pkt)->dst, &addr); | ||
} | ||
|
||
res = net_recv_data(iface, pkt); | ||
if (res < 0) { | ||
SYS_LOG_ERR("Data receive failed."); | ||
net_pkt_unref(pkt); | ||
return res; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
static struct net_if_api loopback_if_api = { | ||
.init = loopback_init, | ||
.send = loopback_send, | ||
}; | ||
|
||
NET_DEVICE_INIT(loopback, "lo", | ||
loopback_dev_init, NULL, NULL, | ||
CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, | ||
&loopback_if_api, DUMMY_L2, | ||
NET_L2_GET_CTX_TYPE(DUMMY_L2), 536); |