Browse Source

Made the temporary buffer part of the TCP senddata() API, to ease the

transition away from uIP.

Prepared ipv4.c for transition away from uIP.
tags/v0.9.3
Michael Brown 18 years ago
parent
commit
8637834031
6 changed files with 61 additions and 38 deletions
  1. 11
    3
      src/include/gpxe/tcp.h
  2. 7
    2
      src/net/ipv4.c
  3. 8
    10
      src/net/tcp.c
  4. 6
    5
      src/net/tcp/ftp.c
  5. 27
    18
      src/net/tcp/iscsi.c
  6. 2
    0
      src/net/uip/uipopt.h

+ 11
- 3
src/include/gpxe/tcp.h View File

@@ -66,6 +66,8 @@ struct tcp_operations {
66 66
 	 * Transmit data
67 67
 	 *
68 68
 	 * @v conn	TCP connection
69
+	 * @v buf	Temporary data buffer
70
+	 * @v len	Length of temporary data buffer
69 71
 	 *
70 72
 	 * The application should transmit whatever it currently wants
71 73
 	 * to send using tcp_send().  If retransmissions are required,
@@ -73,8 +75,16 @@ struct tcp_operations {
73 75
 	 * regenerate the data.  The easiest way to implement this is
74 76
 	 * to ensure that senddata() never changes the application's
75 77
 	 * state.
78
+	 *
79
+	 * The application may use the temporary data buffer to
80
+	 * construct the data to be sent.  Note that merely filling
81
+	 * the buffer will do nothing; the application must call
82
+	 * tcp_send() in order to actually transmit the data.  Use of
83
+	 * the buffer is not compulsory; the application may call
84
+	 * tcp_send() on any block of data.
76 85
 	 */
77
-	void ( * senddata ) ( struct tcp_connection *conn );
86
+	void ( * senddata ) ( struct tcp_connection *conn, void *buf,
87
+			      size_t len );
78 88
 };
79 89
 
80 90
 /**
@@ -88,8 +98,6 @@ struct tcp_connection {
88 98
 	struct tcp_operations *tcp_op;
89 99
 };
90 100
 
91
-extern void *tcp_buffer;
92
-extern size_t tcp_buflen;
93 101
 extern void tcp_connect ( struct tcp_connection *conn );
94 102
 extern void tcp_send ( struct tcp_connection *conn, const void *data,
95 103
 		       size_t len );

+ 7
- 2
src/net/ipv4.c View File

@@ -176,8 +176,9 @@ int ipv4_uip_tx ( struct pk_buff *pkb ) {
176 176
  * This handles IP packets by handing them off to the uIP protocol
177 177
  * stack.
178 178
  */
179
-static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
180
-		     const void *ll_source __unused ) {
179
+static int ipv4_uip_rx ( struct pk_buff *pkb,
180
+			 struct net_device *netdev __unused,
181
+			 const void *ll_source __unused ) {
181 182
 
182 183
 	/* Transfer to uIP buffer.  Horrendously space-inefficient,
183 184
 	 * but will do as a proof-of-concept for now.
@@ -250,7 +251,11 @@ struct net_protocol ipv4_protocol = {
250 251
 	.name = "IP",
251 252
 	.net_proto = htons ( ETH_P_IP ),
252 253
 	.net_addr_len = sizeof ( struct in_addr ),
254
+#if USE_UIP
255
+	.rx = ipv4_uip_rx,
256
+#else
253 257
 	.rx = ipv4_rx,
258
+#endif
254 259
 	.ntoa = ipv4_ntoa,
255 260
 };
256 261
 

+ 8
- 10
src/net/tcp.c View File

@@ -40,11 +40,10 @@
40 40
  *
41 41
  * @code
42 42
  *
43
- *     static void my_senddata ( struct tcp_connection *conn ) {
44
- *         int len;
45
- *
46
- *         len = snprintf ( tcp_buffer, tcp_buflen, "FETCH %s\r\n", filename );
47
- *         tcp_send ( conn, tcp_buffer + already_sent, len - already_sent );
43
+ *     static void my_senddata ( struct tcp_connection *conn, void *buf,
44
+ *				 size_t len ) {
45
+ *         len = snprintf ( buf, len, "FETCH %s\r\n", filename );
46
+ *         tcp_send ( conn, buf + already_sent, len - already_sent );
48 47
  *     }
49 48
  *
50 49
  * @endcode
@@ -53,13 +52,12 @@
53 52
  * variably-sized data.
54 53
  *
55 54
  * Note that you cannot use this simple mechanism if you want to be
56
- * able to construct single data blocks of more than #tcp_buflen
57
- * bytes.
55
+ * able to construct single data blocks of more than #len bytes.
58 56
  */
59
-void *tcp_buffer = uip_buf + ( 40 + UIP_LLH_LEN );
57
+static void *tcp_buffer = uip_buf + ( 40 + UIP_LLH_LEN );
60 58
 
61 59
 /** Size of #tcp_buffer */
62
-size_t tcp_buflen = UIP_BUFSIZE - ( 40 + UIP_LLH_LEN );
60
+static size_t tcp_buflen = UIP_BUFSIZE - ( 40 + UIP_LLH_LEN );
63 61
 
64 62
 /**
65 63
  * Open a TCP connection
@@ -148,7 +146,7 @@ void uip_tcp_appcall ( void ) {
148 146
 		op->newdata ( conn, ( void * ) uip_appdata, uip_len );
149 147
 	if ( ( uip_rexmit() || uip_newdata() || uip_acked() ||
150 148
 	       uip_connected() || uip_poll() ) && op->senddata )
151
-		op->senddata ( conn );
149
+		op->senddata ( conn, tcp_buffer, tcp_buflen );
152 150
 }
153 151
 
154 152
 /* Present here to allow everything to link.  Will go into separate

+ 6
- 5
src/net/tcp/ftp.c View File

@@ -220,20 +220,21 @@ static void ftp_acked ( struct tcp_connection *conn, size_t len ) {
220 220
  * Construct data to send on FTP control channel
221 221
  *
222 222
  * @v conn	TCP connection
223
+ * @v buf	Temporary data buffer
224
+ * @v len	Length of temporary data buffer
223 225
  */
224
-static void ftp_senddata ( struct tcp_connection *conn ) {
226
+static void ftp_senddata ( struct tcp_connection *conn,
227
+			   void *buf, size_t len ) {
225 228
 	struct ftp_request *ftp = tcp_to_ftp ( conn );
226 229
 	const struct ftp_string *string;
227
-	size_t len;
228 230
 
229 231
 	/* Send the as-yet-unACKed portion of the string for the
230 232
 	 * current state.
231 233
 	 */
232 234
 	string = &ftp_strings[ftp->state];
233
-	len = snprintf ( tcp_buffer, tcp_buflen, string->format,
235
+	len = snprintf ( buf, len, string->format,
234 236
 			 ftp_string_data ( ftp, string->data_offset ) );
235
-	tcp_send ( conn, tcp_buffer + ftp->already_sent,
236
-		   len - ftp->already_sent );
237
+	tcp_send ( conn, buf + ftp->already_sent, len - ftp->already_sent );
237 238
 }
238 239
 
239 240
 /**

+ 27
- 18
src/net/tcp/iscsi.c View File

@@ -222,24 +222,27 @@ static void iscsi_data_out_done ( struct iscsi_session *iscsi ) {
222 222
  * Send iSCSI data-out data segment
223 223
  *
224 224
  * @v iscsi		iSCSI session
225
+ * @v buf		Temporary data buffer
226
+ * @v len		Length of temporary data buffer
225 227
  */
226
-static void iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
228
+static void iscsi_tx_data_out ( struct iscsi_session *iscsi,
229
+				void *buf, size_t len ) {
227 230
 	struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
228 231
 	unsigned long offset;
229
-	unsigned long len;
232
+	unsigned long remaining;
230 233
 
231 234
 	offset = ( iscsi->transfer_offset + ntohl ( data_out->offset ) +
232 235
 		   iscsi->tx_offset );
233
-	len = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset );
236
+	remaining = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset);
234 237
 	assert ( iscsi->command != NULL );
235 238
 	assert ( iscsi->command->data_out != NULL );
236 239
 	assert ( ( offset + len ) <= iscsi->command->data_out_len );
237 240
 	
238
-	if ( len > tcp_buflen )
239
-		len = tcp_buflen;
240
-	copy_from_user ( tcp_buffer, iscsi->command->data_out, offset, len );
241
+	if ( remaining < len )
242
+		len = remaining;
243
+	copy_from_user ( buf, iscsi->command->data_out, offset, len );
241 244
 
242
-	tcp_send ( &iscsi->tcp, tcp_buffer, len );
245
+	tcp_send ( &iscsi->tcp, buf, len );
243 246
 }
244 247
 
245 248
 /****************************************************************************
@@ -336,15 +339,15 @@ static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) {
336 339
  * Transmit data segment of an iSCSI login request PDU
337 340
  *
338 341
  * @v iscsi		iSCSI session
342
+ * @v buf		Temporary data buffer
343
+ * @v len		Length of temporary data buffer
339 344
  *
340 345
  * For login requests, the data segment consists of the login strings.
341 346
  */
342
-static void iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
343
-	int len;
344
-
345
-	len = iscsi_build_login_request_strings ( iscsi, tcp_buffer,
346
-						  tcp_buflen );
347
-	tcp_send ( &iscsi->tcp, tcp_buffer + iscsi->tx_offset,
347
+static void iscsi_tx_login_request ( struct iscsi_session *iscsi,
348
+				     void *buf, size_t len ) {
349
+	len = iscsi_build_login_request_strings ( iscsi, buf, len );
350
+	tcp_send ( &iscsi->tcp, buf + iscsi->tx_offset,
348 351
 		   len - iscsi->tx_offset );
349 352
 }
350 353
 
@@ -422,19 +425,22 @@ static void iscsi_start_tx ( struct iscsi_session *iscsi ) {
422 425
  * Transmit data segment of an iSCSI PDU
423 426
  *
424 427
  * @v iscsi		iSCSI session
428
+ * @v buf		Temporary data buffer
429
+ * @v len		Length of temporary data buffer
425 430
  * 
426 431
  * Handle transmission of part of a PDU data segment.  iscsi::tx_bhs
427 432
  * will be valid when this is called.
428 433
  */
429
-static void iscsi_tx_data ( struct iscsi_session *iscsi ) {
434
+static void iscsi_tx_data ( struct iscsi_session *iscsi,
435
+			    void *buf, size_t len ) {
430 436
 	struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
431 437
 
432 438
 	switch ( common->opcode & ISCSI_OPCODE_MASK ) {
433 439
 	case ISCSI_OPCODE_DATA_OUT:
434
-		iscsi_tx_data_out ( iscsi );
440
+		iscsi_tx_data_out ( iscsi, buf, len );
435 441
 		break;
436 442
 	case ISCSI_OPCODE_LOGIN_REQUEST:
437
-		iscsi_tx_login_request ( iscsi );
443
+		iscsi_tx_login_request ( iscsi, buf, len );
438 444
 		break;
439 445
 	default:
440 446
 		assert ( 0 );
@@ -524,10 +530,13 @@ static void iscsi_acked ( struct tcp_connection *conn, size_t len ) {
524 530
  * Transmit iSCSI PDU
525 531
  *
526 532
  * @v iscsi		iSCSI session
533
+ * @v buf		Temporary data buffer
534
+ * @v len		Length of temporary data buffer
527 535
  * 
528 536
  * Constructs data to be sent for the current TX state
529 537
  */
530
-static void iscsi_senddata ( struct tcp_connection *conn ) {
538
+static void iscsi_senddata ( struct tcp_connection *conn,
539
+			     void *buf, size_t len ) {
531 540
 	struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
532 541
 	struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
533 542
 	static const char pad[] = { '\0', '\0', '\0' };
@@ -545,7 +554,7 @@ static void iscsi_senddata ( struct tcp_connection *conn ) {
545 554
 		assert ( 0 );
546 555
 		break;
547 556
 	case ISCSI_TX_DATA:
548
-		iscsi_tx_data ( iscsi );
557
+		iscsi_tx_data ( iscsi, buf, len );
549 558
 		break;
550 559
 	case ISCSI_TX_DATA_PADDING:
551 560
 		tcp_send ( conn, pad, ( ISCSI_DATA_PAD_LEN ( common->lengths )

+ 2
- 0
src/net/uip/uipopt.h View File

@@ -569,4 +569,6 @@ extern void uip_tcp_appcall ( void );
569 569
 #define UIP_IPADDR2 254
570 570
 #define UIP_IPADDR3 1
571 571
 
572
+#define USE_UIP 1
573
+
572 574
 #endif /* __UIPOPT_H__ */

Loading…
Cancel
Save