Add esfq to iproute2 and 2.4 kernel (#1891)
[openwrt.git] / target / linux / generic-2.4 / patches / 230-tun_get_user_backport.patch
1 --- linux-2.4.32/drivers/net/tun.c 2006-10-28 18:21:45.000000000 +0100
2 +++ new.linux-2.4.32/drivers/net/tun.c 2006-10-28 18:50:53.000000000 +0100
3 @@ -185,22 +185,31 @@
4  {
5         struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
6         struct sk_buff *skb;
7 -       size_t len = count;
8 +       size_t len = count, align = 0;
9  
10         if (!(tun->flags & TUN_NO_PI)) {
11                 if ((len -= sizeof(pi)) > count)
12                         return -EINVAL;
13  
14 -               memcpy_fromiovec((void *)&pi, iv, sizeof(pi));
15 +               if(memcpy_fromiovec((void *)&pi, iv, sizeof(pi)))
16 +                       return -EFAULT;
17         }
18
19 -       if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
20 +
21 +       if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV)
22 +               align = NET_IP_ALIGN;
23 +  
24 +       if (!(skb = alloc_skb(len + align, GFP_KERNEL))) {
25                 tun->stats.rx_dropped++;
26                 return -ENOMEM;
27         }
28  
29 -       skb_reserve(skb, 2);
30 -       memcpy_fromiovec(skb_put(skb, len), iv, len);
31 +       if (align)
32 +               skb_reserve(skb, align);
33 +       if (memcpy_fromiovec(skb_put(skb, len), iv, len)) {
34 +               tun->stats.rx_dropped++;
35 +               kfree_skb(skb);
36 +               return -EFAULT;
37 +       }
38  
39         skb->dev = &tun->dev;
40         switch (tun->flags & TUN_TYPE_MASK) {
41 @@ -271,7 +271,8 @@
42                         pi.flags |= TUN_PKT_STRIP;
43                 }
44   
45 -               memcpy_toiovec(iv, (void *) &pi, sizeof(pi));
46 +               if(memcpy_toiovec(iv, (void *) &pi, sizeof(pi)))
47 +                       return -EFAULT;
48                 total += sizeof(pi);
49         }       
50  
51 --- linux-2.4.32/include/linux/skbuff.h 2006-10-28 19:31:31.000000000 +0100
52 +++ new.linux-2.4.32/include/linux/skbuff.h     2006-10-28 19:29:27.000000000 +0100
53 @@ -918,6 +918,49 @@
54         skb->tail+=len;
55  }
56  
57 +/*
58 + * CPUs often take a performance hit when accessing unaligned memory
59 + * locations. The actual performance hit varies, it can be small if the
60 + * hardware handles it or large if we have to take an exception and fix it
61 + * in software.
62 + *
63 + * Since an ethernet header is 14 bytes network drivers often end up with
64 + * the IP header at an unaligned offset. The IP header can be aligned by
65 + * shifting the start of the packet by 2 bytes. Drivers should do this
66 + * with:
67 + *
68 + * skb_reserve(NET_IP_ALIGN);
69 + *
70 + * The downside to this alignment of the IP header is that the DMA is now
71 + * unaligned. On some architectures the cost of an unaligned DMA is high
72 + * and this cost outweighs the gains made by aligning the IP header.
73 + * 
74 + * Since this trade off varies between architectures, we allow NET_IP_ALIGN
75 + * to be overridden.
76 + */
77 +#ifndef NET_IP_ALIGN
78 +#define NET_IP_ALIGN    2
79 +#endif
80 +
81 +/*
82 + * The networking layer reserves some headroom in skb data (via
83 + * dev_alloc_skb). This is used to avoid having to reallocate skb data when
84 + * the header has to grow. In the default case, if the header has to grow
85 + * 16 bytes or less we avoid the reallocation.
86 + *
87 + * Unfortunately this headroom changes the DMA alignment of the resulting
88 + * network packet. As for NET_IP_ALIGN, this unaligned DMA is expensive
89 + * on some architectures. An architecture can override this value,
90 + * perhaps setting it to a cacheline in size (since that will maintain
91 + * cacheline alignment of the DMA). It must be a power of 2.
92 + *
93 + * Various parts of the networking layer expect at least 16 bytes of
94 + * headroom, you should not reduce this.
95 + */
96 +#ifndef NET_SKB_PAD
97 +#define NET_SKB_PAD     16
98 +#endif
99
100  extern int ___pskb_trim(struct sk_buff *skb, unsigned int len, int realloc);
101  
102  static inline void __skb_trim(struct sk_buff *skb, unsigned int len)