Browse Source

[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>
tags/v1.20.1
Michael Brown 14 years ago
parent
commit
9f2e76ea61
2 changed files with 20 additions and 1 deletions
  1. 1
    0
      src/config/general.h
  2. 19
    1
      src/net/netdevice.c

+ 1
- 0
src/config/general.h View File

@@ -134,6 +134,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
134 134
  *
135 135
  */
136 136
 
137
+#define	NETDEV_DISCARD_RATE 0	/* Drop every N packets (0=>no drop) */
137 138
 #undef	BUILD_SERIAL		/* Include an automatic build serial
138 139
 				 * number.  Add "bs" to the list of
139 140
 				 * make targets.  For example:

+ 19
- 1
src/net/netdevice.c View File

@@ -24,6 +24,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
24 24
 #include <byteswap.h>
25 25
 #include <string.h>
26 26
 #include <errno.h>
27
+#include <config/general.h>
27 28
 #include <ipxe/if_ether.h>
28 29
 #include <ipxe/iobuf.h>
29 30
 #include <ipxe/tables.h>
@@ -126,13 +127,23 @@ int netdev_tx ( struct net_device *netdev, struct io_buffer *iobuf ) {
126 127
 	DBGC ( netdev, "NETDEV %p transmitting %p (%p+%zx)\n",
127 128
 	       netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
128 129
 
130
+	/* Enqueue packet */
129 131
 	list_add_tail ( &iobuf->list, &netdev->tx_queue );
130 132
 
133
+	/* Avoid calling transmit() on unopened network devices */
131 134
 	if ( ! netdev_is_open ( netdev ) ) {
132 135
 		rc = -ENETUNREACH;
133 136
 		goto err;
134 137
 	}
135
-		
138
+
139
+	/* Discard packet (for test purposes) if applicable */
140
+	if ( ( NETDEV_DISCARD_RATE > 0 ) &&
141
+	     ( ( random() % NETDEV_DISCARD_RATE ) == 0 ) ) {
142
+		rc = -EAGAIN;
143
+		goto err;
144
+	}
145
+
146
+	/* Transmit packet */
136 147
 	if ( ( rc = netdev->op->transmit ( netdev, iobuf ) ) != 0 )
137 148
 		goto err;
138 149
 
@@ -218,6 +229,13 @@ void netdev_rx ( struct net_device *netdev, struct io_buffer *iobuf ) {
218 229
 	DBGC ( netdev, "NETDEV %p received %p (%p+%zx)\n",
219 230
 	       netdev, iobuf, iobuf->data, iob_len ( iobuf ) );
220 231
 
232
+	/* Discard packet (for test purposes) if applicable */
233
+	if ( ( NETDEV_DISCARD_RATE > 0 ) &&
234
+	     ( ( random() % NETDEV_DISCARD_RATE ) == 0 ) ) {
235
+		netdev_rx_err ( netdev, iobuf, -EAGAIN );
236
+		return;
237
+	}
238
+
221 239
 	/* Enqueue packet */
222 240
 	list_add_tail ( &iobuf->list, &netdev->rx_queue );
223 241
 

Loading…
Cancel
Save