Browse Source

[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>
tags/v1.20.1
Michael Brown 10 years ago
parent
commit
24bbaf6a38
1 changed files with 53 additions and 36 deletions
  1. 53
    36
      src/usr/lotest.c

+ 53
- 36
src/usr/lotest.c View File

@@ -39,6 +39,12 @@ FILE_LICENCE ( GPL2_OR_LATER );
39 39
  *
40 40
  */
41 41
 
42
+/** Loopback testing in progress flag */
43
+static int lotest_active;
44
+
45
+/** Loopback testing received packets */
46
+static LIST_HEAD ( lotest_queue );
47
+
42 48
 /**
43 49
  * Process received packet
44 50
  *
@@ -54,8 +60,32 @@ static int lotest_rx ( struct io_buffer *iobuf,
54 60
 		       const void *ll_dest __unused,
55 61
 		       const void *ll_source __unused,
56 62
 		       unsigned int flags __unused ) {
57
-	free_iob ( iobuf );
58
-	return -ENOTSUP;
63
+
64
+	/* Add to received packet queue if currently performing a test */
65
+	if ( lotest_active ) {
66
+		list_add_tail ( &iobuf->list, &lotest_queue );
67
+	} else {
68
+		free_iob ( iobuf );
69
+	}
70
+
71
+	return 0;
72
+}
73
+
74
+/**
75
+ * Dequeue received packet
76
+ *
77
+ * @ret iobuf		I/O buffer, or NULL
78
+ */
79
+static struct io_buffer * lotest_dequeue ( void ) {
80
+	struct io_buffer *iobuf;
81
+
82
+	/* Remove first packet (if any) from received packet queue */
83
+	iobuf = list_first_entry ( &lotest_queue, struct io_buffer, list );
84
+	if ( ! iobuf )
85
+		return NULL;
86
+	list_del ( &iobuf->list );
87
+
88
+	return iobuf;
59 89
 }
60 90
 
61 91
 /**
@@ -83,23 +113,26 @@ static struct net_protocol lotest_protocol __net_protocol = {
83 113
 	.net_addr_len = 0,
84 114
 };
85 115
 
116
+/**
117
+ * Discard all received loopback test packets
118
+ *
119
+ */
120
+static void lotest_flush ( void ) {
121
+	struct io_buffer *iobuf;
122
+
123
+	while ( ( iobuf = lotest_dequeue() ) != NULL )
124
+		free_iob ( iobuf );
125
+}
126
+
86 127
 /**
87 128
  * Wait for packet to be received
88 129
  *
89
- * @v receiver		Receiving network device*
90 130
  * @v data		Expected data
91 131
  * @v len		Expected data length
92 132
  * @ret rc		Return status code
93 133
  */
94
-static int loopback_wait ( struct net_device *receiver, void *data,
95
-			   size_t len ) {
96
-	struct ll_protocol *ll_protocol = receiver->ll_protocol;
134
+static int loopback_wait ( void *data, size_t len ) {
97 135
 	struct io_buffer *iobuf;
98
-	const void *ll_dest;
99
-	const void *ll_source;
100
-	uint16_t net_proto;
101
-	unsigned int flags;
102
-	int rc;
103 136
 
104 137
 	/* Poll until packet arrives */
105 138
 	while ( 1 ) {
@@ -112,28 +145,10 @@ static int loopback_wait ( struct net_device *receiver, void *data,
112 145
 		net_poll();
113 146
 
114 147
 		/* Dequeue packet, if available */
115
-		iobuf = netdev_rx_dequeue ( receiver );
148
+		iobuf = lotest_dequeue();
116 149
 		if ( ! iobuf )
117 150
 			continue;
118 151
 
119
-		/* Strip link-layer header */
120
-		if ( ( rc = ll_protocol->pull ( receiver, iobuf, &ll_dest,
121
-						&ll_source, &net_proto,
122
-						&flags ) ) != 0 ) {
123
-			printf ( "\nFailed to strip link-layer header: %s",
124
-				 strerror ( rc ) );
125
-			free_iob ( iob_disown ( iobuf ) );
126
-			return rc;
127
-		}
128
-
129
-		/* Ignore non-loopback packets */
130
-		if ( net_proto != lotest_protocol.net_proto ) {
131
-			printf ( "\nReceived spurious packet type %04x\n",
132
-				 ntohs ( net_proto ) );
133
-			free_iob ( iob_disown ( iobuf ) );
134
-			continue;
135
-		}
136
-
137 152
 		/* Check packet length */
138 153
 		if ( iob_len ( iobuf ) != len ) {
139 154
 			printf ( "\nLength mismatch: sent %zd, received %zd",
@@ -206,10 +221,9 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
206 221
 	ifstat ( sender );
207 222
 	ifstat ( receiver );
208 223
 
209
-	/* Freeze receive queue processing on the receiver, so that we
210
-	 * can extract all received packets.
211
-	 */
212
-	netdev_rx_freeze ( receiver );
224
+	/* Start loopback test */
225
+	lotest_flush();
226
+	lotest_active = 1;
213 227
 
214 228
 	/* Perform loopback test */
215 229
 	for ( successes = 0 ; ; successes++ ) {
@@ -240,12 +254,15 @@ int loopback_test ( struct net_device *sender, struct net_device *receiver,
240 254
 		}
241 255
 
242 256
 		/* Wait for received packet */
243
-		if ( ( rc = loopback_wait ( receiver, buf, mtu ) ) != 0 )
257
+		if ( ( rc = loopback_wait ( buf, mtu ) ) != 0 )
244 258
 			break;
245 259
 	}
246 260
 
247 261
 	printf ( "\n");
248
-	netdev_rx_unfreeze ( receiver );
262
+
263
+	/* Stop loopback testing */
264
+	lotest_active = 0;
265
+	lotest_flush();
249 266
 
250 267
 	/* Dump final statistics */
251 268
 	ifstat ( sender );

Loading…
Cancel
Save