If the 2.6.39-stable branch is still active, would you please queue
up these networking bug fixes there?  Thanks!
>From 7dad6104716ab36a17bc50a9d6aef8c8f50724e0 Mon Sep 17 00:00:00 2001
From: Bill Sommerfeld <wsommerf...@google.com>
Date: Tue, 19 Jul 2011 15:22:33 +0000
Subject: [PATCH 03/19] ipv4: Constrain UFO fragment sizes to multiples of 8
 bytes

[ Upstream commit d9be4f7a6f5a8da3133b832eca41c3591420b1ca ]

Because the ip fragment offset field counts 8-byte chunks, ip
fragments other than the last must contain a multiple of 8 bytes of
payload.  ip_ufo_append_data wasn't respecting this constraint and,
depending on the MTU and ip option sizes, could create malformed
non-final fragments.

Google-Bug-Id: 5009328
Signed-off-by: Bill Sommerfeld <wsommerf...@google.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 net/ipv4/ip_output.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 459c011..7cf29b3c 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -731,7 +731,7 @@ static inline int ip_ufo_append_data(struct sock *sk,
                        int getfrag(void *from, char *to, int offset, int len,
                               int odd, struct sk_buff *skb),
                        void *from, int length, int hh_len, int fragheaderlen,
-                       int transhdrlen, int mtu, unsigned int flags)
+                       int transhdrlen, int maxfraglen, unsigned int flags)
 {
        struct sk_buff *skb;
        int err;
@@ -764,7 +764,7 @@ static inline int ip_ufo_append_data(struct sock *sk,
                skb->csum = 0;
 
                /* specify the length of each IP datagram fragment */
-               skb_shinfo(skb)->gso_size = mtu - fragheaderlen;
+               skb_shinfo(skb)->gso_size = maxfraglen - fragheaderlen;
                skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
                __skb_queue_tail(queue, skb);
        }
@@ -828,7 +828,7 @@ static int __ip_append_data(struct sock *sk, struct 
sk_buff_head *queue,
            (rt->dst.dev->features & NETIF_F_UFO)) {
                err = ip_ufo_append_data(sk, queue, getfrag, from, length,
                                         hh_len, fragheaderlen, transhdrlen,
-                                        mtu, flags);
+                                        maxfraglen, flags);
                if (err)
                        goto error;
                return 0;
-- 
1.7.6


>From 038e586849ef82e87c9b1a77bbab326c1659b7a2 Mon Sep 17 00:00:00 2001
From: Julian Anastasov <j...@ssi.bg>
Date: Sun, 7 Aug 2011 22:20:20 -0700
Subject: [PATCH 04/19] ipv4: fix the reusing of routing cache entries

[ Upstream commit d547f727df86059104af2234804fdd538e112015 ]

        compare_keys and ip_route_input_common rely on
rt_oif for distinguishing of input and output routes
with same keys values. But sometimes the input route has
also same hash chain (keyed by iif != 0) with the output
routes (keyed by orig_oif=0). Problem visible if running
with small number of rhash_entries.

        Fix them to use rt_route_iif instead. By this way
input route can not be returned to users that request
output route.

        The patch fixes the ip_rt_bug errors that were
reported in ip_local_out context, mostly for 255.255.255.255
destinations.

Signed-off-by: Julian Anastasov <j...@ssi.bg>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 net/ipv4/route.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 2c2111d..056ef81 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -726,6 +726,7 @@ static inline int compare_keys(struct rtable *rt1, struct 
rtable *rt2)
                ((__force u32)rt1->rt_key_src ^ (__force u32)rt2->rt_key_src) |
                (rt1->rt_mark ^ rt2->rt_mark) |
                (rt1->rt_tos ^ rt2->rt_tos) |
+               (rt1->rt_route_iif ^ rt2->rt_route_iif) |
                (rt1->rt_oif ^ rt2->rt_oif) |
                (rt1->rt_iif ^ rt2->rt_iif)) == 0;
 }
@@ -2286,8 +2287,8 @@ int ip_route_input_common(struct sk_buff *skb, __be32 
daddr, __be32 saddr,
                if ((((__force u32)rth->rt_key_dst ^ (__force u32)daddr) |
                     ((__force u32)rth->rt_key_src ^ (__force u32)saddr) |
                     (rth->rt_iif ^ iif) |
-                    rth->rt_oif |
                     (rth->rt_tos ^ tos)) == 0 &&
+                   rt_is_input_route(rth) &&
                    rth->rt_mark == skb->mark &&
                    net_eq(dev_net(rth->dst.dev), net) &&
                    !rt_is_expired(rth)) {
-- 
1.7.6


>From 65f82358a20a0932cba82094c4d35eff9148db6b Mon Sep 17 00:00:00 2001
From: Eric Dumazet <eric.duma...@gmail.com>
Date: Mon, 8 Aug 2011 23:44:00 -0700
Subject: [PATCH 05/19] ipv6: make fragment identifications less predictable

[ Backport of upstream commit 87c48fa3b4630905f98268dde838ee43626a060c ]

Fernando Gont reported current IPv6 fragment identification generation
was not secure, because using a very predictable system-wide generator,
allowing various attacks.

IPv4 uses inetpeer cache to address this problem and to get good
performance. We'll use this mechanism when IPv6 inetpeer is stable
enough in linux-3.1

For the time being, we use jhash on destination address to provide less
predictable identifications. Also remove a spinlock and use cmpxchg() to
get better SMP performance.

Reported-by: Fernando Gont <ferna...@gont.com.ar>
Signed-off-by: Eric Dumazet <eric.duma...@gmail.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 include/net/ipv6.h      |   12 +-----------
 include/net/transp_v6.h |    2 ++
 net/ipv6/af_inet6.c     |    2 ++
 net/ipv6/ip6_output.c   |   40 +++++++++++++++++++++++++++++++++++-----
 net/ipv6/udp.c          |    2 +-
 5 files changed, 41 insertions(+), 17 deletions(-)

diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 34200f9..6174c75 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -460,17 +460,7 @@ static inline int ipv6_addr_diff(const struct in6_addr 
*a1, const struct in6_add
        return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
 }
 
-static __inline__ void ipv6_select_ident(struct frag_hdr *fhdr)
-{
-       static u32 ipv6_fragmentation_id = 1;
-       static DEFINE_SPINLOCK(ip6_id_lock);
-
-       spin_lock_bh(&ip6_id_lock);
-       fhdr->identification = htonl(ipv6_fragmentation_id);
-       if (++ipv6_fragmentation_id == 0)
-               ipv6_fragmentation_id = 1;
-       spin_unlock_bh(&ip6_id_lock);
-}
+extern void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt);
 
 /*
  *     Prototypes exported by ipv6
diff --git a/include/net/transp_v6.h b/include/net/transp_v6.h
index a8122dc..c913646 100644
--- a/include/net/transp_v6.h
+++ b/include/net/transp_v6.h
@@ -16,6 +16,8 @@ extern struct proto tcpv6_prot;
 
 struct flowi6;
 
+extern void initialize_hashidentrnd(void);
+
 /* extension headers */
 extern int                             ipv6_exthdrs_init(void);
 extern void                            ipv6_exthdrs_exit(void);
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index afcc709..6d8524c 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -1074,6 +1074,8 @@ static int __init inet6_init(void)
                goto out;
        }
 
