From: Greg Kroah-Hartman Date: Mon, 7 Oct 2013 01:47:35 +0000 (-0700) Subject: 3.0-stable patches X-Git-Tag: v3.0.100~24 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=3653b48bc4e7b7a2b0fb06175c42341902390661;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: bonding-fix-broken-promiscuity-reference-counting-issue.patch bridge-clamp-forward_delay-when-enabling-stp.patch caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch dm9601-fix-iff_allmulti-handling.patch ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch resubmit-bridge-fix-message_age_timer-calculation.patch via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch --- diff --git a/queue-3.0/bonding-fix-broken-promiscuity-reference-counting-issue.patch b/queue-3.0/bonding-fix-broken-promiscuity-reference-counting-issue.patch new file mode 100644 index 00000000000..88c76bb9e45 --- /dev/null +++ b/queue-3.0/bonding-fix-broken-promiscuity-reference-counting-issue.patch @@ -0,0 +1,77 @@ +From f15d748be4950f07437139a10fc07aa781e764e3 Mon Sep 17 00:00:00 2001 +From: Neil Horman +Date: Fri, 27 Sep 2013 12:22:15 -0400 +Subject: bonding: Fix broken promiscuity reference counting issue + +From: Neil Horman + +[ Upstream commit 5a0068deb611109c5ba77358be533f763f395ee4 ] + +Recently grabbed this report: +https://bugzilla.redhat.com/show_bug.cgi?id=1005567 + +Of an issue in which the bonding driver, with an attached vlan encountered the +following errors when bond0 was taken down and back up: + +dummy1: promiscuity touches roof, set promiscuity failed. promiscuity feature of +device might be broken. + +The error occurs because, during __bond_release_one, if we release our last +slave, we take on a random mac address and issue a NETDEV_CHANGEADDR +notification. With an attached vlan, the vlan may see that the vlan and bond +mac address were in sync, but no longer are. This triggers a call to dev_uc_add +and dev_set_rx_mode, which enables IFF_PROMISC on the bond device. Then, when +we complete __bond_release_one, we use the current state of the bond flags to +determine if we should decrement the promiscuity of the releasing slave. But +since the bond changed promiscuity state during the release operation, we +incorrectly decrement the slave promisc count when it wasn't in promiscuous mode +to begin with, causing the above error + +Fix is pretty simple, just cache the bonding flags at the start of the function +and use those when determining the need to set promiscuity. + +This is also needed for the ALLMULTI flag + +Reported-by: Mark Wu +CC: Jay Vosburgh +CC: Andy Gospodarek +CC: Mark Wu +CC: "David S. Miller" +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/bonding/bond_main.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/net/bonding/bond_main.c ++++ b/drivers/net/bonding/bond_main.c +@@ -1994,6 +1994,7 @@ int bond_release(struct net_device *bond + struct bonding *bond = netdev_priv(bond_dev); + struct slave *slave, *oldcurrent; + struct sockaddr addr; ++ int old_flags = bond_dev->flags; + u32 old_features = bond_dev->features; + + /* slave is not a slave or master is not master of this slave */ +@@ -2124,12 +2125,18 @@ int bond_release(struct net_device *bond + * already taken care of above when we detached the slave + */ + if (!USES_PRIMARY(bond->params.mode)) { +- /* unset promiscuity level from slave */ +- if (bond_dev->flags & IFF_PROMISC) ++ /* unset promiscuity level from slave ++ * NOTE: The NETDEV_CHANGEADDR call above may change the value ++ * of the IFF_PROMISC flag in the bond_dev, but we need the ++ * value of that flag before that change, as that was the value ++ * when this slave was attached, so we cache at the start of the ++ * function and use it here. Same goes for ALLMULTI below ++ */ ++ if (old_flags & IFF_PROMISC) + dev_set_promiscuity(slave_dev, -1); + + /* unset allmulti level from slave */ +- if (bond_dev->flags & IFF_ALLMULTI) ++ if (old_flags & IFF_ALLMULTI) + dev_set_allmulti(slave_dev, -1); + + /* flush master's mc_list from slave */ diff --git a/queue-3.0/bridge-clamp-forward_delay-when-enabling-stp.patch b/queue-3.0/bridge-clamp-forward_delay-when-enabling-stp.patch new file mode 100644 index 00000000000..4ed1045ba92 --- /dev/null +++ b/queue-3.0/bridge-clamp-forward_delay-when-enabling-stp.patch @@ -0,0 +1,106 @@ +From 37b78fb1b1ea0971526422429a9dff4960b51055 Mon Sep 17 00:00:00 2001 +From: Herbert Xu +Date: Thu, 12 Sep 2013 17:12:05 +1000 +Subject: bridge: Clamp forward_delay when enabling STP + +From: Herbert Xu + +[ Upstream commit be4f154d5ef0ca147ab6bcd38857a774133f5450 ] + +At some point limits were added to forward_delay. However, the +limits are only enforced when STP is enabled. This created a +scenario where you could have a value outside the allowed range +while STP is disabled, which then stuck around even after STP +is enabled. + +This patch fixes this by clamping the value when we enable STP. + +I had to move the locking around a bit to ensure that there is +no window where someone could insert a value outside the range +while we're in the middle of enabling STP. + +Signed-off-by: Herbert Xu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_private.h | 1 + + net/bridge/br_stp.c | 21 +++++++++++++++------ + net/bridge/br_stp_if.c | 12 ++++++++++-- + 3 files changed, 26 insertions(+), 8 deletions(-) + +--- a/net/bridge/br_private.h ++++ b/net/bridge/br_private.h +@@ -492,6 +492,7 @@ extern struct net_bridge_port *br_get_po + extern void br_init_port(struct net_bridge_port *p); + extern void br_become_designated_port(struct net_bridge_port *p); + ++extern void __br_set_forward_delay(struct net_bridge *br, unsigned long t); + extern int br_set_forward_delay(struct net_bridge *br, unsigned long x); + extern int br_set_hello_time(struct net_bridge *br, unsigned long x); + extern int br_set_max_age(struct net_bridge *br, unsigned long x); +--- a/net/bridge/br_stp.c ++++ b/net/bridge/br_stp.c +@@ -517,18 +517,27 @@ int br_set_max_age(struct net_bridge *br + + } + ++void __br_set_forward_delay(struct net_bridge *br, unsigned long t) ++{ ++ br->bridge_forward_delay = t; ++ if (br_is_root_bridge(br)) ++ br->forward_delay = br->bridge_forward_delay; ++} ++ + int br_set_forward_delay(struct net_bridge *br, unsigned long val) + { + unsigned long t = clock_t_to_jiffies(val); ++ int err = -ERANGE; + ++ spin_lock_bh(&br->lock); + if (br->stp_enabled != BR_NO_STP && + (t < BR_MIN_FORWARD_DELAY || t > BR_MAX_FORWARD_DELAY)) +- return -ERANGE; ++ goto unlock; + +- spin_lock_bh(&br->lock); +- br->bridge_forward_delay = t; +- if (br_is_root_bridge(br)) +- br->forward_delay = br->bridge_forward_delay; ++ __br_set_forward_delay(br, t); ++ err = 0; ++ ++unlock: + spin_unlock_bh(&br->lock); +- return 0; ++ return err; + } +--- a/net/bridge/br_stp_if.c ++++ b/net/bridge/br_stp_if.c +@@ -126,6 +126,14 @@ static void br_stp_start(struct net_brid + char *envp[] = { NULL }; + + r = call_usermodehelper(BR_STP_PROG, argv, envp, UMH_WAIT_PROC); ++ ++ spin_lock_bh(&br->lock); ++ ++ if (br->bridge_forward_delay < BR_MIN_FORWARD_DELAY) ++ __br_set_forward_delay(br, BR_MIN_FORWARD_DELAY); ++ else if (br->bridge_forward_delay < BR_MAX_FORWARD_DELAY) ++ __br_set_forward_delay(br, BR_MAX_FORWARD_DELAY); ++ + if (r == 0) { + br->stp_enabled = BR_USER_STP; + br_debug(br, "userspace STP started\n"); +@@ -134,10 +142,10 @@ static void br_stp_start(struct net_brid + br_debug(br, "using kernel STP\n"); + + /* To start timers on any ports left in blocking */ +- spin_lock_bh(&br->lock); + br_port_state_selection(br); +- spin_unlock_bh(&br->lock); + } ++ ++ spin_unlock_bh(&br->lock); + } + + static void br_stp_stop(struct net_bridge *br) diff --git a/queue-3.0/caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch b/queue-3.0/caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch new file mode 100644 index 00000000000..8f3cc1f6098 --- /dev/null +++ b/queue-3.0/caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch @@ -0,0 +1,35 @@ +From b2493cf2dae546a04ab1f56e4ea1ac0206a8bf28 Mon Sep 17 00:00:00 2001 +From: Dave Jones +Date: Thu, 5 Sep 2013 00:11:19 -0400 +Subject: caif: Add missing braces to multiline if in cfctrl_linkup_request + +From: Dave Jones + +[ Upstream commit 0c1db731bfcf3a9fd6c58132134f8b0f423552f0 ] + +The indentation here implies this was meant to be a multi-line if. + +Introduced several years back in commit c85c2951d4da1236e32f1858db418221e624aba5 +("caif: Handle dev_queue_xmit errors.") + +Signed-off-by: Dave Jones +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/caif/cfctrl.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/caif/cfctrl.c ++++ b/net/caif/cfctrl.c +@@ -297,9 +297,10 @@ int cfctrl_linkup_request(struct cflayer + + count = cfctrl_cancel_req(&cfctrl->serv.layer, + user_layer); +- if (count != 1) ++ if (count != 1) { + pr_err("Could not remove request (%d)", count); + return -ENODEV; ++ } + } + return 0; + } diff --git a/queue-3.0/dm9601-fix-iff_allmulti-handling.patch b/queue-3.0/dm9601-fix-iff_allmulti-handling.patch new file mode 100644 index 00000000000..60886c3b932 --- /dev/null +++ b/queue-3.0/dm9601-fix-iff_allmulti-handling.patch @@ -0,0 +1,31 @@ +From 86282dd1143c74794163a9c61cabc6903f48ddf5 Mon Sep 17 00:00:00 2001 +From: Peter Korsgaard +Date: Mon, 30 Sep 2013 23:28:20 +0200 +Subject: dm9601: fix IFF_ALLMULTI handling + +From: Peter Korsgaard + +[ Upstream commit bf0ea6380724beb64f27a722dfc4b0edabff816e ] + +Pass-all-multicast is controlled by bit 3 in RX control, not bit 2 +(pass undersized frames). + +Reported-by: Joseph Chang +Signed-off-by: Peter Korsgaard +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/dm9601.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/usb/dm9601.c ++++ b/drivers/net/usb/dm9601.c +@@ -384,7 +384,7 @@ static void dm9601_set_multicast(struct + rx_ctl |= 0x02; + } else if (net->flags & IFF_ALLMULTI || + netdev_mc_count(net) > DM_MAX_MCAST) { +- rx_ctl |= 0x04; ++ rx_ctl |= 0x08; + } else if (!netdev_mc_empty(net)) { + struct netdev_hw_addr *ha; + diff --git a/queue-3.0/ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch b/queue-3.0/ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch new file mode 100644 index 00000000000..07d22230d3d --- /dev/null +++ b/queue-3.0/ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch @@ -0,0 +1,195 @@ +From e5bac32e196e16f1bfac0ecc7491706c7a11fe79 Mon Sep 17 00:00:00 2001 +From: Ansis Atteka +Date: Wed, 18 Sep 2013 15:29:53 -0700 +Subject: ip: generate unique IP identificator if local fragmentation is allowed + +From: Ansis Atteka + +[ Upstream commit 703133de331a7a7df47f31fb9de51dc6f68a9de8 ] + +If local fragmentation is allowed, then ip_select_ident() and +ip_select_ident_more() need to generate unique IDs to ensure +correct defragmentation on the peer. + +For example, if IPsec (tunnel mode) has to encrypt large skbs +that have local_df bit set, then all IP fragments that belonged +to different ESP datagrams would have used the same identificator. +If one of these IP fragments would get lost or reordered, then +peer could possibly stitch together wrong IP fragments that did +not belong to the same datagram. This would lead to a packet loss +or data corruption. + +Signed-off-by: Ansis Atteka +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/pptp.c | 2 +- + include/net/ip.h | 12 ++++++++---- + include/net/ipip.h | 2 +- + net/ipv4/igmp.c | 4 ++-- + net/ipv4/inetpeer.c | 4 ++-- + net/ipv4/ip_output.c | 6 +++--- + net/ipv4/ipmr.c | 2 +- + net/ipv4/raw.c | 2 +- + net/ipv4/xfrm4_mode_tunnel.c | 2 +- + net/netfilter/ipvs/ip_vs_xmit.c | 2 +- + 10 files changed, 21 insertions(+), 17 deletions(-) + +--- a/drivers/net/pptp.c ++++ b/drivers/net/pptp.c +@@ -282,7 +282,7 @@ static int pptp_xmit(struct ppp_channel + nf_reset(skb); + + skb->ip_summed = CHECKSUM_NONE; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ip_send_check(iph); + + ip_local_out(skb); +--- a/include/net/ip.h ++++ b/include/net/ip.h +@@ -262,9 +262,11 @@ int ip_dont_fragment(struct sock *sk, st + + extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); + +-static inline void ip_select_ident(struct iphdr *iph, struct dst_entry *dst, struct sock *sk) ++static inline void ip_select_ident(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk) + { +- if (iph->frag_off & htons(IP_DF)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + /* This is only to work around buggy Windows95/2000 + * VJ compression implementations. If the ID field + * does not change, they drop every other packet in +@@ -276,9 +278,11 @@ static inline void ip_select_ident(struc + __ip_select_ident(iph, dst, 0); + } + +-static inline void ip_select_ident_more(struct iphdr *iph, struct dst_entry *dst, struct sock *sk, int more) ++static inline void ip_select_ident_more(struct sk_buff *skb, struct dst_entry *dst, struct sock *sk, int more) + { +- if (iph->frag_off & htons(IP_DF)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if ((iph->frag_off & htons(IP_DF)) && !skb->local_df) { + if (sk && inet_sk(sk)->inet_daddr) { + iph->id = htons(inet_sk(sk)->inet_id); + inet_sk(sk)->inet_id += 1 + more; +--- a/include/net/ipip.h ++++ b/include/net/ipip.h +@@ -50,7 +50,7 @@ struct ip_tunnel_prl_entry { + int pkt_len = skb->len - skb_transport_offset(skb); \ + \ + skb->ip_summed = CHECKSUM_NONE; \ +- ip_select_ident(iph, &rt->dst, NULL); \ ++ ip_select_ident(skb, &rt->dst, NULL); \ + \ + err = ip_local_out(skb); \ + if (likely(net_xmit_eval(err) == 0)) { \ +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -342,7 +342,7 @@ static struct sk_buff *igmpv3_newpack(st + pip->saddr = fl4.saddr; + pip->protocol = IPPROTO_IGMP; + pip->tot_len = 0; /* filled in later */ +- ip_select_ident(pip, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ((u8*)&pip[1])[0] = IPOPT_RA; + ((u8*)&pip[1])[1] = 4; + ((u8*)&pip[1])[2] = 0; +@@ -683,7 +683,7 @@ static int igmp_send_report(struct in_de + iph->daddr = dst; + iph->saddr = fl4.saddr; + iph->protocol = IPPROTO_IGMP; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + ((u8*)&iph[1])[0] = IPOPT_RA; + ((u8*)&iph[1])[1] = 4; + ((u8*)&iph[1])[2] = 0; +--- a/net/ipv4/inetpeer.c ++++ b/net/ipv4/inetpeer.c +@@ -31,8 +31,8 @@ + * At the moment of writing this notes identifier of IP packets is generated + * to be unpredictable using this code only for packets subjected + * (actually or potentially) to defragmentation. I.e. DF packets less than +- * PMTU in size uses a constant ID and do not use this code (see +- * ip_select_ident() in include/net/ip.h). ++ * PMTU in size when local fragmentation is disabled use a constant ID and do ++ * not use this code (see ip_select_ident() in include/net/ip.h). + * + * Route cache entries hold references to our nodes. + * New cache entries get references via lookup by destination IP address in +--- a/net/ipv4/ip_output.c ++++ b/net/ipv4/ip_output.c +@@ -161,7 +161,7 @@ int ip_build_and_send_pkt(struct sk_buff + iph->daddr = (opt && opt->opt.srr ? opt->opt.faddr : daddr); + iph->saddr = saddr; + iph->protocol = sk->sk_protocol; +- ip_select_ident(iph, &rt->dst, sk); ++ ip_select_ident(skb, &rt->dst, sk); + + if (opt && opt->opt.optlen) { + iph->ihl += opt->opt.optlen>>2; +@@ -397,7 +397,7 @@ packet_routed: + ip_options_build(skb, &inet_opt->opt, inet->inet_daddr, rt, 0); + } + +- ip_select_ident_more(iph, &rt->dst, sk, ++ ip_select_ident_more(skb, &rt->dst, sk, + (skb_shinfo(skb)->gso_segs ?: 1) - 1); + + skb->priority = sk->sk_priority; +@@ -1340,7 +1340,7 @@ struct sk_buff *__ip_make_skb(struct soc + iph->ihl = 5; + iph->tos = inet->tos; + iph->frag_off = df; +- ip_select_ident(iph, &rt->dst, sk); ++ ip_select_ident(skb, &rt->dst, sk); + iph->ttl = ttl; + iph->protocol = sk->sk_protocol; + iph->saddr = fl4->saddr; +--- a/net/ipv4/ipmr.c ++++ b/net/ipv4/ipmr.c +@@ -1575,7 +1575,7 @@ static void ip_encap(struct sk_buff *skb + iph->protocol = IPPROTO_IPIP; + iph->ihl = 5; + iph->tot_len = htons(skb->len); +- ip_select_ident(iph, skb_dst(skb), NULL); ++ ip_select_ident(skb, skb_dst(skb), NULL); + ip_send_check(iph); + + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); +--- a/net/ipv4/raw.c ++++ b/net/ipv4/raw.c +@@ -379,7 +379,7 @@ static int raw_send_hdrinc(struct sock * + iph->check = 0; + iph->tot_len = htons(length); + if (!iph->id) +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + + iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); + } +--- a/net/ipv4/xfrm4_mode_tunnel.c ++++ b/net/ipv4/xfrm4_mode_tunnel.c +@@ -54,7 +54,7 @@ static int xfrm4_mode_tunnel_output(stru + + top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? + 0 : (XFRM_MODE_SKB_CB(skb)->frag_off & htons(IP_DF)); +- ip_select_ident(top_iph, dst->child, NULL); ++ ip_select_ident(skb, dst->child, NULL); + + top_iph->ttl = ip4_dst_hoplimit(dst->child); + +--- a/net/netfilter/ipvs/ip_vs_xmit.c ++++ b/net/netfilter/ipvs/ip_vs_xmit.c +@@ -853,7 +853,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, s + iph->daddr = cp->daddr.ip; + iph->saddr = saddr; + iph->ttl = old_iph->ttl; +- ip_select_ident(iph, &rt->dst, NULL); ++ ip_select_ident(skb, &rt->dst, NULL); + + /* Another hack: avoid icmp_send in ip_fragment */ + skb->local_df = 1; diff --git a/queue-3.0/ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch b/queue-3.0/ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch new file mode 100644 index 00000000000..86911168365 --- /dev/null +++ b/queue-3.0/ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch @@ -0,0 +1,47 @@ +From b347dcc4cf578a24a1399e6bdbe07536b36c6362 Mon Sep 17 00:00:00 2001 +From: Salam Noureddine +Date: Sun, 29 Sep 2013 13:39:42 -0700 +Subject: ipv4 igmp: use in_dev_put in timer handlers instead of __in_dev_put + +From: Salam Noureddine + +[ Upstream commit e2401654dd0f5f3fb7a8d80dad9554d73d7ca394 ] + +It is possible for the timer handlers to run after the call to +ip_mc_down so use in_dev_put instead of __in_dev_put in the handler +function in order to do proper cleanup when the refcnt reaches 0. +Otherwise, the refcnt can reach zero without the in_device being +destroyed and we end up leaking a reference to the net_device and +see messages like the following, + +unregister_netdevice: waiting for eth0 to become free. Usage count = 1 + +Tested on linux-3.4.43. + +Signed-off-by: Salam Noureddine +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/igmp.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv4/igmp.c ++++ b/net/ipv4/igmp.c +@@ -705,7 +705,7 @@ static void igmp_gq_timer_expire(unsigne + + in_dev->mr_gq_running = 0; + igmpv3_send_report(in_dev, NULL); +- __in_dev_put(in_dev); ++ in_dev_put(in_dev); + } + + static void igmp_ifc_timer_expire(unsigned long data) +@@ -717,7 +717,7 @@ static void igmp_ifc_timer_expire(unsign + in_dev->mr_ifc_count--; + igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval); + } +- __in_dev_put(in_dev); ++ in_dev_put(in_dev); + } + + static void igmp_ifc_event(struct in_device *in_dev) diff --git a/queue-3.0/ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch b/queue-3.0/ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch new file mode 100644 index 00000000000..554ed144c36 --- /dev/null +++ b/queue-3.0/ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch @@ -0,0 +1,47 @@ +From 9eb88baaea39257fbefe05ecdbba3b69fc92f12c Mon Sep 17 00:00:00 2001 +From: Salam Noureddine +Date: Sun, 29 Sep 2013 13:41:34 -0700 +Subject: ipv6 mcast: use in6_dev_put in timer handlers instead of __in6_dev_put + +From: Salam Noureddine + +[ Upstream commit 9260d3e1013701aa814d10c8fc6a9f92bd17d643 ] + +It is possible for the timer handlers to run after the call to +ipv6_mc_down so use in6_dev_put instead of __in6_dev_put in the +handler function in order to do proper cleanup when the refcnt +reaches 0. Otherwise, the refcnt can reach zero without the +inet6_dev being destroyed and we end up leaking a reference to +the net_device and see messages like the following, + +unregister_netdevice: waiting for eth0 to become free. Usage count = 1 + +Tested on linux-3.4.43. + +Signed-off-by: Salam Noureddine +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/mcast.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv6/mcast.c ++++ b/net/ipv6/mcast.c +@@ -2159,7 +2159,7 @@ static void mld_gq_timer_expire(unsigned + + idev->mc_gq_running = 0; + mld_send_report(idev, NULL); +- __in6_dev_put(idev); ++ in6_dev_put(idev); + } + + static void mld_ifc_timer_expire(unsigned long data) +@@ -2172,7 +2172,7 @@ static void mld_ifc_timer_expire(unsigne + if (idev->mc_ifc_count) + mld_ifc_start_timer(idev, idev->mc_maxdelay); + } +- __in6_dev_put(idev); ++ in6_dev_put(idev); + } + + static void mld_ifc_event(struct inet6_dev *idev) diff --git a/queue-3.0/ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch b/queue-3.0/ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch new file mode 100644 index 00000000000..d329ce8f7b2 --- /dev/null +++ b/queue-3.0/ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch @@ -0,0 +1,122 @@ +From 4fda2a5c92e960e7da5f1d015e09bf509360d270 Mon Sep 17 00:00:00 2001 +From: Hannes Frederic Sowa +Date: Sat, 21 Sep 2013 06:27:00 +0200 +Subject: ipv6: udp packets following an UFO enqueued packet need also be handled by UFO + +From: Hannes Frederic Sowa + +[ Upstream commit 2811ebac2521ceac84f2bdae402455baa6a7fb47 ] + +In the following scenario the socket is corked: +If the first UDP packet is larger then the mtu we try to append it to the +write queue via ip6_ufo_append_data. A following packet, which is smaller +than the mtu would be appended to the already queued up gso-skb via +plain ip6_append_data. This causes random memory corruptions. + +In ip6_ufo_append_data we also have to be careful to not queue up the +same skb multiple times. So setup the gso frame only when no first skb +is available. + +This also fixes a shortcoming where we add the current packet's length to +cork->length but return early because of a packet > mtu with dontfrag set +(instead of sutracting it again). + +Found with trinity. + +Cc: YOSHIFUJI Hideaki +Signed-off-by: Hannes Frederic Sowa +Reported-by: Dmitry Vyukov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_output.c | 53 ++++++++++++++++++++------------------------------ + 1 file changed, 22 insertions(+), 31 deletions(-) + +--- a/net/ipv6/ip6_output.c ++++ b/net/ipv6/ip6_output.c +@@ -1141,6 +1141,8 @@ static inline int ip6_ufo_append_data(st + * udp datagram + */ + if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) { ++ struct frag_hdr fhdr; ++ + skb = sock_alloc_send_skb(sk, + hh_len + fragheaderlen + transhdrlen + 20, + (flags & MSG_DONTWAIT), &err); +@@ -1161,12 +1163,6 @@ static inline int ip6_ufo_append_data(st + + skb->ip_summed = CHECKSUM_PARTIAL; + skb->csum = 0; +- } +- +- err = skb_append_datato_frags(sk,skb, getfrag, from, +- (length - transhdrlen)); +- if (!err) { +- struct frag_hdr fhdr; + + /* Specify the length of each IPv6 datagram fragment. + * It has to be a multiple of 8. +@@ -1177,15 +1173,10 @@ static inline int ip6_ufo_append_data(st + ipv6_select_ident(&fhdr, &rt->rt6i_dst.addr); + skb_shinfo(skb)->ip6_frag_id = fhdr.identification; + __skb_queue_tail(&sk->sk_write_queue, skb); +- +- return 0; + } +- /* There is not enough support do UPD LSO, +- * so follow normal path +- */ +- kfree_skb(skb); + +- return err; ++ return skb_append_datato_frags(sk, skb, getfrag, from, ++ (length - transhdrlen)); + } + + static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src, +@@ -1354,27 +1345,27 @@ int ip6_append_data(struct sock *sk, int + * --yoshfuji + */ + +- cork->length += length; +- if (length > mtu) { +- int proto = sk->sk_protocol; +- if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ +- ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); +- return -EMSGSIZE; +- } +- +- if (proto == IPPROTO_UDP && +- (rt->dst.dev->features & NETIF_F_UFO)) { ++ if ((length > mtu) && dontfrag && (sk->sk_protocol == IPPROTO_UDP || ++ sk->sk_protocol == IPPROTO_RAW)) { ++ ipv6_local_rxpmtu(sk, fl6, mtu-exthdrlen); ++ return -EMSGSIZE; ++ } + +- err = ip6_ufo_append_data(sk, getfrag, from, length, +- hh_len, fragheaderlen, +- transhdrlen, mtu, flags, rt); +- if (err) +- goto error; +- return 0; +- } ++ skb = skb_peek_tail(&sk->sk_write_queue); ++ cork->length += length; ++ if (((length > mtu) || ++ (skb && skb_is_gso(skb))) && ++ (sk->sk_protocol == IPPROTO_UDP) && ++ (rt->dst.dev->features & NETIF_F_UFO)) { ++ err = ip6_ufo_append_data(sk, getfrag, from, length, ++ hh_len, fragheaderlen, ++ transhdrlen, mtu, flags, rt); ++ if (err) ++ goto error; ++ return 0; + } + +- if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) ++ if (!skb) + goto alloc_new_skb; + + while (length > 0) { diff --git a/queue-3.0/ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch b/queue-3.0/ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch new file mode 100644 index 00000000000..96743da44fd --- /dev/null +++ b/queue-3.0/ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch @@ -0,0 +1,42 @@ +From cba37df33067187efe2cd594bf9c75c98489462b Mon Sep 17 00:00:00 2001 +From: Ricardo Ribalda +Date: Tue, 1 Oct 2013 08:17:10 +0200 +Subject: ll_temac: Reset dma descriptors indexes on ndo_open + +From: Ricardo Ribalda + +[ Upstream commit 7167cf0e8cd10287b7912b9ffcccd9616f382922 ] + +The dma descriptors indexes are only initialized on the probe function. + +If a packet is on the buffer when temac_stop is called, the dma +descriptors indexes can be left on a incorrect state where no other +package can be sent. + +So an interface could be left in an usable state after ifdow/ifup. + +This patch makes sure that the descriptors indexes are in a proper +status when the device is open. + +Signed-off-by: Ricardo Ribalda Delgado +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ll_temac_main.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/ll_temac_main.c ++++ b/drivers/net/ll_temac_main.c +@@ -302,6 +302,12 @@ static int temac_dma_bd_init(struct net_ + lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1))); + lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p); + ++ /* Init descriptor indexes */ ++ lp->tx_bd_ci = 0; ++ lp->tx_bd_next = 0; ++ lp->tx_bd_tail = 0; ++ lp->rx_bd_ci = 0; ++ + return 0; + + out: diff --git a/queue-3.0/net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch b/queue-3.0/net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch new file mode 100644 index 00000000000..09897ec4bc2 --- /dev/null +++ b/queue-3.0/net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch @@ -0,0 +1,190 @@ +From 88cfed11ed0671996421e5847d11be216e956a4d Mon Sep 17 00:00:00 2001 +From: Daniel Borkmann +Date: Wed, 11 Sep 2013 16:58:36 +0200 +Subject: net: sctp: fix ipv6 ipsec encryption bug in sctp_v6_xmit + +From: Daniel Borkmann + +[ Upstream commit 95ee62083cb6453e056562d91f597552021e6ae7 ] + +Alan Chester reported an issue with IPv6 on SCTP that IPsec traffic is not +being encrypted, whereas on IPv4 it is. Setting up an AH + ESP transport +does not seem to have the desired effect: + +SCTP + IPv4: + + 22:14:20.809645 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 116) + 192.168.0.2 > 192.168.0.5: AH(spi=0x00000042,sumlen=16,seq=0x1): ESP(spi=0x00000044,seq=0x1), length 72 + 22:14:20.813270 IP (tos 0x2,ECT(0), ttl 64, id 0, offset 0, flags [DF], proto AH (51), length 340) + 192.168.0.5 > 192.168.0.2: AH(spi=0x00000043,sumlen=16,seq=0x1): + +SCTP + IPv6: + + 22:31:19.215029 IP6 (class 0x02, hlim 64, next-header SCTP (132) payload length: 364) + fe80::222:15ff:fe87:7fc.3333 > fe80::92e6:baff:fe0d:5a54.36767: sctp + 1) [INIT ACK] [init tag: 747759530] [rwnd: 62464] [OS: 10] [MIS: 10] + +Moreover, Alan says: + + This problem was seen with both Racoon and Racoon2. Other people have seen + this with OpenSwan. When IPsec is configured to encrypt all upper layer + protocols the SCTP connection does not initialize. After using Wireshark to + follow packets, this is because the SCTP packet leaves Box A unencrypted and + Box B believes all upper layer protocols are to be encrypted so it drops + this packet, causing the SCTP connection to fail to initialize. When IPsec + is configured to encrypt just SCTP, the SCTP packets are observed unencrypted. + +In fact, using `socat sctp6-listen:3333 -` on one end and transferring "plaintext" +string on the other end, results in cleartext on the wire where SCTP eventually +does not report any errors, thus in the latter case that Alan reports, the +non-paranoid user might think he's communicating over an encrypted transport on +SCTP although he's not (tcpdump ... -X): + + ... + 0x0030: 5d70 8e1a 0003 001a 177d eb6c 0000 0000 ]p.......}.l.... + 0x0040: 0000 0000 706c 6169 6e74 6578 740a 0000 ....plaintext... + +Only in /proc/net/xfrm_stat we can see XfrmInTmplMismatch increasing on the +receiver side. Initial follow-up analysis from Alan's bug report was done by +Alexey Dobriyan. Also thanks to Vlad Yasevich for feedback on this. + +SCTP has its own implementation of sctp_v6_xmit() not calling inet6_csk_xmit(). +This has the implication that it probably never really got updated along with +changes in inet6_csk_xmit() and therefore does not seem to invoke xfrm handlers. + +SCTP's IPv4 xmit however, properly calls ip_queue_xmit() to do the work. Since +a call to inet6_csk_xmit() would solve this problem, but result in unecessary +route lookups, let us just use the cached flowi6 instead that we got through +sctp_v6_get_dst(). Since all SCTP packets are being sent through sctp_packet_transmit(), +we do the route lookup / flow caching in sctp_transport_route(), hold it in +tp->dst and skb_dst_set() right after that. If we would alter fl6->daddr in +sctp_v6_xmit() to np->opt->srcrt, we possibly could run into the same effect +of not having xfrm layer pick it up, hence, use fl6_update_dst() in sctp_v6_get_dst() +instead to get the correct source routed dst entry, which we assign to the skb. + +Also source address routing example from 625034113 ("sctp: fix sctp to work with +ipv6 source address routing") still works with this patch! Nevertheless, in RFC5095 +it is actually 'recommended' to not use that anyway due to traffic amplification [1]. +So it seems we're not supposed to do that anyway in sctp_v6_xmit(). Moreover, if +we overwrite the flow destination here, the lower IPv6 layer will be unable to +put the correct destination address into IP header, as routing header is added in +ipv6_push_nfrag_opts() but then probably with wrong final destination. Things aside, +result of this patch is that we do not have any XfrmInTmplMismatch increase plus on +the wire with this patch it now looks like: + +SCTP + IPv6: + + 08:17:47.074080 IP6 2620:52:0:102f:7a2b:cbff:fe27:1b0a > 2620:52:0:102f:213:72ff:fe32:7eba: + AH(spi=0x00005fb4,seq=0x1): ESP(spi=0x00005fb5,seq=0x1), length 72 + 08:17:47.074264 IP6 2620:52:0:102f:213:72ff:fe32:7eba > 2620:52:0:102f:7a2b:cbff:fe27:1b0a: + AH(spi=0x00003d54,seq=0x1): ESP(spi=0x00003d55,seq=0x1), length 296 + +This fixes Kernel Bugzilla 24412. This security issue seems to be present since +2.6.18 kernels. Lets just hope some big passive adversary in the wild didn't have +its fun with that. lksctp-tools IPv6 regression test suite passes as well with +this patch. + + [1] http://www.secdev.org/conf/IPv6_RH_security-csw07.pdf + +Reported-by: Alan Chester +Reported-by: Alexey Dobriyan +Signed-off-by: Daniel Borkmann +Cc: Steffen Klassert +Cc: Hannes Frederic Sowa +Acked-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sctp/ipv6.c | 42 ++++++++++++------------------------------ + 1 file changed, 12 insertions(+), 30 deletions(-) + +--- a/net/sctp/ipv6.c ++++ b/net/sctp/ipv6.c +@@ -203,45 +203,22 @@ out: + in6_dev_put(idev); + } + +-/* Based on tcp_v6_xmit() in tcp_ipv6.c. */ + static int sctp_v6_xmit(struct sk_buff *skb, struct sctp_transport *transport) + { + struct sock *sk = skb->sk; + struct ipv6_pinfo *np = inet6_sk(sk); +- struct flowi6 fl6; +- +- memset(&fl6, 0, sizeof(fl6)); +- +- fl6.flowi6_proto = sk->sk_protocol; +- +- /* Fill in the dest address from the route entry passed with the skb +- * and the source address from the transport. +- */ +- ipv6_addr_copy(&fl6.daddr, &transport->ipaddr.v6.sin6_addr); +- ipv6_addr_copy(&fl6.saddr, &transport->saddr.v6.sin6_addr); +- +- fl6.flowlabel = np->flow_label; +- IP6_ECN_flow_xmit(sk, fl6.flowlabel); +- if (ipv6_addr_type(&fl6.saddr) & IPV6_ADDR_LINKLOCAL) +- fl6.flowi6_oif = transport->saddr.v6.sin6_scope_id; +- else +- fl6.flowi6_oif = sk->sk_bound_dev_if; +- +- if (np->opt && np->opt->srcrt) { +- struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt; +- ipv6_addr_copy(&fl6.daddr, rt0->addr); +- } ++ struct flowi6 *fl6 = &transport->fl.u.ip6; + + SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, src:%pI6 dst:%pI6\n", + __func__, skb, skb->len, +- &fl6.saddr, &fl6.daddr); +- +- SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); ++ &fl6->saddr, &fl6->daddr); + + if (!(transport->param_flags & SPP_PMTUD_ENABLE)) + skb->local_df = 1; + +- return ip6_xmit(sk, skb, &fl6, np->opt); ++ SCTP_INC_STATS(SCTP_MIB_OUTSCTPPACKS); ++ ++ return ip6_xmit(sk, skb, fl6, np->opt); + } + + /* Returns the dst cache entry for the given source and destination ip +@@ -254,10 +231,12 @@ static void sctp_v6_get_dst(struct sctp_ + struct dst_entry *dst = NULL; + struct flowi6 *fl6 = &fl->u.ip6; + struct sctp_bind_addr *bp; ++ struct ipv6_pinfo *np = inet6_sk(sk); + struct sctp_sockaddr_entry *laddr; + union sctp_addr *baddr = NULL; + union sctp_addr *daddr = &t->ipaddr; + union sctp_addr dst_saddr; ++ struct in6_addr *final_p, final; + __u8 matchlen = 0; + __u8 bmatchlen; + sctp_scope_t scope; +@@ -280,7 +259,8 @@ static void sctp_v6_get_dst(struct sctp_ + SCTP_DEBUG_PRINTK("SRC=%pI6 - ", &fl6->saddr); + } + +- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); ++ final_p = fl6_update_dst(fl6, np->opt, &final); ++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); + if (!asoc || saddr) + goto out; + +@@ -331,10 +311,12 @@ static void sctp_v6_get_dst(struct sctp_ + } + } + rcu_read_unlock(); ++ + if (baddr) { + ipv6_addr_copy(&fl6->saddr, &baddr->v6.sin6_addr); + fl6->fl6_sport = baddr->v6.sin6_port; +- dst = ip6_dst_lookup_flow(sk, fl6, NULL, false); ++ final_p = fl6_update_dst(fl6, np->opt, &final); ++ dst = ip6_dst_lookup_flow(sk, fl6, final_p, false); + } + + out: diff --git a/queue-3.0/netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch b/queue-3.0/netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch new file mode 100644 index 00000000000..05bc7bc03b3 --- /dev/null +++ b/queue-3.0/netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch @@ -0,0 +1,53 @@ +From 21618d5944e8aafc88ec583fa9294c1e85055215 Mon Sep 17 00:00:00 2001 +From: Nikolay Aleksandrov +Date: Thu, 19 Sep 2013 15:02:35 +0200 +Subject: netpoll: fix NULL pointer dereference in netpoll_cleanup + +From: Nikolay Aleksandrov + +[ Upstream commit d0fe8c888b1fd1a2f84b9962cabcb98a70988aec ] + +I've been hitting a NULL ptr deref while using netconsole because the +np->dev check and the pointer manipulation in netpoll_cleanup are done +without rtnl and the following sequence happens when having a netconsole +over a vlan and we remove the vlan while disabling the netconsole: + CPU 1 CPU2 + removes vlan and calls the notifier +enters store_enabled(), calls +netdev_cleanup which checks np->dev +and then waits for rtnl + executes the netconsole netdev + release notifier making np->dev + == NULL and releases rtnl +continues to dereference a member of +np->dev which at this point is == NULL + +Signed-off-by: Nikolay Aleksandrov +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/core/netpoll.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/net/core/netpoll.c ++++ b/net/core/netpoll.c +@@ -927,15 +927,14 @@ EXPORT_SYMBOL_GPL(__netpoll_cleanup); + + void netpoll_cleanup(struct netpoll *np) + { +- if (!np->dev) +- return; +- + rtnl_lock(); ++ if (!np->dev) ++ goto out; + __netpoll_cleanup(np); +- rtnl_unlock(); +- + dev_put(np->dev); + np->dev = NULL; ++out: ++ rtnl_unlock(); + } + EXPORT_SYMBOL(netpoll_cleanup); + diff --git a/queue-3.0/resubmit-bridge-fix-message_age_timer-calculation.patch b/queue-3.0/resubmit-bridge-fix-message_age_timer-calculation.patch new file mode 100644 index 00000000000..e16457d5072 --- /dev/null +++ b/queue-3.0/resubmit-bridge-fix-message_age_timer-calculation.patch @@ -0,0 +1,37 @@ +From 462ac987836889b18e3507835d37767b3edd95c6 Mon Sep 17 00:00:00 2001 +From: Chris Healy +Date: Wed, 11 Sep 2013 21:37:47 -0700 +Subject: resubmit bridge: fix message_age_timer calculation + +From: Chris Healy + +[ Upstream commit 9a0620133ccce9dd35c00a96405c8d80938c2cc0 ] + +This changes the message_age_timer calculation to use the BPDU's max age as +opposed to the local bridge's max age. This is in accordance with section +8.6.2.3.2 Step 2 of the 802.1D-1998 sprecification. + +With the current implementation, when running with very large bridge +diameters, convergance will not always occur even if a root bridge is +configured to have a longer max age. + +Tested successfully on bridge diameters of ~200. + +Signed-off-by: Chris Healy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_stp.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/bridge/br_stp.c ++++ b/net/bridge/br_stp.c +@@ -191,7 +191,7 @@ static inline void br_record_config_info + p->designated_age = jiffies + bpdu->message_age; + + mod_timer(&p->message_age_timer, jiffies +- + (p->br->max_age - bpdu->message_age)); ++ + (bpdu->max_age - bpdu->message_age)); + } + + /* called under bridge lock */ diff --git a/queue-3.0/series b/queue-3.0/series index 500af5e359c..35532481f5b 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -1,3 +1,16 @@ intel-iommu-fix-leaks-in-pagetable-freeing.patch cpqarray-fix-info-leak-in-ida_locked_ioctl.patch cciss-fix-info-leak-in-cciss_ioctl32_passthru.patch +caif-add-missing-braces-to-multiline-if-in-cfctrl_linkup_request.patch +netpoll-fix-null-pointer-dereference-in-netpoll_cleanup.patch +net-sctp-fix-ipv6-ipsec-encryption-bug-in-sctp_v6_xmit.patch +resubmit-bridge-fix-message_age_timer-calculation.patch +bridge-clamp-forward_delay-when-enabling-stp.patch +ip-generate-unique-ip-identificator-if-local-fragmentation-is-allowed.patch +ipv6-mcast-use-in6_dev_put-in-timer-handlers-instead-of-__in6_dev_put.patch +ipv4-igmp-use-in_dev_put-in-timer-handlers-instead-of-__in_dev_put.patch +ipv6-udp-packets-following-an-ufo-enqueued-packet-need-also-be-handled-by-ufo.patch +via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch +dm9601-fix-iff_allmulti-handling.patch +bonding-fix-broken-promiscuity-reference-counting-issue.patch +ll_temac-reset-dma-descriptors-indexes-on-ndo_open.patch diff --git a/queue-3.0/via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch b/queue-3.0/via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch new file mode 100644 index 00000000000..edc51ae2041 --- /dev/null +++ b/queue-3.0/via-rhine-fix-vlan-priority-field-pcp-ieee-802.1p.patch @@ -0,0 +1,48 @@ +From 25f925d9c35b8713eaa84d2f9f000569fc0c370d Mon Sep 17 00:00:00 2001 +From: Roger Luethi +Date: Sat, 21 Sep 2013 14:24:11 +0200 +Subject: via-rhine: fix VLAN priority field (PCP, IEEE 802.1p) + +From: Roger Luethi + +[ Upstream commit 207070f5221e2a901d56a49df9cde47d9b716cd7 ] + +Outgoing packets sent by via-rhine have their VLAN PCP field off by one +(when hardware acceleration is enabled). The TX descriptor expects only VID +and PCP (without a CFI/DEI bit). + +Peter Boström noticed and reported the bug. + +Signed-off-by: Roger Luethi +Cc: Peter Boström +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/via-rhine.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/net/via-rhine.c ++++ b/drivers/net/via-rhine.c +@@ -32,7 +32,7 @@ + #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + + #define DRV_NAME "via-rhine" +-#define DRV_VERSION "1.5.0" ++#define DRV_VERSION "1.5.1" + #define DRV_RELDATE "2010-10-09" + + +@@ -1518,7 +1518,12 @@ static netdev_tx_t rhine_start_tx(struct + cpu_to_le32(TXDESC | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN)); + + if (unlikely(vlan_tx_tag_present(skb))) { +- rp->tx_ring[entry].tx_status = cpu_to_le32((vlan_tx_tag_get(skb)) << 16); ++ u16 vid_pcp = vlan_tx_tag_get(skb); ++ ++ /* drop CFI/DEI bit, register needs VID and PCP */ ++ vid_pcp = (vid_pcp & VLAN_VID_MASK) | ++ ((vid_pcp & VLAN_PRIO_MASK) >> 1); ++ rp->tx_ring[entry].tx_status = cpu_to_le32((vid_pcp) << 16); + /* request tagging */ + rp->tx_ring[entry].desc_length |= cpu_to_le32(0x020000); + }