Made the temporary buffer part of the TCP senddata() API, to ease the
authorMichael Brown <mcb30@etherboot.org>
Sat, 17 Jun 2006 23:20:54 +0000 (23:20 +0000)
committerMichael Brown <mcb30@etherboot.org>
Sat, 17 Jun 2006 23:20:54 +0000 (23:20 +0000)
transition away from uIP.

Prepared ipv4.c for transition away from uIP.

src/include/gpxe/tcp.h
src/net/ipv4.c
src/net/tcp.c
src/net/tcp/ftp.c
src/net/tcp/iscsi.c
src/net/uip/uipopt.h

index 6c07f4a..fb0c89a 100644 (file)
@@ -66,6 +66,8 @@ struct tcp_operations {
         * Transmit data
         *
         * @v conn      TCP connection
+        * @v buf       Temporary data buffer
+        * @v len       Length of temporary data buffer
         *
         * The application should transmit whatever it currently wants
         * to send using tcp_send().  If retransmissions are required,
@@ -73,8 +75,16 @@ struct tcp_operations {
         * regenerate the data.  The easiest way to implement this is
         * to ensure that senddata() never changes the application's
         * state.
+        *
+        * The application may use the temporary data buffer to
+        * construct the data to be sent.  Note that merely filling
+        * the buffer will do nothing; the application must call
+        * tcp_send() in order to actually transmit the data.  Use of
+        * the buffer is not compulsory; the application may call
+        * tcp_send() on any block of data.
         */
-       void ( * senddata ) ( struct tcp_connection *conn );
+       void ( * senddata ) ( struct tcp_connection *conn, void *buf,
+                             size_t len );
 };
 
 /**
@@ -88,8 +98,6 @@ struct tcp_connection {
        struct tcp_operations *tcp_op;
 };
 
-extern void *tcp_buffer;
-extern size_t tcp_buflen;
 extern void tcp_connect ( struct tcp_connection *conn );
 extern void tcp_send ( struct tcp_connection *conn, const void *data,
                       size_t len );
index 47b8cb7..1e2befd 100644 (file)
@@ -176,8 +176,9 @@ int ipv4_uip_tx ( struct pk_buff *pkb ) {
  * This handles IP packets by handing them off to the uIP protocol
  * stack.
  */
-static int ipv4_rx ( struct pk_buff *pkb, struct net_device *netdev __unused,
-                    const void *ll_source __unused ) {
+static int ipv4_uip_rx ( struct pk_buff *pkb,
+                        struct net_device *netdev __unused,
+                        const void *ll_source __unused ) {
 
        /* Transfer to uIP buffer.  Horrendously space-inefficient,
         * but will do as a proof-of-concept for now.
@@ -250,7 +251,11 @@ struct net_protocol ipv4_protocol = {
        .name = "IP",
        .net_proto = htons ( ETH_P_IP ),
        .net_addr_len = sizeof ( struct in_addr ),
+#if USE_UIP
+       .rx = ipv4_uip_rx,
+#else
        .rx = ipv4_rx,
+#endif
        .ntoa = ipv4_ntoa,
 };
 
index e73708d..afb1838 100644 (file)
  *
  * @code
  *
- *     static void my_senddata ( struct tcp_connection *conn ) {
- *         int len;
- *
- *         len = snprintf ( tcp_buffer, tcp_buflen, "FETCH %s\r\n", filename );
- *         tcp_send ( conn, tcp_buffer + already_sent, len - already_sent );
+ *     static void my_senddata ( struct tcp_connection *conn, void *buf,
+ *                              size_t len ) {
+ *         len = snprintf ( buf, len, "FETCH %s\r\n", filename );
+ *         tcp_send ( conn, buf + already_sent, len - already_sent );
  *     }
  *
  * @endcode
  * variably-sized data.
  *
  * Note that you cannot use this simple mechanism if you want to be
- * able to construct single data blocks of more than #tcp_buflen
- * bytes.
+ * able to construct single data blocks of more than #len bytes.
  */
-void *tcp_buffer = uip_buf + ( 40 + UIP_LLH_LEN );
+static void *tcp_buffer = uip_buf + ( 40 + UIP_LLH_LEN );
 
 /** Size of #tcp_buffer */
-size_t tcp_buflen = UIP_BUFSIZE - ( 40 + UIP_LLH_LEN );
+static size_t tcp_buflen = UIP_BUFSIZE - ( 40 + UIP_LLH_LEN );
 
 /**
  * Open a TCP connection
@@ -148,7 +146,7 @@ void uip_tcp_appcall ( void ) {
                op->newdata ( conn, ( void * ) uip_appdata, uip_len );
        if ( ( uip_rexmit() || uip_newdata() || uip_acked() ||
               uip_connected() || uip_poll() ) && op->senddata )
-               op->senddata ( conn );
+               op->senddata ( conn, tcp_buffer, tcp_buflen );
 }
 
 /* Present here to allow everything to link.  Will go into separate
index ee6c7eb..b0f9fef 100644 (file)
@@ -220,20 +220,21 @@ static void ftp_acked ( struct tcp_connection *conn, size_t len ) {
  * Construct data to send on FTP control channel
  *
  * @v conn     TCP connection
+ * @v buf      Temporary data buffer
+ * @v len      Length of temporary data buffer
  */
-static void ftp_senddata ( struct tcp_connection *conn ) {
+static void ftp_senddata ( struct tcp_connection *conn,
+                          void *buf, size_t len ) {
        struct ftp_request *ftp = tcp_to_ftp ( conn );
        const struct ftp_string *string;
-       size_t len;
 
        /* Send the as-yet-unACKed portion of the string for the
         * current state.
         */
        string = &ftp_strings[ftp->state];
-       len = snprintf ( tcp_buffer, tcp_buflen, string->format,
+       len = snprintf ( buf, len, string->format,
                         ftp_string_data ( ftp, string->data_offset ) );
-       tcp_send ( conn, tcp_buffer + ftp->already_sent,
-                  len - ftp->already_sent );
+       tcp_send ( conn, buf + ftp->already_sent, len - ftp->already_sent );
 }
 
 /**
index 49ccb02..a9a5688 100644 (file)
@@ -222,24 +222,27 @@ static void iscsi_data_out_done ( struct iscsi_session *iscsi ) {
  * Send iSCSI data-out data segment
  *
  * @v iscsi            iSCSI session
+ * @v buf              Temporary data buffer
+ * @v len              Length of temporary data buffer
  */
-static void iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
+static void iscsi_tx_data_out ( struct iscsi_session *iscsi,
+                               void *buf, size_t len ) {
        struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
        unsigned long offset;
-       unsigned long len;
+       unsigned long remaining;
 
        offset = ( iscsi->transfer_offset + ntohl ( data_out->offset ) +
                   iscsi->tx_offset );
-       len = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset );
+       remaining = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset);
        assert ( iscsi->command != NULL );
        assert ( iscsi->command->data_out != NULL );
        assert ( ( offset + len ) <= iscsi->command->data_out_len );
        
-       if ( len > tcp_buflen )
-               len = tcp_buflen;
-       copy_from_user ( tcp_buffer, iscsi->command->data_out, offset, len );
+       if ( remaining < len )
+               len = remaining;
+       copy_from_user ( buf, iscsi->command->data_out, offset, len );
 
-       tcp_send ( &iscsi->tcp, tcp_buffer, len );
+       tcp_send ( &iscsi->tcp, buf, len );
 }
 
 /****************************************************************************
@@ -336,15 +339,15 @@ static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) {
  * Transmit data segment of an iSCSI login request PDU
  *
  * @v iscsi            iSCSI session
+ * @v buf              Temporary data buffer
+ * @v len              Length of temporary data buffer
  *
  * For login requests, the data segment consists of the login strings.
  */
-static void iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
-       int len;
-
-       len = iscsi_build_login_request_strings ( iscsi, tcp_buffer,
-                                                 tcp_buflen );
-       tcp_send ( &iscsi->tcp, tcp_buffer + iscsi->tx_offset,
+static void iscsi_tx_login_request ( struct iscsi_session *iscsi,
+                                    void *buf, size_t len ) {
+       len = iscsi_build_login_request_strings ( iscsi, buf, len );
+       tcp_send ( &iscsi->tcp, buf + iscsi->tx_offset,
                   len - iscsi->tx_offset );
 }
 
@@ -422,19 +425,22 @@ static void iscsi_start_tx ( struct iscsi_session *iscsi ) {
  * Transmit data segment of an iSCSI PDU
  *
  * @v iscsi            iSCSI session
+ * @v buf              Temporary data buffer
+ * @v len              Length of temporary data buffer
  * 
  * Handle transmission of part of a PDU data segment.  iscsi::tx_bhs
  * will be valid when this is called.
  */
-static void iscsi_tx_data ( struct iscsi_session *iscsi ) {
+static void iscsi_tx_data ( struct iscsi_session *iscsi,
+                           void *buf, size_t len ) {
        struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
 
        switch ( common->opcode & ISCSI_OPCODE_MASK ) {
        case ISCSI_OPCODE_DATA_OUT:
-               iscsi_tx_data_out ( iscsi );
+               iscsi_tx_data_out ( iscsi, buf, len );
                break;
        case ISCSI_OPCODE_LOGIN_REQUEST:
-               iscsi_tx_login_request ( iscsi );
+               iscsi_tx_login_request ( iscsi, buf, len );
                break;
        default:
                assert ( 0 );
@@ -524,10 +530,13 @@ static void iscsi_acked ( struct tcp_connection *conn, size_t len ) {
  * Transmit iSCSI PDU
  *
  * @v iscsi            iSCSI session
+ * @v buf              Temporary data buffer
+ * @v len              Length of temporary data buffer
  * 
  * Constructs data to be sent for the current TX state
  */
-static void iscsi_senddata ( struct tcp_connection *conn ) {
+static void iscsi_senddata ( struct tcp_connection *conn,
+                            void *buf, size_t len ) {
        struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
        struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
        static const char pad[] = { '\0', '\0', '\0' };
@@ -545,7 +554,7 @@ static void iscsi_senddata ( struct tcp_connection *conn ) {
                assert ( 0 );
                break;
        case ISCSI_TX_DATA:
-               iscsi_tx_data ( iscsi );
+               iscsi_tx_data ( iscsi, buf, len );
                break;
        case ISCSI_TX_DATA_PADDING:
                tcp_send ( conn, pad, ( ISCSI_DATA_PAD_LEN ( common->lengths )
index b17b890..fc12071 100644 (file)
@@ -569,4 +569,6 @@ extern void uip_tcp_appcall ( void );
 #define UIP_IPADDR2 254
 #define UIP_IPADDR3 1
 
+#define USE_UIP 1
+
 #endif /* __UIPOPT_H__ */