--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Ian Morgan <imorgan@primordial.ca>
+Date: Sun, 19 Oct 2014 08:05:13 -0400
+Subject: ax88179_178a: fix bonding failure
+
+From: Ian Morgan <imorgan@primordial.ca>
+
+[ Upstream commit 95ff88688781db2f64042e69bd499e518bbb36e5 ]
+
+The following patch fixes a bug which causes the ax88179_178a driver to be
+incapable of being added to a bond.
+
+When I brought up the issue with the bonding maintainers, they indicated
+that the real problem was with the NIC driver which must return zero for
+success (of setting the MAC address). I see that several other NIC drivers
+follow that pattern by either simply always returing zero, or by passing
+through a negative (error) result while rewriting any positive return code
+to zero. With that same philisophy applied to the ax88179_178a driver, it
+allows it to work correctly with the bonding driver.
+
+I believe this is suitable for queuing in -stable, as it's a small, simple,
+and obvious fix that corrects a defect with no other known workaround.
+
+This patch is against vanilla 3.17(.0).
+
+Signed-off-by: Ian Morgan <imorgan@primordial.ca>
+
+ drivers/net/usb/ax88179_178a.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/ax88179_178a.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/usb/ax88179_178a.c
++++ b/drivers/net/usb/ax88179_178a.c
+@@ -937,6 +937,7 @@ static int ax88179_set_mac_addr(struct n
+ {
+ struct usbnet *dev = netdev_priv(net);
+ struct sockaddr *addr = p;
++ int ret;
+
+ if (netif_running(net))
+ return -EBUSY;
+@@ -946,8 +947,12 @@ static int ax88179_set_mac_addr(struct n
+ memcpy(net->dev_addr, addr->sa_data, ETH_ALEN);
+
+ /* Set the MAC address */
+- return ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
++ ret = ax88179_write_cmd(dev, AX_ACCESS_MAC, AX_NODE_ID, ETH_ALEN,
+ ETH_ALEN, net->dev_addr);
++ if (ret < 0)
++ return ret;
++
++ return 0;
+ }
+
+ static const struct net_device_ops ax88179_netdev_ops = {
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Anish Bhatt <anish@chelsio.com>
+Date: Wed, 29 Oct 2014 17:54:03 -0700
+Subject: cxgb4 : Fix missing initialization of win0_lock
+
+From: Anish Bhatt <anish@chelsio.com>
+
+[ Upstream commit e327c225c911529898ec300cb96d2088893de3df ]
+
+win0_lock was being used un-initialized, resulting in warning traces
+being seen when lock debugging is enabled (and just wrong)
+
+Fixes : fc5ab0209650 ('cxgb4: Replaced the backdoor mechanism to access the HW
+ memory with PCIe Window method')
+
+Signed-off-by: Anish Bhatt <anish@chelsio.com>
+Signed-off-by: Casey Leedom <leedom@chelsio.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+@@ -6557,6 +6557,7 @@ static int init_one(struct pci_dev *pdev
+
+ spin_lock_init(&adapter->stats_lock);
+ spin_lock_init(&adapter->tid_release_lock);
++ spin_lock_init(&adapter->win0_lock);
+
+ INIT_WORK(&adapter->tid_release_task, process_tid_release_list);
+ INIT_WORK(&adapter->db_full_task, process_db_full);
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Thu, 30 Oct 2014 18:27:12 +0000
+Subject: drivers/net: Disable UFO through virtio
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+[ Upstream commit 3d0ad09412ffe00c9afa201d01effdb6023d09b4 ]
+
+IPv6 does not allow fragmentation by routers, so there is no
+fragmentation ID in the fixed header. UFO for IPv6 requires the ID to
+be passed separately, but there is no provision for this in the virtio
+net protocol.
+
+Until recently our software implementation of UFO/IPv6 generated a new
+ID, but this was a bug. Now we will use ID=0 for any UFO/IPv6 packet
+passed through a tap, which is even worse.
+
+Unfortunately there is no distinction between UFO/IPv4 and v6
+features, so disable UFO on taps and virtio_net completely until we
+have a proper solution.
+
+We cannot depend on VM managers respecting the tap feature flags, so
+keep accepting UFO packets but log a warning the first time we do
+this.
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/macvtap.c | 13 +++++--------
+ drivers/net/tun.c | 19 +++++++++++--------
+ drivers/net/virtio_net.c | 24 ++++++++++++++----------
+ 3 files changed, 30 insertions(+), 26 deletions(-)
+
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -65,7 +65,7 @@ static struct cdev macvtap_cdev;
+ static const struct proto_ops macvtap_socket_ops;
+
+ #define TUN_OFFLOADS (NETIF_F_HW_CSUM | NETIF_F_TSO_ECN | NETIF_F_TSO | \
+- NETIF_F_TSO6 | NETIF_F_UFO)
++ NETIF_F_TSO6)
+ #define RX_OFFLOADS (NETIF_F_GRO | NETIF_F_LRO)
+ #define TAP_FEATURES (NETIF_F_GSO | NETIF_F_SG)
+
+@@ -569,6 +569,8 @@ static int macvtap_skb_from_vnet_hdr(str
+ gso_type = SKB_GSO_TCPV6;
+ break;
+ case VIRTIO_NET_HDR_GSO_UDP:
++ pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
++ current->comm);
+ gso_type = SKB_GSO_UDP;
+ break;
+ default:
+@@ -614,8 +616,6 @@ static void macvtap_skb_to_vnet_hdr(cons
+ vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+ else if (sinfo->gso_type & SKB_GSO_TCPV6)
+ vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+- else if (sinfo->gso_type & SKB_GSO_UDP)
+- vnet_hdr->gso_type = VIRTIO_NET_HDR_GSO_UDP;
+ else
+ BUG();
+ if (sinfo->gso_type & SKB_GSO_TCP_ECN)
+@@ -950,9 +950,6 @@ static int set_offload(struct macvtap_qu
+ if (arg & TUN_F_TSO6)
+ feature_mask |= NETIF_F_TSO6;
+ }
+-
+- if (arg & TUN_F_UFO)
+- feature_mask |= NETIF_F_UFO;
+ }
+
+ /* tun/tap driver inverts the usage for TSO offloads, where
+@@ -963,7 +960,7 @@ static int set_offload(struct macvtap_qu
+ * When user space turns off TSO, we turn off GSO/LRO so that
+ * user-space will not receive TSO frames.
+ */
+- if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO))
++ if (feature_mask & (NETIF_F_TSO | NETIF_F_TSO6))
+ features |= RX_OFFLOADS;
+ else
+ features &= ~RX_OFFLOADS;
+@@ -1064,7 +1061,7 @@ static long macvtap_ioctl(struct file *f
+ case TUNSETOFFLOAD:
+ /* let the user check for future flags */
+ if (arg & ~(TUN_F_CSUM | TUN_F_TSO4 | TUN_F_TSO6 |
+- TUN_F_TSO_ECN | TUN_F_UFO))
++ TUN_F_TSO_ECN))
+ return -EINVAL;
+
+ rtnl_lock();
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -174,7 +174,7 @@ struct tun_struct {
+ struct net_device *dev;
+ netdev_features_t set_features;
+ #define TUN_USER_FEATURES (NETIF_F_HW_CSUM|NETIF_F_TSO_ECN|NETIF_F_TSO| \
+- NETIF_F_TSO6|NETIF_F_UFO)
++ NETIF_F_TSO6)
+
+ int vnet_hdr_sz;
+ int sndbuf;
+@@ -1149,8 +1149,18 @@ static ssize_t tun_get_user(struct tun_s
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+ break;
+ case VIRTIO_NET_HDR_GSO_UDP:
++ {
++ static bool warned;
++
++ if (!warned) {
++ warned = true;
++ netdev_warn(tun->dev,
++ "%s: using disabled UFO feature; please fix this program\n",
++ current->comm);
++ }
+ skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+ break;
++ }
+ default:
+ tun->dev->stats.rx_frame_errors++;
+ kfree_skb(skb);
+@@ -1251,8 +1261,6 @@ static ssize_t tun_put_user(struct tun_s
+ gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+ else if (sinfo->gso_type & SKB_GSO_TCPV6)
+ gso.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+- else if (sinfo->gso_type & SKB_GSO_UDP)
+- gso.gso_type = VIRTIO_NET_HDR_GSO_UDP;
+ else {
+ pr_err("unexpected GSO type: "
+ "0x%x, gso_size %d, hdr_len %d\n",
+@@ -1762,11 +1770,6 @@ static int set_offload(struct tun_struct
+ features |= NETIF_F_TSO6;
+ arg &= ~(TUN_F_TSO4|TUN_F_TSO6);
+ }
+-
+- if (arg & TUN_F_UFO) {
+- features |= NETIF_F_UFO;
+- arg &= ~TUN_F_UFO;
+- }
+ }
+
+ /* This gives the user a way to test for new features in future by
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -497,8 +497,17 @@ static void receive_buf(struct receive_q
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
+ break;
+ case VIRTIO_NET_HDR_GSO_UDP:
++ {
++ static bool warned;
++
++ if (!warned) {
++ warned = true;
++ netdev_warn(dev,
++ "host using disabled UFO feature; please fix it\n");
++ }
+ skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
+ break;
++ }
+ case VIRTIO_NET_HDR_GSO_TCPV6:
+ skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
+ break;
+@@ -885,8 +894,6 @@ static int xmit_skb(struct send_queue *s
+ hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV4;
+ else if (skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)
+ hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_TCPV6;
+- else if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
+- hdr->hdr.gso_type = VIRTIO_NET_HDR_GSO_UDP;
+ else
+ BUG();
+ if (skb_shinfo(skb)->gso_type & SKB_GSO_TCP_ECN)
+@@ -1710,7 +1717,7 @@ static int virtnet_probe(struct virtio_d
+ dev->features |= NETIF_F_HW_CSUM|NETIF_F_SG|NETIF_F_FRAGLIST;
+
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_GSO)) {
+- dev->hw_features |= NETIF_F_TSO | NETIF_F_UFO
++ dev->hw_features |= NETIF_F_TSO
+ | NETIF_F_TSO_ECN | NETIF_F_TSO6;
+ }
+ /* Individual feature bits: what can host handle? */
+@@ -1720,11 +1727,9 @@ static int virtnet_probe(struct virtio_d
+ dev->hw_features |= NETIF_F_TSO6;
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_ECN))
+ dev->hw_features |= NETIF_F_TSO_ECN;
+- if (virtio_has_feature(vdev, VIRTIO_NET_F_HOST_UFO))
+- dev->hw_features |= NETIF_F_UFO;
+
+ if (gso)
+- dev->features |= dev->hw_features & (NETIF_F_ALL_TSO|NETIF_F_UFO);
++ dev->features |= dev->hw_features & NETIF_F_ALL_TSO;
+ /* (!csum && gso) case will be fixed by register_netdev() */
+ }
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_CSUM))
+@@ -1764,8 +1769,7 @@ static int virtnet_probe(struct virtio_d
+ /* If we can receive ANY GSO packets, we must allocate large ones. */
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO4) ||
+ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_TSO6) ||
+- virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN) ||
+- virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_UFO))
++ virtio_has_feature(vdev, VIRTIO_NET_F_GUEST_ECN))
+ vi->big_packets = true;
+
+ if (virtio_has_feature(vdev, VIRTIO_NET_F_MRG_RXBUF))
+@@ -1965,9 +1969,9 @@ static struct virtio_device_id id_table[
+ static unsigned int features[] = {
+ VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
+ VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
+- VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
++ VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6,
+ VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
+- VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
++ VIRTIO_NET_F_GUEST_ECN,
+ VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
+ VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
+ VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Thu, 30 Oct 2014 18:27:17 +0000
+Subject: drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+[ Upstream commit 5188cd44c55db3e92cd9e77a40b5baa7ed4340f7 ]
+
+UFO is now disabled on all drivers that work with virtio net headers,
+but userland may try to send UFO/IPv6 packets anyway. Instead of
+sending with ID=0, we should select identifiers on their behalf (as we
+used to).
+
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Fixes: 916e4cf46d02 ("ipv6: reuse ip6_frag_id from ip6_ufo_append_data")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/macvtap.c | 3 +++
+ drivers/net/tun.c | 6 +++++-
+ include/net/ipv6.h | 2 ++
+ net/ipv6/output_core.c | 34 ++++++++++++++++++++++++++++++++++
+ 4 files changed, 44 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/macvtap.c
++++ b/drivers/net/macvtap.c
+@@ -16,6 +16,7 @@
+ #include <linux/idr.h>
+ #include <linux/fs.h>
+
++#include <net/ipv6.h>
+ #include <net/net_namespace.h>
+ #include <net/rtnetlink.h>
+ #include <net/sock.h>
+@@ -572,6 +573,8 @@ static int macvtap_skb_from_vnet_hdr(str
+ pr_warn_once("macvtap: %s: using disabled UFO feature; please fix this program\n",
+ current->comm);
+ gso_type = SKB_GSO_UDP;
++ if (skb->protocol == htons(ETH_P_IPV6))
++ ipv6_proxy_select_ident(skb);
+ break;
+ default:
+ return -EINVAL;
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -65,6 +65,7 @@
+ #include <linux/nsproxy.h>
+ #include <linux/virtio_net.h>
+ #include <linux/rcupdate.h>
++#include <net/ipv6.h>
+ #include <net/net_namespace.h>
+ #include <net/netns/generic.h>
+ #include <net/rtnetlink.h>
+@@ -1139,6 +1140,8 @@ static ssize_t tun_get_user(struct tun_s
+ break;
+ }
+
++ skb_reset_network_header(skb);
++
+ if (gso.gso_type != VIRTIO_NET_HDR_GSO_NONE) {
+ pr_debug("GSO!\n");
+ switch (gso.gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
+@@ -1159,6 +1162,8 @@ static ssize_t tun_get_user(struct tun_s
+ current->comm);
+ }
+ skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
++ if (skb->protocol == htons(ETH_P_IPV6))
++ ipv6_proxy_select_ident(skb);
+ break;
+ }
+ default:
+@@ -1189,7 +1194,6 @@ static ssize_t tun_get_user(struct tun_s
+ skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
+ }
+
+- skb_reset_network_header(skb);
+ skb_probe_transport_header(skb, 0);
+
+ rxhash = skb_get_hash(skb);
+--- a/include/net/ipv6.h
++++ b/include/net/ipv6.h
+@@ -669,6 +669,8 @@ static inline int ipv6_addr_diff(const s
+ return __ipv6_addr_diff(a1, a2, sizeof(struct in6_addr));
+ }
+
++void ipv6_proxy_select_ident(struct sk_buff *skb);
++
+ int ip6_dst_hoplimit(struct dst_entry *dst);
+
+ static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6,
+--- a/net/ipv6/output_core.c
++++ b/net/ipv6/output_core.c
+@@ -3,11 +3,45 @@
+ * not configured or static. These functions are needed by GSO/GRO implementation.
+ */
+ #include <linux/export.h>
++#include <net/ip.h>
+ #include <net/ipv6.h>
+ #include <net/ip6_fib.h>
+ #include <net/addrconf.h>
+ #include <net/secure_seq.h>
+
++/* This function exists only for tap drivers that must support broken
++ * clients requesting UFO without specifying an IPv6 fragment ID.
++ *
++ * This is similar to ipv6_select_ident() but we use an independent hash
++ * seed to limit information leakage.
++ *
++ * The network header must be set before calling this.
++ */
++void ipv6_proxy_select_ident(struct sk_buff *skb)
++{
++ static u32 ip6_proxy_idents_hashrnd __read_mostly;
++ struct in6_addr buf[2];
++ struct in6_addr *addrs;
++ u32 hash, id;
++
++ addrs = skb_header_pointer(skb,
++ skb_network_offset(skb) +
++ offsetof(struct ipv6hdr, saddr),
++ sizeof(buf), buf);
++ if (!addrs)
++ return;
++
++ net_get_random_once(&ip6_proxy_idents_hashrnd,
++ sizeof(ip6_proxy_idents_hashrnd));
++
++ hash = __ipv6_addr_jhash(&addrs[1], ip6_proxy_idents_hashrnd);
++ hash = __ipv6_addr_jhash(&addrs[0], hash);
++
++ id = ip_idents_reserve(hash, 1);
++ skb_shinfo(skb)->ip6_frag_id = htonl(id);
++}
++EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);
++
+ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr)
+ {
+ u16 offset = sizeof(struct ipv6hdr);
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Ben Hutchings <ben@decadent.org.uk>
+Date: Fri, 31 Oct 2014 03:10:31 +0000
+Subject: drivers/net: macvtap and tun depend on INET
+
+From: Ben Hutchings <ben@decadent.org.uk>
+
+[ Upstream commit de11b0e8c569b96c2cf6a811e3805b7aeef498a3 ]
+
+These drivers now call ipv6_proxy_select_ident(), which is defined
+only if CONFIG_INET is enabled. However, they have really depended
+on CONFIG_INET for as long as they have allowed sending GSO packets
+from userland.
+
+Reported-by: kbuild test robot <fengguang.wu@intel.com>
+Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
+Fixes: f43798c27684 ("tun: Allow GSO using virtio_net_hdr")
+Fixes: b9fb9ee07e67 ("macvtap: add GSO/csum offload support")
+Fixes: 5188cd44c55d ("drivers/net, ipv6: Select IPv6 fragment idents for virtio UFO packets")
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/Kconfig | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -135,6 +135,7 @@ config MACVLAN
+ config MACVTAP
+ tristate "MAC-VLAN based tap driver"
+ depends on MACVLAN
++ depends on INET
+ help
+ This adds a specialized tap character device driver that is based
+ on the MAC-VLAN network interface, called macvtap. A macvtap device
+@@ -201,6 +202,7 @@ config RIONET_RX_SIZE
+
+ config TUN
+ tristate "Universal TUN/TAP device driver support"
++ depends on INET
+ select CRC32
+ ---help---
+ TUN/TAP provides packet reception and transmission for user space
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Tom Herbert <therbert@google.com>
+Date: Thu, 30 Oct 2014 08:40:56 -0700
+Subject: gre: Use inner mac length when computing tunnel length
+
+From: Tom Herbert <therbert@google.com>
+
+[ Upstream commit 14051f0452a2c26a3f4791e6ad6a435e8f1945ff ]
+
+Currently, skb_inner_network_header is used but this does not account
+for Ethernet header for ETH_P_TEB. Use skb_inner_mac_header which
+handles TEB and also should work with IP encapsulation in which case
+inner mac and inner network headers are the same.
+
+Tested: Ran TCP_STREAM over GRE, worked as expected.
+
+Signed-off-by: Tom Herbert <therbert@google.com>
+Acked-by: Alexander Duyck <alexander.h.duyck@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/gre_offload.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv4/gre_offload.c
++++ b/net/ipv4/gre_offload.c
+@@ -51,7 +51,7 @@ static struct sk_buff *gre_gso_segment(s
+
+ greh = (struct gre_base_hdr *)skb_transport_header(skb);
+
+- ghl = skb_inner_network_header(skb) - skb_transport_header(skb);
++ ghl = skb_inner_mac_header(skb) - skb_transport_header(skb);
+ if (unlikely(ghl < sizeof(*greh)))
+ goto out;
+
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Haiyang Zhang <haiyangz@microsoft.com>
+Date: Wed, 22 Oct 2014 13:47:18 -0700
+Subject: hyperv: Fix the total_data_buflen in send path
+
+From: Haiyang Zhang <haiyangz@microsoft.com>
+
+[ Upstream commit 942396b01989d54977120f3625e5ba31afe7a75c ]
+
+total_data_buflen is used by netvsc_send() to decide if a packet can be put
+into send buffer. It should also include the size of RNDIS message before the
+Ethernet frame. Otherwise, a messge with total size bigger than send_section_size
+may be copied into the send buffer, and cause data corruption.
+
+[Request to include this patch to the Stable branches]
+
+Signed-off-by: Haiyang Zhang <haiyangz@microsoft.com>
+Reviewed-by: K. Y. Srinivasan <kys@microsoft.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 | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -556,6 +556,7 @@ do_lso:
+ do_send:
+ /* Start filling in the page buffers with the rndis hdr */
+ rndis_msg->msg_len += rndis_msg_size;
++ packet->total_data_buflen = rndis_msg->msg_len;
+ packet->page_buf_cnt = init_page_array(rndis_msg, rndis_msg_size,
+ skb, &packet->page_buf[0]);
+
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
+Date: Thu, 30 Oct 2014 10:09:53 +0100
+Subject: ipv4: Do not cache routing failures due to disabled forwarding.
+
+From: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
+
+[ Upstream commit fa19c2b050ab5254326f5fc07096dd3c6a8d5d58 ]
+
+If we cache them, the kernel will reuse them, independently of
+whether forwarding is enabled or not. Which means that if forwarding is
+disabled on the input interface where the first routing request comes
+from, then that unreachable result will be cached and reused for
+other interfaces, even if forwarding is enabled on them. The opposite
+is also true.
+
+This can be verified with two interfaces A and B and an output interface
+C, where B has forwarding enabled, but not A and trying
+ip route get $dst iif A from $src && ip route get $dst iif B from $src
+
+Signed-off-by: Nicolas Cavallari <nicolas.cavallari@green-communications.fr>
+Reviewed-by: Julian Anastasov <ja@ssi.bg>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/route.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -1798,6 +1798,7 @@ local_input:
+ no_route:
+ RT_CACHE_STAT_INC(in_no_route);
+ res.type = RTN_UNREACHABLE;
++ res.fi = NULL;
+ goto local_input;
+
+ /*
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Vasily Averin <vvs@parallels.com>
+Date: Wed, 15 Oct 2014 16:24:02 +0400
+Subject: ipv4: dst_entry leak in ip_send_unicast_reply()
+
+From: Vasily Averin <vvs@parallels.com>
+
+[ Upstream commit 4062090e3e5caaf55bed4523a69f26c3265cc1d2 ]
+
+ip_setup_cork() called inside ip_append_data() steals dst entry from rt to cork
+and in case errors in __ip_append_data() nobody frees stolen dst entry
+
+Fixes: 2e77d89b2fa8 ("net: avoid a pair of dst_hold()/dst_release() in ip_append_data()")
+Signed-off-by: Vasily Averin <vvs@parallels.com>
+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/ipv4/ip_output.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -1533,6 +1533,7 @@ void ip_send_unicast_reply(struct net *n
+ struct sk_buff *nskb;
+ struct sock *sk;
+ struct inet_sock *inet;
++ int err;
+
+ if (ip_options_echo(&replyopts.opt.opt, skb))
+ return;
+@@ -1572,8 +1573,13 @@ void ip_send_unicast_reply(struct net *n
+ sock_net_set(sk, net);
+ __skb_queue_head_init(&sk->sk_write_queue);
+ sk->sk_sndbuf = sysctl_wmem_default;
+- ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base, len, 0,
+- &ipc, &rt, MSG_DONTWAIT);
++ err = ip_append_data(sk, &fl4, ip_reply_glue_bits, arg->iov->iov_base,
++ len, 0, &ipc, &rt, MSG_DONTWAIT);
++ if (unlikely(err)) {
++ ip_flush_pending_frames(sk);
++ goto out;
++ }
++
+ nskb = skb_peek(&sk->sk_write_queue);
+ if (nskb) {
+ if (arg->csumoffset >= 0)
+@@ -1585,7 +1591,7 @@ void ip_send_unicast_reply(struct net *n
+ skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb));
+ ip_push_pending_frames(sk, &fl4);
+ }
+-
++out:
+ put_cpu_var(unicast_sock);
+
+ ip_rt_put(rt);
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Li RongQing <roy.qing.li@gmail.com>
+Date: Fri, 17 Oct 2014 16:53:23 +0800
+Subject: ipv4: fix a potential use after free in ip_tunnel_core.c
+
+From: Li RongQing <roy.qing.li@gmail.com>
+
+[ Upstream commit 1245dfc8cadb258386fcd27df38215a0eccb1f17 ]
+
+pskb_may_pull() maybe change skb->data and make eth pointer oboslete,
+so set eth after pskb_may_pull()
+
+Fixes:3d7b46cd("ip_tunnel: push generic protocol handling to ip_tunnel module")
+Cc: Pravin B Shelar <pshelar@nicira.com>
+Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
+Acked-by: Pravin B Shelar <pshelar@nicira.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/ip_tunnel_core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -91,11 +91,12 @@ int iptunnel_pull_header(struct sk_buff
+ skb_pull_rcsum(skb, hdr_len);
+
+ if (inner_proto == htons(ETH_P_TEB)) {
+- struct ethhdr *eh = (struct ethhdr *)skb->data;
++ struct ethhdr *eh;
+
+ if (unlikely(!pskb_may_pull(skb, ETH_HLEN)))
+ return -ENOMEM;
+
++ eh = (struct ethhdr *)skb->data;
+ if (likely(ntohs(eh->h_proto) >= ETH_P_802_3_MIN))
+ skb->protocol = eh->h_proto;
+ else
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Jiri Pirko <jiri@resnulli.us>
+Date: Mon, 13 Oct 2014 16:34:10 +0200
+Subject: ipv4: fix nexthop attlen check in fib_nh_match
+
+From: Jiri Pirko <jiri@resnulli.us>
+
+[ Upstream commit f76936d07c4eeb36d8dbb64ebd30ab46ff85d9f7 ]
+
+fib_nh_match does not match nexthops correctly. Example:
+
+ip route add 172.16.10/24 nexthop via 192.168.122.12 dev eth0 \
+ nexthop via 192.168.122.13 dev eth0
+ip route del 172.16.10/24 nexthop via 192.168.122.14 dev eth0 \
+ nexthop via 192.168.122.15 dev eth0
+
+Del command is successful and route is removed. After this patch
+applied, the route is correctly matched and result is:
+RTNETLINK answers: No such process
+
+Please consider this for stable trees as well.
+
+Fixes: 4e902c57417c4 ("[IPv4]: FIB configuration using struct fib_config")
+Signed-off-by: Jiri Pirko <jiri@resnulli.us>
+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/ipv4/fib_semantics.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv4/fib_semantics.c
++++ b/net/ipv4/fib_semantics.c
+@@ -535,7 +535,7 @@ int fib_nh_match(struct fib_config *cfg,
+ return 1;
+
+ attrlen = rtnh_attrlen(rtnh);
+- if (attrlen < 0) {
++ if (attrlen > 0) {
+ struct nlattr *nla, *attrs = rtnh_attrs(rtnh);
+
+ nla = nla_find(attrs, attrlen, RTA_GATEWAY);
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Eric Dumazet <edumazet@google.com>
+Date: Wed, 22 Oct 2014 19:43:46 -0700
+Subject: macvlan: fix a race on port dismantle and possible skb leaks
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit fe0ca7328d03d36aafecebb3af650e1bb2841c20 ]
+
+We need to cancel the work queue after rcu grace period,
+otherwise it can be rescheduled by incoming packets.
+
+We need to purge queue if some skbs are still in it.
+
+We can use __skb_queue_head_init() variant in
+macvlan_process_broadcast()
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Fixes: 412ca1550cbec ("macvlan: Move broadcasts into a work queue")
+Cc: Herbert Xu <herbert@gondor.apana.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/macvlan.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -201,7 +201,7 @@ static void macvlan_process_broadcast(st
+ struct sk_buff *skb;
+ struct sk_buff_head list;
+
+- skb_queue_head_init(&list);
++ __skb_queue_head_init(&list);
+
+ spin_lock_bh(&port->bc_queue.lock);
+ skb_queue_splice_tail_init(&port->bc_queue, &list);
+@@ -941,9 +941,15 @@ static void macvlan_port_destroy(struct
+ {
+ struct macvlan_port *port = macvlan_port_get_rtnl(dev);
+
+- cancel_work_sync(&port->bc_work);
+ dev->priv_flags &= ~IFF_MACVLAN_PORT;
+ netdev_rx_handler_unregister(dev);
++
++ /* After this point, no packet can schedule bc_work anymore,
++ * but we need to cancel it and purge left skbs if any.
++ */
++ cancel_work_sync(&port->bc_work);
++ __skb_queue_purge(&port->bc_queue);
++
+ kfree_rcu(port, rcu);
+ }
+
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Or Gerlitz <ogerlitz@mellanox.com>
+Date: Thu, 30 Oct 2014 15:59:28 +0200
+Subject: mlx4: Avoid leaking steering rules on flow creation error flow
+
+From: Or Gerlitz <ogerlitz@mellanox.com>
+
+[ Upstream commit 571e1b2c7a4c2fd5faa1648462a6b65fa26530d7 ]
+
+If mlx4_ib_create_flow() attempts to create > 1 rules with the
+firmware, and one of these registrations fail, we leaked the
+already created flow rules.
+
+One example of the leak is when the registration of the VXLAN ghost
+steering rule fails, we didn't unregister the original rule requested
+by the user, introduced in commit d2fce8a9060d "mlx4: Set
+user-space raw Ethernet QPs to properly handle VXLAN traffic".
+
+While here, add dump of the VXLAN portion of steering rules
+so it can actually be seen when flow creation fails.
+
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/infiniband/hw/mlx4/main.c | 10 ++++++++--
+ drivers/net/ethernet/mellanox/mlx4/mcg.c | 4 ++++
+ 2 files changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/infiniband/hw/mlx4/main.c
++++ b/drivers/infiniband/hw/mlx4/main.c
+@@ -1173,18 +1173,24 @@ static struct ib_flow *mlx4_ib_create_fl
+ err = __mlx4_ib_create_flow(qp, flow_attr, domain, type[i],
+ &mflow->reg_id[i]);
+ if (err)
+- goto err_free;
++ goto err_create_flow;
+ i++;
+ }
+
+ if (i < ARRAY_SIZE(type) && flow_attr->type == IB_FLOW_ATTR_NORMAL) {
+ err = mlx4_ib_tunnel_steer_add(qp, flow_attr, &mflow->reg_id[i]);
+ if (err)
+- goto err_free;
++ goto err_create_flow;
++ i++;
+ }
+
+ return &mflow->ibflow;
+
++err_create_flow:
++ while (i) {
++ (void)__mlx4_ib_destroy_flow(to_mdev(qp->device)->dev, mflow->reg_id[i]);
++ i--;
++ }
+ err_free:
+ kfree(mflow);
+ return ERR_PTR(err);
+--- a/drivers/net/ethernet/mellanox/mlx4/mcg.c
++++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c
+@@ -955,6 +955,10 @@ static void mlx4_err_rule(struct mlx4_de
+ cur->ib.dst_gid_msk);
+ break;
+
++ case MLX4_NET_TRANS_RULE_ID_VXLAN:
++ len += snprintf(buf + len, BUF_SIZE - len,
++ "VNID = %d ", be32_to_cpu(cur->vxlan.vni));
++ break;
+ case MLX4_NET_TRANS_RULE_ID_IPV6:
+ break;
+
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Sathya Perla <sathya.perla@emulex.com>
+Date: Wed, 22 Oct 2014 21:42:01 +0530
+Subject: net: fix saving TX flow hash in sock for outgoing connections
+
+From: Sathya Perla <sathya.perla@emulex.com>
+
+[ Upstream commit 9e7ceb060754f134231f68cb29d5db31419fe1ed ]
+
+The commit "net: Save TX flow hash in sock and set in skbuf on xmit"
+introduced the inet_set_txhash() and ip6_set_txhash() routines to calculate
+and record flow hash(sk_txhash) in the socket structure. sk_txhash is used
+to set skb->hash which is used to spread flows across multiple TXQs.
+
+But, the above routines are invoked before the source port of the connection
+is created. Because of this all outgoing connections that just differ in the
+source port get hashed into the same TXQ.
+
+This patch fixes this problem for IPv4/6 by invoking the the above routines
+after the source port is available for the socket.
+
+Fixes: b73c3d0e4("net: Save TX flow hash in sock and set in skbuf on xmit")
+
+Signed-off-by: Sathya Perla <sathya.perla@emulex.com>
+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/ipv4/tcp_ipv4.c | 4 ++--
+ net/ipv6/tcp_ipv6.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -208,8 +208,6 @@ int tcp_v4_connect(struct sock *sk, stru
+ inet->inet_dport = usin->sin_port;
+ inet->inet_daddr = daddr;
+
+- inet_set_txhash(sk);
+-
+ inet_csk(sk)->icsk_ext_hdr_len = 0;
+ if (inet_opt)
+ inet_csk(sk)->icsk_ext_hdr_len = inet_opt->opt.optlen;
+@@ -226,6 +224,8 @@ int tcp_v4_connect(struct sock *sk, stru
+ if (err)
+ goto failure;
+
++ inet_set_txhash(sk);
++
+ rt = ip_route_newports(fl4, rt, orig_sport, orig_dport,
+ inet->inet_sport, inet->inet_dport, sk);
+ if (IS_ERR(rt)) {
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -198,8 +198,6 @@ static int tcp_v6_connect(struct sock *s
+ sk->sk_v6_daddr = usin->sin6_addr;
+ np->flow_label = fl6.flowlabel;
+
+- ip6_set_txhash(sk);
+-
+ /*
+ * TCP over IPv4
+ */
+@@ -295,6 +293,8 @@ static int tcp_v6_connect(struct sock *s
+ if (err)
+ goto late_failure;
+
++ ip6_set_txhash(sk);
++
+ if (!tp->write_seq && likely(!tp->repair))
+ tp->write_seq = secure_tcpv6_sequence_number(np->saddr.s6_addr32,
+ sk->sk_v6_daddr.s6_addr32,
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Or Gerlitz <ogerlitz@mellanox.com>
+Date: Thu, 30 Oct 2014 15:59:27 +0200
+Subject: net/mlx4_en: Don't attempt to TX offload the outer UDP checksum for VXLAN
+
+From: Or Gerlitz <ogerlitz@mellanox.com>
+
+[ Upstream commit a4f2dacbf2a5045e34b98a35d9a3857800f25a7b ]
+
+For VXLAN/NVGRE encapsulation, the current HW doesn't support offloading
+both the outer UDP TX checksum and the inner TCP/UDP TX checksum.
+
+The driver doesn't advertize SKB_GSO_UDP_TUNNEL_CSUM, however we are wrongly
+telling the HW to offload the outer UDP checksum for encapsulated packets,
+fix that.
+
+Fixes: 837052d0ccc5 ('net/mlx4_en: Add netdev support for TCP/IP
+ offloads of vxlan tunneling')
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/mellanox/mlx4/en_tx.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx4/en_tx.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_tx.c
+@@ -808,8 +808,11 @@ netdev_tx_t mlx4_en_xmit(struct sk_buff
+ tx_desc->ctrl.fence_size = (real_size / 16) & 0x3f;
+ tx_desc->ctrl.srcrb_flags = priv->ctrl_flags;
+ if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) {
+- tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
+- MLX4_WQE_CTRL_TCP_UDP_CSUM);
++ if (!skb->encapsulation)
++ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM |
++ MLX4_WQE_CTRL_TCP_UDP_CSUM);
++ else
++ tx_desc->ctrl.srcrb_flags |= cpu_to_be32(MLX4_WQE_CTRL_IP_CSUM);
+ ring->tx_csum++;
+ }
+
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Karl Beldan <karl.beldan@rivierawaves.com>
+Date: Tue, 21 Oct 2014 16:06:05 +0200
+Subject: net: tso: fix unaligned access to crafted TCP header in helper API
+
+From: Karl Beldan <karl.beldan@rivierawaves.com>
+
+[ Upstream commit a63ba13eec092b70d4e5522d692eaeb2f9747387 ]
+
+The crafted header start address is from a driver supplied buffer, which
+one can reasonably expect to be aligned on a 4-bytes boundary.
+However ATM the TSO helper API is only used by ethernet drivers and
+the tcp header will then be aligned to a 2-bytes only boundary from the
+header start address.
+
+Signed-off-by: Karl Beldan <karl.beldan@rivierawaves.com>
+Cc: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/tso.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/core/tso.c
++++ b/net/core/tso.c
+@@ -1,6 +1,7 @@
+ #include <linux/export.h>
+ #include <net/ip.h>
+ #include <net/tso.h>
++#include <asm/unaligned.h>
+
+ /* Calculate expected number of TX descriptors */
+ int tso_count_descs(struct sk_buff *skb)
+@@ -23,7 +24,7 @@ void tso_build_hdr(struct sk_buff *skb,
+ iph->id = htons(tso->ip_id);
+ iph->tot_len = htons(size + hdr_len - mac_hdr_len);
+ tcph = (struct tcphdr *)(hdr + skb_transport_offset(skb));
+- tcph->seq = htonl(tso->tcp_seq);
++ put_unaligned_be32(tso->tcp_seq, &tcph->seq);
+ tso->ip_id++;
+
+ if (!is_last) {
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Thomas Graf <tgraf@suug.ch>
+Date: Tue, 21 Oct 2014 22:05:38 +0200
+Subject: netlink: Re-add locking to netlink_lookup() and seq walker
+
+From: Thomas Graf <tgraf@suug.ch>
+
+[ Upstream commit 78fd1d0ab072d4d9b5f0b7c14a1516665170b565 ]
+
+The synchronize_rcu() in netlink_release() introduces unacceptable
+latency. Reintroduce minimal lookup so we can drop the
+synchronize_rcu() until socket destruction has been RCUfied.
+
+Cc: David S. Miller <davem@davemloft.net>
+Cc: Eric Dumazet <eric.dumazet@gmail.com>
+Reported-by: Steinar H. Gunderson <sgunderson@bigfoot.com>
+Reported-and-tested-by: Heiko Carstens <heiko.carstens@de.ibm.com>
+Signed-off-by: Thomas Graf <tgraf@suug.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netlink/af_netlink.c | 37 +++++++++++++++++++++++++------------
+ 1 file changed, 25 insertions(+), 12 deletions(-)
+
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -96,6 +96,14 @@ static DECLARE_WAIT_QUEUE_HEAD(nl_table_
+ static int netlink_dump(struct sock *sk);
+ static void netlink_skb_destructor(struct sk_buff *skb);
+
++/* nl_table locking explained:
++ * Lookup and traversal are protected with nl_sk_hash_lock or nl_table_lock
++ * combined with an RCU read-side lock. Insertion and removal are protected
++ * with nl_sk_hash_lock while using RCU list modification primitives and may
++ * run in parallel to nl_table_lock protected lookups. Destruction of the
++ * Netlink socket may only occur *after* nl_table_lock has been acquired
++ * either during or after the socket has been removed from the list.
++ */
+ DEFINE_RWLOCK(nl_table_lock);
+ EXPORT_SYMBOL_GPL(nl_table_lock);
+ static atomic_t nl_table_users = ATOMIC_INIT(0);
+@@ -109,10 +117,10 @@ EXPORT_SYMBOL_GPL(nl_sk_hash_lock);
+ static int lockdep_nl_sk_hash_is_held(void)
+ {
+ #ifdef CONFIG_LOCKDEP
+- return (debug_locks) ? lockdep_is_held(&nl_sk_hash_lock) : 1;
+-#else
+- return 1;
++ if (debug_locks)
++ return lockdep_is_held(&nl_sk_hash_lock) || lockdep_is_held(&nl_table_lock);
+ #endif
++ return 1;
+ }
+
+ static ATOMIC_NOTIFIER_HEAD(netlink_chain);
+@@ -1028,11 +1036,13 @@ static struct sock *netlink_lookup(struc
+ struct netlink_table *table = &nl_table[protocol];
+ struct sock *sk;
+
++ read_lock(&nl_table_lock);
+ rcu_read_lock();
+ sk = __netlink_lookup(table, portid, net);
+ if (sk)
+ sock_hold(sk);
+ rcu_read_unlock();
++ read_unlock(&nl_table_lock);
+
+ return sk;
+ }
+@@ -1257,9 +1267,6 @@ static int netlink_release(struct socket
+ }
+ netlink_table_ungrab();
+
+- /* Wait for readers to complete */
+- synchronize_net();
+-
+ kfree(nlk->groups);
+ nlk->groups = NULL;
+
+@@ -1281,6 +1288,7 @@ static int netlink_autobind(struct socke
+
+ retry:
+ cond_resched();
++ netlink_table_grab();
+ rcu_read_lock();
+ if (__netlink_lookup(table, portid, net)) {
+ /* Bind collision, search negative portid values. */
+@@ -1288,9 +1296,11 @@ retry:
+ if (rover > -4097)
+ rover = -4097;
+ rcu_read_unlock();
++ netlink_table_ungrab();
+ goto retry;
+ }
+ rcu_read_unlock();
++ netlink_table_ungrab();
+
+ err = netlink_insert(sk, net, portid);
+ if (err == -EADDRINUSE)
+@@ -2921,14 +2931,16 @@ static struct sock *netlink_seq_socket_i
+ }
+
+ static void *netlink_seq_start(struct seq_file *seq, loff_t *pos)
+- __acquires(RCU)
++ __acquires(nl_table_lock) __acquires(RCU)
+ {
++ read_lock(&nl_table_lock);
+ rcu_read_lock();
+ return *pos ? netlink_seq_socket_idx(seq, *pos - 1) : SEQ_START_TOKEN;
+ }
+
+ static void *netlink_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
++ struct rhashtable *ht;
+ struct netlink_sock *nlk;
+ struct nl_seq_iter *iter;
+ struct net *net;
+@@ -2943,19 +2955,19 @@ static void *netlink_seq_next(struct seq
+ iter = seq->private;
+ nlk = v;
+
+- rht_for_each_entry_rcu(nlk, nlk->node.next, node)
++ i = iter->link;
++ ht = &nl_table[i].hash;
++ rht_for_each_entry(nlk, nlk->node.next, ht, node)
+ if (net_eq(sock_net((struct sock *)nlk), net))
+ return nlk;
+
+- i = iter->link;
+ j = iter->hash_idx + 1;
+
+ do {
+- struct rhashtable *ht = &nl_table[i].hash;
+ const struct bucket_table *tbl = rht_dereference_rcu(ht->tbl, ht);
+
+ for (; j < tbl->size; j++) {
+- rht_for_each_entry_rcu(nlk, tbl->buckets[j], node) {
++ rht_for_each_entry(nlk, tbl->buckets[j], ht, node) {
+ if (net_eq(sock_net((struct sock *)nlk), net)) {
+ iter->link = i;
+ iter->hash_idx = j;
+@@ -2971,9 +2983,10 @@ static void *netlink_seq_next(struct seq
+ }
+
+ static void netlink_seq_stop(struct seq_file *seq, void *v)
+- __releases(RCU)
++ __releases(RCU) __releases(nl_table_lock)
+ {
+ rcu_read_unlock();
++ read_unlock(&nl_table_lock);
+ }
+
+
tracing-syscalls-ignore-numbers-outside-nr_syscalls-range.patch
kvm-emulator-fix-execution-close-to-the-segment-limit.patch
+x86-bpf_jit-fix-two-bugs-in-ebpf-jit-compiler.patch
+ipv4-fix-nexthop-attlen-check-in-fib_nh_match.patch
+vxlan-fix-a-use-after-free-in-vxlan_encap_bypass.patch
+vxlan-using-pskb_may_pull-as-early-as-possible.patch
+vxlan-fix-a-free-after-use.patch
+ipv4-dst_entry-leak-in-ip_send_unicast_reply.patch
+ipv4-fix-a-potential-use-after-free-in-ip_tunnel_core.c.patch
+tipc-fix-bug-in-bundled-buffer-reception.patch
+ax88179_178a-fix-bonding-failure.patch
+netlink-re-add-locking-to-netlink_lookup-and-seq-walker.patch
+net-tso-fix-unaligned-access-to-crafted-tcp-header-in-helper-api.patch
+net-fix-saving-tx-flow-hash-in-sock-for-outgoing-connections.patch
+hyperv-fix-the-total_data_buflen-in-send-path.patch
+tcp-md5-do-not-use-alloc_percpu.patch
+macvlan-fix-a-race-on-port-dismantle-and-possible-skb-leaks.patch
+cxgb4-fix-missing-initialization-of-win0_lock.patch
+ipv4-do-not-cache-routing-failures-due-to-disabled-forwarding.patch
+net-mlx4_en-don-t-attempt-to-tx-offload-the-outer-udp-checksum-for-vxlan.patch
+mlx4-avoid-leaking-steering-rules-on-flow-creation-error-flow.patch
+gre-use-inner-mac-length-when-computing-tunnel-length.patch
+drivers-net-disable-ufo-through-virtio.patch
+drivers-net-ipv6-select-ipv6-fragment-idents-for-virtio-ufo-packets.patch
+drivers-net-macvtap-and-tun-depend-on-inet.patch
+stmmac-pci-set-default-of-the-filter-bins.patch
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Date: Fri, 31 Oct 2014 18:28:03 +0200
+Subject: stmmac: pci: set default of the filter bins
+
+From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+
+[ Upstream commit 1e19e084eae727654052339757ab7f1eaff58bad ]
+
+The commit 3b57de958e2a brought the support for a different amount of the
+filter bins, but didn't update the PCI driver accordingly. This patch appends
+the default values when the device is enumerated via PCI bus.
+
+Fixes: 3b57de958e2a (net: stmmac: Support devicetree configs for mcast and ucast filter entries)
+Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
+@@ -33,6 +33,7 @@ static struct stmmac_dma_cfg dma_cfg;
+ static void stmmac_default_data(void)
+ {
+ memset(&plat_dat, 0, sizeof(struct plat_stmmacenet_data));
++
+ plat_dat.bus_id = 1;
+ plat_dat.phy_addr = 0;
+ plat_dat.interface = PHY_INTERFACE_MODE_GMII;
+@@ -47,6 +48,12 @@ static void stmmac_default_data(void)
+ dma_cfg.pbl = 32;
+ dma_cfg.burst_len = DMA_AXI_BLEN_256;
+ plat_dat.dma_cfg = &dma_cfg;
++
++ /* Set default value for multicast hash bins */
++ plat_dat.multicast_filter_bins = HASH_TABLE_SIZE;
++
++ /* Set default value for unicast filter entries */
++ plat_dat.unicast_filter_entries = 1;
+ }
+
+ /**
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Eric Dumazet <edumazet@google.com>
+Date: Thu, 23 Oct 2014 12:58:58 -0700
+Subject: tcp: md5: do not use alloc_percpu()
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 349ce993ac706869d553a1816426d3a4bfda02b1 ]
+
+percpu tcp_md5sig_pool contains memory blobs that ultimately
+go through sg_set_buf().
+
+-> sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
+
+This requires that whole area is in a physically contiguous portion
+of memory. And that @buf is not backed by vmalloc().
+
+Given that alloc_percpu() can use vmalloc() areas, this does not
+fit the requirements.
+
+Replace alloc_percpu() by a static DEFINE_PER_CPU() as tcp_md5sig_pool
+is small anyway, there is no gain to dynamically allocate it.
+
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Fixes: 765cf9976e93 ("tcp: md5: remove one indirection level in tcp_md5sig_pool")
+Reported-by: Crestez Dan Leonard <cdleonard@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp.c | 59 +++++++++++++++++++--------------------------------------
+ 1 file changed, 20 insertions(+), 39 deletions(-)
+
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -2985,61 +2985,42 @@ EXPORT_SYMBOL(compat_tcp_getsockopt);
+ #endif
+
+ #ifdef CONFIG_TCP_MD5SIG
+-static struct tcp_md5sig_pool __percpu *tcp_md5sig_pool __read_mostly;
++static DEFINE_PER_CPU(struct tcp_md5sig_pool, tcp_md5sig_pool);
+ static DEFINE_MUTEX(tcp_md5sig_mutex);
+-
+-static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool __percpu *pool)
+-{
+- int cpu;
+-
+- for_each_possible_cpu(cpu) {
+- struct tcp_md5sig_pool *p = per_cpu_ptr(pool, cpu);
+-
+- if (p->md5_desc.tfm)
+- crypto_free_hash(p->md5_desc.tfm);
+- }
+- free_percpu(pool);
+-}
++static bool tcp_md5sig_pool_populated = false;
+
+ static void __tcp_alloc_md5sig_pool(void)
+ {
+ int cpu;
+- struct tcp_md5sig_pool __percpu *pool;
+-
+- pool = alloc_percpu(struct tcp_md5sig_pool);
+- if (!pool)
+- return;
+
+ for_each_possible_cpu(cpu) {
+- struct crypto_hash *hash;
++ if (!per_cpu(tcp_md5sig_pool, cpu).md5_desc.tfm) {
++ struct crypto_hash *hash;
+
+- hash = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
+- if (IS_ERR_OR_NULL(hash))
+- goto out_free;
+-
+- per_cpu_ptr(pool, cpu)->md5_desc.tfm = hash;
++ hash = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
++ if (IS_ERR_OR_NULL(hash))
++ return;
++ per_cpu(tcp_md5sig_pool, cpu).md5_desc.tfm = hash;
++ }
+ }
+- /* before setting tcp_md5sig_pool, we must commit all writes
+- * to memory. See ACCESS_ONCE() in tcp_get_md5sig_pool()
++ /* before setting tcp_md5sig_pool_populated, we must commit all writes
++ * to memory. See smp_rmb() in tcp_get_md5sig_pool()
+ */
+ smp_wmb();
+- tcp_md5sig_pool = pool;
+- return;
+-out_free:
+- __tcp_free_md5sig_pool(pool);
++ tcp_md5sig_pool_populated = true;
+ }
+
+ bool tcp_alloc_md5sig_pool(void)
+ {
+- if (unlikely(!tcp_md5sig_pool)) {
++ if (unlikely(!tcp_md5sig_pool_populated)) {
+ mutex_lock(&tcp_md5sig_mutex);
+
+- if (!tcp_md5sig_pool)
++ if (!tcp_md5sig_pool_populated)
+ __tcp_alloc_md5sig_pool();
+
+ mutex_unlock(&tcp_md5sig_mutex);
+ }
+- return tcp_md5sig_pool != NULL;
++ return tcp_md5sig_pool_populated;
+ }
+ EXPORT_SYMBOL(tcp_alloc_md5sig_pool);
+
+@@ -3053,13 +3034,13 @@ EXPORT_SYMBOL(tcp_alloc_md5sig_pool);
+ */
+ struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
+ {
+- struct tcp_md5sig_pool __percpu *p;
+-
+ local_bh_disable();
+- p = ACCESS_ONCE(tcp_md5sig_pool);
+- if (p)
+- return __this_cpu_ptr(p);
+
++ if (tcp_md5sig_pool_populated) {
++ /* coupled with smp_wmb() in __tcp_alloc_md5sig_pool() */
++ smp_rmb();
++ return this_cpu_ptr(&tcp_md5sig_pool);
++ }
+ local_bh_enable();
+ return NULL;
+ }
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Jon Paul Maloy <jon.maloy@ericsson.com>
+Date: Fri, 17 Oct 2014 15:25:28 -0400
+Subject: tipc: fix bug in bundled buffer reception
+
+From: Jon Paul Maloy <jon.maloy@ericsson.com>
+
+[ Upstream commit 643566d4b47e2956110e79c0e6f65db9b9ea42c6 ]
+
+In commit ec8a2e5621db2da24badb3969eda7fd359e1869f ("tipc: same receive
+code path for connection protocol and data messages") we omitted the
+the possiblilty that an arriving message extracted from a bundle buffer
+may be a multicast message. Such messages need to be to be delivered to
+the socket via a separate function, tipc_sk_mcast_rcv(). As a result,
+small multicast messages arriving as members of a bundle buffer will be
+silently dropped.
+
+This commit corrects the error by considering this case in the function
+tipc_link_bundle_rcv().
+
+Signed-off-by: Jon Maloy <jon.maloy@ericsson.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/tipc/link.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/tipc/link.c
++++ b/net/tipc/link.c
+@@ -1936,7 +1936,12 @@ void tipc_link_bundle_rcv(struct sk_buff
+ }
+ omsg = buf_msg(obuf);
+ pos += align(msg_size(omsg));
+- if (msg_isdata(omsg) || (msg_user(omsg) == CONN_MANAGER)) {
++ if (msg_isdata(omsg)) {
++ if (unlikely(msg_type(omsg) == TIPC_MCAST_MSG))
++ tipc_sk_mcast_rcv(obuf);
++ else
++ tipc_sk_rcv(obuf);
++ } else if (msg_user(omsg) == CONN_MANAGER) {
+ tipc_sk_rcv(obuf);
+ } else if (msg_user(omsg) == NAME_DISTRIBUTOR) {
+ tipc_named_rcv(obuf);
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Li RongQing <roy.qing.li@gmail.com>
+Date: Fri, 17 Oct 2014 14:06:16 +0800
+Subject: vxlan: fix a free after use
+
+From: Li RongQing <roy.qing.li@gmail.com>
+
+[ Upstream commit 7a9f526fc3ee49b6034af2f243676ee0a27dcaa8 ]
+
+pskb_may_pull maybe change skb->data and make eth pointer oboslete,
+so eth needs to reload
+
+Fixes: 91269e390d062 ("vxlan: using pskb_may_pull as early as possible")
+Cc: Eric Dumazet <edumazet@google.com>
+Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vxlan.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -1936,6 +1936,7 @@ static netdev_tx_t vxlan_xmit(struct sk_
+ msg->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION)
+ return neigh_reduce(dev, skb);
+ }
++ eth = eth_hdr(skb);
+ #endif
+ }
+
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Li RongQing <roy.qing.li@gmail.com>
+Date: Thu, 16 Oct 2014 08:49:41 +0800
+Subject: vxlan: fix a use after free in vxlan_encap_bypass
+
+From: Li RongQing <roy.qing.li@gmail.com>
+
+[ Upstream commit ce6502a8f9572179f044a4d62667c4645256d6e4 ]
+
+when netif_rx() is done, the netif_rx handled skb maybe be freed,
+and should not be used.
+
+Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vxlan.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -1717,6 +1717,8 @@ static void vxlan_encap_bypass(struct sk
+ struct pcpu_sw_netstats *tx_stats, *rx_stats;
+ union vxlan_addr loopback;
+ union vxlan_addr *remote_ip = &dst_vxlan->default_dst.remote_ip;
++ struct net_device *dev = skb->dev;
++ int len = skb->len;
+
+ tx_stats = this_cpu_ptr(src_vxlan->dev->tstats);
+ rx_stats = this_cpu_ptr(dst_vxlan->dev->tstats);
+@@ -1740,16 +1742,16 @@ static void vxlan_encap_bypass(struct sk
+
+ u64_stats_update_begin(&tx_stats->syncp);
+ tx_stats->tx_packets++;
+- tx_stats->tx_bytes += skb->len;
++ tx_stats->tx_bytes += len;
+ u64_stats_update_end(&tx_stats->syncp);
+
+ if (netif_rx(skb) == NET_RX_SUCCESS) {
+ u64_stats_update_begin(&rx_stats->syncp);
+ rx_stats->rx_packets++;
+- rx_stats->rx_bytes += skb->len;
++ rx_stats->rx_bytes += len;
+ u64_stats_update_end(&rx_stats->syncp);
+ } else {
+- skb->dev->stats.rx_dropped++;
++ dev->stats.rx_dropped++;
+ }
+ }
+
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Li RongQing <roy.qing.li@gmail.com>
+Date: Thu, 16 Oct 2014 09:17:18 +0800
+Subject: vxlan: using pskb_may_pull as early as possible
+
+From: Li RongQing <roy.qing.li@gmail.com>
+
+[ Upstream commit 91269e390d062b526432f2ef1352b8df82e0e0bc ]
+
+pskb_may_pull should be used to check if skb->data has enough space,
+skb->len can not ensure that.
+
+Cc: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/vxlan.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -1440,9 +1440,6 @@ static int neigh_reduce(struct net_devic
+ if (!in6_dev)
+ goto out;
+
+- if (!pskb_may_pull(skb, skb->len))
+- goto out;
+-
+ iphdr = ipv6_hdr(skb);
+ saddr = &iphdr->saddr;
+ daddr = &iphdr->daddr;
+@@ -1929,7 +1926,8 @@ static netdev_tx_t vxlan_xmit(struct sk_
+ return arp_reduce(dev, skb);
+ #if IS_ENABLED(CONFIG_IPV6)
+ else if (ntohs(eth->h_proto) == ETH_P_IPV6 &&
+- skb->len >= sizeof(struct ipv6hdr) + sizeof(struct nd_msg) &&
++ pskb_may_pull(skb, sizeof(struct ipv6hdr)
++ + sizeof(struct nd_msg)) &&
+ ipv6_hdr(skb)->nexthdr == IPPROTO_ICMPV6) {
+ struct nd_msg *msg;
+
--- /dev/null
+From foo@baz Fri Nov 7 11:36:50 PST 2014
+From: Alexei Starovoitov <ast@plumgrid.com>
+Date: Fri, 10 Oct 2014 20:30:23 -0700
+Subject: x86: bpf_jit: fix two bugs in eBPF JIT compiler
+
+From: Alexei Starovoitov <ast@plumgrid.com>
+
+[ Upstream commit e0ee9c12157dc74e49e4731e0d07512e7d1ceb95 ]
+
+1.
+JIT compiler using multi-pass approach to converge to final image size,
+since x86 instructions are variable length. It starts with large
+gaps between instructions (so some jumps may use imm32 instead of imm8)
+and iterates until total program size is the same as in previous pass.
+This algorithm works only if program size is strictly decreasing.
+Programs that use LD_ABS insn need additional code in prologue, but it
+was not emitted during 1st pass, so there was a chance that 2nd pass would
+adjust imm32->imm8 jump offsets to the same number of bytes as increase in
+prologue, which may cause algorithm to erroneously decide that size converged.
+Fix it by always emitting largest prologue in the first pass which
+is detected by oldproglen==0 check.
+Also change error check condition 'proglen != oldproglen' to fail gracefully.
+
+2.
+while staring at the code realized that 64-byte buffer may not be enough
+when 1st insn is large, so increase it to 128 to avoid buffer overflow
+(theoretical maximum size of prologue+div is 109) and add runtime check.
+
+Fixes: 622582786c9e ("net: filter: x86: internal BPF JIT")
+Reported-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
+Tested-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/x86/net/bpf_jit_comp.c | 25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+--- a/arch/x86/net/bpf_jit_comp.c
++++ b/arch/x86/net/bpf_jit_comp.c
+@@ -211,12 +211,17 @@ struct jit_context {
+ bool seen_ld_abs;
+ };
+
++/* maximum number of bytes emitted while JITing one eBPF insn */
++#define BPF_MAX_INSN_SIZE 128
++#define BPF_INSN_SAFETY 64
++
+ static int do_jit(struct bpf_prog *bpf_prog, int *addrs, u8 *image,
+ int oldproglen, struct jit_context *ctx)
+ {
+ struct bpf_insn *insn = bpf_prog->insnsi;
+ int insn_cnt = bpf_prog->len;
+- u8 temp[64];
++ bool seen_ld_abs = ctx->seen_ld_abs | (oldproglen == 0);
++ u8 temp[BPF_MAX_INSN_SIZE + BPF_INSN_SAFETY];
+ int i;
+ int proglen = 0;
+ u8 *prog = temp;
+@@ -254,7 +259,7 @@ static int do_jit(struct bpf_prog *bpf_p
+ EMIT2(0x31, 0xc0); /* xor eax, eax */
+ EMIT3(0x4D, 0x31, 0xED); /* xor r13, r13 */
+
+- if (ctx->seen_ld_abs) {
++ if (seen_ld_abs) {
+ /* r9d : skb->len - skb->data_len (headlen)
+ * r10 : skb->data
+ */
+@@ -655,7 +660,7 @@ xadd: if (is_imm8(insn->off))
+ case BPF_JMP | BPF_CALL:
+ func = (u8 *) __bpf_call_base + imm32;
+ jmp_offset = func - (image + addrs[i]);
+- if (ctx->seen_ld_abs) {
++ if (seen_ld_abs) {
+ EMIT2(0x41, 0x52); /* push %r10 */
+ EMIT2(0x41, 0x51); /* push %r9 */
+ /* need to adjust jmp offset, since
+@@ -669,7 +674,7 @@ xadd: if (is_imm8(insn->off))
+ return -EINVAL;
+ }
+ EMIT1_off32(0xE8, jmp_offset);
+- if (ctx->seen_ld_abs) {
++ if (seen_ld_abs) {
+ EMIT2(0x41, 0x59); /* pop %r9 */
+ EMIT2(0x41, 0x5A); /* pop %r10 */
+ }
+@@ -774,7 +779,8 @@ emit_jmp:
+ goto common_load;
+ case BPF_LD | BPF_ABS | BPF_W:
+ func = CHOOSE_LOAD_FUNC(imm32, sk_load_word);
+-common_load: ctx->seen_ld_abs = true;
++common_load:
++ ctx->seen_ld_abs = seen_ld_abs = true;
+ jmp_offset = func - (image + addrs[i]);
+ if (!func || !is_simm32(jmp_offset)) {
+ pr_err("unsupported bpf func %d addr %p image %p\n",
+@@ -848,6 +854,11 @@ common_load: ctx->seen_ld_abs = true;
+ }
+
+ ilen = prog - temp;
++ if (ilen > BPF_MAX_INSN_SIZE) {
++ pr_err("bpf_jit_compile fatal insn size error\n");
++ return -EFAULT;
++ }
++
+ if (image) {
+ if (unlikely(proglen + ilen > oldproglen)) {
+ pr_err("bpf_jit_compile fatal error\n");
+@@ -904,9 +915,11 @@ void bpf_int_jit_compile(struct bpf_prog
+ goto out;
+ }
+ if (image) {
+- if (proglen != oldproglen)
++ if (proglen != oldproglen) {
+ pr_err("bpf_jit: proglen=%d != oldproglen=%d\n",
+ proglen, oldproglen);
++ goto out;
++ }
+ break;
+ }
+ if (proglen == oldproglen) {