mirror of
https://github.com/xcat2/xNBA.git
synced 2024-11-29 12:49:49 +00:00
[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>
This commit is contained in:
parent
a17ee3610d
commit
24bbaf6a38
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -83,23 +113,26 @@ static struct net_protocol lotest_protocol __net_protocol = {
|
||||
.net_addr_len = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 );
|
||||
|
Loading…
Reference in New Issue
Block a user