]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Jul 2017 09:52:44 +0000 (11:52 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 18 Jul 2017 09:52:44 +0000 (11:52 +0200)
added patches:
brcmfmac-fix-a-memory-leak-in-error-handling-path-in-brcmf_cfg80211_attach.patch
brcmfmac-fix-glom_skb-leak-in-brcmf_sdiod_recv_chain.patch
brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch
ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch
net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch
net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch
net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch
rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch
sfc-don-t-read-beyond-unicast-address-list.patch
vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch
vxlan-fix-hlist-corruption.patch

12 files changed:
queue-4.9/brcmfmac-fix-a-memory-leak-in-error-handling-path-in-brcmf_cfg80211_attach.patch [new file with mode: 0644]
queue-4.9/brcmfmac-fix-glom_skb-leak-in-brcmf_sdiod_recv_chain.patch [new file with mode: 0644]
queue-4.9/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch [new file with mode: 0644]
queue-4.9/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch [new file with mode: 0644]
queue-4.9/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch [new file with mode: 0644]
queue-4.9/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch [new file with mode: 0644]
queue-4.9/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch [new file with mode: 0644]
queue-4.9/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch [new file with mode: 0644]
queue-4.9/series
queue-4.9/sfc-don-t-read-beyond-unicast-address-list.patch [new file with mode: 0644]
queue-4.9/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch [new file with mode: 0644]
queue-4.9/vxlan-fix-hlist-corruption.patch [new file with mode: 0644]

diff --git a/queue-4.9/brcmfmac-fix-a-memory-leak-in-error-handling-path-in-brcmf_cfg80211_attach.patch b/queue-4.9/brcmfmac-fix-a-memory-leak-in-error-handling-path-in-brcmf_cfg80211_attach.patch
new file mode 100644 (file)
index 0000000..ca39cb4
--- /dev/null
@@ -0,0 +1,40 @@
+From 57c00f2fac512837f8de73474ec1f54020015bae Mon Sep 17 00:00:00 2001
+From: Christophe Jaillet <christophe.jaillet@wanadoo.fr>
+Date: Wed, 21 Jun 2017 07:45:53 +0200
+Subject: brcmfmac: Fix a memory leak in error handling path in 'brcmf_cfg80211_attach'
+
+From: Christophe Jaillet <christophe.jaillet@wanadoo.fr>
+
+commit 57c00f2fac512837f8de73474ec1f54020015bae upstream.
+
+If 'wiphy_new()' fails, we leak 'ops'. Add a new label in the error
+handling path to free it in such a case.
+
+Fixes: 5c22fb85102a7 ("brcmfmac: add wowl gtk rekeying offload support")
+Signed-off-by: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -6876,7 +6876,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
+       wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info));
+       if (!wiphy) {
+               brcmf_err("Could not allocate wiphy device\n");
+-              return NULL;
++              goto ops_out;
+       }
+       memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
+       set_wiphy_dev(wiphy, busdev);
+@@ -7010,6 +7010,7 @@ priv_out:
+       ifp->vif = NULL;
+ wiphy_out:
+       brcmf_free_wiphy(wiphy);
++ops_out:
+       kfree(ops);
+       return NULL;
+ }
diff --git a/queue-4.9/brcmfmac-fix-glom_skb-leak-in-brcmf_sdiod_recv_chain.patch b/queue-4.9/brcmfmac-fix-glom_skb-leak-in-brcmf_sdiod_recv_chain.patch
new file mode 100644 (file)
index 0000000..6bfe5e3
--- /dev/null
@@ -0,0 +1,58 @@
+From 5ea59db8a375216e6c915c5586f556766673b5a7 Mon Sep 17 00:00:00 2001
+From: "Peter S. Housel" <housel@acm.org>
+Date: Mon, 12 Jun 2017 11:46:22 +0100
+Subject: brcmfmac: Fix glom_skb leak in brcmf_sdiod_recv_chain
+
+From: Peter S. Housel <housel@acm.org>
+
+commit 5ea59db8a375216e6c915c5586f556766673b5a7 upstream.
+
+An earlier change to this function (3bdae810721b) fixed a leak in the
+case of an unsuccessful call to brcmf_sdiod_buffrw(). However, the
+glom_skb buffer, used for emulating a scattering read, is never used
+or referenced after its contents are copied into the destination
+buffers, and therefore always needs to be freed by the end of the
+function.
+
+Fixes: 3bdae810721b ("brcmfmac: Fix glob_skb leak in brcmf_sdiod_recv_chain")
+Fixes: a413e39a38573 ("brcmfmac: fix brcmf_sdcard_recv_chain() for host without sg support")
+Signed-off-by: Peter S. Housel <housel@acm.org>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c |    7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -705,7 +705,7 @@ done:
+ int brcmf_sdiod_recv_chain(struct brcmf_sdio_dev *sdiodev,
+                          struct sk_buff_head *pktq, uint totlen)
+ {
+-      struct sk_buff *glom_skb;
++      struct sk_buff *glom_skb = NULL;
+       struct sk_buff *skb;
+       u32 addr = sdiodev->sbwad;
+       int err = 0;
+@@ -726,10 +726,8 @@ int brcmf_sdiod_recv_chain(struct brcmf_
+                       return -ENOMEM;
+               err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
+                                        glom_skb);
+-              if (err) {
+-                      brcmu_pkt_buf_free_skb(glom_skb);
++              if (err)
+                       goto done;
+-              }
+               skb_queue_walk(pktq, skb) {
+                       memcpy(skb->data, glom_skb->data, skb->len);
+@@ -740,6 +738,7 @@ int brcmf_sdiod_recv_chain(struct brcmf_
+                                           pktq);
+ done:
++      brcmu_pkt_buf_free_skb(glom_skb);
+       return err;
+ }
diff --git a/queue-4.9/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch b/queue-4.9/brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch
new file mode 100644 (file)
index 0000000..37b4301
--- /dev/null
@@ -0,0 +1,45 @@
+From 8f44c9a41386729fea410e688959ddaa9d51be7c Mon Sep 17 00:00:00 2001
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+Date: Fri, 7 Jul 2017 21:09:06 +0100
+Subject: brcmfmac: fix possible buffer overflow in brcmf_cfg80211_mgmt_tx()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Arend van Spriel <arend.vanspriel@broadcom.com>
+
+commit 8f44c9a41386729fea410e688959ddaa9d51be7c upstream.
+
+The lower level nl80211 code in cfg80211 ensures that "len" is between
+25 and NL80211_ATTR_FRAME (2304).  We subtract DOT11_MGMT_HDR_LEN (24) from
+"len" so thats's max of 2280.  However, the action_frame->data[] buffer is
+only BRCMF_FIL_ACTION_FRAME_SIZE (1800) bytes long so this memcpy() can
+overflow.
+
+       memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
+              le16_to_cpu(action_frame->len));
+
+Fixes: 18e2f61db3b70 ("brcmfmac: P2P action frame tx.")
+Reported-by: "freenerguo(郭大兴)" <freenerguo@tencent.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |    5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -4928,6 +4928,11 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip
+               cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
+                                       GFP_KERNEL);
+       } else if (ieee80211_is_action(mgmt->frame_control)) {
++              if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
++                      brcmf_err("invalid action frame length\n");
++                      err = -EINVAL;
++                      goto exit;
++              }
+               af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
+               if (af_params == NULL) {
+                       brcmf_err("unable to allocate frame\n");
diff --git a/queue-4.9/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch b/queue-4.9/ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch
new file mode 100644 (file)
index 0000000..3eef138
--- /dev/null
@@ -0,0 +1,76 @@
+From ec8add2a4c9df723c94a863b8fcd6d93c472deed Mon Sep 17 00:00:00 2001
+From: Sabrina Dubroca <sd@queasysnail.net>
+Date: Thu, 29 Jun 2017 16:56:54 +0200
+Subject: ipv6: dad: don't remove dynamic addresses if link is down
+
+From: Sabrina Dubroca <sd@queasysnail.net>
+
+commit ec8add2a4c9df723c94a863b8fcd6d93c472deed upstream.
+
+Currently, when the link for $DEV is down, this command succeeds but the
+address is removed immediately by DAD (1):
+
+    ip addr add 1111::12/64 dev $DEV valid_lft 3600 preferred_lft 1800
+
+In the same situation, this will succeed and not remove the address (2):
+
+    ip addr add 1111::12/64 dev $DEV
+    ip addr change 1111::12/64 dev $DEV valid_lft 3600 preferred_lft 1800
+
+The comment in addrconf_dad_begin() when !IF_READY makes it look like
+this is the intended behavior, but doesn't explain why:
+
+     * If the device is not ready:
+     * - keep it tentative if it is a permanent address.
+     * - otherwise, kill it.
+
+We clearly cannot prevent userspace from doing (2), but we can make (1)
+work consistently with (2).
+
+addrconf_dad_stop() is only called in two cases: if DAD failed, or to
+skip DAD when the link is down. In that second case, the fix is to avoid
+deleting the address, like we already do for permanent addresses.
+
+Fixes: 3c21edbd1137 ("[IPV6]: Defer IPv6 device initialization until the link becomes ready.")
+Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ipv6/addrconf.c |   18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -1875,15 +1875,7 @@ static void addrconf_dad_stop(struct ine
+       if (dad_failed)
+               ifp->flags |= IFA_F_DADFAILED;
+-      if (ifp->flags&IFA_F_PERMANENT) {
+-              spin_lock_bh(&ifp->lock);
+-              addrconf_del_dad_work(ifp);
+-              ifp->flags |= IFA_F_TENTATIVE;
+-              spin_unlock_bh(&ifp->lock);
+-              if (dad_failed)
+-                      ipv6_ifa_notify(0, ifp);
+-              in6_ifa_put(ifp);
+-      } else if (ifp->flags&IFA_F_TEMPORARY) {
++      if (ifp->flags&IFA_F_TEMPORARY) {
+               struct inet6_ifaddr *ifpub;
+               spin_lock_bh(&ifp->lock);
+               ifpub = ifp->ifpub;
+@@ -1896,6 +1888,14 @@ static void addrconf_dad_stop(struct ine
+                       spin_unlock_bh(&ifp->lock);
+               }
+               ipv6_del_addr(ifp);
++      } else if (ifp->flags&IFA_F_PERMANENT || !dad_failed) {
++              spin_lock_bh(&ifp->lock);
++              addrconf_del_dad_work(ifp);
++              ifp->flags |= IFA_F_TENTATIVE;
++              spin_unlock_bh(&ifp->lock);
++              if (dad_failed)
++                      ipv6_ifa_notify(0, ifp);
++              in6_ifa_put(ifp);
+       } else {
+               ipv6_del_addr(ifp);
+       }
diff --git a/queue-4.9/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch b/queue-4.9/net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch
new file mode 100644 (file)
index 0000000..6c06b36
--- /dev/null
@@ -0,0 +1,174 @@
+From 9af9959e142c274f4a30fefb71d97d2b028b337f Mon Sep 17 00:00:00 2001
+From: Alban Browaeys <alban.browaeys@gmail.com>
+Date: Mon, 3 Jul 2017 03:20:13 +0200
+Subject: net: core: Fix slab-out-of-bounds in netdev_stats_to_stats64
+
+From: Alban Browaeys <alban.browaeys@gmail.com>
+
+commit 9af9959e142c274f4a30fefb71d97d2b028b337f upstream.
+
+commit 9256645af098 ("net/core: relax BUILD_BUG_ON in
+netdev_stats_to_stats64") made an attempt to read beyond
+the size of the source a possibility.
+
+Fix to only copy src size to dest. As dest might be bigger than src.
+
+ ==================================================================
+ BUG: KASAN: slab-out-of-bounds in netdev_stats_to_stats64+0xe/0x30 at addr ffff8801be248b20
+ Read of size 192 by task VBoxNetAdpCtl/6734
+ CPU: 1 PID: 6734 Comm: VBoxNetAdpCtl Tainted: G           O    4.11.4prahal+intel+ #118
+ Hardware name: LENOVO 20CDCTO1WW/20CDCTO1WW, BIOS GQET52WW (1.32 ) 05/04/2017
+ Call Trace:
+  dump_stack+0x63/0x86
+  kasan_object_err+0x1c/0x70
+  kasan_report+0x270/0x520
+  ? netdev_stats_to_stats64+0xe/0x30
+  ? sched_clock_cpu+0x1b/0x190
+  ? __module_address+0x3e/0x3b0
+  ? unwind_next_frame+0x1ea/0xb00
+  check_memory_region+0x13c/0x1a0
+  memcpy+0x23/0x50
+  netdev_stats_to_stats64+0xe/0x30
+  dev_get_stats+0x1b9/0x230
+  rtnl_fill_stats+0x44/0xc00
+  ? nla_put+0xc6/0x130
+  rtnl_fill_ifinfo+0xe9e/0x3700
+  ? rtnl_fill_vfinfo+0xde0/0xde0
+  ? sched_clock+0x9/0x10
+  ? sched_clock+0x9/0x10
+  ? sched_clock_local+0x120/0x130
+  ? __module_address+0x3e/0x3b0
+  ? unwind_next_frame+0x1ea/0xb00
+  ? sched_clock+0x9/0x10
+  ? sched_clock+0x9/0x10
+  ? sched_clock_cpu+0x1b/0x190
+  ? VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp]
+  ? depot_save_stack+0x1d8/0x4a0
+  ? depot_save_stack+0x34f/0x4a0
+  ? depot_save_stack+0x34f/0x4a0
+  ? save_stack+0xb1/0xd0
+  ? save_stack_trace+0x16/0x20
+  ? save_stack+0x46/0xd0
+  ? kasan_slab_alloc+0x12/0x20
+  ? __kmalloc_node_track_caller+0x10d/0x350
+  ? __kmalloc_reserve.isra.36+0x2c/0xc0
+  ? __alloc_skb+0xd0/0x560
+  ? rtmsg_ifinfo_build_skb+0x61/0x120
+  ? rtmsg_ifinfo.part.25+0x16/0xb0
+  ? rtmsg_ifinfo+0x47/0x70
+  ? register_netdev+0x15/0x30
+  ? vboxNetAdpOsCreate+0xc0/0x1c0 [vboxnetadp]
+  ? vboxNetAdpCreate+0x210/0x400 [vboxnetadp]
+  ? VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp]
+  ? do_vfs_ioctl+0x17f/0xff0
+  ? SyS_ioctl+0x74/0x80
+  ? do_syscall_64+0x182/0x390
+  ? __alloc_skb+0xd0/0x560
+  ? __alloc_skb+0xd0/0x560
+  ? save_stack_trace+0x16/0x20
+  ? init_object+0x64/0xa0
+  ? ___slab_alloc+0x1ae/0x5c0
+  ? ___slab_alloc+0x1ae/0x5c0
+  ? __alloc_skb+0xd0/0x560
+  ? sched_clock+0x9/0x10
+  ? kasan_unpoison_shadow+0x35/0x50
+  ? kasan_kmalloc+0xad/0xe0
+  ? __kmalloc_node_track_caller+0x246/0x350
+  ? __alloc_skb+0xd0/0x560
+  ? kasan_unpoison_shadow+0x35/0x50
+  ? memset+0x31/0x40
+  ? __alloc_skb+0x31f/0x560
+  ? napi_consume_skb+0x320/0x320
+  ? br_get_link_af_size_filtered+0xb7/0x120 [bridge]
+  ? if_nlmsg_size+0x440/0x630
+  rtmsg_ifinfo_build_skb+0x83/0x120
+  rtmsg_ifinfo.part.25+0x16/0xb0
+  rtmsg_ifinfo+0x47/0x70
+  register_netdevice+0xa2b/0xe50
+  ? __kmalloc+0x171/0x2d0
+  ? netdev_change_features+0x80/0x80
+  register_netdev+0x15/0x30
+  vboxNetAdpOsCreate+0xc0/0x1c0 [vboxnetadp]
+  vboxNetAdpCreate+0x210/0x400 [vboxnetadp]
+  ? vboxNetAdpComposeMACAddress+0x1d0/0x1d0 [vboxnetadp]
+  ? kasan_check_write+0x14/0x20
+  VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp]
+  ? VBoxNetAdpLinuxOpen+0x20/0x20 [vboxnetadp]
+  ? lock_acquire+0x11c/0x270
+  ? __audit_syscall_entry+0x2fb/0x660
+  do_vfs_ioctl+0x17f/0xff0
+  ? __audit_syscall_entry+0x2fb/0x660
+  ? ioctl_preallocate+0x1d0/0x1d0
+  ? __audit_syscall_entry+0x2fb/0x660
+  ? kmem_cache_free+0xb2/0x250
+  ? syscall_trace_enter+0x537/0xd00
+  ? exit_to_usermode_loop+0x100/0x100
+  SyS_ioctl+0x74/0x80
+  ? do_sys_open+0x350/0x350
+  ? do_vfs_ioctl+0xff0/0xff0
+  do_syscall_64+0x182/0x390
+  entry_SYSCALL64_slow_path+0x25/0x25
+ RIP: 0033:0x7f7e39a1ae07
+ RSP: 002b:00007ffc6f04c6d8 EFLAGS: 00000206 ORIG_RAX: 0000000000000010
+ RAX: ffffffffffffffda RBX: 00007ffc6f04c730 RCX: 00007f7e39a1ae07
+ RDX: 00007ffc6f04c730 RSI: 00000000c0207601 RDI: 0000000000000007
+ RBP: 00007ffc6f04c700 R08: 00007ffc6f04c780 R09: 0000000000000008
+ R10: 0000000000000541 R11: 0000000000000206 R12: 0000000000000007
+ R13: 00000000c0207601 R14: 00007ffc6f04c730 R15: 0000000000000012
+ Object at ffff8801be248008, in cache kmalloc-4096 size: 4096
+ Allocated:
+ PID = 6734
+  save_stack_trace+0x16/0x20
+  save_stack+0x46/0xd0
+  kasan_kmalloc+0xad/0xe0
+  __kmalloc+0x171/0x2d0
+  alloc_netdev_mqs+0x8a7/0xbe0
+  vboxNetAdpOsCreate+0x65/0x1c0 [vboxnetadp]
+  vboxNetAdpCreate+0x210/0x400 [vboxnetadp]
+  VBoxNetAdpLinuxIOCtlUnlocked+0x14b/0x280 [vboxnetadp]
+  do_vfs_ioctl+0x17f/0xff0
+  SyS_ioctl+0x74/0x80
+  do_syscall_64+0x182/0x390
+  return_from_SYSCALL_64+0x0/0x6a
+ Freed:
+ PID = 5600
+  save_stack_trace+0x16/0x20
+  save_stack+0x46/0xd0
+  kasan_slab_free+0x73/0xc0
+  kfree+0xe4/0x220
+  kvfree+0x25/0x30
+  single_release+0x74/0xb0
+  __fput+0x265/0x6b0
+  ____fput+0x9/0x10
+  task_work_run+0xd5/0x150
+  exit_to_usermode_loop+0xe2/0x100
+  do_syscall_64+0x26c/0x390
+  return_from_SYSCALL_64+0x0/0x6a
+ Memory state around the buggy address:
+  ffff8801be248a80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+  ffff8801be248b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+ >ffff8801be248b80: 00 00 00 00 00 00 00 00 00 00 00 07 fc fc fc fc
+                                                     ^
+  ffff8801be248c00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+  ffff8801be248c80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
+ ==================================================================
+
+Signed-off-by: Alban Browaeys <alban.browaeys@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/core/dev.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -7531,7 +7531,7 @@ void netdev_stats_to_stats64(struct rtnl
+ {
+ #if BITS_PER_LONG == 64
+       BUILD_BUG_ON(sizeof(*stats64) < sizeof(*netdev_stats));
+-      memcpy(stats64, netdev_stats, sizeof(*stats64));
++      memcpy(stats64, netdev_stats, sizeof(*netdev_stats));
+       /* zero out counters that only exist in rtnl_link_stats64 */
+       memset((char *)stats64 + sizeof(*netdev_stats), 0,
+              sizeof(*stats64) - sizeof(*netdev_stats));
diff --git a/queue-4.9/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch b/queue-4.9/net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch
new file mode 100644 (file)
index 0000000..558fb05
--- /dev/null
@@ -0,0 +1,95 @@
+From f06b7549b79e29a672336d4e134524373fb7a232 Mon Sep 17 00:00:00 2001
+From: David Ahern <dsahern@gmail.com>
+Date: Wed, 5 Jul 2017 14:41:46 -0600
+Subject: net: ipv6: Compare lwstate in detecting duplicate nexthops
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: David Ahern <dsahern@gmail.com>
+
+commit f06b7549b79e29a672336d4e134524373fb7a232 upstream.
+
+Lennert reported a failure to add different mpls encaps in a multipath
+route:
+
+  $ ip -6 route add 1234::/16 \
+        nexthop encap mpls 10 via fe80::1 dev ens3 \
+        nexthop encap mpls 20 via fe80::1 dev ens3
+  RTNETLINK answers: File exists
+
+The problem is that the duplicate nexthop detection does not compare
+lwtunnel configuration. Add it.
+
+Fixes: 19e42e451506 ("ipv6: support for fib route lwtunnel encap attributes")
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Reported-by: João Taveira Araújo <joao.taveira@gmail.com>
+Reported-by: Lennert Buytenhek <buytenh@wantstofly.org>
+Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
+Tested-by: Lennert Buytenhek <buytenh@wantstofly.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ include/net/ip6_route.h |    8 ++++++++
+ net/ipv6/ip6_fib.c      |    5 +----
+ net/ipv6/route.c        |    8 +-------
+ 3 files changed, 10 insertions(+), 11 deletions(-)
+
+--- a/include/net/ip6_route.h
++++ b/include/net/ip6_route.h
+@@ -22,6 +22,7 @@ struct route_info {
+ #include <net/flow.h>
+ #include <net/ip6_fib.h>
+ #include <net/sock.h>
++#include <net/lwtunnel.h>
+ #include <linux/ip.h>
+ #include <linux/ipv6.h>
+ #include <linux/route.h>
+@@ -232,4 +233,11 @@ static inline struct in6_addr *rt6_nexth
+               return daddr;
+ }
++static inline bool rt6_duplicate_nexthop(struct rt6_info *a, struct rt6_info *b)
++{
++      return a->dst.dev == b->dst.dev &&
++             a->rt6i_idev == b->rt6i_idev &&
++             ipv6_addr_equal(&a->rt6i_gateway, &b->rt6i_gateway) &&
++             !lwtunnel_cmp_encap(a->dst.lwtstate, b->dst.lwtstate);
++}
+ #endif
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -771,10 +771,7 @@ static int fib6_add_rt2node(struct fib6_
+                               goto next_iter;
+                       }
+-                      if (iter->dst.dev == rt->dst.dev &&
+-                          iter->rt6i_idev == rt->rt6i_idev &&
+-                          ipv6_addr_equal(&iter->rt6i_gateway,
+-                                          &rt->rt6i_gateway)) {
++                      if (rt6_duplicate_nexthop(iter, rt)) {
+                               if (rt->rt6i_nsiblings)
+                                       rt->rt6i_nsiblings = 0;
+                               if (!(iter->rt6i_flags & RTF_EXPIRES))
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2953,17 +2953,11 @@ static int ip6_route_info_append(struct
+                                struct rt6_info *rt, struct fib6_config *r_cfg)
+ {
+       struct rt6_nh *nh;
+-      struct rt6_info *rtnh;
+       int err = -EEXIST;
+       list_for_each_entry(nh, rt6_nh_list, next) {
+               /* check if rt6_info already exists */
+-              rtnh = nh->rt6_info;
+-
+-              if (rtnh->dst.dev == rt->dst.dev &&
+-                  rtnh->rt6i_idev == rt->rt6i_idev &&
+-                  ipv6_addr_equal(&rtnh->rt6i_gateway,
+-                                  &rt->rt6i_gateway))
++              if (rt6_duplicate_nexthop(nh->rt6_info, rt))
+                       return err;
+       }
diff --git a/queue-4.9/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch b/queue-4.9/net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch
new file mode 100644 (file)
index 0000000..d6b1db4
--- /dev/null
@@ -0,0 +1,32 @@
+From 8ff93de7668bd81bc8efa819d1184ebd48fae72d Mon Sep 17 00:00:00 2001
+From: Gal Pressman <galp@mellanox.com>
+Date: Sun, 25 Jun 2017 16:46:25 +0300
+Subject: net/mlx5e: Fix TX carrier errors report in get stats ndo
+
+From: Gal Pressman <galp@mellanox.com>
+
+commit 8ff93de7668bd81bc8efa819d1184ebd48fae72d upstream.
+
+Symbol error during carrier counter from PPCNT was mistakenly reported as
+TX carrier errors in get_stats ndo, although it's an RX counter.
+
+Fixes: 269e6b3af3bf ("net/mlx5e: Report additional error statistics in get stats ndo")
+Signed-off-by: Gal Pressman <galp@mellanox.com>
+Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/ethernet/mellanox/mlx5/core/en_main.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -2671,8 +2671,6 @@ mlx5e_get_stats(struct net_device *dev,
+               PPORT_802_3_GET(pstats, a_frame_check_sequence_errors);
+       stats->rx_frame_errors = PPORT_802_3_GET(pstats, a_alignment_errors);
+       stats->tx_aborted_errors = PPORT_2863_GET(pstats, if_out_discards);
+-      stats->tx_carrier_errors =
+-              PPORT_802_3_GET(pstats, a_symbol_error_during_carrier);
+       stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors +
+                          stats->rx_frame_errors;
+       stats->tx_errors = stats->tx_aborted_errors + stats->tx_carrier_errors;
diff --git a/queue-4.9/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch b/queue-4.9/rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch
new file mode 100644 (file)
index 0000000..d51e91a
--- /dev/null
@@ -0,0 +1,38 @@
+From 0933a578cd55b02dc80f219dc8f2efb17ec61c9a Mon Sep 17 00:00:00 2001
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Date: Thu, 6 Jul 2017 08:15:06 -0700
+Subject: rds: tcp: use sock_create_lite() to create the accept socket
+
+From: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+
+commit 0933a578cd55b02dc80f219dc8f2efb17ec61c9a upstream.
+
+There are two problems with calling sock_create_kern() from
+rds_tcp_accept_one()
+1. it sets up a new_sock->sk that is wasteful, because this ->sk
+   is going to get replaced by inet_accept() in the subsequent ->accept()
+2. The new_sock->sk is a leaked reference in sock_graft() which
+   expects to find a null parent->sk
+
+Avoid these problems by calling sock_create_lite().
+
+Signed-off-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
+Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/rds/tcp_listen.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/rds/tcp_listen.c
++++ b/net/rds/tcp_listen.c
+@@ -129,7 +129,7 @@ int rds_tcp_accept_one(struct socket *so
+       if (!sock) /* module unload or netns delete in progress */
+               return -ENETUNREACH;
+-      ret = sock_create_kern(sock_net(sock->sk), sock->sk->sk_family,
++      ret = sock_create_lite(sock->sk->sk_family,
+                              sock->sk->sk_type, sock->sk->sk_protocol,
+                              &new_sock);
+       if (ret)
index bf49ecaa937a648a63b97abf48a9808e84f98b3f..1263b7add8653ebfae3a2b424a672a5935527ff9 100644 (file)
@@ -12,3 +12,14 @@ bpf-prevent-leaking-pointer-via-xadd-on-unpriviledged.patch
 net-handle-napi_gro_free_stolen_head-case-also-in-napi_frags_finish.patch
 net-mlx5-cancel-delayed-recovery-work-when-unloading-the-driver.patch
 liquidio-fix-bug-in-soft-reset-failure-detection.patch
+net-mlx5e-fix-tx-carrier-errors-report-in-get-stats-ndo.patch
+ipv6-dad-don-t-remove-dynamic-addresses-if-link-is-down.patch
+vxlan-fix-hlist-corruption.patch
+net-core-fix-slab-out-of-bounds-in-netdev_stats_to_stats64.patch
+net-ipv6-compare-lwstate-in-detecting-duplicate-nexthops.patch
+vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch
+rds-tcp-use-sock_create_lite-to-create-the-accept-socket.patch
+brcmfmac-fix-possible-buffer-overflow-in-brcmf_cfg80211_mgmt_tx.patch
+brcmfmac-fix-a-memory-leak-in-error-handling-path-in-brcmf_cfg80211_attach.patch
+brcmfmac-fix-glom_skb-leak-in-brcmf_sdiod_recv_chain.patch
+sfc-don-t-read-beyond-unicast-address-list.patch
diff --git a/queue-4.9/sfc-don-t-read-beyond-unicast-address-list.patch b/queue-4.9/sfc-don-t-read-beyond-unicast-address-list.patch
new file mode 100644 (file)
index 0000000..c3c551b
--- /dev/null
@@ -0,0 +1,62 @@
+From foo@baz Mon Jul 17 18:47:09 CEST 2017
+From: Bert Kenward <bkenward@solarflare.com>
+Date: Wed, 12 Jul 2017 17:19:41 +0100
+Subject: sfc: don't read beyond unicast address list
+
+From: Bert Kenward <bkenward@solarflare.com>
+
+
+[ Upstream commit c70d68150f71b84cea6997a53493e17bf18a54db ]
+
+If we have more than 32 unicast MAC addresses assigned to an interface
+we will read beyond the end of the address table in the driver when
+adding filters. The next 256 entries store multicast addresses, so we
+will end up attempting to insert duplicate filters, which is mostly
+harmless. If we add more than 288 unicast addresses we will then read
+past the multicast address table, which is likely to be more exciting.
+
+Fixes: 12fb0da45c9a ("sfc: clean fallbacks between promisc/normal in efx_ef10_filter_sync_rx_mode")
+Signed-off-by: Bert Kenward <bkenward@solarflare.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ethernet/sfc/ef10.c |    8 +++-----
+ 1 file changed, 3 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/ethernet/sfc/ef10.c
++++ b/drivers/net/ethernet/sfc/ef10.c
+@@ -4399,12 +4399,9 @@ static void efx_ef10_filter_uc_addr_list
+       struct efx_ef10_filter_table *table = efx->filter_state;
+       struct net_device *net_dev = efx->net_dev;
+       struct netdev_hw_addr *uc;
+-      int addr_count;
+       unsigned int i;
+-      addr_count = netdev_uc_count(net_dev);
+       table->uc_promisc = !!(net_dev->flags & IFF_PROMISC);
+-      table->dev_uc_count = 1 + addr_count;
+       ether_addr_copy(table->dev_uc_list[0].addr, net_dev->dev_addr);
+       i = 1;
+       netdev_for_each_uc_addr(uc, net_dev) {
+@@ -4415,6 +4412,8 @@ static void efx_ef10_filter_uc_addr_list
+               ether_addr_copy(table->dev_uc_list[i].addr, uc->addr);
+               i++;
+       }
++
++      table->dev_uc_count = i;
+ }
+ static void efx_ef10_filter_mc_addr_list(struct efx_nic *efx)
+@@ -4422,11 +4421,10 @@ static void efx_ef10_filter_mc_addr_list
+       struct efx_ef10_filter_table *table = efx->filter_state;
+       struct net_device *net_dev = efx->net_dev;
+       struct netdev_hw_addr *mc;
+-      unsigned int i, addr_count;
++      unsigned int i;
+       table->mc_promisc = !!(net_dev->flags & (IFF_PROMISC | IFF_ALLMULTI));
+-      addr_count = netdev_mc_count(net_dev);
+       i = 0;
+       netdev_for_each_mc_addr(mc, net_dev) {
+               if (i >= EFX_EF10_FILTER_DEV_MC_MAX) {
diff --git a/queue-4.9/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch b/queue-4.9/vrf-fix-bug_on-triggered-by-rx-when-destroying-a-vrf.patch
new file mode 100644 (file)
index 0000000..1657e79
--- /dev/null
@@ -0,0 +1,117 @@
+From f630c38ef0d785101363a8992bbd4f302180f86f Mon Sep 17 00:00:00 2001
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Date: Thu, 6 Jul 2017 15:24:40 +0300
+Subject: vrf: fix bug_on triggered by rx when destroying a vrf
+
+From: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+
+commit f630c38ef0d785101363a8992bbd4f302180f86f upstream.
+
+When destroying a VRF device we cleanup the slaves in its ndo_uninit()
+function, but that causes packets to be switched (skb->dev == vrf being
+destroyed) even though we're pass the point where the VRF should be
+receiving any packets while it is being dismantled. This causes a BUG_ON
+to trigger if we have raw sockets (trace below).
+The reason is that the inetdev of the VRF has been destroyed but we're
+still sending packets up the stack with it, so let's free the slaves in
+the dellink callback as David Ahern suggested.
+
+Note that this fix doesn't prevent packets from going up when the VRF
+device is admin down.
+
+[   35.631371] ------------[ cut here ]------------
+[   35.631603] kernel BUG at net/ipv4/fib_frontend.c:285!
+[   35.631854] invalid opcode: 0000 [#1] SMP
+[   35.631977] Modules linked in:
+[   35.632081] CPU: 2 PID: 22 Comm: ksoftirqd/2 Not tainted 4.12.0-rc7+ #45
+[   35.632247] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.7.5-20140531_083030-gandalf 04/01/2014
+[   35.632477] task: ffff88005ad68000 task.stack: ffff88005ad64000
+[   35.632632] RIP: 0010:fib_compute_spec_dst+0xfc/0x1ee
+[   35.632769] RSP: 0018:ffff88005ad67978 EFLAGS: 00010202
+[   35.632910] RAX: 0000000000000001 RBX: ffff880059a7f200 RCX: 0000000000000000
+[   35.633084] RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffffffff82274af0
+[   35.633256] RBP: ffff88005ad679f8 R08: 000000000001ef70 R09: 0000000000000046
+[   35.633430] R10: ffff88005ad679f8 R11: ffff880037731cb0 R12: 0000000000000001
+[   35.633603] R13: ffff8800599e3000 R14: 0000000000000000 R15: ffff8800599cb852
+[   35.634114] FS:  0000000000000000(0000) GS:ffff88005d900000(0000) knlGS:0000000000000000
+[   35.634306] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[   35.634456] CR2: 00007f3563227095 CR3: 000000000201d000 CR4: 00000000000406e0
+[   35.634632] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[   35.634865] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[   35.635055] Call Trace:
+[   35.635271]  ? __lock_acquire+0xf0d/0x1117
+[   35.635522]  ipv4_pktinfo_prepare+0x82/0x151
+[   35.635831]  raw_rcv_skb+0x17/0x3c
+[   35.636062]  raw_rcv+0xe5/0xf7
+[   35.636287]  raw_local_deliver+0x169/0x1d9
+[   35.636534]  ip_local_deliver_finish+0x87/0x1c4
+[   35.636820]  ip_local_deliver+0x63/0x7f
+[   35.637058]  ip_rcv_finish+0x340/0x3a1
+[   35.637295]  ip_rcv+0x314/0x34a
+[   35.637525]  __netif_receive_skb_core+0x49f/0x7c5
+[   35.637780]  ? lock_acquire+0x13f/0x1d7
+[   35.638018]  ? lock_acquire+0x15e/0x1d7
+[   35.638259]  __netif_receive_skb+0x1e/0x94
+[   35.638502]  ? __netif_receive_skb+0x1e/0x94
+[   35.638748]  netif_receive_skb_internal+0x74/0x300
+[   35.639002]  ? dev_gro_receive+0x2ed/0x411
+[   35.639246]  ? lock_is_held_type+0xc4/0xd2
+[   35.639491]  napi_gro_receive+0x105/0x1a0
+[   35.639736]  receive_buf+0xc32/0xc74
+[   35.639965]  ? detach_buf+0x67/0x153
+[   35.640201]  ? virtqueue_get_buf_ctx+0x120/0x176
+[   35.640453]  virtnet_poll+0x128/0x1c5
+[   35.640690]  net_rx_action+0x103/0x343
+[   35.640932]  __do_softirq+0x1c7/0x4b7
+[   35.641171]  run_ksoftirqd+0x23/0x5c
+[   35.641403]  smpboot_thread_fn+0x24f/0x26d
+[   35.641646]  ? sort_range+0x22/0x22
+[   35.641878]  kthread+0x129/0x131
+[   35.642104]  ? __list_add+0x31/0x31
+[   35.642335]  ? __list_add+0x31/0x31
+[   35.642568]  ret_from_fork+0x2a/0x40
+[   35.642804] Code: 05 bd 87 a3 00 01 e8 1f ef 98 ff 4d 85 f6 48 c7 c7 f0 4a 27 82 41 0f 94 c4 31 c9 31 d2 41 0f b6 f4 e8 04 71 a1 ff 45 84 e4 74 02 <0f> 0b 0f b7 93 c4 00 00 00 4d 8b a5 80 05 00 00 48 03 93 d0 00
+[   35.644342] RIP: fib_compute_spec_dst+0xfc/0x1ee RSP: ffff88005ad67978
+
+Fixes: 193125dbd8eb ("net: Introduce VRF device driver")
+Reported-by: Chris Cormier <chriscormier@cumulusnetworks.com>
+Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
+Acked-by: David Ahern <dsahern@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/vrf.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -787,15 +787,10 @@ static int vrf_del_slave(struct net_devi
+ static void vrf_dev_uninit(struct net_device *dev)
+ {
+       struct net_vrf *vrf = netdev_priv(dev);
+-      struct net_device *port_dev;
+-      struct list_head *iter;
+       vrf_rtable_release(dev, vrf);
+       vrf_rt6_release(dev, vrf);
+-      netdev_for_each_lower_dev(dev, port_dev, iter)
+-              vrf_del_slave(dev, port_dev);
+-
+       free_percpu(dev->dstats);
+       dev->dstats = NULL;
+ }
+@@ -1232,6 +1227,12 @@ static int vrf_validate(struct nlattr *t
+ static void vrf_dellink(struct net_device *dev, struct list_head *head)
+ {
++      struct net_device *port_dev;
++      struct list_head *iter;
++
++      netdev_for_each_lower_dev(dev, port_dev, iter)
++              vrf_del_slave(dev, port_dev);
++
+       unregister_netdevice_queue(dev, head);
+ }
diff --git a/queue-4.9/vxlan-fix-hlist-corruption.patch b/queue-4.9/vxlan-fix-hlist-corruption.patch
new file mode 100644 (file)
index 0000000..76cee4d
--- /dev/null
@@ -0,0 +1,119 @@
+From foo@baz Mon Jul 17 18:47:09 CEST 2017
+From: Jiri Benc <jbenc@redhat.com>
+Date: Sun, 2 Jul 2017 19:00:57 +0200
+Subject: vxlan: fix hlist corruption
+
+From: Jiri Benc <jbenc@redhat.com>
+
+
+[ Upstream commit 69e766612c4bcb79e19cebed9eed61d4222c1d47 ]
+
+It's not a good idea to add the same hlist_node to two different hash lists.
+This leads to various hard to debug memory corruptions.
+
+Fixes: b1be00a6c39f ("vxlan: support both IPv4 and IPv6 sockets in a single vxlan device")
+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>
+---
+ drivers/net/vxlan.c |   30 ++++++++++++++++++++----------
+ include/net/vxlan.h |   10 +++++++++-
+ 2 files changed, 29 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -227,15 +227,15 @@ static struct vxlan_sock *vxlan_find_soc
+ static struct vxlan_dev *vxlan_vs_find_vni(struct vxlan_sock *vs, __be32 vni)
+ {
+-      struct vxlan_dev *vxlan;
++      struct vxlan_dev_node *node;
+       /* For flow based devices, map all packets to VNI 0 */
+       if (vs->flags & VXLAN_F_COLLECT_METADATA)
+               vni = 0;
+-      hlist_for_each_entry_rcu(vxlan, vni_head(vs, vni), hlist) {
+-              if (vxlan->default_dst.remote_vni == vni)
+-                      return vxlan;
++      hlist_for_each_entry_rcu(node, vni_head(vs, vni), hlist) {
++              if (node->vxlan->default_dst.remote_vni == vni)
++                      return node->vxlan;
+       }
+       return NULL;
+@@ -2309,17 +2309,22 @@ static void vxlan_vs_del_dev(struct vxla
+       struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
+       spin_lock(&vn->sock_lock);
+-      hlist_del_init_rcu(&vxlan->hlist);
++      hlist_del_init_rcu(&vxlan->hlist4.hlist);
++#if IS_ENABLED(CONFIG_IPV6)
++      hlist_del_init_rcu(&vxlan->hlist6.hlist);
++#endif
+       spin_unlock(&vn->sock_lock);
+ }
+-static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan)
++static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan,
++                           struct vxlan_dev_node *node)
+ {
+       struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
+       __be32 vni = vxlan->default_dst.remote_vni;
++      node->vxlan = vxlan;
+       spin_lock(&vn->sock_lock);
+-      hlist_add_head_rcu(&vxlan->hlist, vni_head(vs, vni));
++      hlist_add_head_rcu(&node->hlist, vni_head(vs, vni));
+       spin_unlock(&vn->sock_lock);
+ }
+@@ -2778,6 +2783,7 @@ static int __vxlan_sock_add(struct vxlan
+ {
+       struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
+       struct vxlan_sock *vs = NULL;
++      struct vxlan_dev_node *node;
+       if (!vxlan->cfg.no_share) {
+               spin_lock(&vn->sock_lock);
+@@ -2795,12 +2801,16 @@ static int __vxlan_sock_add(struct vxlan
+       if (IS_ERR(vs))
+               return PTR_ERR(vs);
+ #if IS_ENABLED(CONFIG_IPV6)
+-      if (ipv6)
++      if (ipv6) {
+               rcu_assign_pointer(vxlan->vn6_sock, vs);
+-      else
++              node = &vxlan->hlist6;
++      } else
+ #endif
++      {
+               rcu_assign_pointer(vxlan->vn4_sock, vs);
+-      vxlan_vs_add_dev(vs, vxlan);
++              node = &vxlan->hlist4;
++      }
++      vxlan_vs_add_dev(vs, vxlan, node);
+       return 0;
+ }
+--- a/include/net/vxlan.h
++++ b/include/net/vxlan.h
+@@ -221,9 +221,17 @@ struct vxlan_config {
+       bool                    no_share;
+ };
++struct vxlan_dev_node {
++      struct hlist_node hlist;
++      struct vxlan_dev *vxlan;
++};
++
+ /* Pseudo network device */
+ struct vxlan_dev {
+-      struct hlist_node hlist;        /* vni hash table */
++      struct vxlan_dev_node hlist4;   /* vni hash table for IPv4 socket */
++#if IS_ENABLED(CONFIG_IPV6)
++      struct vxlan_dev_node hlist6;   /* vni hash table for IPv6 socket */
++#endif
+       struct list_head  next;         /* vxlan's per namespace list */
+       struct vxlan_sock __rcu *vn4_sock;      /* listening socket for IPv4 */
+ #if IS_ENABLED(CONFIG_IPV6)