mirror of https://github.com/ipxe/ipxe.git
[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>pull/1/head
parent
e4419ff97c
commit
9f2e76ea61
|
@ -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
|
#undef BUILD_SERIAL /* Include an automatic build serial
|
||||||
* number. Add "bs" to the list of
|
* number. Add "bs" to the list of
|
||||||
* make targets. For example:
|
* make targets. For example:
|
||||||
|
|
|
@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
#include <byteswap.h>
|
#include <byteswap.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <config/general.h>
|
||||||
#include <ipxe/if_ether.h>
|
#include <ipxe/if_ether.h>
|
||||||
#include <ipxe/iobuf.h>
|
#include <ipxe/iobuf.h>
|
||||||
#include <ipxe/tables.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",
|
DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n",
|
||||||
netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
|
netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
|
||||||
|
|
||||||
|
/* Enqueue packet */
|
||||||
list_add_tail ( &iobuf->list, &netdev->tx_queue );
|
list_add_tail ( &iobuf->list, &netdev->tx_queue );
|
||||||
|
|
||||||
|
/* Avoid calling transmit() on unopened network devices */
|
||||||
if ( ! netdev_is_open ( netdev ) ) {
|
if ( ! netdev_is_open ( netdev ) ) {
|
||||||
rc = -ENETUNREACH;
|
rc = -ENETUNREACH;
|
||||||
goto err;
|
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 )
|
if ( ( rc = netdev->op->transmit ( netdev, iobuf ) ) != 0 )
|
||||||
goto err;
|
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",
|
DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
|
||||||
netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
|
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 */
|
/* Enqueue packet */
|
||||||
list_add_tail ( &iobuf->list, &netdev->rx_queue );
|
list_add_tail ( &iobuf->list, &netdev->rx_queue );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue