--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: KY Srinivasan <kys@microsoft.com>
+Date: Sun, 28 Sep 2014 22:16:43 -0700
+Subject: hyperv: Fix a bug in netvsc_start_xmit()
+
+From: KY Srinivasan <kys@microsoft.com>
+
+[ 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 <longli@microsoft.com>.
+
+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 <kys@microsoft.com>
+Tested-by: Long Li <longli@microsoft.com>
+Tested-by: Sitsofe Wheeler <sitsofe@yahoo.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Date: Thu, 2 Oct 2014 18:26:49 +0200
+Subject: ip6_gre: fix flowi6_proto value in xmit path
+
+From: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+
+[ 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 <matthieu.tdo@6wind.com>
+Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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)
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Gao feng <gaofeng@cn.fujitsu.com>
+Date: Fri, 24 Jan 2014 16:29:11 +0800
+Subject: ipv6: reallocate addrconf router for ipv6 address when lo device up
+
+From: Gao feng <gaofeng@cn.fujitsu.com>
+
+[ 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 <sd@queasysnail.net>
+CC: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Reported-by: Weilong Chen <chenweilong@huawei.com>
+Signed-off-by: Weilong Chen <chenweilong@huawei.com>
+Signed-off-by: Gao feng <gaofeng@cn.fujitsu.com>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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);
+
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Guillaume Nault <g.nault@alphalink.fr>
+Date: Wed, 3 Sep 2014 14:12:55 +0200
+Subject: l2tp: fix race while getting PMTU on PPP pseudo-wire
+
+From: Guillaume Nault <g.nault@alphalink.fr>
+
+[ 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: [<ffffffffa049db88>] 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:[<ffffffffa049db88>] [<ffffffffa049db88>] 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] [<ffffffffa049da80>] ? pppol2tp_connect+0x235/0x41e [l2tp_ppp]
+[ 1937.664005] [<ffffffff81109b57>] ? might_fault+0x9e/0xa5
+[ 1937.664005] [<ffffffff81109b0e>] ? might_fault+0x55/0xa5
+[ 1937.664005] [<ffffffff8114c566>] ? rcu_read_unlock+0x1c/0x26
+[ 1937.664005] [<ffffffff81309196>] SYSC_connect+0x87/0xb1
+[ 1937.664005] [<ffffffff813e56f7>] ? sysret_check+0x1b/0x56
+[ 1937.664005] [<ffffffff8107590d>] ? trace_hardirqs_on_caller+0x145/0x1a1
+[ 1937.664005] [<ffffffff81213dee>] ? trace_hardirqs_on_thunk+0x3a/0x3f
+[ 1937.664005] [<ffffffff8114c262>] ? spin_lock+0x9/0xb
+[ 1937.664005] [<ffffffff813092b4>] SyS_connect+0x9/0xb
+[ 1937.664005] [<ffffffff813e56d2>] 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 [<ffffffffa049db88>] pppol2tp_connect+0x33d/0x41e [l2tp_ppp]
+[ 1937.664005] RSP <ffff8800c43c7de8>
+[ 1937.664005] CR2: 0000000000000020
+[ 1939.559375] ---[ end trace 82d44500f28f8708 ]---
+
+Fixes: f34c4a35d879 ("l2tp: take PMTU from tunnel UDP socket")
+Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
+Acked-by: Eric Dumazet <edumazet@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+Date: Tue, 12 Aug 2014 10:35:19 +0200
+Subject: myri10ge: check for DMA mapping errors
+
+From: Stanislaw Gruszka <sgruszka@redhat.com>
+
+[ Upstream commit 10545937e866ccdbb7ab583031dbdcc6b14e4eb4 ]
+
+On IOMMU systems DMA mapping can fail, we need to check for
+that possibility.
+
+Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Jiri Benc <jbenc@redhat.com>
+Date: Thu, 21 Aug 2014 21:33:44 +0200
+Subject: openvswitch: fix panic with multiple vlan headers
+
+From: Jiri Benc <jbenc@redhat.com>
+
+[ 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 <ypei@redhat.com>
+Signed-off-by: Jiri Benc <jbenc@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Eric Dumazet <edumazet@google.com>
+Date: Fri, 15 Aug 2014 09:16:04 -0700
+Subject: packet: handle too big packets for PACKET_V3
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ 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 <edumazet@google.com>
+Fixes: f6fb8f100b80 ("af-packet: TPACKET_V3 flexible buffer implementation.")
+Acked-by: Daniel Borkmann <dborkman@redhat.com>
+Acked-by: Neil Horman <nhorman@tuxdriver.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Vlad Yasevich <vyasevich@gmail.com>
+Date: Fri, 3 Oct 2014 18:16:20 -0400
+Subject: sctp: handle association restarts when the socket is closed.
+
+From: Vlad Yasevich <vyasevich@gmail.com>
+
+[ 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 <David.Laight@aculab.com>
+Signed-off-by: Vlad Yasevich <vyasevich@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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:
--- /dev/null
+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
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Shmulik Ladkani <shmulik.ladkani@gmail.com>
+Date: Thu, 14 Aug 2014 15:27:20 +0300
+Subject: sit: Fix ipip6_tunnel_lookup device matching criteria
+
+From: Shmulik Ladkani <shmulik.ladkani@gmail.com>
+
+[ 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 <shmulik.ladkani@gmail.com>
+Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Neal Cardwell <ncardwell@google.com>
+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 <ncardwell@google.com>
+
+[ 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 <ncardwell@google.com>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Diagnosed-by: Willem de Bruijn <willemb@google.com>
+Fixes: 563d34d057862 ("tcp: dont drop MTU reduction indications")
+Reviewed-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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,
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Per Hurtig <per.hurtig@kau.se>
+Date: Thu, 12 Jun 2014 17:08:32 +0200
+Subject: tcp: fixing TLP's FIN recovery
+
+From: Per Hurtig <per.hurtig@kau.se>
+
+[ 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 <per.hurtig@kau.se>
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Acked-by: Nandita Dukkipati <nanditad@google.com>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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))
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Vlad Yasevich <vyasevich@gmail.com>
+Date: Tue, 30 Sep 2014 19:39:36 -0400
+Subject: tg3: Allow for recieve of full-size 8021AD frames
+
+From: Vlad Yasevich <vyasevich@gmail.com>
+
+[ 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 <prashant@broadcom.com>
+CC: Prashant Sreedharan <prashant@broadcom.com>
+CC: Michael Chan <mchan@broadcom.com>
+Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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;
+ }
--- /dev/null
+From foo@baz Sun Oct 12 16:27:58 CEST 2014
+From: Vlad Yasevich <vyasevich@gmail.com>
+Date: Thu, 18 Sep 2014 10:31:17 -0400
+Subject: tg3: Work around HW/FW limitations with vlan encapsulated frames
+
+From: Vlad Yasevich <vyasevich@gmail.com>
+
+[ 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 <prashant@broadcom.com>
+CC: Michael Chan <mchan@broadcom.com>
+Signed-off-by: Vladislav Yasevich <vyasevic@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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) &&