Skip to content

Commit

Permalink
drivers: net: loopback: Network loopback interface driver
Browse files Browse the repository at this point in the history
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
pfalcon authored and jukkar committed Oct 23, 2017
1 parent 0612651 commit 15c64b2
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 0 deletions.
27 changes: 27 additions & 0 deletions drivers/net/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,30 @@ config SLIP_MAC_ADDR
random.

endif

#
# Net loopback options
#
menuconfig NET_LOOPBACK
bool
prompt "Net loopback driver"
select NET_L2_DUMMY

if NET_LOOPBACK

config SYS_LOG_NET_LOOPBACK_LEVEL
int
prompt "Net loopback driver log level"
depends on SYS_LOG && NET_LOOPBACK
default 0
range 0 4
help
Sets log level for the driver.
Levels are:
0 OFF, do not write
1 ERROR, only write SYS_LOG_ERR
2 WARNING, write SYS_LOG_WRN in addition to previous level
3 INFO, write SYS_LOG_INF in addition to previous levels
4 DEBUG, write SYS_LOG_DBG in addition to previous levels

endif
1 change: 1 addition & 0 deletions drivers/net/Makefile
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
obj-$(CONFIG_SLIP) = slip.o
obj-$(CONFIG_NET_LOOPBACK) = loopback.o
85 changes: 85 additions & 0 deletions drivers/net/loopback.c
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);

0 comments on commit 15c64b2

Please sign in to comment.