+       initialize_hashidentrnd();
+
        err = proto_register(&tcpv6_prot, 1);
        if (err)
                goto out;
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 46cf7be..32d78c0 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -596,6 +596,35 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
        return offset;
 }
 
+static u32 hashidentrnd __read_mostly;
+#define FID_HASH_SZ 16
+static u32 ipv6_fragmentation_id[FID_HASH_SZ];
+
+void __init initialize_hashidentrnd(void)
+{
+       get_random_bytes(&hashidentrnd, sizeof(hashidentrnd));
+}
+
+static u32 __ipv6_select_ident(const struct in6_addr *addr)
+{
+       u32 newid, oldid, hash = jhash2((u32 *)addr, 4, hashidentrnd);
+       u32 *pid = &ipv6_fragmentation_id[hash % FID_HASH_SZ];
+
+       do {
+               oldid = *pid;
+               newid = oldid + 1;
+               if (!(hash + newid))
+                       newid++;
+       } while (cmpxchg(pid, oldid, newid) != oldid);
+
+       return hash + newid;
+}
+
+void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt)
+{
+       fhdr->identification = htonl(__ipv6_select_ident(&rt->rt6i_dst.addr));
+}
+
 int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
 {
        struct sk_buff *frag;
@@ -680,7 +709,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct 
sk_buff *))
                skb_reset_network_header(skb);
                memcpy(skb_network_header(skb), tmp_hdr, hlen);
 
-               ipv6_select_ident(fh);
+               ipv6_select_ident(fh, rt);
                fh->nexthdr = nexthdr;
                fh->reserved = 0;
                fh->frag_off = htons(IP6_MF);
@@ -826,7 +855,7 @@ slow_path:
                fh->nexthdr = nexthdr;
                fh->reserved = 0;
                if (!frag_id) {
-                       ipv6_select_ident(fh);
+                       ipv6_select_ident(fh, rt);
                        frag_id = fh->identification;
                } else
                        fh->identification = frag_id;
@@ -1072,7 +1101,8 @@ static inline int ip6_ufo_append_data(struct sock *sk,
                        int getfrag(void *from, char *to, int offset, int len,
                        int odd, struct sk_buff *skb),
                        void *from, int length, int hh_len, int fragheaderlen,
-                       int transhdrlen, int mtu,unsigned int flags)
+                       int transhdrlen, int mtu,unsigned int flags,
+                       struct rt6_info *rt)
 
 {
        struct sk_buff *skb;
@@ -1116,7 +1146,7 @@ static inline int ip6_ufo_append_data(struct sock *sk,
                skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
                                             sizeof(struct frag_hdr)) & ~7;
                skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
-               ipv6_select_ident(&fhdr);
+               ipv6_select_ident(&fhdr, rt);
                skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
                __skb_queue_tail(&sk->sk_write_queue, skb);
 
@@ -1280,7 +1310,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void 
*from, char *to,
 
                        err = ip6_ufo_append_data(sk, getfrag, from, length,
                                                  hh_len, fragheaderlen,
-                                                 transhdrlen, mtu, flags);
+                                                 transhdrlen, mtu, flags, rt);
                        if (err)
                                goto error;
                        return 0;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index b31a2f3..a70053b 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1359,7 +1359,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff 
*skb, u32 features)
        fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen);
        fptr->nexthdr = nexthdr;
        fptr->reserved = 0;
