From 087349ee051ebdc2ec17e02475369783a7cdfdbc Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sun, 12 Oct 2014 16:38:20 +0200 Subject: [PATCH] 3.10-stable patches added patches: hyperv-fix-a-bug-in-netvsc_start_xmit.patch ip6_gre-fix-flowi6_proto-value-in-xmit-path.patch ipv6-reallocate-addrconf-router-for-ipv6-address-when-lo-device-up.patch l2tp-fix-race-while-getting-pmtu-on-ppp-pseudo-wire.patch myri10ge-check-for-dma-mapping-errors.patch openvswitch-fix-panic-with-multiple-vlan-headers.patch packet-handle-too-big-packets-for-packet_v3.patch sctp-handle-association-restarts-when-the-socket-is-closed.patch sit-fix-ipip6_tunnel_lookup-device-matching-criteria.patch tcp-fix-tcp_release_cb-to-dispatch-via-address-family-for-mtu_reduced.patch tcp-fixing-tlp-s-fin-recovery.patch tg3-allow-for-recieve-of-full-size-8021ad-frames.patch tg3-work-around-hw-fw-limitations-with-vlan-encapsulated-frames.patch --- ...yperv-fix-a-bug-in-netvsc_start_xmit.patch | 44 +++++ ...-fix-flowi6_proto-value-in-xmit-path.patch | 42 +++++ ...r-for-ipv6-address-when-lo-device-up.patch | 62 +++++++ ...hile-getting-pmtu-on-ppp-pseudo-wire.patch | 76 ++++++++ ...yri10ge-check-for-dma-mapping-errors.patch | 175 ++++++++++++++++++ ...fix-panic-with-multiple-vlan-headers.patch | 55 ++++++ ...handle-too-big-packets-for-packet_v3.patch | 83 +++++++++ ...n-restarts-when-the-socket-is-closed.patch | 79 ++++++++ queue-3.10/series | 13 ++ ...nnel_lookup-device-matching-criteria.patch | 55 ++++++ ...h-via-address-family-for-mtu_reduced.patch | 134 ++++++++++++++ .../tcp-fixing-tlp-s-fin-recovery.patch | 37 ++++ ...r-recieve-of-full-size-8021ad-frames.patch | 41 ++++ ...ations-with-vlan-encapsulated-frames.patch | 68 +++++++ 14 files changed, 964 insertions(+) create mode 100644 queue-3.10/hyperv-fix-a-bug-in-netvsc_start_xmit.patch create mode 100644 queue-3.10/ip6_gre-fix-flowi6_proto-value-in-xmit-path.patch create mode 100644 queue-3.10/ipv6-reallocate-addrconf-router-for-ipv6-address-when-lo-device-up.patch create mode 100644 queue-3.10/l2tp-fix-race-while-getting-pmtu-on-ppp-pseudo-wire.patch create mode 100644 queue-3.10/myri10ge-check-for-dma-mapping-errors.patch create mode 100644 queue-3.10/openvswitch-fix-panic-with-multiple-vlan-headers.patch create mode 100644 queue-3.10/packet-handle-too-big-packets-for-packet_v3.patch create mode 100644 queue-3.10/sctp-handle-association-restarts-when-the-socket-is-closed.patch create mode 100644 queue-3.10/series create mode 100644 queue-3.10/sit-fix-ipip6_tunnel_lookup-device-matching-criteria.patch create mode 100644 queue-3.10/tcp-fix-tcp_release_cb-to-dispatch-via-address-family-for-mtu_reduced.patch create mode 100644 queue-3.10/tcp-fixing-tlp-s-fin-recovery.patch create mode 100644 queue-3.10/tg3-allow-for-recieve-of-full-size-8021ad-frames.patch create mode 100644 queue-3.10/tg3-work-around-hw-fw-limitations-with-vlan-encapsulated-frames.patch diff --git a/queue-3.10/hyperv-fix-a-bug-in-netvsc_start_xmit.patch b/queue-3.10/hyperv-fix-a-bug-in-netvsc_start_xmit.patch new file mode 100644 index 00000000000..32291cb45d1 --- /dev/null +++ b/queue-3.10/hyperv-fix-a-bug-in-netvsc_start_xmit.patch @@ -0,0 +1,44 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: KY Srinivasan +Date: Sun, 28 Sep 2014 22:16:43 -0700 +Subject: hyperv: Fix a bug in netvsc_start_xmit() + +From: KY Srinivasan + +[ Upstream commit dedb845ded56ded1c62f5398a94ffa8615d4592d ] + +After the packet is successfully sent, we should not touch the skb +as it may have been freed. This patch is based on the work done by +Long Li . + +In this version of the patch I have fixed issues pointed out by David. +David, please queue this up for stable. + +Signed-off-by: K. Y. Srinivasan +Tested-by: Long Li +Tested-by: Sitsofe Wheeler +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/hyperv/netvsc_drv.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/hyperv/netvsc_drv.c ++++ b/drivers/net/hyperv/netvsc_drv.c +@@ -138,6 +138,7 @@ static int netvsc_start_xmit(struct sk_b + struct hv_netvsc_packet *packet; + int ret; + unsigned int i, num_pages, npg_data; ++ u32 skb_length = skb->len; + + /* Add multipages for skb->data and additional 2 for RNDIS */ + npg_data = (((unsigned long)skb->data + skb_headlen(skb) - 1) +@@ -208,7 +209,7 @@ static int netvsc_start_xmit(struct sk_b + ret = rndis_filter_send(net_device_ctx->device_ctx, + packet); + if (ret == 0) { +- net->stats.tx_bytes += skb->len; ++ net->stats.tx_bytes += skb_length; + net->stats.tx_packets++; + } else { + kfree(packet); diff --git a/queue-3.10/ip6_gre-fix-flowi6_proto-value-in-xmit-path.patch b/queue-3.10/ip6_gre-fix-flowi6_proto-value-in-xmit-path.patch new file mode 100644 index 00000000000..56098efb7e6 --- /dev/null +++ b/queue-3.10/ip6_gre-fix-flowi6_proto-value-in-xmit-path.patch @@ -0,0 +1,42 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Nicolas Dichtel +Date: Thu, 2 Oct 2014 18:26:49 +0200 +Subject: ip6_gre: fix flowi6_proto value in xmit path + +From: Nicolas Dichtel + +[ Upstream commit 3be07244b7337760a3269d56b2f4a63e72218648 ] + +In xmit path, we build a flowi6 which will be used for the output route lookup. +We are sending a GRE packet, neither IPv4 nor IPv6 encapsulated packet, thus the +protocol should be IPPROTO_GRE. + +Fixes: c12b395a4664 ("gre: Support GRE over IPv6") +Reported-by: Matthieu Ternisien d'Ouville +Signed-off-by: Nicolas Dichtel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/ip6_gre.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/ipv6/ip6_gre.c ++++ b/net/ipv6/ip6_gre.c +@@ -787,7 +787,7 @@ static inline int ip6gre_xmit_ipv4(struc + encap_limit = t->parms.encap_limit; + + memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); +- fl6.flowi6_proto = IPPROTO_IPIP; ++ fl6.flowi6_proto = IPPROTO_GRE; + + dsfield = ipv4_get_dsfield(iph); + +@@ -837,7 +837,7 @@ static inline int ip6gre_xmit_ipv6(struc + encap_limit = t->parms.encap_limit; + + memcpy(&fl6, &t->fl.u.ip6, sizeof(fl6)); +- fl6.flowi6_proto = IPPROTO_IPV6; ++ fl6.flowi6_proto = IPPROTO_GRE; + + dsfield = ipv6_get_dsfield(ipv6h); + if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS) diff --git a/queue-3.10/ipv6-reallocate-addrconf-router-for-ipv6-address-when-lo-device-up.patch b/queue-3.10/ipv6-reallocate-addrconf-router-for-ipv6-address-when-lo-device-up.patch new file mode 100644 index 00000000000..cef5d1f9487 --- /dev/null +++ b/queue-3.10/ipv6-reallocate-addrconf-router-for-ipv6-address-when-lo-device-up.patch @@ -0,0 +1,62 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Gao feng +Date: Fri, 24 Jan 2014 16:29:11 +0800 +Subject: ipv6: reallocate addrconf router for ipv6 address when lo device up + +From: Gao feng + +[ Upstream commit 33d99113b1102c2d2f8603b9ba72d89d915c13f5 ] + +commit 25fb6ca4ed9cad72f14f61629b68dc03c0d9713f +"net IPv6 : Fix broken IPv6 routing table after loopback down-up" +allocates addrconf router for ipv6 address when lo device up. +but commit a881ae1f625c599b460cc8f8a7fcb1c438f699ad +"ipv6:don't call addrconf_dst_alloc again when enable lo" breaks +this behavior. + +Since the addrconf router is moved to the garbage list when +lo device down, we should release this router and rellocate +a new one for ipv6 address when lo device up. + +This patch solves bug 67951 on bugzilla +https://bugzilla.kernel.org/show_bug.cgi?id=67951 + +change from v1: +use ip6_rt_put to repleace ip6_del_rt, thanks Hannes! +change code style, suggested by Sergei. + +CC: Sabrina Dubroca +CC: Hannes Frederic Sowa +Reported-by: Weilong Chen +Signed-off-by: Weilong Chen +Signed-off-by: Gao feng +Acked-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/addrconf.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -2691,8 +2691,18 @@ static void init_loopback(struct net_dev + if (sp_ifa->flags & (IFA_F_DADFAILED | IFA_F_TENTATIVE)) + continue; + +- if (sp_ifa->rt) +- continue; ++ if (sp_ifa->rt) { ++ /* This dst has been added to garbage list when ++ * lo device down, release this obsolete dst and ++ * reallocate a new router for ifa. ++ */ ++ if (sp_ifa->rt->dst.obsolete > 0) { ++ ip6_rt_put(sp_ifa->rt); ++ sp_ifa->rt = NULL; ++ } else { ++ continue; ++ } ++ } + + sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); + diff --git a/queue-3.10/l2tp-fix-race-while-getting-pmtu-on-ppp-pseudo-wire.patch b/queue-3.10/l2tp-fix-race-while-getting-pmtu-on-ppp-pseudo-wire.patch new file mode 100644 index 00000000000..84ef5913736 --- /dev/null +++ b/queue-3.10/l2tp-fix-race-while-getting-pmtu-on-ppp-pseudo-wire.patch @@ -0,0 +1,76 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Guillaume Nault +Date: Wed, 3 Sep 2014 14:12:55 +0200 +Subject: l2tp: fix race while getting PMTU on PPP pseudo-wire + +From: Guillaume Nault + +[ Upstream commit eed4d839b0cdf9d84b0a9bc63de90fd5e1e886fb ] + +Use dst_entry held by sk_dst_get() to retrieve tunnel's PMTU. + +The dst_mtu(__sk_dst_get(tunnel->sock)) call was racy. __sk_dst_get() +could return NULL if tunnel->sock->sk_dst_cache was reset just before the +call, thus making dst_mtu() dereference a NULL pointer: + +[ 1937.661598] BUG: unable to handle kernel NULL pointer dereference at 0000000000000020 +[ 1937.664005] IP: [] pppol2tp_connect+0x33d/0x41e [l2tp_ppp] +[ 1937.664005] PGD daf0c067 PUD d9f93067 PMD 0 +[ 1937.664005] Oops: 0000 [#1] SMP +[ 1937.664005] Modules linked in: l2tp_ppp l2tp_netlink l2tp_core ip6table_filter ip6_tables iptable_filter ip_tables ebtable_nat ebtables x_tables udp_tunnel pppoe pppox ppp_generic slhc deflate ctr twofish_generic twofish_x86_64_3way xts lrw gf128mul glue_helper twofish_x86_64 twofish_common blowfish_generic blowfish_x86_64 blowfish_common des_generic cbc xcbc rmd160 sha512_generic hmac crypto_null af_key xfrm_algo 8021q garp bridge stp llc tun atmtcp clip atm ext3 mbcache jbd iTCO_wdt coretemp kvm_intel iTCO_vendor_support kvm pcspkr evdev ehci_pci lpc_ich mfd_core i5400_edac edac_core i5k_amb shpchp button processor thermal_sys xfs crc32c_generic libcrc32c dm_mod usbhid sg hid sr_mod sd_mod cdrom crc_t10dif crct10dif_common ata_generic ahci ata_piix tg3 libahci libata uhci_hcd ptp ehci_hcd pps_core usbcore scsi_mod libphy usb_common [last unloaded: l2tp_core] +[ 1937.664005] CPU: 0 PID: 10022 Comm: l2tpstress Tainted: G O 3.17.0-rc1 #1 +[ 1937.664005] Hardware name: HP ProLiant DL160 G5, BIOS O12 08/22/2008 +[ 1937.664005] task: ffff8800d8fda790 ti: ffff8800c43c4000 task.ti: ffff8800c43c4000 +[ 1937.664005] RIP: 0010:[] [] pppol2tp_connect+0x33d/0x41e [l2tp_ppp] +[ 1937.664005] RSP: 0018:ffff8800c43c7de8 EFLAGS: 00010282 +[ 1937.664005] RAX: ffff8800da8a7240 RBX: ffff8800d8c64600 RCX: 000001c325a137b5 +[ 1937.664005] RDX: 8c6318c6318c6320 RSI: 000000000000010c RDI: 0000000000000000 +[ 1937.664005] RBP: ffff8800c43c7ea8 R08: 0000000000000000 R09: 0000000000000000 +[ 1937.664005] R10: ffffffffa048e2c0 R11: ffff8800d8c64600 R12: ffff8800ca7a5000 +[ 1937.664005] R13: ffff8800c439bf40 R14: 000000000000000c R15: 0000000000000009 +[ 1937.664005] FS: 00007fd7f610f700(0000) GS:ffff88011a600000(0000) knlGS:0000000000000000 +[ 1937.664005] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b +[ 1937.664005] CR2: 0000000000000020 CR3: 00000000d9d75000 CR4: 00000000000027e0 +[ 1937.664005] Stack: +[ 1937.664005] ffffffffa049da80 ffff8800d8fda790 000000000000005b ffff880000000009 +[ 1937.664005] ffff8800daf3f200 0000000000000003 ffff8800c43c7e48 ffffffff81109b57 +[ 1937.664005] ffffffff81109b0e ffffffff8114c566 0000000000000000 0000000000000000 +[ 1937.664005] Call Trace: +[ 1937.664005] [] ? pppol2tp_connect+0x235/0x41e [l2tp_ppp] +[ 1937.664005] [] ? might_fault+0x9e/0xa5 +[ 1937.664005] [] ? might_fault+0x55/0xa5 +[ 1937.664005] [] ? rcu_read_unlock+0x1c/0x26 +[ 1937.664005] [] SYSC_connect+0x87/0xb1 +[ 1937.664005] [] ? sysret_check+0x1b/0x56 +[ 1937.664005] [] ? trace_hardirqs_on_caller+0x145/0x1a1 +[ 1937.664005] [] ? trace_hardirqs_on_thunk+0x3a/0x3f +[ 1937.664005] [] ? spin_lock+0x9/0xb +[ 1937.664005] [] SyS_connect+0x9/0xb +[ 1937.664005] [] system_call_fastpath+0x16/0x1b +[ 1937.664005] Code: 10 2a 84 81 e8 65 76 bd e0 65 ff 0c 25 10 bb 00 00 4d 85 ed 74 37 48 8b 85 60 ff ff ff 48 8b 80 88 01 00 00 48 8b b8 10 02 00 00 <48> 8b 47 20 ff 50 20 85 c0 74 0f 83 e8 28 89 83 10 01 00 00 89 +[ 1937.664005] RIP [] pppol2tp_connect+0x33d/0x41e [l2tp_ppp] +[ 1937.664005] RSP +[ 1937.664005] CR2: 0000000000000020 +[ 1939.559375] ---[ end trace 82d44500f28f8708 ]--- + +Fixes: f34c4a35d879 ("l2tp: take PMTU from tunnel UDP socket") +Signed-off-by: Guillaume Nault +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/l2tp/l2tp_ppp.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/net/l2tp/l2tp_ppp.c ++++ b/net/l2tp/l2tp_ppp.c +@@ -756,7 +756,8 @@ static int pppol2tp_connect(struct socke + /* If PMTU discovery was enabled, use the MTU that was discovered */ + dst = sk_dst_get(tunnel->sock); + if (dst != NULL) { +- u32 pmtu = dst_mtu(__sk_dst_get(tunnel->sock)); ++ u32 pmtu = dst_mtu(dst); ++ + if (pmtu != 0) + session->mtu = session->mru = pmtu - + PPPOL2TP_HEADER_OVERHEAD; diff --git a/queue-3.10/myri10ge-check-for-dma-mapping-errors.patch b/queue-3.10/myri10ge-check-for-dma-mapping-errors.patch new file mode 100644 index 00000000000..4ba5999de01 --- /dev/null +++ b/queue-3.10/myri10ge-check-for-dma-mapping-errors.patch @@ -0,0 +1,175 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Stanislaw Gruszka +Date: Tue, 12 Aug 2014 10:35:19 +0200 +Subject: myri10ge: check for DMA mapping errors + +From: Stanislaw Gruszka + +[ Upstream commit 10545937e866ccdbb7ab583031dbdcc6b14e4eb4 ] + +On IOMMU systems DMA mapping can fail, we need to check for +that possibility. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 88 +++++++++++++++-------- + 1 file changed, 58 insertions(+), 30 deletions(-) + +--- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c ++++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +@@ -856,6 +856,10 @@ static int myri10ge_dma_test(struct myri + return -ENOMEM; + dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE, + DMA_BIDIRECTIONAL); ++ if (unlikely(pci_dma_mapping_error(mgp->pdev, dmatest_bus))) { ++ __free_page(dmatest_page); ++ return -ENOMEM; ++ } + + /* Run a small DMA test. + * The magic multipliers to the length tell the firmware +@@ -1191,6 +1195,7 @@ myri10ge_alloc_rx_pages(struct myri10ge_ + int bytes, int watchdog) + { + struct page *page; ++ dma_addr_t bus; + int idx; + #if MYRI10GE_ALLOC_SIZE > 4096 + int end_offset; +@@ -1215,11 +1220,21 @@ myri10ge_alloc_rx_pages(struct myri10ge_ + rx->watchdog_needed = 1; + return; + } ++ ++ bus = pci_map_page(mgp->pdev, page, 0, ++ MYRI10GE_ALLOC_SIZE, ++ PCI_DMA_FROMDEVICE); ++ if (unlikely(pci_dma_mapping_error(mgp->pdev, bus))) { ++ __free_pages(page, MYRI10GE_ALLOC_ORDER); ++ if (rx->fill_cnt - rx->cnt < 16) ++ rx->watchdog_needed = 1; ++ return; ++ } ++ + rx->page = page; + rx->page_offset = 0; +- rx->bus = pci_map_page(mgp->pdev, page, 0, +- MYRI10GE_ALLOC_SIZE, +- PCI_DMA_FROMDEVICE); ++ rx->bus = bus; ++ + } + rx->info[idx].page = rx->page; + rx->info[idx].page_offset = rx->page_offset; +@@ -2576,6 +2591,35 @@ myri10ge_submit_req(struct myri10ge_tx_b + mb(); + } + ++static void myri10ge_unmap_tx_dma(struct myri10ge_priv *mgp, ++ struct myri10ge_tx_buf *tx, int idx) ++{ ++ unsigned int len; ++ int last_idx; ++ ++ /* Free any DMA resources we've alloced and clear out the skb slot */ ++ last_idx = (idx + 1) & tx->mask; ++ idx = tx->req & tx->mask; ++ do { ++ len = dma_unmap_len(&tx->info[idx], len); ++ if (len) { ++ if (tx->info[idx].skb != NULL) ++ pci_unmap_single(mgp->pdev, ++ dma_unmap_addr(&tx->info[idx], ++ bus), len, ++ PCI_DMA_TODEVICE); ++ else ++ pci_unmap_page(mgp->pdev, ++ dma_unmap_addr(&tx->info[idx], ++ bus), len, ++ PCI_DMA_TODEVICE); ++ dma_unmap_len_set(&tx->info[idx], len, 0); ++ tx->info[idx].skb = NULL; ++ } ++ idx = (idx + 1) & tx->mask; ++ } while (idx != last_idx); ++} ++ + /* + * Transmit a packet. We need to split the packet so that a single + * segment does not cross myri10ge->tx_boundary, so this makes segment +@@ -2599,7 +2643,7 @@ static netdev_tx_t myri10ge_xmit(struct + u32 low; + __be32 high_swapped; + unsigned int len; +- int idx, last_idx, avail, frag_cnt, frag_idx, count, mss, max_segments; ++ int idx, avail, frag_cnt, frag_idx, count, mss, max_segments; + u16 pseudo_hdr_offset, cksum_offset, queue; + int cum_len, seglen, boundary, rdma_count; + u8 flags, odd_flag; +@@ -2696,9 +2740,12 @@ again: + + /* map the skb for DMA */ + len = skb_headlen(skb); ++ bus = pci_map_single(mgp->pdev, skb->data, len, PCI_DMA_TODEVICE); ++ if (unlikely(pci_dma_mapping_error(mgp->pdev, bus))) ++ goto drop; ++ + idx = tx->req & tx->mask; + tx->info[idx].skb = skb; +- bus = pci_map_single(mgp->pdev, skb->data, len, PCI_DMA_TODEVICE); + dma_unmap_addr_set(&tx->info[idx], bus, bus); + dma_unmap_len_set(&tx->info[idx], len, len); + +@@ -2797,12 +2844,16 @@ again: + break; + + /* map next fragment for DMA */ +- idx = (count + tx->req) & tx->mask; + frag = &skb_shinfo(skb)->frags[frag_idx]; + frag_idx++; + len = skb_frag_size(frag); + bus = skb_frag_dma_map(&mgp->pdev->dev, frag, 0, len, + DMA_TO_DEVICE); ++ if (unlikely(pci_dma_mapping_error(mgp->pdev, bus))) { ++ myri10ge_unmap_tx_dma(mgp, tx, idx); ++ goto drop; ++ } ++ idx = (count + tx->req) & tx->mask; + dma_unmap_addr_set(&tx->info[idx], bus, bus); + dma_unmap_len_set(&tx->info[idx], len, len); + } +@@ -2833,31 +2884,8 @@ again: + return NETDEV_TX_OK; + + abort_linearize: +- /* Free any DMA resources we've alloced and clear out the skb +- * slot so as to not trip up assertions, and to avoid a +- * double-free if linearizing fails */ ++ myri10ge_unmap_tx_dma(mgp, tx, idx); + +- last_idx = (idx + 1) & tx->mask; +- idx = tx->req & tx->mask; +- tx->info[idx].skb = NULL; +- do { +- len = dma_unmap_len(&tx->info[idx], len); +- if (len) { +- if (tx->info[idx].skb != NULL) +- pci_unmap_single(mgp->pdev, +- dma_unmap_addr(&tx->info[idx], +- bus), len, +- PCI_DMA_TODEVICE); +- else +- pci_unmap_page(mgp->pdev, +- dma_unmap_addr(&tx->info[idx], +- bus), len, +- PCI_DMA_TODEVICE); +- dma_unmap_len_set(&tx->info[idx], len, 0); +- tx->info[idx].skb = NULL; +- } +- idx = (idx + 1) & tx->mask; +- } while (idx != last_idx); + if (skb_is_gso(skb)) { + netdev_err(mgp->dev, "TSO but wanted to linearize?!?!?\n"); + goto drop; diff --git a/queue-3.10/openvswitch-fix-panic-with-multiple-vlan-headers.patch b/queue-3.10/openvswitch-fix-panic-with-multiple-vlan-headers.patch new file mode 100644 index 00000000000..288f2fce2ed --- /dev/null +++ b/queue-3.10/openvswitch-fix-panic-with-multiple-vlan-headers.patch @@ -0,0 +1,55 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Jiri Benc +Date: Thu, 21 Aug 2014 21:33:44 +0200 +Subject: openvswitch: fix panic with multiple vlan headers + +From: Jiri Benc + +[ Upstream commit 2ba5af42a7b59ef01f9081234d8855140738defd ] + +When there are multiple vlan headers present in a received frame, the first +one is put into vlan_tci and protocol is set to ETH_P_8021Q. Anything in the +skb beyond the VLAN TPID may be still non-linear, including the inner TCI +and ethertype. While ovs_flow_extract takes care of IP and IPv6 headers, it +does nothing with ETH_P_8021Q. Later, if OVS_ACTION_ATTR_POP_VLAN is +executed, __pop_vlan_tci pulls the next vlan header into vlan_tci. + +This leads to two things: + +1. Part of the resulting ethernet header is in the non-linear part of the + skb. When eth_type_trans is called later as the result of + OVS_ACTION_ATTR_OUTPUT, kernel BUGs in __skb_pull. Also, __pop_vlan_tci + is in fact accessing random data when it reads past the TPID. + +2. network_header points into the ethernet header instead of behind it. + mac_len is set to a wrong value (10), too. + +Reported-by: Yulong Pei +Signed-off-by: Jiri Benc +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/openvswitch/actions.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/net/openvswitch/actions.c ++++ b/net/openvswitch/actions.c +@@ -40,6 +40,9 @@ static int do_execute_actions(struct dat + + static int make_writable(struct sk_buff *skb, int write_len) + { ++ if (!pskb_may_pull(skb, write_len)) ++ return -ENOMEM; ++ + if (!skb_cloned(skb) || skb_clone_writable(skb, write_len)) + return 0; + +@@ -68,6 +71,8 @@ static int __pop_vlan_tci(struct sk_buff + + vlan_set_encap_proto(skb, vhdr); + skb->mac_header += VLAN_HLEN; ++ if (skb_network_offset(skb) < ETH_HLEN) ++ skb_set_network_header(skb, ETH_HLEN); + skb_reset_mac_len(skb); + + return 0; diff --git a/queue-3.10/packet-handle-too-big-packets-for-packet_v3.patch b/queue-3.10/packet-handle-too-big-packets-for-packet_v3.patch new file mode 100644 index 00000000000..88a31c0b962 --- /dev/null +++ b/queue-3.10/packet-handle-too-big-packets-for-packet_v3.patch @@ -0,0 +1,83 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Eric Dumazet +Date: Fri, 15 Aug 2014 09:16:04 -0700 +Subject: packet: handle too big packets for PACKET_V3 + +From: Eric Dumazet + +[ Upstream commit dc808110bb62b64a448696ecac3938902c92e1ab ] + +af_packet can currently overwrite kernel memory by out of bound +accesses, because it assumed a [new] block can always hold one frame. + +This is not generally the case, even if most existing tools do it right. + +This patch clamps too long frames as API permits, and issue a one time +error on syslog. + +[ 394.357639] tpacket_rcv: packet too big, clamped from 5042 to 3966. macoff=82 + +In this example, packet header tp_snaplen was set to 3966, +and tp_len was set to 5042 (skb->len) + +Signed-off-by: Eric Dumazet +Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.") +Acked-by: Daniel Borkmann +Acked-by: Neil Horman +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/packet/af_packet.c | 17 +++++++++++++++++ + net/packet/internal.h | 1 + + 2 files changed, 18 insertions(+) + +--- a/net/packet/af_packet.c ++++ b/net/packet/af_packet.c +@@ -565,6 +565,7 @@ static void init_prb_bdqc(struct packet_ + p1->tov_in_jiffies = msecs_to_jiffies(p1->retire_blk_tov); + p1->blk_sizeof_priv = req_u->req3.tp_sizeof_priv; + ++ p1->max_frame_len = p1->kblk_size - BLK_PLUS_PRIV(p1->blk_sizeof_priv); + prb_init_ft_ops(p1, req_u); + prb_setup_retire_blk_timer(po, tx_ring); + prb_open_block(p1, pbd); +@@ -1803,6 +1804,18 @@ static int tpacket_rcv(struct sk_buff *s + if ((int)snaplen < 0) + snaplen = 0; + } ++ } else if (unlikely(macoff + snaplen > ++ GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len)) { ++ u32 nval; ++ ++ nval = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len - macoff; ++ pr_err_once("tpacket_rcv: packet too big, clamped from %u to %u. macoff=%u\n", ++ snaplen, nval, macoff); ++ snaplen = nval; ++ if (unlikely((int)snaplen < 0)) { ++ snaplen = 0; ++ macoff = GET_PBDQC_FROM_RB(&po->rx_ring)->max_frame_len; ++ } + } + spin_lock(&sk->sk_receive_queue.lock); + h.raw = packet_current_rx_frame(po, skb, +@@ -3642,6 +3655,10 @@ static int packet_set_ring(struct sock * + goto out; + if (unlikely(req->tp_block_size & (PAGE_SIZE - 1))) + goto out; ++ if (po->tp_version >= TPACKET_V3 && ++ (int)(req->tp_block_size - ++ BLK_PLUS_PRIV(req_u->req3.tp_sizeof_priv)) <= 0) ++ goto out; + if (unlikely(req->tp_frame_size < po->tp_hdrlen + + po->tp_reserve)) + goto out; +--- a/net/packet/internal.h ++++ b/net/packet/internal.h +@@ -29,6 +29,7 @@ struct tpacket_kbdq_core { + char *pkblk_start; + char *pkblk_end; + int kblk_size; ++ unsigned int max_frame_len; + unsigned int knum_blocks; + uint64_t knxt_seq_num; + char *prev; diff --git a/queue-3.10/sctp-handle-association-restarts-when-the-socket-is-closed.patch b/queue-3.10/sctp-handle-association-restarts-when-the-socket-is-closed.patch new file mode 100644 index 00000000000..dd9a62576a4 --- /dev/null +++ b/queue-3.10/sctp-handle-association-restarts-when-the-socket-is-closed.patch @@ -0,0 +1,79 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Vlad Yasevich +Date: Fri, 3 Oct 2014 18:16:20 -0400 +Subject: sctp: handle association restarts when the socket is closed. + +From: Vlad Yasevich + +[ Upstream commit bdf6fa52f01b941d4a80372d56de465bdbbd1d23 ] + +Currently association restarts do not take into consideration the +state of the socket. When a restart happens, the current assocation +simply transitions into established state. This creates a condition +where a remote system, through a the restart procedure, may create a +local association that is no way reachable by user. The conditions +to trigger this are as follows: + 1) Remote does not acknoledge some data causing data to remain + outstanding. + 2) Local application calls close() on the socket. Since data + is still outstanding, the association is placed in SHUTDOWN_PENDING + state. However, the socket is closed. + 3) The remote tries to create a new association, triggering a restart + on the local system. The association moves from SHUTDOWN_PENDING + to ESTABLISHED. At this point, it is no longer reachable by + any socket on the local system. + +This patch addresses the above situation by moving the newly ESTABLISHED +association into SHUTDOWN-SENT state and bundling a SHUTDOWN after +the COOKIE-ACK chunk. This way, the restarted associate immidiately +enters the shutdown procedure and forces the termination of the +unreachable association. + +Reported-by: David Laight +Signed-off-by: Vlad Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sctp/command.h | 2 +- + net/sctp/sm_statefuns.c | 19 ++++++++++++++++--- + 2 files changed, 17 insertions(+), 4 deletions(-) + +--- a/include/net/sctp/command.h ++++ b/include/net/sctp/command.h +@@ -118,7 +118,7 @@ typedef enum { + * analysis of the state functions, but in reality just taken from + * thin air in the hopes othat we don't trigger a kernel panic. + */ +-#define SCTP_MAX_NUM_COMMANDS 14 ++#define SCTP_MAX_NUM_COMMANDS 20 + + typedef union { + __s32 i32; +--- a/net/sctp/sm_statefuns.c ++++ b/net/sctp/sm_statefuns.c +@@ -1782,9 +1782,22 @@ static sctp_disposition_t sctp_sf_do_dup + /* Update the content of current association. */ + sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_ASSOC, SCTP_ASOC(new_asoc)); + sctp_add_cmd_sf(commands, SCTP_CMD_EVENT_ULP, SCTP_ULPEVENT(ev)); +- sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, +- SCTP_STATE(SCTP_STATE_ESTABLISHED)); +- sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); ++ if (sctp_state(asoc, SHUTDOWN_PENDING) && ++ (sctp_sstate(asoc->base.sk, CLOSING) || ++ sock_flag(asoc->base.sk, SOCK_DEAD))) { ++ /* if were currently in SHUTDOWN_PENDING, but the socket ++ * has been closed by user, don't transition to ESTABLISHED. ++ * Instead trigger SHUTDOWN bundled with COOKIE_ACK. ++ */ ++ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); ++ return sctp_sf_do_9_2_start_shutdown(net, ep, asoc, ++ SCTP_ST_CHUNK(0), NULL, ++ commands); ++ } else { ++ sctp_add_cmd_sf(commands, SCTP_CMD_NEW_STATE, ++ SCTP_STATE(SCTP_STATE_ESTABLISHED)); ++ sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(repl)); ++ } + return SCTP_DISPOSITION_CONSUME; + + nomem_ev: diff --git a/queue-3.10/series b/queue-3.10/series new file mode 100644 index 00000000000..11230a48d47 --- /dev/null +++ b/queue-3.10/series @@ -0,0 +1,13 @@ +myri10ge-check-for-dma-mapping-errors.patch +sit-fix-ipip6_tunnel_lookup-device-matching-criteria.patch +tcp-fix-tcp_release_cb-to-dispatch-via-address-family-for-mtu_reduced.patch +packet-handle-too-big-packets-for-packet_v3.patch +openvswitch-fix-panic-with-multiple-vlan-headers.patch +l2tp-fix-race-while-getting-pmtu-on-ppp-pseudo-wire.patch +tg3-work-around-hw-fw-limitations-with-vlan-encapsulated-frames.patch +tg3-allow-for-recieve-of-full-size-8021ad-frames.patch +hyperv-fix-a-bug-in-netvsc_start_xmit.patch +ip6_gre-fix-flowi6_proto-value-in-xmit-path.patch +sctp-handle-association-restarts-when-the-socket-is-closed.patch +tcp-fixing-tlp-s-fin-recovery.patch +ipv6-reallocate-addrconf-router-for-ipv6-address-when-lo-device-up.patch diff --git a/queue-3.10/sit-fix-ipip6_tunnel_lookup-device-matching-criteria.patch b/queue-3.10/sit-fix-ipip6_tunnel_lookup-device-matching-criteria.patch new file mode 100644 index 00000000000..529a21fd34d --- /dev/null +++ b/queue-3.10/sit-fix-ipip6_tunnel_lookup-device-matching-criteria.patch @@ -0,0 +1,55 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Shmulik Ladkani +Date: Thu, 14 Aug 2014 15:27:20 +0300 +Subject: sit: Fix ipip6_tunnel_lookup device matching criteria + +From: Shmulik Ladkani + +[ Upstream commit bc8fc7b8f825ef17a0fb9e68c18ce94fa66ab337 ] + +As of 4fddbf5d78 ("sit: strictly restrict incoming traffic to tunnel link device"), +when looking up a tunnel, tunnel's underlying interface (t->parms.link) +is verified to match incoming traffic's ingress device. + +However the comparison was incorrectly based on skb->dev->iflink. + +Instead, dev->ifindex should be used, which correctly represents the +interface from which the IP stack hands the ipip6 packets. + +This allows setting up sit tunnels bound to vlan interfaces (otherwise +incoming ipip6 traffic on the vlan interface was dropped due to +ipip6_tunnel_lookup match failure). + +Signed-off-by: Shmulik Ladkani +Acked-by: Nicolas Dichtel +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv6/sit.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/net/ipv6/sit.c ++++ b/net/ipv6/sit.c +@@ -101,19 +101,19 @@ static struct ip_tunnel *ipip6_tunnel_lo + for_each_ip_tunnel_rcu(t, sitn->tunnels_r_l[h0 ^ h1]) { + if (local == t->parms.iph.saddr && + remote == t->parms.iph.daddr && +- (!dev || !t->parms.link || dev->iflink == t->parms.link) && ++ (!dev || !t->parms.link || dev->ifindex == t->parms.link) && + (t->dev->flags & IFF_UP)) + return t; + } + for_each_ip_tunnel_rcu(t, sitn->tunnels_r[h0]) { + if (remote == t->parms.iph.daddr && +- (!dev || !t->parms.link || dev->iflink == t->parms.link) && ++ (!dev || !t->parms.link || dev->ifindex == t->parms.link) && + (t->dev->flags & IFF_UP)) + return t; + } + for_each_ip_tunnel_rcu(t, sitn->tunnels_l[h1]) { + if (local == t->parms.iph.saddr && +- (!dev || !t->parms.link || dev->iflink == t->parms.link) && ++ (!dev || !t->parms.link || dev->ifindex == t->parms.link) && + (t->dev->flags & IFF_UP)) + return t; + } diff --git a/queue-3.10/tcp-fix-tcp_release_cb-to-dispatch-via-address-family-for-mtu_reduced.patch b/queue-3.10/tcp-fix-tcp_release_cb-to-dispatch-via-address-family-for-mtu_reduced.patch new file mode 100644 index 00000000000..09ec912e041 --- /dev/null +++ b/queue-3.10/tcp-fix-tcp_release_cb-to-dispatch-via-address-family-for-mtu_reduced.patch @@ -0,0 +1,134 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Neal Cardwell +Date: Thu, 14 Aug 2014 12:40:05 -0400 +Subject: tcp: fix tcp_release_cb() to dispatch via address family for mtu_reduced() + +From: Neal Cardwell + +[ Upstream commit 4fab9071950c2021d846e18351e0f46a1cffd67b ] + +Make sure we use the correct address-family-specific function for +handling MTU reductions from within tcp_release_cb(). + +Previously AF_INET6 sockets were incorrectly always using the IPv6 +code path when sometimes they were handling IPv4 traffic and thus had +an IPv4 dst. + +Signed-off-by: Neal Cardwell +Signed-off-by: Eric Dumazet +Diagnosed-by: Willem de Bruijn +Fixes: 563d34d057862 ("tcp: dont drop MTU reduction indications") +Reviewed-by: Hannes Frederic Sowa +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/net/inet_connection_sock.h | 1 + + include/net/sock.h | 1 - + include/net/tcp.h | 1 + + net/ipv4/tcp_ipv4.c | 5 +++-- + net/ipv4/tcp_output.c | 2 +- + net/ipv6/tcp_ipv6.c | 3 ++- + 6 files changed, 8 insertions(+), 5 deletions(-) + +--- a/include/net/inet_connection_sock.h ++++ b/include/net/inet_connection_sock.h +@@ -62,6 +62,7 @@ struct inet_connection_sock_af_ops { + void (*addr2sockaddr)(struct sock *sk, struct sockaddr *); + int (*bind_conflict)(const struct sock *sk, + const struct inet_bind_bucket *tb, bool relax); ++ void (*mtu_reduced)(struct sock *sk); + }; + + /** inet_connection_sock - INET connection oriented sock +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -932,7 +932,6 @@ struct proto { + struct sk_buff *skb); + + void (*release_cb)(struct sock *sk); +- void (*mtu_reduced)(struct sock *sk); + + /* Keeping track of sk's, looking them up, and port selection methods. */ + void (*hash)(struct sock *sk); +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -460,6 +460,7 @@ extern const u8 *tcp_parse_md5sig_option + */ + + extern void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb); ++void tcp_v4_mtu_reduced(struct sock *sk); + extern int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb); + extern struct sock * tcp_create_openreq_child(struct sock *sk, + struct request_sock *req, +--- a/net/ipv4/tcp_ipv4.c ++++ b/net/ipv4/tcp_ipv4.c +@@ -268,7 +268,7 @@ EXPORT_SYMBOL(tcp_v4_connect); + * It can be called through tcp_release_cb() if socket was owned by user + * at the time tcp_v4_err() was called to handle ICMP message. + */ +-static void tcp_v4_mtu_reduced(struct sock *sk) ++void tcp_v4_mtu_reduced(struct sock *sk) + { + struct dst_entry *dst; + struct inet_sock *inet = inet_sk(sk); +@@ -298,6 +298,7 @@ static void tcp_v4_mtu_reduced(struct so + tcp_simple_retransmit(sk); + } /* else let the usual retransmit timer handle it */ + } ++EXPORT_SYMBOL(tcp_v4_mtu_reduced); + + static void do_redirect(struct sk_buff *skb, struct sock *sk) + { +@@ -2142,6 +2143,7 @@ const struct inet_connection_sock_af_ops + .compat_setsockopt = compat_ip_setsockopt, + .compat_getsockopt = compat_ip_getsockopt, + #endif ++ .mtu_reduced = tcp_v4_mtu_reduced, + }; + EXPORT_SYMBOL(ipv4_specific); + +@@ -2867,7 +2869,6 @@ struct proto tcp_prot = { + .sendpage = tcp_sendpage, + .backlog_rcv = tcp_v4_do_rcv, + .release_cb = tcp_release_cb, +- .mtu_reduced = tcp_v4_mtu_reduced, + .hash = inet_hash, + .unhash = inet_unhash, + .get_port = inet_csk_get_port, +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -775,7 +775,7 @@ void tcp_release_cb(struct sock *sk) + __sock_put(sk); + } + if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) { +- sk->sk_prot->mtu_reduced(sk); ++ inet_csk(sk)->icsk_af_ops->mtu_reduced(sk); + __sock_put(sk); + } + } +--- a/net/ipv6/tcp_ipv6.c ++++ b/net/ipv6/tcp_ipv6.c +@@ -1651,6 +1651,7 @@ static const struct inet_connection_sock + .compat_setsockopt = compat_ipv6_setsockopt, + .compat_getsockopt = compat_ipv6_getsockopt, + #endif ++ .mtu_reduced = tcp_v6_mtu_reduced, + }; + + #ifdef CONFIG_TCP_MD5SIG +@@ -1682,6 +1683,7 @@ static const struct inet_connection_sock + .compat_setsockopt = compat_ipv6_setsockopt, + .compat_getsockopt = compat_ipv6_getsockopt, + #endif ++ .mtu_reduced = tcp_v4_mtu_reduced, + }; + + #ifdef CONFIG_TCP_MD5SIG +@@ -1919,7 +1921,6 @@ struct proto tcpv6_prot = { + .sendpage = tcp_sendpage, + .backlog_rcv = tcp_v6_do_rcv, + .release_cb = tcp_release_cb, +- .mtu_reduced = tcp_v6_mtu_reduced, + .hash = tcp_v6_hash, + .unhash = inet_unhash, + .get_port = inet_csk_get_port, diff --git a/queue-3.10/tcp-fixing-tlp-s-fin-recovery.patch b/queue-3.10/tcp-fixing-tlp-s-fin-recovery.patch new file mode 100644 index 00000000000..6a1caccda2b --- /dev/null +++ b/queue-3.10/tcp-fixing-tlp-s-fin-recovery.patch @@ -0,0 +1,37 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Per Hurtig +Date: Thu, 12 Jun 2014 17:08:32 +0200 +Subject: tcp: fixing TLP's FIN recovery + +From: Per Hurtig + +[ Upstream commit bef1909ee3ed1ca39231b260a8d3b4544ecd0c8f ] + +Fix to a problem observed when losing a FIN segment that does not +contain data. In such situations, TLP is unable to recover from +*any* tail loss and instead adds at least PTO ms to the +retransmission process, i.e., RTO = RTO + PTO. + +Signed-off-by: Per Hurtig +Signed-off-by: Eric Dumazet +Acked-by: Nandita Dukkipati +Acked-by: Neal Cardwell +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_output.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/net/ipv4/tcp_output.c ++++ b/net/ipv4/tcp_output.c +@@ -2036,9 +2036,7 @@ void tcp_send_loss_probe(struct sock *sk + if (WARN_ON(!skb || !tcp_skb_pcount(skb))) + goto rearm_timer; + +- /* Probe with zero data doesn't trigger fast recovery. */ +- if (skb->len > 0) +- err = __tcp_retransmit_skb(sk, skb); ++ err = __tcp_retransmit_skb(sk, skb); + + /* Record snd_nxt for loss detection. */ + if (likely(!err)) diff --git a/queue-3.10/tg3-allow-for-recieve-of-full-size-8021ad-frames.patch b/queue-3.10/tg3-allow-for-recieve-of-full-size-8021ad-frames.patch new file mode 100644 index 00000000000..916eaec967d --- /dev/null +++ b/queue-3.10/tg3-allow-for-recieve-of-full-size-8021ad-frames.patch @@ -0,0 +1,41 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Vlad Yasevich +Date: Tue, 30 Sep 2014 19:39:36 -0400 +Subject: tg3: Allow for recieve of full-size 8021AD frames + +From: Vlad Yasevich + +[ Upstream commit 7d3083ee36b51e425b6abd76778a2046906b0fd3 ] + +When receiving a vlan-tagged frame that still contains +a vlan header, the length of the packet will be greater +then MTU+ETH_HLEN since it will account of the extra +vlan header. TG3 checks this for the case for 802.1Q, +but not for 802.1ad. As a result, full sized 802.1ad +frames get dropped by the card. + +Add a check for 802.1ad protocol when receving full +sized frames. + +Suggested-by: Prashant Sreedharan +CC: Prashant Sreedharan +CC: Michael Chan +Signed-off-by: Vladislav Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/tg3.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -6767,7 +6767,8 @@ static int tg3_rx(struct tg3_napi *tnapi + skb->protocol = eth_type_trans(skb, tp->dev); + + if (len > (tp->dev->mtu + ETH_HLEN) && +- skb->protocol != htons(ETH_P_8021Q)) { ++ skb->protocol != htons(ETH_P_8021Q) && ++ skb->protocol != htons(ETH_P_8021AD)) { + dev_kfree_skb(skb); + goto drop_it_no_recycle; + } diff --git a/queue-3.10/tg3-work-around-hw-fw-limitations-with-vlan-encapsulated-frames.patch b/queue-3.10/tg3-work-around-hw-fw-limitations-with-vlan-encapsulated-frames.patch new file mode 100644 index 00000000000..8fd08f22c1b --- /dev/null +++ b/queue-3.10/tg3-work-around-hw-fw-limitations-with-vlan-encapsulated-frames.patch @@ -0,0 +1,68 @@ +From foo@baz Sun Oct 12 16:27:58 CEST 2014 +From: Vlad Yasevich +Date: Thu, 18 Sep 2014 10:31:17 -0400 +Subject: tg3: Work around HW/FW limitations with vlan encapsulated frames + +From: Vlad Yasevich + +[ Upstream commit 476c18850c6cbaa3f2bb661ae9710645081563b9 ] + +TG3 appears to have an issue performing TSO and checksum offloading +correclty when the frame has been vlan encapsulated (non-accelrated). +In these cases, tcp checksum is not correctly updated. + +This patch attempts to work around this issue. After the patch, +802.1ad vlans start working correctly over tg3 devices. + +CC: Prashant Sreedharan +CC: Michael Chan +Signed-off-by: Vladislav Yasevich +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/broadcom/tg3.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/broadcom/tg3.c ++++ b/drivers/net/ethernet/broadcom/tg3.c +@@ -7759,8 +7759,6 @@ static netdev_tx_t tg3_start_xmit(struct + + entry = tnapi->tx_prod; + base_flags = 0; +- if (skb->ip_summed == CHECKSUM_PARTIAL) +- base_flags |= TXD_FLAG_TCPUDP_CSUM; + + mss = skb_shinfo(skb)->gso_size; + if (mss) { +@@ -7776,6 +7774,13 @@ static netdev_tx_t tg3_start_xmit(struct + + hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb) - ETH_HLEN; + ++ /* HW/FW can not correctly segment packets that have been ++ * vlan encapsulated. ++ */ ++ if (skb->protocol == htons(ETH_P_8021Q) || ++ skb->protocol == htons(ETH_P_8021AD)) ++ return tg3_tso_bug(tp, skb); ++ + if (!skb_is_gso_v6(skb)) { + iph->check = 0; + iph->tot_len = htons(mss + hdr_len); +@@ -7822,6 +7827,17 @@ static netdev_tx_t tg3_start_xmit(struct + base_flags |= tsflags << 12; + } + } ++ } else if (skb->ip_summed == CHECKSUM_PARTIAL) { ++ /* HW/FW can not correctly checksum packets that have been ++ * vlan encapsulated. ++ */ ++ if (skb->protocol == htons(ETH_P_8021Q) || ++ skb->protocol == htons(ETH_P_8021AD)) { ++ if (skb_checksum_help(skb)) ++ goto drop; ++ } else { ++ base_flags |= TXD_FLAG_TCPUDP_CSUM; ++ } + } + + if (tg3_flag(tp, USE_JUMBO_BDFLAG) && -- 2.47.3