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
  *
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
  * Process received packet
49
  * Process received packet
44
  *
50
  *
54
 		       const void *ll_dest __unused,
60
 		       const void *ll_dest __unused,
55
 		       const void *ll_source __unused,
61
 		       const void *ll_source __unused,
56
 		       unsigned int flags __unused ) {
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
 	.net_addr_len = 0,
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
  * Wait for packet to be received
128
  * Wait for packet to be received
88
  *
129
  *
89
- * @v receiver		Receiving network device*
90
  * @v data		Expected data
130
  * @v data		Expected data
91
  * @v len		Expected data length
131
  * @v len		Expected data length
92
  * @ret rc		Return status code
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
 	struct io_buffer *iobuf;
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
 	/* Poll until packet arrives */
137
 	/* Poll until packet arrives */
105
 	while ( 1 ) {
138
 	while ( 1 ) {
112
 		net_poll();
145
 		net_poll();
113
 
146
 
114
 		/* Dequeue packet, if available */
147
 		/* Dequeue packet, if available */
115
-		iobuf = netdev_rx_dequeue ( receiver );
148
+		iobuf = lotest_dequeue();
116
 		if ( ! iobuf )
149
 		if ( ! iobuf )
117
 			continue;
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
 		/* Check packet length */
152
 		/* Check packet length */
138
 		if ( iob_len ( iobuf ) != len ) {
153
 		if ( iob_len ( iobuf ) != len ) {
139
 			printf ( "\nLength mismatch: sent %zd, received %zd",
154
 			printf ( "\nLength mismatch: sent %zd, received %zd",
206
 	ifstat ( sender );
221
 	ifstat ( sender );
207
 	ifstat ( receiver );
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
 	/* Perform loopback test */
228
 	/* Perform loopback test */
215
 	for ( successes = 0 ; ; successes++ ) {
229
 	for ( successes = 0 ; ; successes++ ) {
240
 		}
254
 		}
241
 
255
 
242
 		/* Wait for received packet */
256
 		/* Wait for received packet */
243
-		if ( ( rc = loopback_wait ( receiver, buf, mtu ) ) != 0 )
257
+		if ( ( rc = loopback_wait ( buf, mtu ) ) != 0 )
244
 			break;
258
 			break;
245
 	}
259
 	}
246
 
260
 
247
 	printf ( "\n");
261
 	printf ( "\n");
248
-	netdev_rx_unfreeze ( receiver );
262
+
263
+	/* Stop loopback testing */
264
+	lotest_active = 0;
265
+	lotest_flush();
249
 
266
 
250
 	/* Dump final statistics */
267
 	/* Dump final statistics */
251
 	ifstat ( sender );
268
 	ifstat ( sender );

Loading…
Cancel
Save