-       ipv6_select_ident(fptr);
+       ipv6_select_ident(fptr, (struct rt6_info *)skb_dst(skb));
 
        /* Fragment the skb. ipv6 header and the remaining fields of the
         * fragment header are updated in ipv6_gso_segment()
-- 
1.7.6


>From cbfb5e1b88169bf6582d0b272c9865b7bfb83a42 Mon Sep 17 00:00:00 2001
From: Simon Horman <ho...@verge.net.au>
Date: Thu, 19 May 2011 21:32:57 +0900
Subject: [PATCH 06/19] IPVS: Free resources on module removal

[ Upstream commit 7676e345824f162191b1fe2058ad948a6cf91c20 ]

This resolves a panic on module removal.

Reported-by: Dave Jones <da...@redhat.com>
Acked-by: Julian Anastasov <j...@ssi.bg>
Signed-off-by: Hans Schillstrom <hans.schillst...@ericsson.com>
Signed-off-by: Simon Horman <ho...@verge.net.au>
---
 net/netfilter/ipvs/ip_vs_ctl.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 37890f2..9b9039b 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3774,6 +3774,7 @@ err_sock:
 void ip_vs_control_cleanup(void)
 {
        EnterFunction(2);
+       unregister_netdevice_notifier(&ip_vs_dst_notifier);
        ip_vs_genl_unregister();
        nf_unregister_sockopt(&ip_vs_sockopts);
        LeaveFunction(2);
-- 
1.7.6


>From 4d16911ebb73a1371ad5ff8ba38c06bd89baafbf Mon Sep 17 00:00:00 2001
From: Julia Lawall <ju...@diku.dk>
Date: Thu, 28 Jul 2011 02:46:01 +0000
Subject: [PATCH 07/19] net: adjust array index

[ Upstream commit a1889c0d2039a53ae04abb9f20c62500bd312bf3 ]

Convert array index from the loop bound to the loop index.

A simplified version of the semantic patch that fixes this problem is as
follows: (http://coccinelle.lip6.fr/)

// <smpl>
@@
expression e1,e2,ar;
@@

for(e1 = 0; e1 < e2; e1++) { <...
  ar[
- e2
+ e1
  ]
  ...> }
// </smpl>

Signed-off-by: Julia Lawall <ju...@diku.dk>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 net/ipv4/igmp.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 57ca93a..4f0fb25 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1732,7 +1732,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 
*pmca, int sfmode,
 
                pmc->sfcount[sfmode]--;
                for (j=0; j<i; j++)
-                       (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[i]);
+                       (void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]);
        } else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) {
 #ifdef CONFIG_IP_MULTICAST
                struct ip_sf_list *psf;
-- 
1.7.6


>From be05e372dfced4e96a7cae075ed6bd12c44ebae2 Mon Sep 17 00:00:00 2001
From: Julia Lawall <ju...@diku.dk>
Date: Thu, 28 Jul 2011 02:46:03 +0000
Subject: [PATCH 08/19] drivers/net/niu.c: adjust array index

[ Upstream commit 956837f7c954443f426a82ba6f17b33488cf9a0c ]

Convert array index from the loop bound to the loop index.

A simplified version of the semantic patch that fixes this problem is as
follows: (http://coccinelle.lip6.fr/)

// <smpl>
@@
expression e1,e2,ar;
@@

for(e1 = 0; e1 < e2; e1++) { <...
  ar[
- e2
+ e1
  ]
  ...> }
// </smpl>

Signed-off-by: Julia Lawall <ju...@diku.dk>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 drivers/net/niu.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/niu.c b/drivers/net/niu.c
index 32678b6..7eb9920 100644
--- a/drivers/net/niu.c
+++ b/drivers/net/niu.c
@@ -9207,7 +9207,7 @@ static int __devinit niu_ldg_init(struct niu *np)
 
        first_chan = 0;
        for (i = 0; i < port; i++)
-               first_chan += parent->rxchan_per_port[port];
+               first_chan += parent->rxchan_per_port[i];
        num_chan = parent->rxchan_per_port[port];
 
        for (i = first_chan; i < (first_chan + num_chan); i++) {
@@ -9223,7 +9223,7 @@ static int __devinit niu_ldg_init(struct niu *np)
 
        first_chan = 0;
        for (i = 0; i < port; i++)
-               first_chan += parent->txchan_per_port[port];
+               first_chan += parent->txchan_per_port[i];
        num_chan = parent->txchan_per_port[port];
        for (i = first_chan; i < (first_chan + num_chan); i++) {
                err = niu_ldg_assign_ldn(np, parent,
-- 
1.7.6


>From 1841500141667c7195c9966a07a1d0f76003fb8b Mon Sep 17 00:00:00 2001
From: Eric Dumazet <eric.duma...@gmail.com>
Date: Fri, 29 Jul 2011 19:22:42 +0000
Subject: [PATCH 09/19] sch_sfq: fix sfq_enqueue()

[ Upstream commit e1738bd9cecc5c867b0e2996470c1ff20f66ba79 ]

commit 8efa88540635 (sch_sfq: avoid giving spurious NET_XMIT_CN signals)
forgot to call qdisc_tree_decrease_qlen() to signal upper levels that a
packet (from another flow) was dropped, leading to various problems.

With help from Michal Soltys and Michal Pokrywka, who did a bisection.

Bugzilla ref: https://bugzilla.kernel.org/show_bug.cgi?id=39372
Debian ref: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=631945

Reported-by: Lucas Bocchi <lucas.boc...@gmail.com>
Reported-and-bisected-by: Michal Pokrywka <wolfm...@o2.pl>
Signed-off-by: Eric Dumazet <eric.duma...@gmail.com>
CC: Michal Soltys <sol...@ziu.info>
Acked-by: Patrick McHardy <ka...@trash.net>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 net/sched/sch_sfq.c |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 6d96275..35e39c1 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -410,7 +410,12 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
        /* Return Congestion Notification only if we dropped a packet
         * from this flow.
         */
-       return (qlen != slot->qlen) ? NET_XMIT_CN : NET_XMIT_SUCCESS;
+       if (qlen != slot->qlen)
+               return NET_XMIT_CN;
+
+       /* As we dropped a packet, better let upper stack know this */
+       qdisc_tree_decrease_qlen(sch, 1);
+       return NET_XMIT_SUCCESS;
 }
 
 static struct sk_buff *
-- 
1.7.6


>From 416aa0f949722a85a0a6a5331294c8cf2f26ec94 Mon Sep 17 00:00:00 2001
From: Zoltan Kiss <scha...@sch.bme.hu>
Date: Sun, 24 Jul 2011 13:09:30 +0000
Subject: [PATCH 10/19] IPv4: Send gratuitous ARP for secondary IP addresses
 also

[ Upstream commit b76d0789c92a816a5539dc14232a700b8d62a53a ]

If a device event generates gratuitous ARP messages, only primary
address is used for sending. This patch iterates through the whole
list. Tested with 2 IP addresses configuration on bonding interface.

Signed-off-by: Zoltan Kiss <scha...@sch.bme.hu>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 net/ipv4/devinet.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index cd9ca08..575a9fd 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1134,15 +1134,15 @@ static void inetdev_send_gratuitous_arp(struct 
net_device *dev,
                                        struct in_device *in_dev)
 
 {
-       struct in_ifaddr *ifa = in_dev->ifa_list;
-
-       if (!ifa)
-               return;
+       struct in_ifaddr *ifa;
 
-       arp_send(ARPOP_REQUEST, ETH_P_ARP,
-                ifa->ifa_local, dev,
-                ifa->ifa_local, NULL,
-                dev->dev_addr, NULL);
+       for (ifa = in_dev->ifa_list; ifa;
+            ifa = ifa->ifa_next) {
+               arp_send(ARPOP_REQUEST, ETH_P_ARP,
+                        ifa->ifa_local, dev,
+                        ifa->ifa_local, NULL,
+                        dev->dev_addr, NULL);
+       }
 }
 
 /* Called only under RTNL semaphore */
-- 
1.7.6


>From f42a7fef15478b83a06d8aefcc9a7f056dec9992 Mon Sep 17 00:00:00 2001
From: Neil Horman <nhor...@tuxdriver.com>
Date: Tue, 26 Jul 2011 06:05:37 +0000
Subject: [PATCH 11/19] net: add IFF_SKB_TX_SHARED flag to priv_flags

[ Upstream commit d8873315065f1f527c7c380402cf59b1e1d0ae36 ]

