summaryrefslogtreecommitdiffstats
path: root/src/usr
diff options
context:
space:
mode:
authorMichael Brown2014-03-14 00:35:18 +0100
committerMichael Brown2014-03-14 00:35:18 +0100
commit24bbaf6a38f52ef7e942fb4cea36529091af2a0c (patch)
tree57d5c2ab40e2feae137740580a91c91db506ff81 /src/usr
parent[console] Fix display of characters with top bit set (diff)
downloadipxe-24bbaf6a38f52ef7e942fb4cea36529091af2a0c.tar.gz
ipxe-24bbaf6a38f52ef7e942fb4cea36529091af2a0c.tar.xz
ipxe-24bbaf6a38f52ef7e942fb4cea36529091af2a0c.zip
[lotest] Allow loopback testing on shared networks
Allow for extraneous packets to be received during loopback testing, and so permit loopback tests to be performed when ports are connected to a switch (rather than requiring ports to be directly connected with a loopback cable). Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/usr')
-rw-r--r--src/usr/lotest.c89
1 files changed, 53 insertions, 36 deletions
diff --git a/src/usr/lotest.c b/src/usr/lotest.c
index 51d1a5d6..9e2ac331 100644
--- a/src/usr/lotest.c
+++ b/src/usr/lotest.c
@@ -39,6 +39,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
*
*/
+/** Loopback testing in progress flag */
+static int lotest_active;
+
+/** Loopback testing received packets */
+static LIST_HEAD ( lotest_queue );
+
/**
* Process received packet
*
@@ -54,8 +60,32 @@ static int lotest_rx ( struct io_buffer *iobuf,
const void *ll_dest __unused,
const void *ll_source __unused,
unsigned int flags __unused ) {
- free_iob ( iobuf );
- return -ENOTSUP;
+
+ /* Add to received packet queue if currently performing a test */
+ if ( lotest_active ) {
+ list_add_tail ( &iobuf->list, &lotest_queue );
+ } else {
+ free_iob ( iobuf );
+ }
+
+ return 0;
+}
+
+/**
+ * Dequeue received packet
+ *
+ * @ret iobuf I/O buffer, or NULL
+ */
+static struct io_buffer * lotest_dequeue ( void ) {
+ struct io_buffer *iobuf;
+
+ /* Remove first packet (if any) from received packet queue */
+ iobuf = list_first_entry ( &lotest_queue, struct io_buffer, list );
+ if ( ! iobuf )
+ return NULL;
+ list_del ( &iobuf->list );
+
+ return iobuf;
}
/**
@@ -84,22 +114,25 @@ static struct net_protocol lotest_protocol __net_protocol = {
};
/**
+ * Discard all received loopback test packets
+ *
+ */
+static void lotest_flush ( void ) {
+ struct io_buffer *iobuf;
+
+ while ( ( iobuf = lotest_dequeue() ) != NULL )
+ free_iob ( iobuf );
+}
+
+/**
* Wait for packet to be received
*
- * @v receiver Receiving network device*
* @v data Expected data
* @v len Expected data length
* @ret rc Return status code
*/
-static int loopback_wait ( struct net_device *receiver, void *data,
- size_t len ) {
- struct ll_protocol *ll_protocol = receiver->ll_protocol;
+static int loopback_wait ( void *data, size_t len ) {
struct io_buffer *iobuf;
- const void *ll_dest;
- const void *ll_source;
- uint16_t net_proto;
- unsigned int flags;
- int rc;
/* Poll until packet arrives */
while ( 1 ) {
@@ -112,28 +145,10 @@ static int loopback_wait ( struct net_device *receiver, void *data,
net_poll();
/* Dequeue packet, if available */
- iobuf = netdev_rx_dequeue ( receiver );
+ iobuf = lotest_dequeue();
if ( ! iobuf )
continue;
- /* Strip link-layer header */
- if ( ( rc = ll_protocol->pull ( receiver, iobuf, &ll_dest,
- &ll_source, &net_proto,
- &flags ) ) != 0 ) {
- printf ( "\nFailed to strip link-layer header: %s",
- strerror ( rc ) );
- free_iob ( iob_disown ( iobuf ) );
- return rc;
- }
-
- /* Ignore non-loopback packets */
- if ( net_proto != lotest_protocol.net_proto ) {
- printf ( "\nReceived spurious packet type %04x\n",
- ntohs ( net_proto ) );
- free_iob ( iob_disown ( iobuf ) );
- continue;
- }
-
/* Check packet length */
if ( iob_len ( iobuf ) != len ) {
printf ( "\nLength mismatch: sent %zd, received %zd",
@@ -206,10 +221,9 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
ifstat ( sender );
ifstat ( receiver );
- /* Freeze receive queue processing on the receiver, so that we
- * can extract all received packets.
- */
- netdev_rx_freeze ( receiver );
+ /* Start loopback test */
+ lotest_flush();
+ lotest_active = 1;
/* Perform loopback test */
for ( successes = 0 ; ; successes++ ) {
@@ -240,12 +254,15 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
}
/* Wait for received packet */
- if ( ( rc = loopback_wait ( receiver, buf, mtu ) ) != 0 )
+ if ( ( rc = loopback_wait ( buf, mtu ) ) != 0 )
break;
}
printf ( "\n");
- netdev_rx_unfreeze ( receiver );
+
+ /* Stop loopback testing */
+ lotest_active = 0;
+ lotest_flush();
/* Dump final statistics */
ifstat ( sender );