From ad828b10dba757b1a137324c8e180e291e3a0ebe Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 12 Nov 2010 17:22:36 -0800 Subject: [PATCH] .35 patches --- ...r-ethernet-at-full-line-rate-traffic.patch | 61 +++++++ .../gianfar-fix-double-lock-typo.patch | 30 ++++ ...ruesize-mismatch-in-ip-fragmentation.patch | 158 ++++++++++++++++++ ...cnt-problem-related-to-postdad-state.patch | 46 +++++ ...alizers-to-prevent-integer-overflows.patch | 86 ++++++++++ ...w-parameter-to-retransmits_timed_out.patch | 107 ++++++++++++ ...t-add-a-recursion-limit-in-xmit-path.patch | 63 +++++++ ...tions-for-privileged-ethtool-actions.patch | 45 +++++ ...packets-to-flow-through-veth-devices.patch | 36 ++++ ...-ipv6-pmtu-disc.-w-asymmetric-routes.patch | 65 +++++++ ...he-condition-passed-to-sk_wait_event.patch | 70 ++++++++ .../netxen-dont-set-skb-truesize.patch | 40 +++++ ...header-retrieval-after-pskb_may_pull.patch | 43 +++++ .../qlcnic-dont-set-skb-truesize.patch | 49 ++++++ ...r6040-fix-multicast-filter-some-more.patch | 83 +++++++++ ...7d6742985da1fbf12ae26cde6a096fd35b5c.patch | 124 ++++++++++++++ ...ca79d3852a3623f606f781e013d61486828a.patch | 152 +++++++++++++++++ ...ix-signedness-issues-wrt.-digi-count.patch | 41 +++++ queue-2.6.35/series | 20 +++ queue-2.6.35/tcp-fix-race-in-tcp_poll.patch | 58 +++++++ .../xfrm4-strip-ecn-bits-from-tos-field.patch | 31 ++++ 21 files changed, 1408 insertions(+) create mode 100644 queue-2.6.35/gianfar-fix-crashes-on-rx-path-was-re-new-linux-2.6.36-rc5-crash-with-gianfar-ethernet-at-full-line-rate-traffic.patch create mode 100644 queue-2.6.35/gianfar-fix-double-lock-typo.patch create mode 100644 queue-2.6.35/ip-fix-truesize-mismatch-in-ip-fragmentation.patch create mode 100644 queue-2.6.35/ipv6-fix-refcnt-problem-related-to-postdad-state.patch create mode 100644 queue-2.6.35/limit-sysctl_tcp_mem-and-sysctl_udp_mem-initializers-to-prevent-integer-overflows.patch create mode 100644 queue-2.6.35/net-2.6-syn-retransmits-add-new-parameter-to-retransmits_timed_out.patch create mode 100644 queue-2.6.35/net-add-a-recursion-limit-in-xmit-path.patch create mode 100644 queue-2.6.35/net-clear-heap-allocations-for-privileged-ethtool-actions.patch create mode 100644 queue-2.6.35/net-core-allow-tagged-vlan-packets-to-flow-through-veth-devices.patch create mode 100644 queue-2.6.35/net-fix-ipv6-pmtu-disc.-w-asymmetric-routes.patch create mode 100644 queue-2.6.35/net-fix-the-condition-passed-to-sk_wait_event.patch create mode 100644 queue-2.6.35/netxen-dont-set-skb-truesize.patch create mode 100644 queue-2.6.35/phonet-correct-header-retrieval-after-pskb_may_pull.patch create mode 100644 queue-2.6.35/qlcnic-dont-set-skb-truesize.patch create mode 100644 queue-2.6.35/r6040-fix-multicast-filter-some-more.patch create mode 100644 queue-2.6.35/revert-c6537d6742985da1fbf12ae26cde6a096fd35b5c.patch create mode 100644 queue-2.6.35/revert-d88dca79d3852a3623f606f781e013d61486828a.patch create mode 100644 queue-2.6.35/rose-fix-signedness-issues-wrt.-digi-count.patch create mode 100644 queue-2.6.35/tcp-fix-race-in-tcp_poll.patch create mode 100644 queue-2.6.35/xfrm4-strip-ecn-bits-from-tos-field.patch diff --git a/queue-2.6.35/gianfar-fix-crashes-on-rx-path-was-re-new-linux-2.6.36-rc5-crash-with-gianfar-ethernet-at-full-line-rate-traffic.patch b/queue-2.6.35/gianfar-fix-crashes-on-rx-path-was-re-new-linux-2.6.36-rc5-crash-with-gianfar-ethernet-at-full-line-rate-traffic.patch new file mode 100644 index 00000000000..96d923faae0 --- /dev/null +++ b/queue-2.6.35/gianfar-fix-crashes-on-rx-path-was-re-new-linux-2.6.36-rc5-crash-with-gianfar-ethernet-at-full-line-rate-traffic.patch @@ -0,0 +1,61 @@ +From 6d55ef9bbe6f8973bbd9ce5b120dcd20abf8d6dd Mon Sep 17 00:00:00 2001 +From: Jarek Poplawski +Date: Tue, 19 Oct 2010 00:06:36 +0000 +Subject: gianfar: Fix crashes on RX path (Was Re: [Bugme-new] [Bug 19692] New: linux-2.6.36-rc5 crash with gianfar ethernet at full line rate traffic) + + +From: Jarek Poplawski + +[ Upstream commit 0d1fe1111c667e9c713d7efc7ae468a605f236a4 ] + +The rx_recycle queue is global per device but can be accesed by many +napi handlers at the same time, so it needs full skb_queue primitives +(with locking). Otherwise, various crashes caused by broken skbs are +possible. + +This patch resolves, at least partly, bugzilla bug 19692. (Because of +some doubts that there could be still something around which is hard +to reproduce my proposal is to leave this bug opened for a month.) + +Fixes commit: 0fd56bb5be6455d0d42241e65aed057244665e5e ("gianfar: Add +support for skb recycling") + +Reported-by: emin ak +Tested-by: emin ak +Signed-off-by: Jarek Poplawski +CC: Andy Fleming +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/gianfar.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/net/gianfar.c ++++ b/drivers/net/gianfar.c +@@ -2427,7 +2427,7 @@ static int gfar_clean_tx_ring(struct gfa + if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size && + skb_recycle_check(skb, priv->rx_buffer_size + + RXBUF_ALIGNMENT)) +- __skb_queue_head(&priv->rx_recycle, skb); ++ skb_queue_head(&priv->rx_recycle, skb); + else + dev_kfree_skb_any(skb); + +@@ -2498,7 +2498,7 @@ struct sk_buff * gfar_new_skb(struct net + struct gfar_private *priv = netdev_priv(dev); + struct sk_buff *skb = NULL; + +- skb = __skb_dequeue(&priv->rx_recycle); ++ skb = skb_dequeue(&priv->rx_recycle); + if (!skb) + skb = netdev_alloc_skb(dev, + priv->rx_buffer_size + RXBUF_ALIGNMENT); +@@ -2675,7 +2675,7 @@ int gfar_clean_rx_ring(struct gfar_priv_ + * recycle list. + */ + skb_reserve(skb, -GFAR_CB(skb)->alignamount); +- __skb_queue_head(&priv->rx_recycle, skb); ++ skb_queue_head(&priv->rx_recycle, skb); + } + } else { + /* Increment the number of packets */ diff --git a/queue-2.6.35/gianfar-fix-double-lock-typo.patch b/queue-2.6.35/gianfar-fix-double-lock-typo.patch new file mode 100644 index 00000000000..9ccb5fc7b7a --- /dev/null +++ b/queue-2.6.35/gianfar-fix-double-lock-typo.patch @@ -0,0 +1,30 @@ +From e358ecdac5d09bf5859e715cf7e2cc2628708fbe Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 13 Oct 2010 09:19:55 +0000 +Subject: gianfar: fix double lock typo + + +From: Dan Carpenter + +[ Upstream commit 9756403b16cfeda85efe77e62832a2f6b5752fdf ] + +This should be a _restore() instead of a _save(). + +Signed-off-by: Dan Carpenter +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/gianfar_ethtool.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/gianfar_ethtool.c ++++ b/drivers/net/gianfar_ethtool.c +@@ -538,7 +538,7 @@ static int gfar_set_rx_csum(struct net_d + + unlock_tx_qs(priv); + unlock_rx_qs(priv); +- local_irq_save(flags); ++ local_irq_restore(flags); + + for (i = 0; i < priv->num_rx_queues; i++) + gfar_clean_rx_ring(priv->rx_queue[i], diff --git a/queue-2.6.35/ip-fix-truesize-mismatch-in-ip-fragmentation.patch b/queue-2.6.35/ip-fix-truesize-mismatch-in-ip-fragmentation.patch new file mode 100644 index 00000000000..723a494b001 --- /dev/null +++ b/queue-2.6.35/ip-fix-truesize-mismatch-in-ip-fragmentation.patch @@ -0,0 +1,158 @@ +From caca8bb3d012f88958ba37f044bafa870a2dd8cf Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 21 Sep 2010 08:47:45 +0000 +Subject: ip: fix truesize mismatch in ip fragmentation + + +From: Eric Dumazet + +[ Upstream commit 3d13008e7345fa7a79d8f6438150dc15d6ba6e9d ] + +Special care should be taken when slow path is hit in ip_fragment() : + +When walking through frags, we transfert truesize ownership from skb to +frags. Then if we hit a slow_path condition, we must undo this or risk +uncharging frags->truesize twice, and in the end, having negative socket +sk_wmem_alloc counter, or even freeing socket sooner than expected. + +Many thanks to Nick Bowler, who provided a very clean bug report and +test program. + +Thanks to Jarek for reviewing my first patch and providing a V2 + +While Nick bisection pointed to commit 2b85a34e911 (net: No more +expensive sock_hold()/sock_put() on each tx), underlying bug is older +(2.6.12-rc5) + +A side effect is to extend work done in commit b2722b1c3a893e +(ip_fragment: also adjust skb->truesize for packets not owned by a +socket) to ipv6 as well. + +Reported-and-bisected-by: Nick Bowler +Tested-by: Nick Bowler +Signed-off-by: Eric Dumazet +CC: Jarek Poplawski +CC: Patrick McHardy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ip_output.c | 19 +++++++++++++------ + net/ipv6/ip6_output.c | 18 +++++++++++++----- + 2 files changed, 26 insertions(+), 11 deletions(-) + +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -488,9 +488,8 @@ int ip_fragment(struct sk_buff *skb, int + * we can switch to copy when see the first bad fragment. + */ + if (skb_has_frags(skb)) { +- struct sk_buff *frag; ++ struct sk_buff *frag, *frag2; + int first_len = skb_pagelen(skb); +- int truesizes = 0; + + if (first_len - hlen > mtu || + ((first_len - hlen) & 7) || +@@ -503,18 +502,18 @@ int ip_fragment(struct sk_buff *skb, int + if (frag->len > mtu || + ((frag->len & 7) && frag->next) || + skb_headroom(frag) < hlen) +- goto slow_path; ++ goto slow_path_clean; + + /* Partially cloned skb? */ + if (skb_shared(frag)) +- goto slow_path; ++ goto slow_path_clean; + + BUG_ON(frag->sk); + if (skb->sk) { + frag->sk = skb->sk; + frag->destructor = sock_wfree; + } +- truesizes += frag->truesize; ++ skb->truesize -= frag->truesize; + } + + /* Everything is OK. Generate! */ +@@ -524,7 +523,6 @@ int ip_fragment(struct sk_buff *skb, int + frag = skb_shinfo(skb)->frag_list; + skb_frag_list_init(skb); + skb->data_len = first_len - skb_headlen(skb); +- skb->truesize -= truesizes; + skb->len = first_len; + iph->tot_len = htons(first_len); + iph->frag_off = htons(IP_MF); +@@ -576,6 +574,15 @@ int ip_fragment(struct sk_buff *skb, int + } + IP_INC_STATS(dev_net(dev), IPSTATS_MIB_FRAGFAILS); + return err; ++ ++slow_path_clean: ++ skb_walk_frags(skb, frag2) { ++ if (frag2 == frag) ++ break; ++ frag2->sk = NULL; ++ frag2->destructor = NULL; ++ skb->truesize += frag2->truesize; ++ } + } + + slow_path: +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -639,7 +639,7 @@ static int ip6_fragment(struct sk_buff * + + if (skb_has_frags(skb)) { + int first_len = skb_pagelen(skb); +- int truesizes = 0; ++ struct sk_buff *frag2; + + if (first_len - hlen > mtu || + ((first_len - hlen) & 7) || +@@ -651,18 +651,18 @@ static int ip6_fragment(struct sk_buff * + if (frag->len > mtu || + ((frag->len & 7) && frag->next) || + skb_headroom(frag) < hlen) +- goto slow_path; ++ goto slow_path_clean; + + /* Partially cloned skb? */ + if (skb_shared(frag)) +- goto slow_path; ++ goto slow_path_clean; + + BUG_ON(frag->sk); + if (skb->sk) { + frag->sk = skb->sk; + frag->destructor = sock_wfree; +- truesizes += frag->truesize; + } ++ skb->truesize -= frag->truesize; + } + + err = 0; +@@ -693,7 +693,6 @@ static int ip6_fragment(struct sk_buff * + + first_len = skb_pagelen(skb); + skb->data_len = first_len - skb_headlen(skb); +- skb->truesize -= truesizes; + skb->len = first_len; + ipv6_hdr(skb)->payload_len = htons(first_len - + sizeof(struct ipv6hdr)); +@@ -756,6 +755,15 @@ static int ip6_fragment(struct sk_buff * + IPSTATS_MIB_FRAGFAILS); + dst_release(&rt->u.dst); + return err; ++ ++slow_path_clean: ++ skb_walk_frags(skb, frag2) { ++ if (frag2 == frag) ++ break; ++ frag2->sk = NULL; ++ frag2->destructor = NULL; ++ skb->truesize += frag2->truesize; ++ } + } + + slow_path: diff --git a/queue-2.6.35/ipv6-fix-refcnt-problem-related-to-postdad-state.patch b/queue-2.6.35/ipv6-fix-refcnt-problem-related-to-postdad-state.patch new file mode 100644 index 00000000000..8f0edf36869 --- /dev/null +++ b/queue-2.6.35/ipv6-fix-refcnt-problem-related-to-postdad-state.patch @@ -0,0 +1,46 @@ +From 247233cf062e6495e9c101d3def007ee8f7522a1 Mon Sep 17 00:00:00 2001 +From: Ursula Braun +Date: Sun, 24 Oct 2010 23:06:43 +0000 +Subject: ipv6: fix refcnt problem related to POSTDAD state + + +From: Ursula Braun + +[ Upstream commit 801715f95be37b865af83b9909ad93da141a9306 ] + +After running this bonding setup script + modprobe bonding miimon=100 mode=0 max_bonds=1 + ifconfig bond0 10.1.1.1/16 + ifenslave bond0 eth1 + ifenslave bond0 eth3 +on s390 with qeth-driven slaves, modprobe -r fails with this message + unregister_netdevice: waiting for bond0 to become free. Usage count = 1 +due to twice detection of duplicate address. +Problem is caused by a missing decrease of ifp->refcnt in addrconf_dad_failure. +An extra call of in6_ifa_put(ifp) solves it. +Problem has been introduced with commit f2344a131bccdbfc5338e17fa71a807dee7944fa. + +Signed-off-by: Ursula Braun +Cc: David S. Miller +Cc: Herbert Xu +Acked-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/addrconf.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -1424,8 +1424,10 @@ void addrconf_dad_failure(struct inet6_i + { + struct inet6_dev *idev = ifp->idev; + +- if (addrconf_dad_end(ifp)) ++ if (addrconf_dad_end(ifp)) { ++ in6_ifa_put(ifp); + return; ++ } + + if (net_ratelimit()) + printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n", diff --git a/queue-2.6.35/limit-sysctl_tcp_mem-and-sysctl_udp_mem-initializers-to-prevent-integer-overflows.patch b/queue-2.6.35/limit-sysctl_tcp_mem-and-sysctl_udp_mem-initializers-to-prevent-integer-overflows.patch new file mode 100644 index 00000000000..f93ca145b16 --- /dev/null +++ b/queue-2.6.35/limit-sysctl_tcp_mem-and-sysctl_udp_mem-initializers-to-prevent-integer-overflows.patch @@ -0,0 +1,86 @@ +From 550b16ca026832bbca1a6b2f9dec779f19054ea1 Mon Sep 17 00:00:00 2001 +From: holt@sgi.com +Date: Wed, 20 Oct 2010 02:03:37 +0000 +Subject: Limit sysctl_tcp_mem and sysctl_udp_mem initializers to prevent integer overflows. + + +On a 16TB x86_64 machine, sysctl_tcp_mem[2], sysctl_udp_mem[2], and +sysctl_sctp_mem[2] can integer overflow. Set limit such that they are +maximized without overflowing. + +Signed-off-by: Robin Holt +To: "David S. Miller" +Cc: Willy Tarreau +Cc: linux-kernel@vger.kernel.org +Cc: netdev@vger.kernel.org +Cc: linux-sctp@vger.kernel.org +Cc: Alexey Kuznetsov +Cc: "Pekka Savola (ipv6)" +Cc: James Morris +Cc: Hideaki YOSHIFUJI +Cc: Patrick McHardy +Cc: Vlad Yasevich +Cc: Sridhar Samudrala +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp.c | 4 +++- + net/ipv4/udp.c | 4 +++- + net/sctp/protocol.c | 4 +++- + 3 files changed, 9 insertions(+), 3 deletions(-) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -3252,12 +3252,14 @@ void __init tcp_init(void) + + /* Set the pressure threshold to be a fraction of global memory that + * is up to 1/2 at 256 MB, decreasing toward zero with the amount of +- * memory, with a floor of 128 pages. ++ * memory, with a floor of 128 pages, and a ceiling that prevents an ++ * integer overflow. + */ + nr_pages = totalram_pages - totalhigh_pages; + limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); + limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); + limit = max(limit, 128UL); ++ limit = min(limit, INT_MAX * 4UL / 3 / 2); + sysctl_tcp_mem[0] = limit / 4 * 3; + sysctl_tcp_mem[1] = limit; + sysctl_tcp_mem[2] = sysctl_tcp_mem[0] * 2; +--- a/net/ipv4/udp.c ++++ b/net/ipv4/udp.c +@@ -2167,12 +2167,14 @@ void __init udp_init(void) + udp_table_init(&udp_table, "UDP"); + /* Set the pressure threshold up by the same strategy of TCP. It is a + * fraction of global memory that is up to 1/2 at 256 MB, decreasing +- * toward zero with the amount of memory, with a floor of 128 pages. ++ * toward zero with the amount of memory, with a floor of 128 pages, ++ * and a ceiling that prevents an integer overflow. + */ + nr_pages = totalram_pages - totalhigh_pages; + limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); + limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); + limit = max(limit, 128UL); ++ limit = min(limit, INT_MAX * 4UL / 3 / 2); + sysctl_udp_mem[0] = limit / 4 * 3; + sysctl_udp_mem[1] = limit; + sysctl_udp_mem[2] = sysctl_udp_mem[0] * 2; +--- a/net/sctp/protocol.c ++++ b/net/sctp/protocol.c +@@ -1161,7 +1161,8 @@ SCTP_STATIC __init int sctp_init(void) + + /* Set the pressure threshold to be a fraction of global memory that + * is up to 1/2 at 256 MB, decreasing toward zero with the amount of +- * memory, with a floor of 128 pages. ++ * memory, with a floor of 128 pages, and a ceiling that prevents an ++ * integer overflow. + * Note this initalizes the data in sctpv6_prot too + * Unabashedly stolen from tcp_init + */ +@@ -1169,6 +1170,7 @@ SCTP_STATIC __init int sctp_init(void) + limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); + limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); + limit = max(limit, 128UL); ++ limit = min(limit, INT_MAX * 4UL / 3 / 2); + sysctl_sctp_mem[0] = limit / 4 * 3; + sysctl_sctp_mem[1] = limit; + sysctl_sctp_mem[2] = sysctl_sctp_mem[0] * 2; diff --git a/queue-2.6.35/net-2.6-syn-retransmits-add-new-parameter-to-retransmits_timed_out.patch b/queue-2.6.35/net-2.6-syn-retransmits-add-new-parameter-to-retransmits_timed_out.patch new file mode 100644 index 00000000000..4b8a18f0fc2 --- /dev/null +++ b/queue-2.6.35/net-2.6-syn-retransmits-add-new-parameter-to-retransmits_timed_out.patch @@ -0,0 +1,107 @@ +From 1a42cd1d666b1d79d029a49e033490f1c1e8181c Mon Sep 17 00:00:00 2001 +From: Damian Lukowski +Date: Tue, 28 Sep 2010 13:08:32 -0700 +Subject: net-2.6: SYN retransmits: Add new parameter to retransmits_timed_out() + + +From: Damian Lukowski + +[ Upstream commit 4d22f7d372f5769c6c0149e427ed6353e2dcfe61 ] + +Fixes kernel Bugzilla Bug 18952 + +This patch adds a syn_set parameter to the retransmits_timed_out() +routine and updates its callers. If not set, TCP_RTO_MIN is taken +as the calculation basis as before. If set, TCP_TIMEOUT_INIT is +used instead, so that sysctl_syn_retries represents the actual +amount of SYN retransmissions in case no SYNACKs are received when +establishing a new connection. + +Signed-off-by: Damian Lukowski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_timer.c | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +--- a/net/ipv4/tcp_timer.c ++++ b/net/ipv4/tcp_timer.c +@@ -136,13 +136,16 @@ static void tcp_mtu_probing(struct inet_ + + /* This function calculates a "timeout" which is equivalent to the timeout of a + * TCP connection after "boundary" unsuccessful, exponentially backed-off +- * retransmissions with an initial RTO of TCP_RTO_MIN. ++ * retransmissions with an initial RTO of TCP_RTO_MIN or TCP_TIMEOUT_INIT if ++ * syn_set flag is set. + */ + static bool retransmits_timed_out(struct sock *sk, +- unsigned int boundary) ++ unsigned int boundary, ++ bool syn_set) + { + unsigned int timeout, linear_backoff_thresh; + unsigned int start_ts; ++ unsigned int rto_base = syn_set ? TCP_TIMEOUT_INIT : TCP_RTO_MIN; + + if (!inet_csk(sk)->icsk_retransmits) + return false; +@@ -152,12 +155,12 @@ static bool retransmits_timed_out(struct + else + start_ts = tcp_sk(sk)->retrans_stamp; + +- linear_backoff_thresh = ilog2(TCP_RTO_MAX/TCP_RTO_MIN); ++ linear_backoff_thresh = ilog2(TCP_RTO_MAX/rto_base); + + if (boundary <= linear_backoff_thresh) +- timeout = ((2 << boundary) - 1) * TCP_RTO_MIN; ++ timeout = ((2 << boundary) - 1) * rto_base; + else +- timeout = ((2 << linear_backoff_thresh) - 1) * TCP_RTO_MIN + ++ timeout = ((2 << linear_backoff_thresh) - 1) * rto_base + + (boundary - linear_backoff_thresh) * TCP_RTO_MAX; + + return (tcp_time_stamp - start_ts) >= timeout; +@@ -168,14 +171,15 @@ static int tcp_write_timeout(struct sock + { + struct inet_connection_sock *icsk = inet_csk(sk); + int retry_until; +- bool do_reset; ++ bool do_reset, syn_set = 0; + + if ((1 << sk->sk_state) & (TCPF_SYN_SENT | TCPF_SYN_RECV)) { + if (icsk->icsk_retransmits) + dst_negative_advice(sk); + retry_until = icsk->icsk_syn_retries ? : sysctl_tcp_syn_retries; ++ syn_set = 1; + } else { +- if (retransmits_timed_out(sk, sysctl_tcp_retries1)) { ++ if (retransmits_timed_out(sk, sysctl_tcp_retries1, 0)) { + /* Black hole detection */ + tcp_mtu_probing(icsk, sk); + +@@ -188,14 +192,14 @@ static int tcp_write_timeout(struct sock + + retry_until = tcp_orphan_retries(sk, alive); + do_reset = alive || +- !retransmits_timed_out(sk, retry_until); ++ !retransmits_timed_out(sk, retry_until, 0); + + if (tcp_out_of_resources(sk, do_reset)) + return 1; + } + } + +- if (retransmits_timed_out(sk, retry_until)) { ++ if (retransmits_timed_out(sk, retry_until, syn_set)) { + /* Has it gone just too far? */ + tcp_write_err(sk); + return 1; +@@ -437,7 +441,7 @@ out_reset_timer: + icsk->icsk_rto = min(icsk->icsk_rto << 1, TCP_RTO_MAX); + } + inet_csk_reset_xmit_timer(sk, ICSK_TIME_RETRANS, icsk->icsk_rto, TCP_RTO_MAX); +- if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1)) ++ if (retransmits_timed_out(sk, sysctl_tcp_retries1 + 1, 0)) + __sk_dst_reset(sk); + + out:; diff --git a/queue-2.6.35/net-add-a-recursion-limit-in-xmit-path.patch b/queue-2.6.35/net-add-a-recursion-limit-in-xmit-path.patch new file mode 100644 index 00000000000..f45b7c533ce --- /dev/null +++ b/queue-2.6.35/net-add-a-recursion-limit-in-xmit-path.patch @@ -0,0 +1,63 @@ +From 1806f7eec9ae3fbd0d96c780219200f7663cf8ae Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Wed, 29 Sep 2010 13:23:09 -0700 +Subject: net: add a recursion limit in xmit path + + +From: Eric Dumazet + +[ Upstream commits 745e20f1b626b1be4b100af5d4bf7b3439392f8f and + 11a766ce915fc9f8663714eac6d59239388534ea ] + +As tunnel devices are going to be lockless, we need to make sure a +misconfigured machine wont enter an infinite loop. + +Add a percpu variable, and limit to three the number of stacked xmits. + +Reported-by: Jesse Gross +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -2110,6 +2110,9 @@ static inline int skb_needs_linearize(st + illegal_highdma(dev, skb))); + } + ++static DEFINE_PER_CPU(int, xmit_recursion); ++#define RECURSION_LIMIT 10 ++ + /** + * dev_queue_xmit - transmit a buffer + * @skb: buffer to transmit +@@ -2194,10 +2197,15 @@ gso: + + if (txq->xmit_lock_owner != cpu) { + ++ if (__this_cpu_read(xmit_recursion) > RECURSION_LIMIT) ++ goto recursion_alert; ++ + HARD_TX_LOCK(dev, txq, cpu); + + if (!netif_tx_queue_stopped(txq)) { ++ __this_cpu_inc(xmit_recursion); + rc = dev_hard_start_xmit(skb, dev, txq); ++ __this_cpu_dec(xmit_recursion); + if (dev_xmit_complete(rc)) { + HARD_TX_UNLOCK(dev, txq); + goto out; +@@ -2209,7 +2217,9 @@ gso: + "queue packet!\n", dev->name); + } else { + /* Recursion is detected! It is possible, +- * unfortunately */ ++ * unfortunately ++ */ ++recursion_alert: + if (net_ratelimit()) + printk(KERN_CRIT "Dead loop on virtual device " + "%s, fix it urgently!\n", dev->name); diff --git a/queue-2.6.35/net-clear-heap-allocations-for-privileged-ethtool-actions.patch b/queue-2.6.35/net-clear-heap-allocations-for-privileged-ethtool-actions.patch new file mode 100644 index 00000000000..72b175fc87c --- /dev/null +++ b/queue-2.6.35/net-clear-heap-allocations-for-privileged-ethtool-actions.patch @@ -0,0 +1,45 @@ +From c04782e5e18de8b49e51fdd1e1a3eb1bcb115e6d Mon Sep 17 00:00:00 2001 +From: Kees Cook +Date: Mon, 11 Oct 2010 12:23:25 -0700 +Subject: net: clear heap allocations for privileged ethtool actions + + +From: Kees Cook + +[ Upstream commit b00916b189d13a615ff05c9242201135992fcda3 ] + +Several other ethtool functions leave heap uncleared (potentially) by +drivers. Some interfaces appear safe (eeprom, etc), in that the sizes +are well controlled. In some situations (e.g. unchecked error conditions), +the heap will remain unchanged in areas before copying back to userspace. +Note that these are less of an issue since these all require CAP_NET_ADMIN. + +Cc: stable@kernel.org +Signed-off-by: Kees Cook +Acked-by: Ben Hutchings +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/ethtool.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/core/ethtool.c ++++ b/net/core/ethtool.c +@@ -482,7 +482,7 @@ static int ethtool_get_rx_ntuple(struct + + gstrings.len = ret; + +- data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); ++ data = kzalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER); + if (!data) + return -ENOMEM; + +@@ -719,7 +719,7 @@ static int ethtool_get_regs(struct net_d + if (regs.len > reglen) + regs.len = reglen; + +- regbuf = kmalloc(reglen, GFP_USER); ++ regbuf = kzalloc(reglen, GFP_USER); + if (!regbuf) + return -ENOMEM; + diff --git a/queue-2.6.35/net-core-allow-tagged-vlan-packets-to-flow-through-veth-devices.patch b/queue-2.6.35/net-core-allow-tagged-vlan-packets-to-flow-through-veth-devices.patch new file mode 100644 index 00000000000..b6a4858d5cb --- /dev/null +++ b/queue-2.6.35/net-core-allow-tagged-vlan-packets-to-flow-through-veth-devices.patch @@ -0,0 +1,36 @@ +From abe3896c9e0f215bda8742570536f934f51b4589 Mon Sep 17 00:00:00 2001 +From: Ben Greear +Date: Thu, 21 Oct 2010 04:06:29 -0700 +Subject: net/core: Allow tagged VLAN packets to flow through VETH devices. + + +From: Ben Greear + +[ Upstream commit d2ed817766987fd05e69b7da65d4861b38f1aa2a ] + +When there are VLANs on a VETH device, the packets being transmitted +through the VETH device may be 4 bytes bigger than MTU. A check +in dev_forward_skb did not take this into account and so dropped +these packets. + +This patch is needed at least as far back as 2.6.34.7 and should +be considered for -stable. + +Signed-off-by: Ben Greear +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/dev.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -1491,7 +1491,7 @@ int dev_forward_skb(struct net_device *d + nf_reset(skb); + + if (!(dev->flags & IFF_UP) || +- (skb->len > (dev->mtu + dev->hard_header_len))) { ++ (skb->len > (dev->mtu + dev->hard_header_len + VLAN_HLEN))) { + kfree_skb(skb); + return NET_RX_DROP; + } diff --git a/queue-2.6.35/net-fix-ipv6-pmtu-disc.-w-asymmetric-routes.patch b/queue-2.6.35/net-fix-ipv6-pmtu-disc.-w-asymmetric-routes.patch new file mode 100644 index 00000000000..d192a01bce9 --- /dev/null +++ b/queue-2.6.35/net-fix-ipv6-pmtu-disc.-w-asymmetric-routes.patch @@ -0,0 +1,65 @@ +From 7c83b2b827503a9b9edc466a03955f101b0b5d70 Mon Sep 17 00:00:00 2001 +From: Maciej Å»enczykowski +Date: Sun, 3 Oct 2010 14:49:00 -0700 +Subject: net: Fix IPv6 PMTU disc. w/ asymmetric routes + + +From: Maciej Å»enczykowski + +[ Upstream commit ae878ae280bea286ff2b1e1cb6e609dd8cb4501d ] + +Signed-off-by: Maciej Å»enczykowski +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/route.c | 28 ++++++++++++++++++++++++---- + 1 file changed, 24 insertions(+), 4 deletions(-) + +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -1559,14 +1559,13 @@ out: + * i.e. Path MTU discovery + */ + +-void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, +- struct net_device *dev, u32 pmtu) ++static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr, ++ struct net *net, u32 pmtu, int ifindex) + { + struct rt6_info *rt, *nrt; +- struct net *net = dev_net(dev); + int allfrag = 0; + +- rt = rt6_lookup(net, daddr, saddr, dev->ifindex, 0); ++ rt = rt6_lookup(net, daddr, saddr, ifindex, 0); + if (rt == NULL) + return; + +@@ -1634,6 +1633,27 @@ out: + dst_release(&rt->u.dst); + } + ++void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr, ++ struct net_device *dev, u32 pmtu) ++{ ++ struct net *net = dev_net(dev); ++ ++ /* ++ * RFC 1981 states that a node "MUST reduce the size of the packets it ++ * is sending along the path" that caused the Packet Too Big message. ++ * Since it's not possible in the general case to determine which ++ * interface was used to send the original packet, we update the MTU ++ * on the interface that will be used to send future packets. We also ++ * update the MTU on the interface that received the Packet Too Big in ++ * case the original packet was forced out that interface with ++ * SO_BINDTODEVICE or similar. This is the next best thing to the ++ * correct behaviour, which would be to update the MTU on all ++ * interfaces. ++ */ ++ rt6_do_pmtu_disc(daddr, saddr, net, pmtu, 0); ++ rt6_do_pmtu_disc(daddr, saddr, net, pmtu, dev->ifindex); ++} ++ + /* + * Misc support functions + */ diff --git a/queue-2.6.35/net-fix-the-condition-passed-to-sk_wait_event.patch b/queue-2.6.35/net-fix-the-condition-passed-to-sk_wait_event.patch new file mode 100644 index 00000000000..116003fbe02 --- /dev/null +++ b/queue-2.6.35/net-fix-the-condition-passed-to-sk_wait_event.patch @@ -0,0 +1,70 @@ +From e7005d6b461e4256394baa81c27609eea9bfd60c Mon Sep 17 00:00:00 2001 +From: Nagendra Tomar +Date: Sat, 2 Oct 2010 23:45:06 +0000 +Subject: net: Fix the condition passed to sk_wait_event() + + +From: Nagendra Tomar + +[ Upstream commit 482964e56e1320cb7952faa1932d8ecf59c4bf75 ] + +This patch fixes the condition (3rd arg) passed to sk_wait_event() in +sk_stream_wait_memory(). The incorrect check in sk_stream_wait_memory() +causes the following soft lockup in tcp_sendmsg() when the global tcp +memory pool has exhausted. + +>>> snip <<< + +localhost kernel: BUG: soft lockup - CPU#3 stuck for 11s! [sshd:6429] +localhost kernel: CPU 3: +localhost kernel: RIP: 0010:[sk_stream_wait_memory+0xcd/0x200] [sk_stream_wait_memory+0xcd/0x200] sk_stream_wait_memory+0xcd/0x200 +localhost kernel: +localhost kernel: Call Trace: +localhost kernel: [sk_stream_wait_memory+0x1b1/0x200] sk_stream_wait_memory+0x1b1/0x200 +localhost kernel: [] autoremove_wake_function+0x0/0x40 +localhost kernel: [ipv6:tcp_sendmsg+0x6e6/0xe90] tcp_sendmsg+0x6e6/0xce0 +localhost kernel: [sock_aio_write+0x126/0x140] sock_aio_write+0x126/0x140 +localhost kernel: [xfs:do_sync_write+0xf1/0x130] do_sync_write+0xf1/0x130 +localhost kernel: [] autoremove_wake_function+0x0/0x40 +localhost kernel: [hrtimer_start+0xe3/0x170] hrtimer_start+0xe3/0x170 +localhost kernel: [vfs_write+0x185/0x190] vfs_write+0x185/0x190 +localhost kernel: [sys_write+0x50/0x90] sys_write+0x50/0x90 +localhost kernel: [system_call+0x7e/0x83] system_call+0x7e/0x83 + +>>> snip <<< + +What is happening is, that the sk_wait_event() condition passed from +sk_stream_wait_memory() evaluates to true for the case of tcp global memory +exhaustion. This is because both sk_stream_memory_free() and vm_wait are true +which causes sk_wait_event() to *not* call schedule_timeout(). +Hence sk_stream_wait_memory() returns immediately to the caller w/o sleeping. +This causes the caller to again try allocation, which again fails and again +calls sk_stream_wait_memory(), and so on. + +[ Bug introduced by commit c1cbe4b7ad0bc4b1d98ea708a3fecb7362aa4088 + ("[NET]: Avoid atomic xchg() for non-error case") -DaveM ] + +Signed-off-by: Nagendra Singh Tomar +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/stream.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/net/core/stream.c ++++ b/net/core/stream.c +@@ -144,10 +144,10 @@ int sk_stream_wait_memory(struct sock *s + + set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); + sk->sk_write_pending++; +- sk_wait_event(sk, ¤t_timeo, !sk->sk_err && +- !(sk->sk_shutdown & SEND_SHUTDOWN) && +- sk_stream_memory_free(sk) && +- vm_wait); ++ sk_wait_event(sk, ¤t_timeo, sk->sk_err || ++ (sk->sk_shutdown & SEND_SHUTDOWN) || ++ (sk_stream_memory_free(sk) && ++ !vm_wait)); + sk->sk_write_pending--; + + if (vm_wait) { diff --git a/queue-2.6.35/netxen-dont-set-skb-truesize.patch b/queue-2.6.35/netxen-dont-set-skb-truesize.patch new file mode 100644 index 00000000000..81c1590ae7c --- /dev/null +++ b/queue-2.6.35/netxen-dont-set-skb-truesize.patch @@ -0,0 +1,40 @@ +From ac908dce03301c346ac14dd838c5ae12190738d8 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 21 Sep 2010 13:04:04 -0700 +Subject: netxen: dont set skb->truesize + + +From: Eric Dumazet + +[ Upstream commit 7e96dc7045bff8758804b047c0dfb6868f182500 ] + +skb->truesize is set in core network. + +Dont change it unless dealing with fragments. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/netxen/netxen_nic_init.c | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/net/netxen/netxen_nic_init.c ++++ b/drivers/net/netxen/netxen_nic_init.c +@@ -1540,7 +1540,6 @@ netxen_process_rcv(struct netxen_adapter + if (pkt_offset) + skb_pull(skb, pkt_offset); + +- skb->truesize = skb->len + sizeof(struct sk_buff); + skb->protocol = eth_type_trans(skb, netdev); + + napi_gro_receive(&sds_ring->napi, skb); +@@ -1602,8 +1601,6 @@ netxen_process_lro(struct netxen_adapter + + skb_put(skb, lro_length + data_offset); + +- skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb); +- + skb_pull(skb, l2_hdr_offset); + skb->protocol = eth_type_trans(skb, netdev); + diff --git a/queue-2.6.35/phonet-correct-header-retrieval-after-pskb_may_pull.patch b/queue-2.6.35/phonet-correct-header-retrieval-after-pskb_may_pull.patch new file mode 100644 index 00000000000..167f426ab46 --- /dev/null +++ b/queue-2.6.35/phonet-correct-header-retrieval-after-pskb_may_pull.patch @@ -0,0 +1,43 @@ +From 928bd781ab0964d100d4ba3ab4c7e00bff59ac81 Mon Sep 17 00:00:00 2001 +From: Kumar Sanghvi +Date: Mon, 27 Sep 2010 23:10:42 +0000 +Subject: Phonet: Correct header retrieval after pskb_may_pull + + +From: Kumar Sanghvi + +[ Upstream commit a91e7d471e2e384035b9746ea707ccdcd353f5dd ] + +Retrieve the header after doing pskb_may_pull since, pskb_may_pull +could change the buffer structure. + +This is based on the comment given by Eric Dumazet on Phonet +Pipe controller patch for a similar problem. + +Signed-off-by: Kumar Sanghvi +Acked-by: Linus Walleij +Acked-by: Eric Dumazet +Acked-by: Rémi Denis-Courmont +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/phonet/pep.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/phonet/pep.c ++++ b/net/phonet/pep.c +@@ -225,12 +225,13 @@ static void pipe_grant_credits(struct so + static int pipe_rcv_status(struct sock *sk, struct sk_buff *skb) + { + struct pep_sock *pn = pep_sk(sk); +- struct pnpipehdr *hdr = pnp_hdr(skb); ++ struct pnpipehdr *hdr; + int wake = 0; + + if (!pskb_may_pull(skb, sizeof(*hdr) + 4)) + return -EINVAL; + ++ hdr = pnp_hdr(skb); + if (hdr->data[0] != PN_PEP_TYPE_COMMON) { + LIMIT_NETDEBUG(KERN_DEBUG"Phonet unknown PEP type: %u\n", + (unsigned)hdr->data[0]); diff --git a/queue-2.6.35/qlcnic-dont-set-skb-truesize.patch b/queue-2.6.35/qlcnic-dont-set-skb-truesize.patch new file mode 100644 index 00000000000..a0af6730af7 --- /dev/null +++ b/queue-2.6.35/qlcnic-dont-set-skb-truesize.patch @@ -0,0 +1,49 @@ +From 35f1fe8a1df0c9730fecb4efc94a3d532e0a7f08 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Mon, 20 Sep 2010 02:28:59 +0000 +Subject: qlcnic: dont set skb->truesize + + +From: Eric Dumazet + +[ Upstream commit 8df8fd27123054b02007361bd5483775db84b4a8 ] + +skb->truesize is set in core network. + +Dont change it unless dealing with fragments. + +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/qlcnic/qlcnic_init.c | 5 ----- + 1 file changed, 5 deletions(-) + +--- a/drivers/net/qlcnic/qlcnic_init.c ++++ b/drivers/net/qlcnic/qlcnic_init.c +@@ -1363,7 +1363,6 @@ qlcnic_process_rcv(struct qlcnic_adapter + if (pkt_offset) + skb_pull(skb, pkt_offset); + +- skb->truesize = skb->len + sizeof(struct sk_buff); + skb->protocol = eth_type_trans(skb, netdev); + + napi_gro_receive(&sds_ring->napi, skb); +@@ -1425,8 +1424,6 @@ qlcnic_process_lro(struct qlcnic_adapter + + skb_put(skb, lro_length + data_offset); + +- skb->truesize = skb->len + sizeof(struct sk_buff) + skb_headroom(skb); +- + skb_pull(skb, l2_hdr_offset); + skb->protocol = eth_type_trans(skb, netdev); + +@@ -1659,8 +1656,6 @@ qlcnic_process_rcv_diag(struct qlcnic_ad + if (pkt_offset) + skb_pull(skb, pkt_offset); + +- skb->truesize = skb->len + sizeof(struct sk_buff); +- + if (!qlcnic_check_loopback_buff(skb->data)) + adapter->diag_cnt++; + diff --git a/queue-2.6.35/r6040-fix-multicast-filter-some-more.patch b/queue-2.6.35/r6040-fix-multicast-filter-some-more.patch new file mode 100644 index 00000000000..9839b6588ff --- /dev/null +++ b/queue-2.6.35/r6040-fix-multicast-filter-some-more.patch @@ -0,0 +1,83 @@ +From b48e03c38425b219c6fe80ecf20dd9af252cb4c5 Mon Sep 17 00:00:00 2001 +From: Ben Hutchings +Date: Thu, 14 Oct 2010 17:41:53 +0000 +Subject: r6040: Fix multicast filter some more + + +From: Ben Hutchings + +[ Upstream commit e2269308359d5863b6aa1fcb95a425a2ab255f1f ] + +This code has been broken forever, but in several different and +creative ways. + +So far as I can work out, the R6040 MAC filter has 4 exact-match +entries, the first of which the driver uses for its assigned unicast +address, plus a 64-entry hash-based filter for multicast addresses +(maybe unicast as well?). + +The original version of this code would write the first 4 multicast +addresses as exact-match entries from offset 1 (bug #1: there is no +entry 4 so this could write to some PHY registers). It would fill the +remainder of the exact-match entries with the broadcast address (bug #2: +this would overwrite the last used entry). If more than 4 multicast +addresses were configured, it would set up the hash table, write some +random crap to the MAC control register (bug #3) and finally walk off +the end of the list when filling the exact-match entries (bug #4). + +All of this seems to be pointless, since it sets the promiscuous bit +when the interface is made promiscuous or if >4 multicast addresses +are enabled, and never clears it (bug #5, masking bug #2). + +The recent(ish) changes to the multicast list fixed bug #4, but +completely removed the limit on iteration over the exact-match entries +(bug #6). + +Bug #4 was reported as + and more recently +as . Florian Fainelli attempted to fix +these in commit 3bcf8229a8c49769e48d3e0bd1e20d8e003f8106, but that +actually dealt with bugs #1-3, bug #4 having been fixed in mainline at +that point. + +That commit fixes the most important current bug #6. + +Signed-off-by: Ben Hutchings +Cc: stable@kernel.org [2.6.35 only] +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/r6040.c | 22 ++++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +--- a/drivers/net/r6040.c ++++ b/drivers/net/r6040.c +@@ -988,16 +988,18 @@ static void r6040_multicast_list(struct + /* Multicast Address 1~4 case */ + i = 0; + netdev_for_each_mc_addr(ha, dev) { +- if (i < MCAST_MAX) { +- adrp = (u16 *) ha->addr; +- iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); +- iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); +- iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); +- } else { +- iowrite16(0xffff, ioaddr + MID_1L + 8 * i); +- iowrite16(0xffff, ioaddr + MID_1M + 8 * i); +- iowrite16(0xffff, ioaddr + MID_1H + 8 * i); +- } ++ if (i >= MCAST_MAX) ++ break; ++ adrp = (u16 *) ha->addr; ++ iowrite16(adrp[0], ioaddr + MID_1L + 8 * i); ++ iowrite16(adrp[1], ioaddr + MID_1M + 8 * i); ++ iowrite16(adrp[2], ioaddr + MID_1H + 8 * i); ++ i++; ++ } ++ while (i < MCAST_MAX) { ++ iowrite16(0xffff, ioaddr + MID_1L + 8 * i); ++ iowrite16(0xffff, ioaddr + MID_1M + 8 * i); ++ iowrite16(0xffff, ioaddr + MID_1H + 8 * i); + i++; + } + } diff --git a/queue-2.6.35/revert-c6537d6742985da1fbf12ae26cde6a096fd35b5c.patch b/queue-2.6.35/revert-c6537d6742985da1fbf12ae26cde6a096fd35b5c.patch new file mode 100644 index 00000000000..f0be777ef0f --- /dev/null +++ b/queue-2.6.35/revert-c6537d6742985da1fbf12ae26cde6a096fd35b5c.patch @@ -0,0 +1,124 @@ +From fff9ab5bfcb77c846b0ce0f13f25267c2935443e Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Thu, 21 Oct 2010 01:06:15 +0000 +Subject: Revert c6537d6742985da1fbf12ae26cde6a096fd35b5c + + +From: Neil Horman + +[ Upstream commit 8c974438085d2c81b006daeaab8801eedbd19758 ] + +Backout the tipc changes to the flags int he subscription message. These +changees, while reasonable on the surface, interefere with user space ABI +compatibility which is a no-no. This was part of the changes to fix the +endianess issues in the TIPC protocol, which would be really nice to do but we +need to do so in a way that is backwards compatible with user space. + +Signed-off-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/tipc.h | 30 ++++++++++++++++++------------ + net/tipc/subscr.c | 15 +++++---------- + 2 files changed, 23 insertions(+), 22 deletions(-) + +--- a/include/linux/tipc.h ++++ b/include/linux/tipc.h +@@ -127,17 +127,23 @@ static inline unsigned int tipc_node(__u + * TIPC topology subscription service definitions + */ + +-#define TIPC_SUB_SERVICE 0x00 /* Filter for service availability */ +-#define TIPC_SUB_PORTS 0x01 /* Filter for port availability */ +-#define TIPC_SUB_CANCEL 0x04 /* Cancel a subscription */ ++#define TIPC_SUB_PORTS 0x01 /* filter for port availability */ ++#define TIPC_SUB_SERVICE 0x02 /* filter for service availability */ ++#define TIPC_SUB_CANCEL 0x04 /* cancel a subscription */ ++#if 0 ++/* The following filter options are not currently implemented */ ++#define TIPC_SUB_NO_BIND_EVTS 0x04 /* filter out "publish" events */ ++#define TIPC_SUB_NO_UNBIND_EVTS 0x08 /* filter out "withdraw" events */ ++#define TIPC_SUB_SINGLE_EVT 0x10 /* expire after first event */ ++#endif + + #define TIPC_WAIT_FOREVER ~0 /* timeout for permanent subscription */ + + struct tipc_subscr { +- struct tipc_name_seq seq; /* NBO. Name sequence of interest */ +- __u32 timeout; /* NBO. Subscription duration (in ms) */ +- __u32 filter; /* NBO. Bitmask of filter options */ +- char usr_handle[8]; /* Opaque. Available for subscriber use */ ++ struct tipc_name_seq seq; /* name sequence of interest */ ++ __u32 timeout; /* subscription duration (in ms) */ ++ __u32 filter; /* bitmask of filter options */ ++ char usr_handle[8]; /* available for subscriber use */ + }; + + #define TIPC_PUBLISHED 1 /* publication event */ +@@ -145,11 +151,11 @@ struct tipc_subscr { + #define TIPC_SUBSCR_TIMEOUT 3 /* subscription timeout event */ + + struct tipc_event { +- __u32 event; /* NBO. Event type, as defined above */ +- __u32 found_lower; /* NBO. Matching name seq instances */ +- __u32 found_upper; /* " " " " " */ +- struct tipc_portid port; /* NBO. Associated port */ +- struct tipc_subscr s; /* Original, associated subscription */ ++ __u32 event; /* event type */ ++ __u32 found_lower; /* matching name seq instances */ ++ __u32 found_upper; /* " " " " */ ++ struct tipc_portid port; /* associated port */ ++ struct tipc_subscr s; /* associated subscription */ + }; + + /* +--- a/net/tipc/subscr.c ++++ b/net/tipc/subscr.c +@@ -274,7 +274,7 @@ static void subscr_cancel(struct tipc_su + { + struct subscription *sub; + struct subscription *sub_temp; +- __u32 type, lower, upper, timeout, filter; ++ __u32 type, lower, upper; + int found = 0; + + /* Find first matching subscription, exit if not found */ +@@ -282,18 +282,12 @@ static void subscr_cancel(struct tipc_su + type = ntohl(s->seq.type); + lower = ntohl(s->seq.lower); + upper = ntohl(s->seq.upper); +- timeout = ntohl(s->timeout); +- filter = ntohl(s->filter) & ~TIPC_SUB_CANCEL; + + list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, + subscription_list) { + if ((type == sub->seq.type) && + (lower == sub->seq.lower) && +- (upper == sub->seq.upper) && +- (timeout == sub->timeout) && +- (filter == sub->filter) && +- !memcmp(s->usr_handle,sub->evt.s.usr_handle, +- sizeof(s->usr_handle)) ){ ++ (upper == sub->seq.upper)) { + found = 1; + break; + } +@@ -310,7 +304,7 @@ static void subscr_cancel(struct tipc_su + k_term_timer(&sub->timer); + spin_lock_bh(subscriber->lock); + } +- dbg("Cancel: removing sub %u,%u,%u from subscriber %p list\n", ++ dbg("Cancel: removing sub %u,%u,%u from subscriber %x list\n", + sub->seq.type, sub->seq.lower, sub->seq.upper, subscriber); + subscr_del(sub); + } +@@ -358,7 +352,8 @@ static struct subscription *subscr_subsc + sub->seq.upper = ntohl(s->seq.upper); + sub->timeout = ntohl(s->timeout); + sub->filter = ntohl(s->filter); +- if ((sub->filter && (sub->filter != TIPC_SUB_PORTS)) || ++ if ((!(sub->filter & TIPC_SUB_PORTS) == ++ !(sub->filter & TIPC_SUB_SERVICE)) || + (sub->seq.lower > sub->seq.upper)) { + warn("Subscription rejected, illegal request\n"); + kfree(sub); diff --git a/queue-2.6.35/revert-d88dca79d3852a3623f606f781e013d61486828a.patch b/queue-2.6.35/revert-d88dca79d3852a3623f606f781e013d61486828a.patch new file mode 100644 index 00000000000..f4cda2c12aa --- /dev/null +++ b/queue-2.6.35/revert-d88dca79d3852a3623f606f781e013d61486828a.patch @@ -0,0 +1,152 @@ +From 9c480ba062e1b8f890e47a876f1c42e88c9f7803 Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Thu, 21 Oct 2010 01:06:16 +0000 +Subject: Revert d88dca79d3852a3623f606f781e013d61486828a + + +From: Neil Horman + +[ Upstream commit db5a753bf198ef7a50e17d2ff358adf37efe8648 ] + +TIPC needs to have its endianess issues fixed. Unfortunately, the format of a +subscriber message is passed in directly from user space, so requiring this +message to be in network byte order breaks user space ABI. Revert this change +until such time as we can determine how to do this in a backwards compatible +manner. + +Signed-off-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/tipc/subscr.c | 57 +++++++++++++++++++++++++++++++++--------------------- + net/tipc/subscr.h | 2 + + 2 files changed, 37 insertions(+), 22 deletions(-) + +--- a/net/tipc/subscr.c ++++ b/net/tipc/subscr.c +@@ -76,6 +76,19 @@ struct top_srv { + static struct top_srv topsrv = { 0 }; + + /** ++ * htohl - convert value to endianness used by destination ++ * @in: value to convert ++ * @swap: non-zero if endianness must be reversed ++ * ++ * Returns converted value ++ */ ++ ++static u32 htohl(u32 in, int swap) ++{ ++ return swap ? swab32(in) : in; ++} ++ ++/** + * subscr_send_event - send a message containing a tipc_event to the subscriber + * + * Note: Must not hold subscriber's server port lock, since tipc_send() will +@@ -94,11 +107,11 @@ static void subscr_send_event(struct sub + msg_sect.iov_base = (void *)&sub->evt; + msg_sect.iov_len = sizeof(struct tipc_event); + +- sub->evt.event = htonl(event); +- sub->evt.found_lower = htonl(found_lower); +- sub->evt.found_upper = htonl(found_upper); +- sub->evt.port.ref = htonl(port_ref); +- sub->evt.port.node = htonl(node); ++ sub->evt.event = htohl(event, sub->swap); ++ sub->evt.found_lower = htohl(found_lower, sub->swap); ++ sub->evt.found_upper = htohl(found_upper, sub->swap); ++ sub->evt.port.ref = htohl(port_ref, sub->swap); ++ sub->evt.port.node = htohl(node, sub->swap); + tipc_send(sub->server_ref, 1, &msg_sect); + } + +@@ -274,23 +287,16 @@ static void subscr_cancel(struct tipc_su + { + struct subscription *sub; + struct subscription *sub_temp; +- __u32 type, lower, upper; + int found = 0; + + /* Find first matching subscription, exit if not found */ + +- type = ntohl(s->seq.type); +- lower = ntohl(s->seq.lower); +- upper = ntohl(s->seq.upper); +- + list_for_each_entry_safe(sub, sub_temp, &subscriber->subscription_list, + subscription_list) { +- if ((type == sub->seq.type) && +- (lower == sub->seq.lower) && +- (upper == sub->seq.upper)) { +- found = 1; +- break; +- } ++ if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) { ++ found = 1; ++ break; ++ } + } + if (!found) + return; +@@ -319,10 +325,16 @@ static struct subscription *subscr_subsc + struct subscriber *subscriber) + { + struct subscription *sub; ++ int swap; ++ ++ /* Determine subscriber's endianness */ ++ ++ swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE)); + + /* Detect & process a subscription cancellation request */ + +- if (ntohl(s->filter) & TIPC_SUB_CANCEL) { ++ if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) { ++ s->filter &= ~htohl(TIPC_SUB_CANCEL, swap); + subscr_cancel(s, subscriber); + return NULL; + } +@@ -347,11 +359,11 @@ static struct subscription *subscr_subsc + + /* Initialize subscription object */ + +- sub->seq.type = ntohl(s->seq.type); +- sub->seq.lower = ntohl(s->seq.lower); +- sub->seq.upper = ntohl(s->seq.upper); +- sub->timeout = ntohl(s->timeout); +- sub->filter = ntohl(s->filter); ++ sub->seq.type = htohl(s->seq.type, swap); ++ sub->seq.lower = htohl(s->seq.lower, swap); ++ sub->seq.upper = htohl(s->seq.upper, swap); ++ sub->timeout = htohl(s->timeout, swap); ++ sub->filter = htohl(s->filter, swap); + if ((!(sub->filter & TIPC_SUB_PORTS) == + !(sub->filter & TIPC_SUB_SERVICE)) || + (sub->seq.lower > sub->seq.upper)) { +@@ -364,6 +376,7 @@ static struct subscription *subscr_subsc + INIT_LIST_HEAD(&sub->nameseq_list); + list_add(&sub->subscription_list, &subscriber->subscription_list); + sub->server_ref = subscriber->port_ref; ++ sub->swap = swap; + memcpy(&sub->evt.s, s, sizeof(struct tipc_subscr)); + atomic_inc(&topsrv.subscription_count); + if (sub->timeout != TIPC_WAIT_FOREVER) { +--- a/net/tipc/subscr.h ++++ b/net/tipc/subscr.h +@@ -53,6 +53,7 @@ typedef void (*tipc_subscr_event) (struc + * @nameseq_list: adjacent subscriptions in name sequence's subscription list + * @subscription_list: adjacent subscriptions in subscriber's subscription list + * @server_ref: object reference of server port associated with subscription ++ * @swap: indicates if subscriber uses opposite endianness in its messages + * @evt: template for events generated by subscription + */ + +@@ -65,6 +66,7 @@ struct subscription { + struct list_head nameseq_list; + struct list_head subscription_list; + u32 server_ref; ++ int swap; + struct tipc_event evt; + }; + diff --git a/queue-2.6.35/rose-fix-signedness-issues-wrt.-digi-count.patch b/queue-2.6.35/rose-fix-signedness-issues-wrt.-digi-count.patch new file mode 100644 index 00000000000..32406eabafb --- /dev/null +++ b/queue-2.6.35/rose-fix-signedness-issues-wrt.-digi-count.patch @@ -0,0 +1,41 @@ +From ccef1914831504334ab04ccd84756aae9abb42a8 Mon Sep 17 00:00:00 2001 +From: David S. Miller +Date: Mon, 20 Sep 2010 15:40:35 -0700 +Subject: rose: Fix signedness issues wrt. digi count. + + +From: David S. Miller + +[ Upstream commit 9828e6e6e3f19efcb476c567b9999891d051f52f ] + +Just use explicit casts, since we really can't change the +types of structures exported to userspace which have been +around for 15 years or so. + +Reported-by: Dan Rosenberg +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/rose/af_rose.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/rose/af_rose.c ++++ b/net/rose/af_rose.c +@@ -679,7 +679,7 @@ static int rose_bind(struct socket *sock + if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) + return -EINVAL; + +- if (addr->srose_ndigis > ROSE_MAX_DIGIS) ++ if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) + return -EINVAL; + + if ((dev = rose_dev_get(&addr->srose_addr)) == NULL) { +@@ -739,7 +739,7 @@ static int rose_connect(struct socket *s + if (addr_len == sizeof(struct sockaddr_rose) && addr->srose_ndigis > 1) + return -EINVAL; + +- if (addr->srose_ndigis > ROSE_MAX_DIGIS) ++ if ((unsigned int) addr->srose_ndigis > ROSE_MAX_DIGIS) + return -EINVAL; + + /* Source + Destination digis should not exceed ROSE_MAX_DIGIS */ diff --git a/queue-2.6.35/series b/queue-2.6.35/series index 32ae294d4ad..873dcfb2ec5 100644 --- a/queue-2.6.35/series +++ b/queue-2.6.35/series @@ -55,3 +55,23 @@ libsas-fix-ncq-mixing-with-non-ncq.patch gdth-integer-overflow-in-ioctl.patch fix-race-when-removing-scsi-devices.patch fix-regressions-in-scsi_internal_device_block.patch +net-clear-heap-allocations-for-privileged-ethtool-actions.patch +gianfar-fix-double-lock-typo.patch +gianfar-fix-crashes-on-rx-path-was-re-new-linux-2.6.36-rc5-crash-with-gianfar-ethernet-at-full-line-rate-traffic.patch +ip-fix-truesize-mismatch-in-ip-fragmentation.patch +ipv6-fix-refcnt-problem-related-to-postdad-state.patch +net-fix-ipv6-pmtu-disc.-w-asymmetric-routes.patch +netxen-dont-set-skb-truesize.patch +qlcnic-dont-set-skb-truesize.patch +phonet-correct-header-retrieval-after-pskb_may_pull.patch +r6040-fix-multicast-filter-some-more.patch +rose-fix-signedness-issues-wrt.-digi-count.patch +net-fix-the-condition-passed-to-sk_wait_event.patch +limit-sysctl_tcp_mem-and-sysctl_udp_mem-initializers-to-prevent-integer-overflows.patch +tcp-fix-race-in-tcp_poll.patch +net-2.6-syn-retransmits-add-new-parameter-to-retransmits_timed_out.patch +revert-c6537d6742985da1fbf12ae26cde6a096fd35b5c.patch +revert-d88dca79d3852a3623f606f781e013d61486828a.patch +net-add-a-recursion-limit-in-xmit-path.patch +net-core-allow-tagged-vlan-packets-to-flow-through-veth-devices.patch +xfrm4-strip-ecn-bits-from-tos-field.patch diff --git a/queue-2.6.35/tcp-fix-race-in-tcp_poll.patch b/queue-2.6.35/tcp-fix-race-in-tcp_poll.patch new file mode 100644 index 00000000000..c5a9db9f030 --- /dev/null +++ b/queue-2.6.35/tcp-fix-race-in-tcp_poll.patch @@ -0,0 +1,58 @@ +From b13825cf3edd764e271df93a7024238eb9a5b161 Mon Sep 17 00:00:00 2001 +From: Tom Marshall +Date: Mon, 20 Sep 2010 15:42:05 -0700 +Subject: tcp: Fix race in tcp_poll + + +From: Tom Marshall + +[ Upstream commit a4d258036ed9b2a1811c3670c6099203a0f284a0 ] + +If a RST comes in immediately after checking sk->sk_err, tcp_poll will +return POLLIN but not POLLOUT. Fix this by checking sk->sk_err at the end +of tcp_poll. Additionally, ensure the correct order of operations on SMP +machines with memory barriers. + +Signed-off-by: Tom Marshall +Signed-off-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp.c | 7 +++++-- + net/ipv4/tcp_input.c | 2 ++ + 2 files changed, 7 insertions(+), 2 deletions(-) + +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -388,8 +388,6 @@ unsigned int tcp_poll(struct file *file, + */ + + mask = 0; +- if (sk->sk_err) +- mask = POLLERR; + + /* + * POLLHUP is certainly not done right. But poll() doesn't +@@ -459,6 +457,11 @@ unsigned int tcp_poll(struct file *file, + if (tp->urg_data & TCP_URG_VALID) + mask |= POLLPRI; + } ++ /* This barrier is coupled with smp_wmb() in tcp_reset() */ ++ smp_rmb(); ++ if (sk->sk_err) ++ mask |= POLLERR; ++ + return mask; + } + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -4041,6 +4041,8 @@ static void tcp_reset(struct sock *sk) + default: + sk->sk_err = ECONNRESET; + } ++ /* This barrier is coupled with smp_rmb() in tcp_poll() */ ++ smp_wmb(); + + if (!sock_flag(sk, SOCK_DEAD)) + sk->sk_error_report(sk); diff --git a/queue-2.6.35/xfrm4-strip-ecn-bits-from-tos-field.patch b/queue-2.6.35/xfrm4-strip-ecn-bits-from-tos-field.patch new file mode 100644 index 00000000000..76ad163d9a0 --- /dev/null +++ b/queue-2.6.35/xfrm4-strip-ecn-bits-from-tos-field.patch @@ -0,0 +1,31 @@ +From 78813c5af9277f6e3256c05614094dbfc2034071 Mon Sep 17 00:00:00 2001 +From: Ulrich Weber +Date: Wed, 22 Sep 2010 06:45:11 +0000 +Subject: xfrm4: strip ECN bits from tos field + + +From: Ulrich Weber + +[ Upstream commit 94e2238969e89f5112297ad2a00103089dde7e8f ] + +otherwise ECT(1) bit will get interpreted as RTO_ONLINK +and routing will fail with XfrmOutBundleGenError. + +Signed-off-by: Ulrich Weber +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/xfrm4_policy.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ipv4/xfrm4_policy.c ++++ b/net/ipv4/xfrm4_policy.c +@@ -61,7 +61,7 @@ static int xfrm4_get_saddr(struct net *n + + static int xfrm4_get_tos(struct flowi *fl) + { +- return fl->fl4_tos; ++ return IPTOS_RT_MASK & fl->fl4_tos; /* Strip ECN bits */ + } + + static int xfrm4_init_path(struct xfrm_dst *path, struct dst_entry *dst, -- 2.47.2