summaryrefslogtreecommitdiffstats
path: root/src/net/netdevice.c
diff options
context:
space:
mode:
authorMichael Brown2010-07-20 21:52:08 +0200
committerMichael Brown2010-07-20 21:58:10 +0200
commit9f2e76ea614a77e8fd314065f2019bb4d5c8fe60 (patch)
treea0323b6471153a60af39e403559af1816dab49e4 /src/net/netdevice.c
parent[virtio] Replace virtio-net with native iPXE driver (diff)
downloadipxe-9f2e76ea614a77e8fd314065f2019bb4d5c8fe60.tar.gz
ipxe-9f2e76ea614a77e8fd314065f2019bb4d5c8fe60.tar.xz
ipxe-9f2e76ea614a77e8fd314065f2019bb4d5c8fe60.zip
[netdevice] Provide a test mechanism for discarding packets at random
Setting NETDEV_DISCARD_RATE to a non-zero value will cause one in every NETDEV_DISCARD_RATE packets to be discarded at random on both the transmit and receive datapaths, allowing the robustness of upper-layer network protocols to be tested even in simulation environments that provide wholly reliable packet transmission. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/net/netdevice.c')
-rw-r--r--src/net/netdevice.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/src/net/netdevice.c b/src/net/netdevice.c
index 01fa1d55..3fa96660 100644
--- a/src/net/netdevice.c
+++ b/src/net/netdevice.c
@@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
#include <byteswap.h>
#include <string.h>
#include <errno.h>
+#include <config/general.h>
#include <ipxe/if_ether.h>
#include <ipxe/iobuf.h>
#include <ipxe/tables.h>
@@ -126,13 +127,23 @@ int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) {
DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n",
netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
+ /* Enqueue packet */
list_add_tail ( &iobuf->list, &netdev->tx_queue );
+ /* Avoid calling transmit() on unopened network devices */
if ( ! netdev_is_open ( netdev ) ) {
rc = -ENETUNREACH;
goto err;
}
-
+
+ /* Discard packet (for test purposes) if applicable */
+ if ( ( NETDEV_DISCARD_RATE > 0 ) &&
+ ( ( random() % NETDEV_DISCARD_RATE ) == 0 ) ) {
+ rc = -EAGAIN;
+ goto err;
+ }
+
+ /* Transmit packet */
if ( ( rc = netdev->op->transmit ( netdev, iobuf ) ) != 0 )
goto err;
@@ -218,6 +229,13 @@ void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) {
DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
+ /* Discard packet (for test purposes) if applicable */
+ if ( ( NETDEV_DISCARD_RATE > 0 ) &&
+ ( ( random() % NETDEV_DISCARD_RATE ) == 0 ) ) {
+ netdev_rx_err ( netdev, iobuf, -EAGAIN );
+ return;
+ }
+
/* Enqueue packet */
list_add_tail ( &iobuf->list, &netdev->rx_queue );