diff --git a/src/config/general.h b/src/config/general.h index c9bf72614..623138f55 100644 --- a/src/config/general.h +++ b/src/config/general.h @@ -134,6 +134,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); * */ +#define NETDEV_DISCARD_RATE 0 /* Drop every N packets (0=>no drop) */ #undef BUILD_SERIAL /* Include an automatic build serial * number. Add "bs" to the list of * make targets. For example: diff --git a/src/net/netdevice.c b/src/net/netdevice.c index 01fa1d55e..3fa966600 100644 --- a/src/net/netdevice.c +++ b/src/net/netdevice.c @@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include #include @@ -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 );