From: Greg Kroah-Hartman Date: Tue, 26 Feb 2013 22:55:05 +0000 (-0800) Subject: 3.0-stable patches X-Git-Tag: v3.7.10~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2cfd824d4afb9f706a0e1d3d78fc4d8f1112a843;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: bridge-set-priority-of-stp-packets.patch ipv4-fix-a-bug-in-ping_err.patch ipv6-use-a-stronger-hash-for-tcp.patch xen-netback-cancel-the-credit-timer-when-taking-the-vif-down.patch xen-netback-correctly-return-errors-from-netbk_count_requests.patch --- diff --git a/queue-3.0/bridge-set-priority-of-stp-packets.patch b/queue-3.0/bridge-set-priority-of-stp-packets.patch new file mode 100644 index 00000000000..d315f3ae5f9 --- /dev/null +++ b/queue-3.0/bridge-set-priority-of-stp-packets.patch @@ -0,0 +1,41 @@ +From ec24b0dd4c9535d8df3f9f46fbc0cdd2e1c27704 Mon Sep 17 00:00:00 2001 +From: Stephen Hemminger +Date: Mon, 11 Feb 2013 08:22:22 +0000 +Subject: bridge: set priority of STP packets + + +From: Stephen Hemminger + +[ Upstream commit 547b4e718115eea74087e28d7fa70aec619200db ] + +Spanning Tree Protocol packets should have always been marked as +control packets, this causes them to get queued in the high prirority +FIFO. As Radia Perlman mentioned in her LCA talk, STP dies if bridge +gets overloaded and can't communicate. This is a long-standing bug back +to the first versions of Linux bridge. + +Signed-off-by: Stephen Hemminger +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_stp_bpdu.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/net/bridge/br_stp_bpdu.c ++++ b/net/bridge/br_stp_bpdu.c +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -40,6 +41,7 @@ static void br_send_bpdu(struct net_brid + + skb->dev = p->dev; + skb->protocol = htons(ETH_P_802_2); ++ skb->priority = TC_PRIO_CONTROL; + + skb_reserve(skb, LLC_RESERVE); + memcpy(__skb_put(skb, length), data, length); diff --git a/queue-3.0/ipv4-fix-a-bug-in-ping_err.patch b/queue-3.0/ipv4-fix-a-bug-in-ping_err.patch new file mode 100644 index 00000000000..2a91e2402d6 --- /dev/null +++ b/queue-3.0/ipv4-fix-a-bug-in-ping_err.patch @@ -0,0 +1,32 @@ +From 028dbd1f0615d1ed1f0dde7d321c9f9af593cad8 Mon Sep 17 00:00:00 2001 +From: Li Wei +Date: Thu, 21 Feb 2013 00:09:54 +0000 +Subject: ipv4: fix a bug in ping_err(). + + +From: Li Wei + +[ Upstream commit b531ed61a2a2a77eeb2f7c88b49aa5ec7d9880d8 ] + +We should get 'type' and 'code' from the outer ICMP header. + +Signed-off-by: Li Wei +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/ping.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv4/ping.c ++++ b/net/ipv4/ping.c +@@ -320,8 +320,8 @@ void ping_err(struct sk_buff *skb, u32 i + struct iphdr *iph = (struct iphdr *)skb->data; + struct icmphdr *icmph = (struct icmphdr *)(skb->data+(iph->ihl<<2)); + struct inet_sock *inet_sock; +- int type = icmph->type; +- int code = icmph->code; ++ int type = icmp_hdr(skb)->type; ++ int code = icmp_hdr(skb)->code; + struct net *net = dev_net(skb->dev); + struct sock *sk; + int harderr; diff --git a/queue-3.0/ipv6-use-a-stronger-hash-for-tcp.patch b/queue-3.0/ipv6-use-a-stronger-hash-for-tcp.patch new file mode 100644 index 00000000000..cc2a69bdf17 --- /dev/null +++ b/queue-3.0/ipv6-use-a-stronger-hash-for-tcp.patch @@ -0,0 +1,120 @@ +From 34f215c27921bcaa9b4af3d0a393825f08a6c75d Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Thu, 21 Feb 2013 12:18:52 +0000 +Subject: ipv6: use a stronger hash for tcp + + +From: Eric Dumazet + +[ Upstream commit 08dcdbf6a7b9d14c2302c5bd0c5390ddf122f664 ] + +It looks like its possible to open thousands of TCP IPv6 +sessions on a server, all landing in a single slot of TCP hash +table. Incoming packets have to lookup sockets in a very +long list. + +We should hash all bits from foreign IPv6 addresses, using +a salt and hash mix, not a simple XOR. + +inet6_ehashfn() can also separately use the ports, instead +of xoring them. + +Reported-by: Neal Cardwell +Signed-off-by: Eric Dumazet +Cc: Yuchung Cheng +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/inet6_hashtables.h | 8 ++++---- + include/net/inet_sock.h | 1 + + include/net/ipv6.h | 12 ++++++++++++ + net/ipv4/af_inet.c | 9 +++++++-- + 4 files changed, 24 insertions(+), 6 deletions(-) + +--- a/include/net/inet6_hashtables.h ++++ b/include/net/inet6_hashtables.h +@@ -28,16 +28,16 @@ + + struct inet_hashinfo; + +-/* I have no idea if this is a good hash for v6 or not. -DaveM */ + static inline unsigned int inet6_ehashfn(struct net *net, + const struct in6_addr *laddr, const u16 lport, + const struct in6_addr *faddr, const __be16 fport) + { +- u32 ports = (lport ^ (__force u16)fport); ++ u32 ports = (((u32)lport) << 16) | (__force u32)fport; + + return jhash_3words((__force u32)laddr->s6_addr32[3], +- (__force u32)faddr->s6_addr32[3], +- ports, inet_ehash_secret + net_hash_mix(net)); ++ ipv6_addr_jhash(faddr), ++ ports, ++ inet_ehash_secret + net_hash_mix(net)); + } + + static inline int inet6_sk_ehashfn(const struct sock *sk) +--- a/include/net/inet_sock.h ++++ b/include/net/inet_sock.h +@@ -199,6 +199,7 @@ static inline void inet_sk_copy_descenda + extern int inet_sk_rebuild_header(struct sock *sk); + + extern u32 inet_ehash_secret; ++extern u32 ipv6_hash_secret; + extern void build_ehash_secret(void); + + static inline unsigned int inet_ehashfn(struct net *net, +--- a/include/net/ipv6.h ++++ b/include/net/ipv6.h +@@ -15,6 +15,7 @@ + + #include + #include ++#include + #include + #include + #include +@@ -386,6 +387,17 @@ struct ip6_create_arg { + void ip6_frag_init(struct inet_frag_queue *q, void *a); + int ip6_frag_match(struct inet_frag_queue *q, void *a); + ++/* more secured version of ipv6_addr_hash() */ ++static inline u32 ipv6_addr_jhash(const struct in6_addr *a) ++{ ++ u32 v = (__force u32)a->s6_addr32[0] ^ (__force u32)a->s6_addr32[1]; ++ ++ return jhash_3words(v, ++ (__force u32)a->s6_addr32[2], ++ (__force u32)a->s6_addr32[3], ++ ipv6_hash_secret); ++} ++ + static inline int ipv6_addr_any(const struct in6_addr *a) + { + return (a->s6_addr32[0] | a->s6_addr32[1] | +--- a/net/ipv4/af_inet.c ++++ b/net/ipv4/af_inet.c +@@ -226,8 +226,12 @@ EXPORT_SYMBOL(inet_listen); + u32 inet_ehash_secret __read_mostly; + EXPORT_SYMBOL(inet_ehash_secret); + ++u32 ipv6_hash_secret __read_mostly; ++EXPORT_SYMBOL(ipv6_hash_secret); ++ + /* +- * inet_ehash_secret must be set exactly once ++ * inet_ehash_secret must be set exactly once, and to a non nul value ++ * ipv6_hash_secret must be set exactly once. + */ + void build_ehash_secret(void) + { +@@ -237,7 +241,8 @@ void build_ehash_secret(void) + get_random_bytes(&rnd, sizeof(rnd)); + } while (rnd == 0); + +- cmpxchg(&inet_ehash_secret, 0, rnd); ++ if (cmpxchg(&inet_ehash_secret, 0, rnd) == 0) ++ get_random_bytes(&ipv6_hash_secret, sizeof(ipv6_hash_secret)); + } + EXPORT_SYMBOL(build_ehash_secret); + diff --git a/queue-3.0/series b/queue-3.0/series index 8edb32ac9ae..ac0022b97b6 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -39,3 +39,8 @@ pcmcia-vrc4171-add-missing-spinlock-init.patch fbcon-don-t-lose-the-console-font-across-generic-chip-driver-switch.patch fb-rework-locking-to-fix-lock-ordering-on-takeover.patch fb-yet-another-band-aid-for-fixing-lockdep-mess.patch +bridge-set-priority-of-stp-packets.patch +xen-netback-correctly-return-errors-from-netbk_count_requests.patch +xen-netback-cancel-the-credit-timer-when-taking-the-vif-down.patch +ipv4-fix-a-bug-in-ping_err.patch +ipv6-use-a-stronger-hash-for-tcp.patch diff --git a/queue-3.0/xen-netback-cancel-the-credit-timer-when-taking-the-vif-down.patch b/queue-3.0/xen-netback-cancel-the-credit-timer-when-taking-the-vif-down.patch new file mode 100644 index 00000000000..ec0b20229e2 --- /dev/null +++ b/queue-3.0/xen-netback-cancel-the-credit-timer-when-taking-the-vif-down.patch @@ -0,0 +1,55 @@ +From c702e3772a6f5464ec7d59affdbbb41c2e483f6b Mon Sep 17 00:00:00 2001 +From: David Vrabel +Date: Thu, 14 Feb 2013 03:18:58 +0000 +Subject: xen-netback: cancel the credit timer when taking the vif down + + +From: David Vrabel + +[ Upstream commit 3e55f8b306cf305832a4ac78aa82e1b40e818ece ] + +If the credit timer is left armed after calling +xen_netbk_remove_xenvif(), then it may fire and attempt to schedule +the vif which will then oops as vif->netbk == NULL. + +This may happen both in the fatal error path and during normal +disconnection from the front end. + +The sequencing during shutdown is critical to ensure that: a) +vif->netbk doesn't become unexpectedly NULL; and b) the net device/vif +is not freed. + +1. Mark as unschedulable (netif_carrier_off()). +2. Synchronously cancel the timer. +3. Remove the vif from the schedule list. +4. Remove it from it netback thread group. +5. Wait for vif->refcnt to become 0. + +Signed-off-by: David Vrabel +Acked-by: Ian Campbell +Reported-by: Christopher S. Aker +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/xen-netback/interface.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/drivers/net/xen-netback/interface.c ++++ b/drivers/net/xen-netback/interface.c +@@ -132,6 +132,7 @@ static void xenvif_up(struct xenvif *vif + static void xenvif_down(struct xenvif *vif) + { + disable_irq(vif->irq); ++ del_timer_sync(&vif->credit_timeout); + xen_netbk_deschedule_xenvif(vif); + xen_netbk_remove_xenvif(vif); + } +@@ -362,8 +363,6 @@ void xenvif_disconnect(struct xenvif *vi + atomic_dec(&vif->refcnt); + wait_event(vif->waiting_to_free, atomic_read(&vif->refcnt) == 0); + +- del_timer_sync(&vif->credit_timeout); +- + if (vif->irq) + unbind_from_irqhandler(vif->irq, vif); + diff --git a/queue-3.0/xen-netback-correctly-return-errors-from-netbk_count_requests.patch b/queue-3.0/xen-netback-correctly-return-errors-from-netbk_count_requests.patch new file mode 100644 index 00000000000..82a2d3d27a9 --- /dev/null +++ b/queue-3.0/xen-netback-correctly-return-errors-from-netbk_count_requests.patch @@ -0,0 +1,73 @@ +From f61e2d50b5f1f3cb7629ef56030d53729985ccfc Mon Sep 17 00:00:00 2001 +From: David Vrabel +Date: Thu, 14 Feb 2013 03:18:57 +0000 +Subject: xen-netback: correctly return errors from netbk_count_requests() + + +From: David Vrabel + +[ Upstream commit 35876b5ffc154c357476b2c3bdab10feaf4bd8f0 ] + +netbk_count_requests() could detect an error, call +netbk_fatal_tx_error() but return 0. The vif may then be used +afterwards (e.g., in a call to netbk_tx_error(). + +Since netbk_fatal_tx_error() could set vif->refcnt to 1, the vif may +be freed immediately after the call to netbk_fatal_tx_error() (e.g., +if the vif is also removed). + +Netback thread Xenwatch thread +------------------------------------------- +netbk_fatal_tx_err() netback_remove() + xenvif_disconnect() + ... + free_netdev() +netbk_tx_err() Oops! + +Signed-off-by: Wei Liu +Signed-off-by: Jan Beulich +Signed-off-by: David Vrabel +Reported-by: Christopher S. Aker +Acked-by: Ian Campbell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/xen-netback/netback.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/xen-netback/netback.c ++++ b/drivers/net/xen-netback/netback.c +@@ -870,13 +870,13 @@ static int netbk_count_requests(struct x + if (frags >= work_to_do) { + netdev_err(vif->dev, "Need more frags\n"); + netbk_fatal_tx_err(vif); +- return -frags; ++ return -ENODATA; + } + + if (unlikely(frags >= MAX_SKB_FRAGS)) { + netdev_err(vif->dev, "Too many frags\n"); + netbk_fatal_tx_err(vif); +- return -frags; ++ return -E2BIG; + } + + memcpy(txp, RING_GET_REQUEST(&vif->tx, cons + frags), +@@ -884,7 +884,7 @@ static int netbk_count_requests(struct x + if (txp->size > first->size) { + netdev_err(vif->dev, "Frag is bigger than frame.\n"); + netbk_fatal_tx_err(vif); +- return -frags; ++ return -EIO; + } + + first->size -= txp->size; +@@ -894,7 +894,7 @@ static int netbk_count_requests(struct x + netdev_err(vif->dev, "txp->offset: %x, size: %u\n", + txp->offset, txp->size); + netbk_fatal_tx_err(vif); +- return -frags; ++ return -EINVAL; + } + } while ((txp++)->flags & XEN_NETTXF_more_data); + return frags;