OSDN Git Service

[PATCH] via-rhine: zero pad short packets on Rhine I ethernet cards
authorCraig Brind <craigbrind@gmail.com>
Mon, 24 Apr 2006 21:35:41 +0000 (23:35 +0200)
committerMarcelo Tosatti <marcelo@dmt.cnet>
Sun, 30 Apr 2006 17:37:05 +0000 (14:37 -0300)
Fixes Rhine I cards disclosing fragments of previously transmitted
frames in new transmissions.

Before transmission, any socket buffer (skb) shorter than the ethernet
minimum length of 60 bytes was zero-padded. On Rhine I cards the data
can later be copied into an aligned transmission buffer without copying
this padding. This resulted in the transmission of the frame with the
extra bytes beyond the provided content leaking the previous contents of
this buffer on to the network.

Now zero-padding is repeated in the local aligned buffer if one is used.

Following a suggestion from the via-rhine maintainer, no attempt is made
here to avoid the duplicated effort of padding the skb if it is known
that an aligned buffer will definitely be used. This is to make the
change "obviously correct" and allow it to be applied to a stable kernel
if necessary. There is no change to the flow of control and the changes
are only to the Rhine I code path.

Signed-off-by: Craig Brind <craigbrind@gmail.com>
Signed-off-by: Roger Luethi <rl@hellgate.ch>
drivers/net/via-rhine.c

index 0c62b02..91e12bd 100644 (file)
 
        LK1.1.19 (Roger Luethi)
        - Increase Tx threshold for unspecified errors
+       - Craig Brind: Zero padded aligned buffers for short packets
 
 */
 
@@ -1308,10 +1309,14 @@ static int via_rhine_start_tx(struct sk_buff *skb, struct net_device *dev)
                        np->stats.tx_dropped++;
                        return 0;
                }
+               /* Padding is not copied and so must be redone. */
                skb_copy_and_csum_dev(skb, np->tx_buf[entry]);
+               if (skb->len < ETH_ZLEN)
+                       memset(np->tx_buf[entry] + skb->len, 0,
+                              ETH_ZLEN - skb->len);
                np->tx_skbuff_dma[entry] = 0;
                np->tx_ring[entry].addr = cpu_to_le32(np->tx_bufs_dma +
-                                                                                 (np->tx_buf[entry] - np->tx_bufs));
+                                         (np->tx_buf[entry] - np->tx_bufs));
        } else {
                np->tx_skbuff_dma[entry] =
                        pci_map_single(np->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);