WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

[Xen-changelog] Fix netfront to accept received packets at a wider range

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] Fix netfront to accept received packets at a wider range of
From: Xen patchbot -unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Tue, 06 Dec 2005 17:52:26 +0000
Delivery-date: Wed, 07 Dec 2005 11:52:40 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# HG changeset patch
# User kaf24@xxxxxxxxxxxxxxxxxxxx
# Node ID 4e9c643968ffd0526258dc1ae7d1fee6123be718
# Parent  8b5c047f6e23c8e9dea7a84187b284b18bd44250
Fix netfront to accept received packets at a wider range of
offsets within a memory page. Also fix, skb realloc-and-copy
when copying really is required (we were forgetting whether
the packet data is known valid, and checksumming packets that
do not have the csum field filled in).

Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx>

diff -r 8b5c047f6e23 -r 4e9c643968ff 
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Dec  6 
11:49:05 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c      Tue Dec  6 
14:02:54 2005
@@ -76,9 +76,6 @@
         skb_shinfo(_skb)->frag_list = NULL;           \
     } while (0)
 
-/* Allow headroom on each rx pkt for Ethernet header, alignment padding, ... */
-#define RX_HEADROOM 200
-
 static unsigned long rx_pfn_array[NET_RX_RING_SIZE];
 static multicall_entry_t rx_mcl[NET_RX_RING_SIZE+1];
 static mmu_update_t rx_mmu[NET_RX_RING_SIZE];
@@ -153,14 +150,15 @@
 #endif
 
 #ifdef DEBUG
-#define DPRINTK(fmt, args...) \
-       printk(KERN_ALERT "netfront (%s:%d) " fmt, __FUNCTION__, __LINE__, 
##args)
+#define DPRINTK(fmt, args...)                                          \
+       printk(KERN_ALERT "netfront (%s:%d) " fmt, __FUNCTION__,        \
+              __LINE__, ##args)
 #else
 #define DPRINTK(fmt, args...) ((void)0)
 #endif
-#define IPRINTK(fmt, args...) \
+#define IPRINTK(fmt, args...)                          \
        printk(KERN_INFO "netfront: " fmt, ##args)
-#define WPRINTK(fmt, args...) \
+#define WPRINTK(fmt, args...)                          \
        printk(KERN_WARNING "netfront: " fmt, ##args)
 
 
@@ -537,7 +535,9 @@
         */
        batch_target = np->rx_target - (req_prod - np->rx.rsp_cons);
        for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
-               skb = alloc_xen_skb(dev->mtu + RX_HEADROOM);
+               skb = alloc_xen_skb(
+                       (PAGE_SIZE - sizeof(struct skb_shared_info)) &
+                       (-SKB_DATA_ALIGN(1)));
                if (skb == NULL)
                        break;
                __skb_queue_tail(&np->rx_batch, skb);
@@ -567,7 +567,8 @@
                rx_pfn_array[i] = virt_to_mfn(skb->head);
 
                /* Remove this page from map before passing back to Xen. */
-               set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT, 
INVALID_P2M_ENTRY);
+               set_phys_to_machine(__pa(skb->head) >> PAGE_SHIFT,
+                                   INVALID_P2M_ENTRY);
 
                MULTI_update_va_mapping(rx_mcl+i, (unsigned long)skb->head,
                                        __pte(0), 0);
@@ -809,36 +810,43 @@
        }
 
        while ((skb = __skb_dequeue(&rxq)) != NULL) {
+               if (skb->len > (dev->mtu + ETH_HLEN)) {
+                       if (net_ratelimit())
+                               printk(KERN_INFO "Received packet too big for "
+                                      "MTU (%d > %d)\n",
+                                      skb->len - ETH_HLEN, dev->mtu);
+                       skb->len  = 0;
+                       skb->tail = skb->data;
+                       init_skb_shinfo(skb);
+                       dev_kfree_skb(skb);
+                       continue;
+               }
+
                /*
                 * Enough room in skbuff for the data we were passed? Also,
                 * Linux expects at least 16 bytes headroom in each rx buffer.
                 */
                if (unlikely(skb->tail > skb->end) || 
                    unlikely((skb->data - skb->head) < 16)) {
-                       nskb = NULL;
-
-                       /* Only copy the packet if it fits in the MTU. */
-                       if (skb->len <= (dev->mtu + ETH_HLEN)) {
-                               if ((skb->tail > skb->end) && net_ratelimit())
+                       if (net_ratelimit()) {
+                               if (skb->tail > skb->end)
                                        printk(KERN_INFO "Received packet "
-                                              "needs %zd bytes more "
-                                              "headroom.\n",
+                                              "is %zd bytes beyond tail.\n",
                                               skb->tail - skb->end);
-
-                               nskb = alloc_xen_skb(skb->len + 2);
-                               if (nskb != NULL) {
-                                       skb_reserve(nskb, 2);
-                                       skb_put(nskb, skb->len);
-                                       memcpy(nskb->data,
-                                              skb->data,
-                                              skb->len);
-                                       nskb->dev = skb->dev;
-                               }
+                               else
+                                       printk(KERN_INFO "Received packet "
+                                              "is %zd bytes before head.\n",
+                                              16 - (skb->data - skb->head));
                        }
-                       else if (net_ratelimit())
-                               printk(KERN_INFO "Received packet too big for "
-                                      "MTU (%d > %d)\n",
-                                      skb->len - ETH_HLEN, dev->mtu);
+
+                       nskb = alloc_xen_skb(skb->len + 2);
+                       if (nskb != NULL) {
+                               skb_reserve(nskb, 2);
+                               skb_put(nskb, skb->len);
+                               memcpy(nskb->data, skb->data, skb->len);
+                               nskb->dev = skb->dev;
+                               nskb->ip_summed = skb->ip_summed;
+                       }
 
                        /* Reinitialise and then destroy the old skbuff. */
                        skb->len  = 0;

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog

<Prev in Thread] Current Thread [Next in Thread>