drivers: net: loopback: Add interface to simulate packet drop

To allow for high level robustness tests on protocols, add an interface
to control the packet drop rate. A rate of 0 means no packet dropped, a
rate of 1 means all packets being dropped.

Signed-off-by: Sjors Hettinga <s.a.hettinga@gmail.com>
This commit is contained in:
Sjors Hettinga 2022-03-31 11:16:53 +02:00 committed by Maureen Helm
commit 951983191b
3 changed files with 71 additions and 0 deletions

View file

@ -183,6 +183,12 @@ menuconfig NET_LOOPBACK
if NET_LOOPBACK if NET_LOOPBACK
config NET_LOOPBACK_SIMULATE_PACKET_DROP
bool "Controlable packet drop"
help
Enable interface to have a controlable packet drop rate, only for
testing, should not be enabled for normal applications
module = NET_LOOPBACK module = NET_LOOPBACK
module-dep = LOG module-dep = LOG
module-str = Log level for network loopback driver module-str = Log level for network loopback driver

View file

@ -21,6 +21,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME);
#include <net/buf.h> #include <net/buf.h>
#include <net/net_ip.h> #include <net/net_ip.h>
#include <net/net_if.h> #include <net/net_if.h>
#include <net/loopback.h>
#include <net/dummy.h> #include <net/dummy.h>
@ -60,6 +61,20 @@ static void loopback_init(struct net_if *iface)
} }
} }
#ifdef CONFIG_NET_LOOPBACK_SIMULATE_PACKET_DROP
static float loopback_packet_drop_ratio = 0.0f;
static float loopback_packet_drop_state = 0.0f;
int loopback_set_packet_drop_ratio(float ratio)
{
if (ratio < 0.0f || ratio > 1.0f) {
return -EINVAL;
}
loopback_packet_drop_ratio = ratio;
return 0;
}
#endif
static int loopback_send(const struct device *dev, struct net_pkt *pkt) static int loopback_send(const struct device *dev, struct net_pkt *pkt)
{ {
struct net_pkt *cloned; struct net_pkt *cloned;
@ -103,6 +118,23 @@ static int loopback_send(const struct device *dev, struct net_pkt *pkt)
goto out; goto out;
} }
#ifdef CONFIG_NET_LOOPBACK_SIMULATE_PACKET_DROP
/* Drop packets based on the loopback_packet_drop_ratio
* a ratio of 0.2 will drop one every 5 packets
*/
loopback_packet_drop_state += loopback_packet_drop_ratio;
if (loopback_packet_drop_state >= 1.0f) {
/* Administrate we dropped a packet */
loopback_packet_drop_state -= 1.0f;
/* Clean up the packet */
net_pkt_unref(cloned);
/* Pretent everything was fine */
res = 0;
goto out;
}
#endif
res = net_recv_data(net_pkt_iface(cloned), cloned); res = net_recv_data(net_pkt_iface(cloned), cloned);
if (res < 0) { if (res < 0) {
LOG_ERR("Data receive failed."); LOG_ERR("Data receive failed.");

33
include/net/loopback.h Normal file
View file

@ -0,0 +1,33 @@
/** @file
* @brief Loopback control interface
*/
/*
* Copyright (c) 2022 Radarxense B.V.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_NET_LOOPBACK_H_
#define ZEPHYR_INCLUDE_NET_LOOPBACK_H_
#ifdef __cplusplus
extern "C" {
#endif
#ifdef CONFIG_NET_LOOPBACK_SIMULATE_PACKET_DROP
/**
* @brief Set the packet drop rate
*
* @param[in] ratio Value between 0 = no packet loss and 1 = all packets dropped
*
* @return 0 on success, otherwise a negative integer.
*/
int loopback_set_packet_drop_ratio(float ratio);
#endif
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_NET_LOOPBACK_H_ */