From: Greg Kroah-Hartman Date: Wed, 13 Jul 2016 22:39:07 +0000 (+0900) Subject: 4.6-stable patches X-Git-Tag: v4.6.5~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=23de047cfb0d43dd965a610edcc5eca545b0f736;p=thirdparty%2Fkernel%2Fstable-queue.git 4.6-stable patches added patches: cdc_ncm-workaround-for-em7455-silent-data-interface.patch geneve-fix-max_mtu-setting.patch ipv6-fix-mem-leak-in-rt6i_pcpu.patch macsec-set-actual-real-device-for-xmit-when-protect_frames.patch net_sched-fix-mirrored-packets-checksum.patch packet-use-symmetric-hash-for-packet_fanout_hash.patch --- diff --git a/queue-4.6/cdc_ncm-workaround-for-em7455-silent-data-interface.patch b/queue-4.6/cdc_ncm-workaround-for-em7455-silent-data-interface.patch new file mode 100644 index 00000000000..fab63e3c991 --- /dev/null +++ b/queue-4.6/cdc_ncm-workaround-for-em7455-silent-data-interface.patch @@ -0,0 +1,57 @@ +From foo@baz Thu Jul 14 07:36:41 JST 2016 +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= +Date: Sun, 3 Jul 2016 22:24:50 +0200 +Subject: cdc_ncm: workaround for EM7455 "silent" data interface +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: =?UTF-8?q?Bj=C3=B8rn=20Mork?= + +[ Upstream commit c086e7096170390594c425114d98172bc9aceb8a ] + +Several Lenovo users have reported problems with their Sierra +Wireless EM7455 modem. The driver has loaded successfully and +the MBIM management channel has appeared to work, including +establishing a connection to the mobile network. But no frames +have been received over the data interface. + +The problem affects all EM7455 and MC7455, and is assumed to +affect other modems based on the same Qualcomm chipset and +baseband firmware. + +Testing narrowed the problem down to what seems to be a +firmware timing bug during initialization. Adding a short sleep +while probing is sufficient to make the problem disappear. +Experiments have shown that 1-2 ms is too little to have any +effect, while 10-20 ms is enough to reliably succeed. + +Reported-by: Stefan Armbruster +Reported-by: Ralph Plawetzki +Reported-by: Andreas Fett +Reported-by: Rasmus Lerdorf +Reported-by: Samo Ratnik +Reported-and-tested-by: Aleksander Morgado +Signed-off-by: Bjørn Mork +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/usb/cdc_ncm.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/drivers/net/usb/cdc_ncm.c ++++ b/drivers/net/usb/cdc_ncm.c +@@ -852,6 +852,13 @@ int cdc_ncm_bind_common(struct usbnet *d + if (cdc_ncm_init(dev)) + goto error2; + ++ /* Some firmwares need a pause here or they will silently fail ++ * to set up the interface properly. This value was decided ++ * empirically on a Sierra Wireless MC7455 running 02.08.02.00 ++ * firmware. ++ */ ++ usleep_range(10000, 20000); ++ + /* configure data interface */ + temp = usb_set_interface(dev->udev, iface_no, data_altsetting); + if (temp) { diff --git a/queue-4.6/geneve-fix-max_mtu-setting.patch b/queue-4.6/geneve-fix-max_mtu-setting.patch new file mode 100644 index 00000000000..4022d6d26f5 --- /dev/null +++ b/queue-4.6/geneve-fix-max_mtu-setting.patch @@ -0,0 +1,41 @@ +From foo@baz Thu Jul 14 07:36:41 JST 2016 +From: Haishuang Yan +Date: Sat, 2 Jul 2016 15:02:48 +0800 +Subject: geneve: fix max_mtu setting + +From: Haishuang Yan + +[ Upstream commit d5d5e8d55732c7c35c354e45e3b0af2795978a57 ] + +For ipv6+udp+geneve encapsulation data, the max_mtu should subtract +sizeof(ipv6hdr), instead of sizeof(iphdr). + +Signed-off-by: Haishuang Yan +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/geneve.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/drivers/net/geneve.c ++++ b/drivers/net/geneve.c +@@ -1092,12 +1092,17 @@ static netdev_tx_t geneve_xmit(struct sk + + static int __geneve_change_mtu(struct net_device *dev, int new_mtu, bool strict) + { ++ struct geneve_dev *geneve = netdev_priv(dev); + /* The max_mtu calculation does not take account of GENEVE + * options, to avoid excluding potentially valid + * configurations. + */ +- int max_mtu = IP_MAX_MTU - GENEVE_BASE_HLEN - sizeof(struct iphdr) +- - dev->hard_header_len; ++ int max_mtu = IP_MAX_MTU - GENEVE_BASE_HLEN - dev->hard_header_len; ++ ++ if (geneve->remote.sa.sa_family == AF_INET6) ++ max_mtu -= sizeof(struct ipv6hdr); ++ else ++ max_mtu -= sizeof(struct iphdr); + + if (new_mtu < 68) + return -EINVAL; diff --git a/queue-4.6/ipv6-fix-mem-leak-in-rt6i_pcpu.patch b/queue-4.6/ipv6-fix-mem-leak-in-rt6i_pcpu.patch new file mode 100644 index 00000000000..09386578535 --- /dev/null +++ b/queue-4.6/ipv6-fix-mem-leak-in-rt6i_pcpu.patch @@ -0,0 +1,47 @@ +From foo@baz Thu Jul 14 07:36:41 JST 2016 +From: Martin KaFai Lau +Date: Tue, 5 Jul 2016 12:10:23 -0700 +Subject: ipv6: Fix mem leak in rt6i_pcpu + +From: Martin KaFai Lau + +[ Upstream commit 903ce4abdf374e3365d93bcb3df56c62008835ba ] + +It was first reported and reproduced by Petr (thanks!) in +https://bugzilla.kernel.org/show_bug.cgi?id=119581 + +free_percpu(rt->rt6i_pcpu) used to always happen in ip6_dst_destroy(). + +However, after fixing a deadlock bug in +commit 9c7370a166b4 ("ipv6: Fix a potential deadlock when creating pcpu rt"), +free_percpu() is not called before setting non_pcpu_rt->rt6i_pcpu to NULL. + +It is worth to note that rt6i_pcpu is protected by table->tb6_lock. + +kmemleak somehow did not report it. We nailed it down by +observing the pcpu entries in /proc/vmallocinfo (first suggested +by Hannes, thanks!). + +Signed-off-by: Martin KaFai Lau +Fixes: 9c7370a166b4 ("ipv6: Fix a potential deadlock when creating pcpu rt") +Reported-by: Petr Novopashenniy +Tested-by: Petr Novopashenniy +Acked-by: Hannes Frederic Sowa +Cc: Hannes Frederic Sowa +Cc: Petr Novopashenniy +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_fib.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -177,6 +177,7 @@ static void rt6_free_pcpu(struct rt6_inf + } + } + ++ free_percpu(non_pcpu_rt->rt6i_pcpu); + non_pcpu_rt->rt6i_pcpu = NULL; + } + diff --git a/queue-4.6/macsec-set-actual-real-device-for-xmit-when-protect_frames.patch b/queue-4.6/macsec-set-actual-real-device-for-xmit-when-protect_frames.patch new file mode 100644 index 00000000000..12440dc50de --- /dev/null +++ b/queue-4.6/macsec-set-actual-real-device-for-xmit-when-protect_frames.patch @@ -0,0 +1,34 @@ +From foo@baz Thu Jul 14 07:36:41 JST 2016 +From: Daniel Borkmann +Date: Fri, 1 Jul 2016 00:00:54 +0200 +Subject: macsec: set actual real device for xmit when !protect_frames + +From: Daniel Borkmann + +[ Upstream commit 79c62220d74a4a3f961a2cb7320da09eebf5daf7 ] + +Avoid recursions of dev_queue_xmit() to the wrong net device when +frames are unprotected, since at that time skb->dev still points to +our own macsec dev and unlike macsec_encrypt_finish() dev pointer +doesn't get updated to real underlying device. + +Fixes: c09440f7dcb3 ("macsec: introduce IEEE 802.1AE driver") +Signed-off-by: Daniel Borkmann +Acked-by: Sabrina Dubroca +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/macsec.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/macsec.c ++++ b/drivers/net/macsec.c +@@ -2564,6 +2564,7 @@ static netdev_tx_t macsec_start_xmit(str + u64_stats_update_begin(&secy_stats->syncp); + secy_stats->stats.OutPktsUntagged++; + u64_stats_update_end(&secy_stats->syncp); ++ skb->dev = macsec->real_dev; + len = skb->len; + ret = dev_queue_xmit(skb); + count_tx(dev, ret, len); diff --git a/queue-4.6/net_sched-fix-mirrored-packets-checksum.patch b/queue-4.6/net_sched-fix-mirrored-packets-checksum.patch new file mode 100644 index 00000000000..01e75e89971 --- /dev/null +++ b/queue-4.6/net_sched-fix-mirrored-packets-checksum.patch @@ -0,0 +1,91 @@ +From foo@baz Thu Jul 14 07:36:41 JST 2016 +From: WANG Cong +Date: Thu, 30 Jun 2016 10:15:22 -0700 +Subject: net_sched: fix mirrored packets checksum + +From: WANG Cong + +[ Upstream commit 82a31b9231f02d9c1b7b290a46999d517b0d312a ] + +Similar to commit 9b368814b336 ("net: fix bridge multicast packet checksum validation") +we need to fixup the checksum for CHECKSUM_COMPLETE when +pushing skb on RX path. Otherwise we get similar splats. + +Cc: Jamal Hadi Salim +Cc: Tom Herbert +Signed-off-by: Cong Wang +Acked-by: Jamal Hadi Salim +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/skbuff.h | 19 +++++++++++++++++++ + net/core/skbuff.c | 18 ------------------ + net/sched/act_mirred.c | 2 +- + 3 files changed, 20 insertions(+), 19 deletions(-) + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2861,6 +2861,25 @@ static inline void skb_postpush_rcsum(st + } + + /** ++ * skb_push_rcsum - push skb and update receive checksum ++ * @skb: buffer to update ++ * @len: length of data pulled ++ * ++ * This function performs an skb_push on the packet and updates ++ * the CHECKSUM_COMPLETE checksum. It should be used on ++ * receive path processing instead of skb_push unless you know ++ * that the checksum difference is zero (e.g., a valid IP header) ++ * or you are setting ip_summed to CHECKSUM_NONE. ++ */ ++static inline unsigned char *skb_push_rcsum(struct sk_buff *skb, ++ unsigned int len) ++{ ++ skb_push(skb, len); ++ skb_postpush_rcsum(skb, skb->data, len); ++ return skb->data; ++} ++ ++/** + * pskb_trim_rcsum - trim received skb and update checksum + * @skb: buffer to trim + * @len: new length +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -3016,24 +3016,6 @@ int skb_append_pagefrags(struct sk_buff + EXPORT_SYMBOL_GPL(skb_append_pagefrags); + + /** +- * skb_push_rcsum - push skb and update receive checksum +- * @skb: buffer to update +- * @len: length of data pulled +- * +- * This function performs an skb_push on the packet and updates +- * the CHECKSUM_COMPLETE checksum. It should be used on +- * receive path processing instead of skb_push unless you know +- * that the checksum difference is zero (e.g., a valid IP header) +- * or you are setting ip_summed to CHECKSUM_NONE. +- */ +-static unsigned char *skb_push_rcsum(struct sk_buff *skb, unsigned len) +-{ +- skb_push(skb, len); +- skb_postpush_rcsum(skb, skb->data, len); +- return skb->data; +-} +- +-/** + * skb_pull_rcsum - pull skb and update receive checksum + * @skb: buffer to update + * @len: length of data pulled +--- a/net/sched/act_mirred.c ++++ b/net/sched/act_mirred.c +@@ -180,7 +180,7 @@ static int tcf_mirred(struct sk_buff *sk + + if (!(at & AT_EGRESS)) { + if (m->tcfm_ok_push) +- skb_push(skb2, skb->mac_len); ++ skb_push_rcsum(skb2, skb->mac_len); + } + + /* mirror is always swallowed */ diff --git a/queue-4.6/packet-use-symmetric-hash-for-packet_fanout_hash.patch b/queue-4.6/packet-use-symmetric-hash-for-packet_fanout_hash.patch new file mode 100644 index 00000000000..56cff569f5f --- /dev/null +++ b/queue-4.6/packet-use-symmetric-hash-for-packet_fanout_hash.patch @@ -0,0 +1,122 @@ +From foo@baz Thu Jul 14 07:36:41 JST 2016 +From: "David S. Miller" +Date: Fri, 1 Jul 2016 16:07:50 -0400 +Subject: packet: Use symmetric hash for PACKET_FANOUT_HASH. + +From: "David S. Miller" + +[ Upstream commit eb70db8756717b90c01ccc765fdefc4dd969fc74 ] + +People who use PACKET_FANOUT_HASH want a symmetric hash, meaning that +they want packets going in both directions on a flow to hash to the +same bucket. + +The core kernel SKB hash became non-symmetric when the ipv6 flow label +and other entities were incorporated into the standard flow hash order +to increase entropy. + +But there are no users of PACKET_FANOUT_HASH who want an assymetric +hash, they all want a symmetric one. + +Therefore, use the flow dissector to compute a flat symmetric hash +over only the protocol, addresses and ports. This hash does not get +installed into and override the normal skb hash, so this change has +no effect whatsoever on the rest of the stack. + +Reported-by: Eric Leblond +Tested-by: Eric Leblond +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/skbuff.h | 1 + + net/core/flow_dissector.c | 43 +++++++++++++++++++++++++++++++++++++++++++ + net/packet/af_packet.c | 2 +- + 3 files changed, 45 insertions(+), 1 deletion(-) + +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -1062,6 +1062,7 @@ __skb_set_sw_hash(struct sk_buff *skb, _ + } + + void __skb_get_hash(struct sk_buff *skb); ++u32 __skb_get_hash_symmetric(struct sk_buff *skb); + u32 skb_get_poff(const struct sk_buff *skb); + u32 __skb_get_poff(const struct sk_buff *skb, void *data, + const struct flow_keys *keys, int hlen); +--- a/net/core/flow_dissector.c ++++ b/net/core/flow_dissector.c +@@ -651,6 +651,23 @@ void make_flow_keys_digest(struct flow_k + } + EXPORT_SYMBOL(make_flow_keys_digest); + ++static struct flow_dissector flow_keys_dissector_symmetric __read_mostly; ++ ++u32 __skb_get_hash_symmetric(struct sk_buff *skb) ++{ ++ struct flow_keys keys; ++ ++ __flow_hash_secret_init(); ++ ++ memset(&keys, 0, sizeof(keys)); ++ __skb_flow_dissect(skb, &flow_keys_dissector_symmetric, &keys, ++ NULL, 0, 0, 0, ++ FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL); ++ ++ return __flow_hash_from_keys(&keys, hashrnd); ++} ++EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric); ++ + /** + * __skb_get_hash: calculate a flow hash + * @skb: sk_buff to calculate flow hash from +@@ -868,6 +885,29 @@ static const struct flow_dissector_key f + }, + }; + ++static const struct flow_dissector_key flow_keys_dissector_symmetric_keys[] = { ++ { ++ .key_id = FLOW_DISSECTOR_KEY_CONTROL, ++ .offset = offsetof(struct flow_keys, control), ++ }, ++ { ++ .key_id = FLOW_DISSECTOR_KEY_BASIC, ++ .offset = offsetof(struct flow_keys, basic), ++ }, ++ { ++ .key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS, ++ .offset = offsetof(struct flow_keys, addrs.v4addrs), ++ }, ++ { ++ .key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS, ++ .offset = offsetof(struct flow_keys, addrs.v6addrs), ++ }, ++ { ++ .key_id = FLOW_DISSECTOR_KEY_PORTS, ++ .offset = offsetof(struct flow_keys, ports), ++ }, ++}; ++ + static const struct flow_dissector_key flow_keys_buf_dissector_keys[] = { + { + .key_id = FLOW_DISSECTOR_KEY_CONTROL, +@@ -889,6 +929,9 @@ static int __init init_default_flow_diss + skb_flow_dissector_init(&flow_keys_dissector, + flow_keys_dissector_keys, + ARRAY_SIZE(flow_keys_dissector_keys)); ++ skb_flow_dissector_init(&flow_keys_dissector_symmetric, ++ flow_keys_dissector_symmetric_keys, ++ ARRAY_SIZE(flow_keys_dissector_symmetric_keys)); + skb_flow_dissector_init(&flow_keys_buf_dissector, + flow_keys_buf_dissector_keys, + ARRAY_SIZE(flow_keys_buf_dissector_keys)); +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -1340,7 +1340,7 @@ static unsigned int fanout_demux_hash(st + struct sk_buff *skb, + unsigned int num) + { +- return reciprocal_scale(skb_get_hash(skb), num); ++ return reciprocal_scale(__skb_get_hash_symmetric(skb), num); + } + + static unsigned int fanout_demux_lb(struct packet_fanout *f, diff --git a/queue-4.6/series b/queue-4.6/series index 6c646b3d828..620fc473c96 100644 --- a/queue-4.6/series +++ b/queue-4.6/series @@ -67,3 +67,9 @@ irqchip-mips-gic-fix-irqs-in-gic_dev_domain.patch mm-export-migrate_page_move_mapping-and-migrate_page_copy.patch ubifs-implement-migratepage.patch sched-fair-fix-cfs_rq-avg-tracking-underflow.patch +packet-use-symmetric-hash-for-packet_fanout_hash.patch +net_sched-fix-mirrored-packets-checksum.patch +macsec-set-actual-real-device-for-xmit-when-protect_frames.patch +geneve-fix-max_mtu-setting.patch +cdc_ncm-workaround-for-em7455-silent-data-interface.patch +ipv6-fix-mem-leak-in-rt6i_pcpu.patch