Pktgen attempts to transmit shared skbs to net devices, which can't be used by
some drivers as they keep state information in skbs.  This patch adds a flag
marking drivers as being able to handle shared skbs in their tx path.  Drivers
are defaulted to being unable to do so, but calling ether_setup enables this
flag, as 90% of the drivers calling ether_setup touch real hardware and can
handle shared skbs.  A subsequent patch will audit drivers to ensure that the
flag is set properly

Signed-off-by: Neil Horman <nhor...@tuxdriver.com>
Reported-by: Jiri Pirko <jpi...@redhat.com>
CC: Robert Olsson <robert.ols...@its.uu.se>
CC: Eric Dumazet <eric.duma...@gmail.com>
CC: Alexey Dobriyan <adobri...@gmail.com>
CC: David S. Miller <da...@davemloft.net>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 include/linux/if.h |    2 ++
 net/core/pktgen.c  |    8 +++++---
 net/ethernet/eth.c |    1 +
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/include/linux/if.h b/include/linux/if.h
index 3bc63e6..03489ca 100644
--- a/include/linux/if.h
+++ b/include/linux/if.h
@@ -76,6 +76,8 @@
 #define IFF_BRIDGE_PORT        0x4000          /* device used as bridge port */
 #define IFF_OVS_DATAPATH       0x8000  /* device used as Open vSwitch
                                         * datapath port */
+#define IFF_TX_SKB_SHARING     0x10000 /* The interface supports sharing
+                                        * skbs on transmit */
 
 #define IF_GET_IFACE   0x0001          /* for querying only */
 #define IF_GET_PROTO   0x0002
diff --git a/net/core/pktgen.c b/net/core/pktgen.c
index aeeece7..8697f74 100644
--- a/net/core/pktgen.c
+++ b/net/core/pktgen.c
@@ -1079,7 +1079,9 @@ static ssize_t pktgen_if_write(struct file *file,
                len = num_arg(&user_buffer[i], 10, &value);
                if (len < 0)
                        return len;
-
+               if ((value > 0) &&
+                   (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING)))
+                       return -ENOTSUPP;
                i += len;
                pkt_dev->clone_skb = value;
 
@@ -3694,7 +3696,6 @@ static int pktgen_add_device(struct pktgen_thread *t, 
const char *ifname)
        pkt_dev->min_pkt_size = ETH_ZLEN;
        pkt_dev->max_pkt_size = ETH_ZLEN;
        pkt_dev->nfrags = 0;
-       pkt_dev->clone_skb = pg_clone_skb_d;
        pkt_dev->delay = pg_delay_d;
        pkt_dev->count = pg_count_d;
        pkt_dev->sofar = 0;
@@ -3702,7 +3703,6 @@ static int pktgen_add_device(struct pktgen_thread *t, 
const char *ifname)
        pkt_dev->udp_src_max = 9;
        pkt_dev->udp_dst_min = 9;
        pkt_dev->udp_dst_max = 9;
-
        pkt_dev->vlan_p = 0;
        pkt_dev->vlan_cfi = 0;
        pkt_dev->vlan_id = 0xffff;
@@ -3714,6 +3714,8 @@ static int pktgen_add_device(struct pktgen_thread *t, 
const char *ifname)
        err = pktgen_setup_dev(pkt_dev, ifname);
        if (err)
                goto out1;
+       if (pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING)
+               pkt_dev->clone_skb = pg_clone_skb_d;
 
        pkt_dev->entry = proc_create_data(ifname, 0600, pg_proc_dir,
                                          &pktgen_if_fops, pkt_dev);
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index 44d2b42..2780e9b 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -340,6 +340,7 @@ void ether_setup(struct net_device *dev)
        dev->addr_len           = ETH_ALEN;
        dev->tx_queue_len       = 1000; /* Ethernet wants good queues */
        dev->flags              = IFF_BROADCAST|IFF_MULTICAST;
+       dev->priv_flags         = IFF_TX_SKB_SHARING;
 
        memset(dev->broadcast, 0xFF, ETH_ALEN);
 
-- 
1.7.6


>From 1991a03569df62077456ff9621709223fb96c0b4 Mon Sep 17 00:00:00 2001
From: Neil Horman <nhor...@tuxdriver.com>
Date: Tue, 26 Jul 2011 06:05:38 +0000
Subject: [PATCH 12/19] net: Audit drivers to identify those needing
 IFF_TX_SKB_SHARING cleared

[ Upstream commit 550fd08c2cebad61c548def135f67aba284c6162 ]

