]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[ncm] Reserve headroom in received packets
authorMichael Brown <mcb30@ipxe.org>
Fri, 6 Feb 2015 15:46:43 +0000 (15:46 +0000)
committerMichael Brown <mcb30@ipxe.org>
Fri, 6 Feb 2015 15:46:43 +0000 (15:46 +0000)
Some protocols (such as ARP) may modify the received packet and re-use
the same I/O buffer for transmission of a reply.  To allow this,
reserve sufficient headroom at the start of each received packet
buffer for our transmit datapath headers.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/ncm.c

index 8a3f938846d9f6baa17d10c48c0a1a5700fba0c6..0fc3ab794b550da9d101d6b7e7b7d7c348a87628 100644 (file)
@@ -390,6 +390,7 @@ static void ncm_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
        size_t ndp_len;
        size_t pkt_offset;
        size_t pkt_len;
+       size_t headroom;
        size_t len;
 
        /* Profile overall bulk IN completion */
@@ -460,13 +461,22 @@ static void ncm_in_complete ( struct usb_endpoint *ep, struct io_buffer *iobuf,
                 * while the device is running.  We therefore copy the
                 * data to a new I/O buffer even if this is the only
                 * (or last) packet within the buffer.
+                *
+                * We reserve enough space at the start of each buffer
+                * to allow for our own transmission header, to
+                * support protocols such as ARP which may modify the
+                * received packet and reuse the same I/O buffer for
+                * transmission.
                 */
-               pkt = alloc_iob ( pkt_len );
+               headroom = ( sizeof ( struct ncm_ntb_header ) +
+                            ncm->out.padding );
+               pkt = alloc_iob ( headroom + pkt_len );
                if ( ! pkt ) {
                        /* Record error and continue */
                        netdev_rx_err ( netdev, NULL, -ENOMEM );
                        continue;
                }
+               iob_reserve ( pkt, headroom );
                memcpy ( iob_put ( pkt, pkt_len ),
                         ( iobuf->data + pkt_offset ), pkt_len );