After the last patch, We are left in a state in which only drivers calling
ether_setup have IFF_TX_SKB_SHARING set (we assume that drivers touching real
hardware call ether_setup for their net_devices and don't hold any state in
their skbs.  There are a handful of drivers that violate this assumption of
course, and need to be fixed up.  This patch identifies those drivers, and marks
them as not being able to support the safe transmission of skbs by clearning the
IFF_TX_SKB_SHARING flag in priv_flags

Signed-off-by: Neil Horman <nhor...@tuxdriver.com>
CC: Karsten Keil <i...@linux-pingi.de>
CC: "David S. Miller" <da...@davemloft.net>
CC: Jay Vosburgh <fu...@us.ibm.com>
CC: Andy Gospodarek <a...@greyhouse.net>
CC: Patrick McHardy <ka...@trash.net>
CC: Krzysztof Halasa <k...@pm.waw.pl>
CC: "John W. Linville" <linvi...@tuxdriver.com>
CC: Greg Kroah-Hartman <gre...@suse.de>
CC: Marcel Holtmann <mar...@holtmann.org>
CC: Johannes Berg <johan...@sipsolutions.net>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 drivers/isdn/i4l/isdn_net.c                  |    3 +++
 drivers/net/bonding/bond_main.c              |    6 ++++--
 drivers/net/ifb.c                            |    2 +-
 drivers/net/macvlan.c                        |    2 +-
 drivers/net/tun.c                            |    1 +
 drivers/net/veth.c                           |    2 ++
 drivers/net/wan/hdlc_fr.c                    |    5 +++--
 drivers/net/wireless/airo.c                  |    1 +
 drivers/net/wireless/hostap/hostap_main.c    |    1 +
 drivers/staging/ath6kl/os/linux/ar6000_drv.c |    1 +
 net/8021q/vlan_dev.c                         |    2 +-
 net/bluetooth/bnep/netdev.c                  |    1 +
 net/l2tp/l2tp_eth.c                          |    2 +-
 net/mac80211/iface.c                         |    1 +
 14 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/drivers/isdn/i4l/isdn_net.c b/drivers/isdn/i4l/isdn_net.c
index 2a7d17c..fb3ba59 100644
--- a/drivers/isdn/i4l/isdn_net.c
+++ b/drivers/isdn/i4l/isdn_net.c
@@ -2533,6 +2533,9 @@ static void _isdn_setup(struct net_device *dev)
 
        /* Setup the generic properties */
        dev->flags = IFF_NOARP|IFF_POINTOPOINT;
+
+       /* isdn prepends a header in the tx path, can't share skbs */
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->header_ops = NULL;
        dev->netdev_ops = &isdn_netdev_ops;
 
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index ffb0fde..c0094ec 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1607,8 +1607,10 @@ int bond_enslave(struct net_device *bond_dev, struct 
net_device *slave_dev)
 
                        if (slave_dev->type != ARPHRD_ETHER)
                                bond_setup_by_slave(bond_dev, slave_dev);
-                       else
+                       else {
                                ether_setup(bond_dev);
+                               bond_dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+                       }
 
                        netdev_bonding_change(bond_dev,
                                              NETDEV_POST_TYPE_CHANGE);
@@ -4508,7 +4510,7 @@ static void bond_setup(struct net_device *bond_dev)
        bond_dev->tx_queue_len = 0;
        bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
        bond_dev->priv_flags |= IFF_BONDING;
-       bond_dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
+       bond_dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
 
        /* At first, we block adding VLANs. That's the only way to
         * prevent problems that occur when adding VLANs over an
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c
index e07d487..c60f596 100644
--- a/drivers/net/ifb.c
+++ b/drivers/net/ifb.c
@@ -145,7 +145,7 @@ static void ifb_setup(struct net_device *dev)
 
        dev->flags |= IFF_NOARP;
        dev->flags &= ~IFF_MULTICAST;
-       dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
+       dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
        random_ether_addr(dev->dev_addr);
 }
 
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 6d357d6..fa71da1 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -562,7 +562,7 @@ void macvlan_common_setup(struct net_device *dev)
 {
        ether_setup(dev);
 
-       dev->priv_flags        &= ~IFF_XMIT_DST_RELEASE;
+       dev->priv_flags        &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
        dev->netdev_ops         = &macvlan_netdev_ops;
        dev->destructor         = free_netdev;
        dev->header_ops         = &macvlan_hard_header_ops,
diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index f5e9ac0..2776926 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -494,6 +494,7 @@ static void tun_net_init(struct net_device *dev)
                dev->netdev_ops = &tap_netdev_ops;
                /* Ethernet TAP Device */
                ether_setup(dev);
+               dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 
                random_ether_addr(dev->dev_addr);
 
diff --git a/drivers/net/veth.c b/drivers/net/veth.c
index 3b99f64..6e9202e 100644
--- a/drivers/net/veth.c
+++ b/drivers/net/veth.c
@@ -300,6 +300,8 @@ static void veth_setup(struct net_device *dev)
 {
        ether_setup(dev);
 
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+
        dev->netdev_ops = &veth_netdev_ops;
        dev->ethtool_ops = &veth_ethtool_ops;
        dev->features |= NETIF_F_LLTX;
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 0edb535..5ba5428 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1083,9 +1083,10 @@ static int fr_add_pvc(struct net_device *frad, unsigned 
int dlci, int type)
 
        used = pvc_is_used(pvc);
 
-       if (type == ARPHRD_ETHER)
+       if (type == ARPHRD_ETHER) {
                dev = alloc_netdev(0, "pvceth%d", ether_setup);
-       else
+               dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+       } else
                dev = alloc_netdev(0, "pvc%d", pvc_setup);
 
        if (!dev) {
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 4e5c7a1..f246845 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2822,6 +2822,7 @@ static struct net_device *_init_airo_card( unsigned short 
irq, int port,
        dev->wireless_data = &ai->wireless_data;
        dev->irq = irq;
        dev->base_addr = port;
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 
        SET_NETDEV_DEV(dev, dmdev);
 
diff --git a/drivers/net/wireless/hostap/hostap_main.c 
b/drivers/net/wireless/hostap/hostap_main.c
index 1d9aed6..5f15e6e 100644
--- a/drivers/net/wireless/hostap/hostap_main.c
+++ b/drivers/net/wireless/hostap/hostap_main.c
@@ -860,6 +860,7 @@ void hostap_setup_dev(struct net_device *dev, local_info_t 
*local,
 
        iface = netdev_priv(dev);
        ether_setup(dev);
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 
        /* kernel callbacks */
        if (iface) {
diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c 
b/drivers/staging/ath6kl/os/linux/ar6000_drv.c
index 97d6ce6..2e8d3ee 100644
--- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c
+++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c
@@ -6438,6 +6438,7 @@ int ar6000_create_ap_interface(struct ar6_softc *ar, char 
*ap_ifname)
     
     ether_setup(dev);
     init_netdev(dev, ap_ifname);
+    dev->priv_flags &= ~IFF_TX_SKB_SHARING;
 
     if (register_netdev(dev)) {
         AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: 
register_netdev failed\n"));
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index f11e61e..954d282 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -878,7 +878,7 @@ void vlan_setup(struct net_device *dev)
        ether_setup(dev);
 
        dev->priv_flags         |= IFF_802_1Q_VLAN;
-       dev->priv_flags         &= ~IFF_XMIT_DST_RELEASE;
+       dev->priv_flags         &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
        dev->tx_queue_len       = 0;
 
        dev->netdev_ops         = &vlan_netdev_ops;
diff --git a/net/bluetooth/bnep/netdev.c b/net/bluetooth/bnep/netdev.c
index 8c100c9..d4f5dff 100644
--- a/net/bluetooth/bnep/netdev.c
+++ b/net/bluetooth/bnep/netdev.c
@@ -231,6 +231,7 @@ void bnep_net_setup(struct net_device *dev)
        dev->addr_len = ETH_ALEN;
 
        ether_setup(dev);
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->netdev_ops = &bnep_netdev_ops;
 
        dev->watchdog_timeo  = HZ * 2;
diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c
index a8193f5..d2726a7 100644
--- a/net/l2tp/l2tp_eth.c
+++ b/net/l2tp/l2tp_eth.c
@@ -103,7 +103,7 @@ static struct net_device_ops l2tp_eth_netdev_ops = {
 static void l2tp_eth_dev_setup(struct net_device *dev)
 {
        ether_setup(dev);
-
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->netdev_ops         = &l2tp_eth_netdev_ops;
        dev->destructor         = free_netdev;
 }
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 4054399..ad16111 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -698,6 +698,7 @@ static const struct net_device_ops ieee80211_monitorif_ops 
= {
 static void ieee80211_if_setup(struct net_device *dev)
 {
        ether_setup(dev);
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
        dev->netdev_ops = &ieee80211_dataif_ops;
        dev->destructor = free_netdev;
 }
-- 
1.7.6


>From d015100d182c7814e5e1b535426606935c6bfc7e Mon Sep 17 00:00:00 2001
From: Andy Gospodarek <a...@greyhouse.net>
Date: Tue, 26 Jul 2011 11:12:27 +0000
Subject: [PATCH 13/19] bonding: fix string comparison errors

[ Upstream commit f4bb2e9c4fa9e5fdddf90589703613fd1a9c519f ]

When a bond contains a device where one name is the subset of another
(eth1 and eth10, for example), one cannot properly set the primary
device or the currently active device.

This was reported and based on work by Takuma Umeya.  I also verified
the problem and tested that this fix resolves it.

V2: A few did not like the the current code or my changes, so I
refactored bonding_store_primary and bonding_store_active_slave to be a
bit cleaner, dropped the use of strnicmp since we did not really need
the comparison to be case insensitive, and formatted the input string
from sysfs so a comparison to IFNAMSIZ could be used.

I also discovered an error in bonding_store_active_slave that would
modify bond->primary_slave rather than bond->curr_active_slave before
forcing the bonding driver to choose a new active slave.

V3: Actually sending the proper patch....

Signed-off-by: Andy Gospodarek <a...@greyhouse.net>
Reported-by: Takuma Umeya <tum...@redhat.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 drivers/net/bonding/bond_sysfs.c |  133 ++++++++++++++++++++------------------
 1 files changed, 71 insertions(+), 62 deletions(-)

diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 8a2717e..99b5964 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1052,6 +1052,7 @@ static ssize_t bonding_store_primary(struct device *d,
        int i;
        struct slave *slave;
        struct bonding *bond = to_bond(d);
+       char ifname[IFNAMSIZ];
 
        if (!rtnl_trylock())
                return restart_syscall();
@@ -1062,32 +1063,33 @@ static ssize_t bonding_store_primary(struct device *d,
        if (!USES_PRIMARY(bond->params.mode)) {
                pr_info("%s: Unable to set primary slave; %s is in mode %d\n",
                        bond->dev->name, bond->dev->name, bond->params.mode);
-       } else {
-               bond_for_each_slave(bond, slave, i) {
-                       if (strnicmp
-                           (slave->dev->name, buf,
-                            strlen(slave->dev->name)) == 0) {
-                               pr_info("%s: Setting %s as primary slave.\n",
-                                       bond->dev->name, slave->dev->name);
-                               bond->primary_slave = slave;
-                               strcpy(bond->params.primary, slave->dev->name);
-                               bond_select_active_slave(bond);
-                               goto out;
-                       }
-               }
+               goto out;
+       }
 
-               /* if we got here, then we didn't match the name of any slave */
+       sscanf(buf, "%16s", ifname); /* IFNAMSIZ */
 
-               if (strlen(buf) == 0 || buf[0] == '\n') {
-                       pr_info("%s: Setting primary slave to None.\n",
-                               bond->dev->name);
-                       bond->primary_slave = NULL;
-                               bond_select_active_slave(bond);
-               } else {
-                       pr_info("%s: Unable to set %.*s as primary slave as it 
is not a slave.\n",
-                               bond->dev->name, (int)strlen(buf) - 1, buf);
+       /* check to see if we are clearing primary */
+       if (!strlen(ifname) || buf[0] == '\n') {
+               pr_info("%s: Setting primary slave to None.\n",
+                       bond->dev->name);
+               bond->primary_slave = NULL;
+               bond_select_active_slave(bond);
+               goto out;
+       }
+
+       bond_for_each_slave(bond, slave, i) {
+               if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
+                       pr_info("%s: Setting %s as primary slave.\n",
+                               bond->dev->name, slave->dev->name);
+                       bond->primary_slave = slave;
+                       strcpy(bond->params.primary, slave->dev->name);
+                       bond_select_active_slave(bond);
+                       goto out;
                }
        }
+
+       pr_info("%s: Unable to set %.*s as primary slave.\n",
+               bond->dev->name, (int)strlen(buf) - 1, buf);
 out:
        write_unlock_bh(&bond->curr_slave_lock);
        read_unlock(&bond->lock);
@@ -1222,6 +1224,7 @@ static ssize_t bonding_store_active_slave(struct device 
*d,
        struct slave *old_active = NULL;
        struct slave *new_active = NULL;
        struct bonding *bond = to_bond(d);
+       char ifname[IFNAMSIZ];
 
        if (!rtnl_trylock())
                return restart_syscall();
@@ -1230,56 +1233,62 @@ static ssize_t bonding_store_active_slave(struct device 
*d,
        read_lock(&bond->lock);
        write_lock_bh(&bond->curr_slave_lock);
 
-       if (!USES_PRIMARY(bond->params.mode))
+       if (!USES_PRIMARY(bond->params.mode)) {
                pr_info("%s: Unable to change active slave; %s is in mode %d\n",
                        bond->dev->name, bond->dev->name, bond->params.mode);
-       else {
-               bond_for_each_slave(bond, slave, i) {
-                       if (strnicmp
-                           (slave->dev->name, buf,
-                            strlen(slave->dev->name)) == 0) {
-                               old_active = bond->curr_active_slave;
-                               new_active = slave;
-                               if (new_active == old_active) {
-                                       /* do nothing */
-                                       pr_info("%s: %s is already the current 
active slave.\n",
+               goto out;
+       }
+
+       sscanf(buf, "%16s", ifname); /* IFNAMSIZ */
+
+       /* check to see if we are clearing active */
+       if (!strlen(ifname) || buf[0] == '\n') {
+               pr_info("%s: Clearing current active slave.\n",
+                       bond->dev->name);
+               bond->curr_active_slave = NULL;
+               bond_select_active_slave(bond);
+               goto out;
+       }
+
+       bond_for_each_slave(bond, slave, i) {
+               if (strncmp(slave->dev->name, ifname, IFNAMSIZ) == 0) {
+                       old_active = bond->curr_active_slave;
+                       new_active = slave;
+                       if (new_active == old_active) {
+                               /* do nothing */
+                               pr_info("%s: %s is already the current"
+                                       " active slave.\n",
+                                       bond->dev->name,
+                                       slave->dev->name);
+                               goto out;
+                       }
+                       else {
+                               if ((new_active) &&
+                                   (old_active) &&
+                                   (new_active->link == BOND_LINK_UP) &&
+                                   IS_UP(new_active->dev)) {
+                                       pr_info("%s: Setting %s as active"
+                                               " slave.\n",
                                                bond->dev->name,
                                                slave->dev->name);
-                                       goto out;
+                                       bond_change_active_slave(bond,
+                                                                new_active);
                                }
                                else {
-                                       if ((new_active) &&
-                                           (old_active) &&
-                                           (new_active->link == BOND_LINK_UP) 
&&
-                                           IS_UP(new_active->dev)) {
-                                               pr_info("%s: Setting %s as 
active slave.\n",
-                                                       bond->dev->name,
-                                                       slave->dev->name);
-                                                       
bond_change_active_slave(bond, new_active);
-                                       }
-                                       else {
-                                               pr_info("%s: Could not set %s 
as active slave; either %s is down or the link is down.\n",
-                                                       bond->dev->name,
-                                                       slave->dev->name,
-                                                       slave->dev->name);
-                                       }
-                                       goto out;
+                                       pr_info("%s: Could not set %s as"
+                                               " active slave; either %s is"
+                                               " down or the link is down.\n",
+                                               bond->dev->name,
+                                               slave->dev->name,
+                                               slave->dev->name);
                                }
+                               goto out;
                        }
                }
-
-               /* if we got here, then we didn't match the name of any slave */
-
-               if (strlen(buf) == 0 || buf[0] == '\n') {
-                       pr_info("%s: Setting active slave to None.\n",
-                               bond->dev->name);
-                       bond->primary_slave = NULL;
-                       bond_select_active_slave(bond);
-               } else {
-                       pr_info("%s: Unable to set %.*s as active slave as it 
is not a slave.\n",
-                               bond->dev->name, (int)strlen(buf) - 1, buf);
-               }
        }
+
+       pr_info("%s: Unable to set %.*s as active slave.\n",
+               bond->dev->name, (int)strlen(buf) - 1, buf);
  out:
        write_unlock_bh(&bond->curr_slave_lock);
        read_unlock(&bond->lock);
-- 
1.7.6


>From 854f1bf2d74e2bea0c316e51ffad509ca9694d9e Mon Sep 17 00:00:00 2001
From: Chris Clayton <chris2...@googlemail.com>
Date: Tue, 26 Jul 2011 12:20:22 +0000
Subject: [PATCH 14/19] Fix cdc-phonet build

[ Upstream commit a0295a3b6775ab88f5883684e14bbda8d287822d ]

Try to send to correct address this time!

----------  Forwarded Message  ----------

Subject: [PATCH] Fix cdc-phonet build
Date: Saturday 23 Jul 2011
From: Chris Clayton <chris2...@googlemail.com>
To: linux-...@vger.kernel.org

cdc-phonet does not presently build on linux-3.0 because there is no entry for 
it in
drivers/net/Makefile. This patch adds that entry.

Signed-off-by: Chris Clayton <chris2...@googlemail.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 drivers/net/Makefile |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index e5a7375..e4301b7 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -281,6 +281,7 @@ obj-$(CONFIG_USB_HSO)               += usb/
 obj-$(CONFIG_USB_USBNET)        += usb/
 obj-$(CONFIG_USB_ZD1201)        += usb/
 obj-$(CONFIG_USB_IPHETH)        += usb/
+obj-$(CONFIG_USB_CDC_PHONET)   += usb/
 
 obj-$(CONFIG_WLAN) += wireless/
 obj-$(CONFIG_NET_TULIP) += tulip/
-- 
1.7.6


>From 64b75aa978c28bb703a2e33e3c76395b8b44ea61 Mon Sep 17 00:00:00 2001
From: Tushar Gohad <tgo...@mvista.com>
Date: Thu, 28 Jul 2011 10:36:20 +0000
Subject: [PATCH 15/19] xfrm: Fix key lengths for rfc3686(ctr(aes))

[ Upstream commit 4203223a1aed862b4445fdcd260d6139603a51d9 ]

Fix the min and max bit lengths for AES-CTR (RFC3686) keys.
The number of bits in key spec is the key length (128/256)
plus 32 bits of nonce.

This change takes care of the "Invalid key length" errors
reported by setkey when specifying 288 bit keys for aes-ctr.

Signed-off-by: Tushar Gohad <tgo...@mvista.com>
Acked-by: Herbert Xu <herb...@gondor.apana.org.au>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 net/xfrm/xfrm_algo.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c
index 58064d9..791ab2e 100644
--- a/net/xfrm/xfrm_algo.c
+++ b/net/xfrm/xfrm_algo.c
@@ -462,8 +462,8 @@ static struct xfrm_algo_desc ealg_list[] = {
        .desc = {
                .sadb_alg_id = SADB_X_EALG_AESCTR,
                .sadb_alg_ivlen = 8,
-               .sadb_alg_minbits = 128,
-               .sadb_alg_maxbits = 256
+               .sadb_alg_minbits = 160,
+               .sadb_alg_maxbits = 288
        }
 },
 };
-- 
1.7.6


>From fea3a594d557fe60dfc0919ba082d29ec7f0fcd1 Mon Sep 17 00:00:00 2001
From: Klement Fish <kleme...@azet.sk>
Date: Thu, 28 Jul 2011 06:03:22 +0000
Subject: [PATCH 16/19] sis190: Rx filter init is needed for MAC address
 change.

[ Upstream commit fe66101f14813b77d84f6450d51772a2af2b81a1 ]

Addresses https://bugzilla.kernel.org/show_bug.cgi?id=34552

Signed-off-by: Klement Fish <kleme...@azet.sk>
Acked-by: Francois Romieu <rom...@fr.zoreil.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 drivers/net/sis190.c |   12 +++++++++++-
 1 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index b436e00..f6d26ab 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1824,6 +1824,16 @@ static int sis190_ioctl(struct net_device *dev, struct 
ifreq *ifr, int cmd)
                generic_mii_ioctl(&tp->mii_if, if_mii(ifr), cmd, NULL);
 }
 
+static int sis190_mac_addr(struct net_device  *dev, void *p)
+{
+       int rc;
+
+       rc = eth_mac_addr(dev, p);
+       if (!rc)
+               sis190_init_rxfilter(dev);
+       return rc;
+}
+
 static const struct net_device_ops sis190_netdev_ops = {
        .ndo_open               = sis190_open,
        .ndo_stop               = sis190_close,
@@ -1832,7 +1842,7 @@ static const struct net_device_ops sis190_netdev_ops = {
        .ndo_tx_timeout         = sis190_tx_timeout,
        .ndo_set_multicast_list = sis190_set_rx_mode,
        .ndo_change_mtu         = eth_change_mtu,
-       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_set_mac_address    = sis190_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
        .ndo_poll_controller     = sis190_netpoll,
-- 
1.7.6


>From b0242d7b758b352a714d6aad256cb6602e20afb9 Mon Sep 17 00:00:00 2001
From: Lennart Sorensen <lsore...@csclub.uwaterloo.ca>
Date: Thu, 28 Jul 2011 13:18:11 +0000
Subject: [PATCH 17/19] r8169: Add support for D-Link 530T rev C1 (Kernel Bug
 38862)

[ Upstream commit 93a3aa25933461d76141179fc94aa32d5f9d954a ]

The D-Link DGE-530T rev C1 is a re-badged Realtek 8169 named DLG10028C,
unlike the previous revisions which were skge based.  It is probably
the same as the discontinued DGE-528T (0x4300) other than the PCI ID.

The PCI ID is 0x1186:0x4302.

Adding it to r8169.c where 0x1186:0x4300 is already found makes the card
be detected and work.

This fixes https://bugzilla.kernel.org/show_bug.cgi?id=38862

Signed-off-by: Len Sorensen <lsore...@csclub.uwaterloo.ca>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 drivers/net/r8169.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 397c368..615316b 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -197,6 +197,7 @@ static DEFINE_PCI_DEVICE_TABLE(rtl8169_pci_tbl) = {
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8168), 0, 0, RTL_CFG_1 },
        { PCI_DEVICE(PCI_VENDOR_ID_REALTEK,     0x8169), 0, 0, RTL_CFG_0 },
        { PCI_DEVICE(PCI_VENDOR_ID_DLINK,       0x4300), 0, 0, RTL_CFG_0 },
+       { PCI_DEVICE(PCI_VENDOR_ID_DLINK,       0x4302), 0, 0, RTL_CFG_0 },
        { PCI_DEVICE(PCI_VENDOR_ID_AT,          0xc107), 0, 0, RTL_CFG_0 },
        { PCI_DEVICE(0x16ec,                    0x0116), 0, 0, RTL_CFG_0 },
        { PCI_VENDOR_ID_LINKSYS,                0x1032,
-- 
1.7.6


>From f19ec3de8e65055cf36e9d9fd9df029275a464e7 Mon Sep 17 00:00:00 2001
From: stephen hemminger <shemmin...@vyatta.com>
Date: Fri, 22 Jul 2011 12:53:56 +0000
Subject: [PATCH 18/19] net: allow netif_carrier to be called safely from IRQ

[ Upstream commit 1821f7cd65ad9ea56580b830ac79bf4c4fef59cb ]

As reported by Ben Greer and Froncois Romieu. The code path in
the netif_carrier code leads it to try and disable
a late workqueue to reenable it immediately
netif_carrier_on
-> linkwatch_fire_event
   -> linkwatch_schedule_work
      -> cancel_delayed_work
         -> del_timer_sync

If __cancel_delayed_work is used instead then there is no
problem of waiting for running linkwatch_event.

There is a race between linkwatch_event running re-scheduling
but it is harmless to schedule an extra scan of the linkwatch queue.

Signed-off-by: Stephen Hemminger <shemmin...@vyatta.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 net/core/link_watch.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/net/core/link_watch.c b/net/core/link_watch.c
index a7b3421..357bd4e 100644
--- a/net/core/link_watch.c
+++ b/net/core/link_watch.c
@@ -126,7 +126,7 @@ static void linkwatch_schedule_work(int urgent)
                return;
 
        /* It's already running which is good enough. */
-       if (!cancel_delayed_work(&linkwatch_work))
+       if (!__cancel_delayed_work(&linkwatch_work))
                return;
 
        /* Otherwise we reschedule it again for immediate execution. */
-- 
1.7.6


>From ed08e028ad1b52960385d04b88e8d5ac518da543 Mon Sep 17 00:00:00 2001
From: "x...@mail.ru" <x...@mail.ru>
Date: Fri, 22 Jul 2011 20:49:40 +0000
Subject: [PATCH 19/19] gre: fix improper error handling

[ Upstream commit 559fafb94ad9e4cd8774f39241917c57396f9fc5 ]

Fix improper protocol err_handler, current implementation is fully
unapplicable and may cause kernel crash due to double kfree_skb.

Signed-off-by: Dmitry Kozlov <x...@mail.ru>
Acked-by: Eric Dumazet <eric.duma...@gmail.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
---
 net/ipv4/gre.c |   21 ++++++---------------
 1 files changed, 6 insertions(+), 15 deletions(-)

diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c
index c6933f2..3e3f75d 100644
--- a/net/ipv4/gre.c
+++ b/net/ipv4/gre.c
@@ -15,6 +15,7 @@
 #include <linux/kmod.h>
 #include <linux/skbuff.h>
 #include <linux/in.h>
+#include <linux/ip.h>
 #include <linux/netdevice.h>
 #include <linux/version.h>
 #include <linux/spinlock.h>
@@ -97,27 +98,17 @@ drop:
 static void gre_err(struct sk_buff *skb, u32 info)
 {
        const struct gre_protocol *proto;
-       u8 ver;
-
-       if (!pskb_may_pull(skb, 12))
-               goto drop;
+       const struct iphdr *iph = (const struct iphdr *)skb->data;
+       u8 ver = skb->data[(iph->ihl<<2) + 1]&0x7f;
 
-       ver = skb->data[1]&0x7f;
        if (ver >= GREPROTO_MAX)
-               goto drop;
+               return;
 
        rcu_read_lock();
        proto = rcu_dereference(gre_proto[ver]);
-       if (!proto || !proto->err_handler)
-               goto drop_unlock;
-       proto->err_handler(skb, info);
-       rcu_read_unlock();
-       return;
-
-drop_unlock:
+       if (proto && proto->err_handler)
+               proto->err_handler(skb, info);
        rcu_read_unlock();
-drop:
-       kfree_skb(skb);
 }
 
 static const struct net_protocol net_gre_protocol = {
-- 
1.7.6

_______________________________________________
stable mailing list
stable@linux.kernel.org
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to