]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.11-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Jun 2017 16:58:27 +0000 (18:58 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 29 Jun 2017 16:58:27 +0000 (18:58 +0200)
added patches:
af_unix-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-and-connect-handlers.patch
decnet-always-not-take-dst-__refcnt-when-inserting-dst-into-hash-table.patch
decnet-dn_rtmsg-improve-input-length-sanitization-in-dnrmg_receive_user_skb.patch
fix-an-intermittent-pr_emerg-warning-about-lo-becoming-free.patch
igmp-acquire-pmc-lock-for-ip_mc_clear_src.patch
igmp-add-a-missing-spin_lock_init.patch
ipv6-do-not-leak-throw-route-references.patch
ipv6-fix-calling-in6_ifa_hold-incorrectly-for-dad-work.patch
mac80211-free-netdev-on-dev_alloc_name-error.patch
net-8021q-fix-one-possible-panic-caused-by-bug_on-in-free_netdev.patch
net-caif-fix-a-sleep-in-atomic-bug-in-cfpkt_create_pfx.patch
net-don-t-call-strlen-on-non-terminated-string-in-dev_set_alias.patch
net-don-t-global-icmp-rate-limit-packets-originating-from-loopback.patch
net-fix-inconsistent-teardown-and-release-of-private-netdev-state.patch
net-ipv6-release-route-when-device-is-unregistering.patch
net-mlx5-enable-4k-uar-only-when-page-size-is-bigger-than-4k.patch
net-mlx5-remove-several-module-events-out-of-ethtool-stats.patch
net-mlx5-wait-for-fw-readiness-before-initializing-command-interface.patch
net-mlx5e-added-bw-check-for-dim-decision-mechanism.patch
net-mlx5e-avoid-doing-a-cleanup-call-if-the-profile-doesn-t-have-it.patch
net-mlx5e-fix-min-inline-value-for-vf-rep-sqs.patch
net-mlx5e-fix-timestamping-capabilities-reporting.patch
net-mlx5e-fix-wrong-indications-in-dim-due-to-counter-wraparound.patch
net-s390-fix-up-for-fix-inconsistent-teardown-and-release-of-private-netdev-state.patch
net-tipc-fix-a-sleep-in-atomic-bug-in-tipc_msg_reverse.patch
net-vrf-make-add_fib_rules-per-network-namespace-flag.patch
net-zero-ifla_vf_info-in-rtnl_fill_vfinfo.patch
proc-snmp6-use-correct-type-in-memset.patch
qmi_wwan-new-telewell-and-sierra-device-ids.patch
rtnetlink-add-ifla_group-to-ifla_policy.patch
sctp-disable-bh-in-sctp_for_each_endpoint.patch
sctp-return-next-obj-by-passing-pos-1-into-sctp_transport_get_idx.patch

33 files changed:
queue-4.11/af_unix-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-and-connect-handlers.patch [new file with mode: 0644]
queue-4.11/decnet-always-not-take-dst-__refcnt-when-inserting-dst-into-hash-table.patch [new file with mode: 0644]
queue-4.11/decnet-dn_rtmsg-improve-input-length-sanitization-in-dnrmg_receive_user_skb.patch [new file with mode: 0644]
queue-4.11/fix-an-intermittent-pr_emerg-warning-about-lo-becoming-free.patch [new file with mode: 0644]
queue-4.11/igmp-acquire-pmc-lock-for-ip_mc_clear_src.patch [new file with mode: 0644]
queue-4.11/igmp-add-a-missing-spin_lock_init.patch [new file with mode: 0644]
queue-4.11/ipv6-do-not-leak-throw-route-references.patch [new file with mode: 0644]
queue-4.11/ipv6-fix-calling-in6_ifa_hold-incorrectly-for-dad-work.patch [new file with mode: 0644]
queue-4.11/mac80211-free-netdev-on-dev_alloc_name-error.patch [new file with mode: 0644]
queue-4.11/net-8021q-fix-one-possible-panic-caused-by-bug_on-in-free_netdev.patch [new file with mode: 0644]
queue-4.11/net-caif-fix-a-sleep-in-atomic-bug-in-cfpkt_create_pfx.patch [new file with mode: 0644]
queue-4.11/net-don-t-call-strlen-on-non-terminated-string-in-dev_set_alias.patch [new file with mode: 0644]
queue-4.11/net-don-t-global-icmp-rate-limit-packets-originating-from-loopback.patch [new file with mode: 0644]
queue-4.11/net-fix-inconsistent-teardown-and-release-of-private-netdev-state.patch [new file with mode: 0644]
queue-4.11/net-ipv6-release-route-when-device-is-unregistering.patch [new file with mode: 0644]
queue-4.11/net-mlx5-enable-4k-uar-only-when-page-size-is-bigger-than-4k.patch [new file with mode: 0644]
queue-4.11/net-mlx5-remove-several-module-events-out-of-ethtool-stats.patch [new file with mode: 0644]
queue-4.11/net-mlx5-wait-for-fw-readiness-before-initializing-command-interface.patch [new file with mode: 0644]
queue-4.11/net-mlx5e-added-bw-check-for-dim-decision-mechanism.patch [new file with mode: 0644]
queue-4.11/net-mlx5e-avoid-doing-a-cleanup-call-if-the-profile-doesn-t-have-it.patch [new file with mode: 0644]
queue-4.11/net-mlx5e-fix-min-inline-value-for-vf-rep-sqs.patch [new file with mode: 0644]
queue-4.11/net-mlx5e-fix-timestamping-capabilities-reporting.patch [new file with mode: 0644]
queue-4.11/net-mlx5e-fix-wrong-indications-in-dim-due-to-counter-wraparound.patch [new file with mode: 0644]
queue-4.11/net-s390-fix-up-for-fix-inconsistent-teardown-and-release-of-private-netdev-state.patch [new file with mode: 0644]
queue-4.11/net-tipc-fix-a-sleep-in-atomic-bug-in-tipc_msg_reverse.patch [new file with mode: 0644]
queue-4.11/net-vrf-make-add_fib_rules-per-network-namespace-flag.patch [new file with mode: 0644]
queue-4.11/net-zero-ifla_vf_info-in-rtnl_fill_vfinfo.patch [new file with mode: 0644]
queue-4.11/proc-snmp6-use-correct-type-in-memset.patch [new file with mode: 0644]
queue-4.11/qmi_wwan-new-telewell-and-sierra-device-ids.patch [new file with mode: 0644]
queue-4.11/rtnetlink-add-ifla_group-to-ifla_policy.patch [new file with mode: 0644]
queue-4.11/sctp-disable-bh-in-sctp_for_each_endpoint.patch [new file with mode: 0644]
queue-4.11/sctp-return-next-obj-by-passing-pos-1-into-sctp_transport_get_idx.patch [new file with mode: 0644]
queue-4.11/series

diff --git a/queue-4.11/af_unix-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-and-connect-handlers.patch b/queue-4.11/af_unix-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-and-connect-handlers.patch
new file mode 100644 (file)
index 0000000..342341d
--- /dev/null
@@ -0,0 +1,47 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Mateusz Jurczyk <mjurczyk@google.com>
+Date: Thu, 8 Jun 2017 11:13:36 +0200
+Subject: af_unix: Add sockaddr length checks before accessing sa_family in bind and connect handlers
+
+From: Mateusz Jurczyk <mjurczyk@google.com>
+
+
+[ Upstream commit defbcf2decc903a28d8398aa477b6881e711e3ea ]
+
+Verify that the caller-provided sockaddr structure is large enough to
+contain the sa_family field, before accessing it in bind() and connect()
+handlers of the AF_UNIX socket. Since neither syscall enforces a minimum
+size of the corresponding memory region, very short sockaddrs (zero or
+one byte long) result in operating on uninitialized memory while
+referencing .sa_family.
+
+Signed-off-by: Mateusz Jurczyk <mjurczyk@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/unix/af_unix.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -999,7 +999,8 @@ static int unix_bind(struct socket *sock
+       struct path path = { NULL, NULL };
+       err = -EINVAL;
+-      if (sunaddr->sun_family != AF_UNIX)
++      if (addr_len < offsetofend(struct sockaddr_un, sun_family) ||
++          sunaddr->sun_family != AF_UNIX)
+               goto out;
+       if (addr_len == sizeof(short)) {
+@@ -1110,6 +1111,10 @@ static int unix_dgram_connect(struct soc
+       unsigned int hash;
+       int err;
++      err = -EINVAL;
++      if (alen < offsetofend(struct sockaddr, sa_family))
++              goto out;
++
+       if (addr->sa_family != AF_UNSPEC) {
+               err = unix_mkname(sunaddr, alen, &hash);
+               if (err < 0)
diff --git a/queue-4.11/decnet-always-not-take-dst-__refcnt-when-inserting-dst-into-hash-table.patch b/queue-4.11/decnet-always-not-take-dst-__refcnt-when-inserting-dst-into-hash-table.patch
new file mode 100644 (file)
index 0000000..1b9642b
--- /dev/null
@@ -0,0 +1,89 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Wei Wang <weiwan@google.com>
+Date: Fri, 16 Jun 2017 10:46:37 -0700
+Subject: decnet: always not take dst->__refcnt when inserting dst into hash table
+
+From: Wei Wang <weiwan@google.com>
+
+
+[ Upstream commit 76371d2e3ad1f84426a30ebcd8c3b9b98f4c724f ]
+
+In the existing dn_route.c code, dn_route_output_slow() takes
+dst->__refcnt before calling dn_insert_route() while dn_route_input_slow()
+does not take dst->__refcnt before calling dn_insert_route().
+This makes the whole routing code very buggy.
+In dn_dst_check_expire(), dnrt_free() is called when rt expires. This
+makes the routes inserted by dn_route_output_slow() not able to be
+freed as the refcnt is not released.
+In dn_dst_gc(), dnrt_drop() is called to release rt which could
+potentially cause the dst->__refcnt to be dropped to -1.
+In dn_run_flush(), dst_free() is called to release all the dst. Again,
+it makes the dst inserted by dn_route_output_slow() not able to be
+released and also, it does not wait on the rcu and could potentially
+cause crash in the path where other users still refer to this dst.
+
+This patch makes sure both input and output path do not take
+dst->__refcnt before calling dn_insert_route() and also makes sure
+dnrt_free()/dst_free() is called when removing dst from the hash table.
+The only difference between those 2 calls is that dnrt_free() waits on
+the rcu while dst_free() does not.
+
+Signed-off-by: Wei Wang <weiwan@google.com>
+Acked-by: Martin KaFai Lau <kafai@fb.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/decnet/dn_route.c |   14 ++++----------
+ 1 file changed, 4 insertions(+), 10 deletions(-)
+
+--- a/net/decnet/dn_route.c
++++ b/net/decnet/dn_route.c
+@@ -188,12 +188,6 @@ static inline void dnrt_free(struct dn_r
+       call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
+ }
+-static inline void dnrt_drop(struct dn_route *rt)
+-{
+-      dst_release(&rt->dst);
+-      call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
+-}
+-
+ static void dn_dst_check_expire(unsigned long dummy)
+ {
+       int i;
+@@ -248,7 +242,7 @@ static int dn_dst_gc(struct dst_ops *ops
+                       }
+                       *rtp = rt->dst.dn_next;
+                       rt->dst.dn_next = NULL;
+-                      dnrt_drop(rt);
++                      dnrt_free(rt);
+                       break;
+               }
+               spin_unlock_bh(&dn_rt_hash_table[i].lock);
+@@ -350,7 +344,7 @@ static int dn_insert_route(struct dn_rou
+                       dst_use(&rth->dst, now);
+                       spin_unlock_bh(&dn_rt_hash_table[hash].lock);
+-                      dnrt_drop(rt);
++                      dst_free(&rt->dst);
+                       *rp = rth;
+                       return 0;
+               }
+@@ -380,7 +374,7 @@ static void dn_run_flush(unsigned long d
+               for(; rt; rt = next) {
+                       next = rcu_dereference_raw(rt->dst.dn_next);
+                       RCU_INIT_POINTER(rt->dst.dn_next, NULL);
+-                      dst_free((struct dst_entry *)rt);
++                      dnrt_free(rt);
+               }
+ nothing_to_declare:
+@@ -1187,7 +1181,7 @@ make_route:
+       if (dev_out->flags & IFF_LOOPBACK)
+               flags |= RTCF_LOCAL;
+-      rt = dst_alloc(&dn_dst_ops, dev_out, 1, DST_OBSOLETE_NONE, DST_HOST);
++      rt = dst_alloc(&dn_dst_ops, dev_out, 0, DST_OBSOLETE_NONE, DST_HOST);
+       if (rt == NULL)
+               goto e_nobufs;
diff --git a/queue-4.11/decnet-dn_rtmsg-improve-input-length-sanitization-in-dnrmg_receive_user_skb.patch b/queue-4.11/decnet-dn_rtmsg-improve-input-length-sanitization-in-dnrmg_receive_user_skb.patch
new file mode 100644 (file)
index 0000000..a6de6ee
--- /dev/null
@@ -0,0 +1,42 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Mateusz Jurczyk <mjurczyk@google.com>
+Date: Wed, 7 Jun 2017 16:14:29 +0200
+Subject: decnet: dn_rtmsg: Improve input length sanitization in dnrmg_receive_user_skb
+
+From: Mateusz Jurczyk <mjurczyk@google.com>
+
+
+[ Upstream commit dd0da17b209ed91f39872766634ca967c170ada1 ]
+
+Verify that the length of the socket buffer is sufficient to cover the
+nlmsghdr structure before accessing the nlh->nlmsg_len field for further
+input sanitization. If the client only supplies 1-3 bytes of data in
+sk_buff, then nlh->nlmsg_len remains partially uninitialized and
+contains leftover memory from the corresponding kernel allocation.
+Operating on such data may result in indeterminate evaluation of the
+nlmsg_len < sizeof(*nlh) expression.
+
+The bug was discovered by a runtime instrumentation designed to detect
+use of uninitialized memory in the kernel. The patch prevents this and
+other similar tools (e.g. KMSAN) from flagging this behavior in the future.
+
+Signed-off-by: Mateusz Jurczyk <mjurczyk@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/decnet/netfilter/dn_rtmsg.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/net/decnet/netfilter/dn_rtmsg.c
++++ b/net/decnet/netfilter/dn_rtmsg.c
+@@ -102,7 +102,9 @@ static inline void dnrmg_receive_user_sk
+ {
+       struct nlmsghdr *nlh = nlmsg_hdr(skb);
+-      if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len)
++      if (skb->len < sizeof(*nlh) ||
++          nlh->nlmsg_len < sizeof(*nlh) ||
++          skb->len < nlh->nlmsg_len)
+               return;
+       if (!netlink_capable(skb, CAP_NET_ADMIN))
diff --git a/queue-4.11/fix-an-intermittent-pr_emerg-warning-about-lo-becoming-free.patch b/queue-4.11/fix-an-intermittent-pr_emerg-warning-about-lo-becoming-free.patch
new file mode 100644 (file)
index 0000000..2a27124
--- /dev/null
@@ -0,0 +1,76 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Krister Johansen <kjlx@templeofstupid.com>
+Date: Thu, 8 Jun 2017 13:12:38 -0700
+Subject: Fix an intermittent pr_emerg warning about lo becoming free.
+
+From: Krister Johansen <kjlx@templeofstupid.com>
+
+
+[ Upstream commit f186ce61bb8235d80068c390dc2aad7ca427a4c2 ]
+
+It looks like this:
+
+Message from syslogd@flamingo at Apr 26 00:45:00 ...
+ kernel:unregister_netdevice: waiting for lo to become free. Usage count = 4
+
+They seem to coincide with net namespace teardown.
+
+The message is emitted by netdev_wait_allrefs().
+
+Forced a kdump in netdev_run_todo, but found that the refcount on the lo
+device was already 0 at the time we got to the panic.
+
+Used bcc to check the blocking in netdev_run_todo.  The only places
+where we're off cpu there are in the rcu_barrier() and msleep() calls.
+That behavior is expected.  The msleep time coincides with the amount of
+time we spend waiting for the refcount to reach zero; the rcu_barrier()
+wait times are not excessive.
+
+After looking through the list of callbacks that the netdevice notifiers
+invoke in this path, it appears that the dst_dev_event is the most
+interesting.  The dst_ifdown path places a hold on the loopback_dev as
+part of releasing the dev associated with the original dst cache entry.
+Most of our notifier callbacks are straight-forward, but this one a)
+looks complex, and b) places a hold on the network interface in
+question.
+
+I constructed a new bcc script that watches various events in the
+liftime of a dst cache entry.  Note that dst_ifdown will take a hold on
+the loopback device until the invalidated dst entry gets freed.
+
+[      __dst_free] on DST: ffff883ccabb7900 IF tap1008300eth0 invoked at 1282115677036183
+    __dst_free
+    rcu_nocb_kthread
+    kthread
+    ret_from_fork
+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/core/dst.c |   14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+--- a/net/core/dst.c
++++ b/net/core/dst.c
+@@ -469,6 +469,20 @@ static int dst_dev_event(struct notifier
+               spin_lock_bh(&dst_garbage.lock);
+               dst = dst_garbage.list;
+               dst_garbage.list = NULL;
++              /* The code in dst_ifdown places a hold on the loopback device.
++               * If the gc entry processing is set to expire after a lengthy
++               * interval, this hold can cause netdev_wait_allrefs() to hang
++               * out and wait for a long time -- until the the loopback
++               * interface is released.  If we're really unlucky, it'll emit
++               * pr_emerg messages to console too.  Reset the interval here,
++               * so dst cleanups occur in a more timely fashion.
++               */
++              if (dst_garbage.timer_inc > DST_GC_INC) {
++                      dst_garbage.timer_inc = DST_GC_INC;
++                      dst_garbage.timer_expires = DST_GC_MIN;
++                      mod_delayed_work(system_wq, &dst_gc_work,
++                                       dst_garbage.timer_expires);
++              }
+               spin_unlock_bh(&dst_garbage.lock);
+               if (last)
diff --git a/queue-4.11/igmp-acquire-pmc-lock-for-ip_mc_clear_src.patch b/queue-4.11/igmp-acquire-pmc-lock-for-ip_mc_clear_src.patch
new file mode 100644 (file)
index 0000000..86b2724
--- /dev/null
@@ -0,0 +1,82 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: WANG Cong <xiyou.wangcong@gmail.com>
+Date: Mon, 12 Jun 2017 09:52:26 -0700
+Subject: igmp: acquire pmc lock for ip_mc_clear_src()
+
+From: WANG Cong <xiyou.wangcong@gmail.com>
+
+
+[ Upstream commit c38b7d327aafd1e3ad7ff53eefac990673b65667 ]
+
+Andrey reported a use-after-free in add_grec():
+
+        for (psf = *psf_list; psf; psf = psf_next) {
+               ...
+                psf_next = psf->sf_next;
+
+where the struct ip_sf_list's were already freed by:
+
+ kfree+0xe8/0x2b0 mm/slub.c:3882
+ ip_mc_clear_src+0x69/0x1c0 net/ipv4/igmp.c:2078
+ ip_mc_dec_group+0x19a/0x470 net/ipv4/igmp.c:1618
+ ip_mc_drop_socket+0x145/0x230 net/ipv4/igmp.c:2609
+ inet_release+0x4e/0x1c0 net/ipv4/af_inet.c:411
+ sock_release+0x8d/0x1e0 net/socket.c:597
+ sock_close+0x16/0x20 net/socket.c:1072
+
+This happens because we don't hold pmc->lock in ip_mc_clear_src()
+and a parallel mr_ifc_timer timer could jump in and access them.
+
+The RCU lock is there but it is merely for pmc itself, this
+spinlock could actually ensure we don't access them in parallel.
+
+Thanks to Eric and Long for discussion on this bug.
+
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Cc: Eric Dumazet <edumazet@google.com>
+Cc: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Reviewed-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/igmp.c |   21 +++++++++++++--------
+ 1 file changed, 13 insertions(+), 8 deletions(-)
+
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -2071,21 +2071,26 @@ static int ip_mc_add_src(struct in_devic
+ static void ip_mc_clear_src(struct ip_mc_list *pmc)
+ {
+-      struct ip_sf_list *psf, *nextpsf;
++      struct ip_sf_list *psf, *nextpsf, *tomb, *sources;
+-      for (psf = pmc->tomb; psf; psf = nextpsf) {
++      spin_lock_bh(&pmc->lock);
++      tomb = pmc->tomb;
++      pmc->tomb = NULL;
++      sources = pmc->sources;
++      pmc->sources = NULL;
++      pmc->sfmode = MCAST_EXCLUDE;
++      pmc->sfcount[MCAST_INCLUDE] = 0;
++      pmc->sfcount[MCAST_EXCLUDE] = 1;
++      spin_unlock_bh(&pmc->lock);
++
++      for (psf = tomb; psf; psf = nextpsf) {
+               nextpsf = psf->sf_next;
+               kfree(psf);
+       }
+-      pmc->tomb = NULL;
+-      for (psf = pmc->sources; psf; psf = nextpsf) {
++      for (psf = sources; psf; psf = nextpsf) {
+               nextpsf = psf->sf_next;
+               kfree(psf);
+       }
+-      pmc->sources = NULL;
+-      pmc->sfmode = MCAST_EXCLUDE;
+-      pmc->sfcount[MCAST_INCLUDE] = 0;
+-      pmc->sfcount[MCAST_EXCLUDE] = 1;
+ }
+ /* Join a multicast group
diff --git a/queue-4.11/igmp-add-a-missing-spin_lock_init.patch b/queue-4.11/igmp-add-a-missing-spin_lock_init.patch
new file mode 100644 (file)
index 0000000..1fcea3e
--- /dev/null
@@ -0,0 +1,57 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: WANG Cong <xiyou.wangcong@gmail.com>
+Date: Tue, 20 Jun 2017 10:46:27 -0700
+Subject: igmp: add a missing spin_lock_init()
+
+From: WANG Cong <xiyou.wangcong@gmail.com>
+
+
+[ Upstream commit b4846fc3c8559649277e3e4e6b5cec5348a8d208 ]
+
+Andrey reported a lockdep warning on non-initialized
+spinlock:
+
+ INFO: trying to register non-static key.
+ the code is fine but needs lockdep annotation.
+ turning off the locking correctness validator.
+ CPU: 1 PID: 4099 Comm: a.out Not tainted 4.12.0-rc6+ #9
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
+ Call Trace:
+  __dump_stack lib/dump_stack.c:16
+  dump_stack+0x292/0x395 lib/dump_stack.c:52
+  register_lock_class+0x717/0x1aa0 kernel/locking/lockdep.c:755
+  ? 0xffffffffa0000000
+  __lock_acquire+0x269/0x3690 kernel/locking/lockdep.c:3255
+  lock_acquire+0x22d/0x560 kernel/locking/lockdep.c:3855
+  __raw_spin_lock_bh ./include/linux/spinlock_api_smp.h:135
+  _raw_spin_lock_bh+0x36/0x50 kernel/locking/spinlock.c:175
+  spin_lock_bh ./include/linux/spinlock.h:304
+  ip_mc_clear_src+0x27/0x1e0 net/ipv4/igmp.c:2076
+  igmpv3_clear_delrec+0xee/0x4f0 net/ipv4/igmp.c:1194
+  ip_mc_destroy_dev+0x4e/0x190 net/ipv4/igmp.c:1736
+
+We miss a spin_lock_init() in igmpv3_add_delrec(), probably
+because previously we never use it on this code path. Since
+we already unlink it from the global mc_tomb list, it is
+probably safe not to acquire this spinlock here. It does not
+harm to have it although, to avoid conditional locking.
+
+Fixes: c38b7d327aaf ("igmp: acquire pmc lock for ip_mc_clear_src()")
+Reported-by: Andrey Konovalov <andreyknvl@google.com>
+Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/igmp.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/ipv4/igmp.c
++++ b/net/ipv4/igmp.c
+@@ -1112,6 +1112,7 @@ static void igmpv3_add_delrec(struct in_
+       pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
+       if (!pmc)
+               return;
++      spin_lock_init(&pmc->lock);
+       spin_lock_bh(&im->lock);
+       pmc->interface = im->interface;
+       in_dev_hold(in_dev);
diff --git a/queue-4.11/ipv6-do-not-leak-throw-route-references.patch b/queue-4.11/ipv6-do-not-leak-throw-route-references.patch
new file mode 100644 (file)
index 0000000..4e5f38d
--- /dev/null
@@ -0,0 +1,95 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Serhey Popovych <serhe.popovych@gmail.com>
+Date: Tue, 20 Jun 2017 13:29:25 +0300
+Subject: ipv6: Do not leak throw route references
+
+From: Serhey Popovych <serhe.popovych@gmail.com>
+
+
+[ Upstream commit 07f615574f8ac499875b21c1142f26308234a92c ]
+
+While commit 73ba57bfae4a ("ipv6: fix backtracking for throw routes")
+does good job on error propagation to the fib_rules_lookup()
+in fib rules core framework that also corrects throw routes
+handling, it does not solve route reference leakage problem
+happened when we return -EAGAIN to the fib_rules_lookup()
+and leave routing table entry referenced in arg->result.
+
+If rule with matched throw route isn't last matched in the
+list we overwrite arg->result losing reference on throw
+route stored previously forever.
+
+We also partially revert commit ab997ad40839 ("ipv6: fix the
+incorrect return value of throw route") since we never return
+routing table entry with dst.error == -EAGAIN when
+CONFIG_IPV6_MULTIPLE_TABLES is on. Also there is no point
+to check for RTF_REJECT flag since it is always set throw
+route.
+
+Fixes: 73ba57bfae4a ("ipv6: fix backtracking for throw routes")
+Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/fib6_rules.c |   22 ++++++----------------
+ net/ipv6/ip6_fib.c    |    3 +--
+ 2 files changed, 7 insertions(+), 18 deletions(-)
+
+--- a/net/ipv6/fib6_rules.c
++++ b/net/ipv6/fib6_rules.c
+@@ -32,7 +32,6 @@ struct fib6_rule {
+ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
+                                  int flags, pol_lookup_t lookup)
+ {
+-      struct rt6_info *rt;
+       struct fib_lookup_arg arg = {
+               .lookup_ptr = lookup,
+               .flags = FIB_LOOKUP_NOREF,
+@@ -44,21 +43,11 @@ struct dst_entry *fib6_rule_lookup(struc
+       fib_rules_lookup(net->ipv6.fib6_rules_ops,
+                        flowi6_to_flowi(fl6), flags, &arg);
+-      rt = arg.result;
++      if (arg.result)
++              return arg.result;
+-      if (!rt) {
+-              dst_hold(&net->ipv6.ip6_null_entry->dst);
+-              return &net->ipv6.ip6_null_entry->dst;
+-      }
+-
+-      if (rt->rt6i_flags & RTF_REJECT &&
+-          rt->dst.error == -EAGAIN) {
+-              ip6_rt_put(rt);
+-              rt = net->ipv6.ip6_null_entry;
+-              dst_hold(&rt->dst);
+-      }
+-
+-      return &rt->dst;
++      dst_hold(&net->ipv6.ip6_null_entry->dst);
++      return &net->ipv6.ip6_null_entry->dst;
+ }
+ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
+@@ -121,7 +110,8 @@ static int fib6_rule_action(struct fib_r
+                       flp6->saddr = saddr;
+               }
+               err = rt->dst.error;
+-              goto out;
++              if (err != -EAGAIN)
++                      goto out;
+       }
+ again:
+       ip6_rt_put(rt);
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -289,8 +289,7 @@ struct dst_entry *fib6_rule_lookup(struc
+       struct rt6_info *rt;
+       rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags);
+-      if (rt->rt6i_flags & RTF_REJECT &&
+-          rt->dst.error == -EAGAIN) {
++      if (rt->dst.error == -EAGAIN) {
+               ip6_rt_put(rt);
+               rt = net->ipv6.ip6_null_entry;
+               dst_hold(&rt->dst);
diff --git a/queue-4.11/ipv6-fix-calling-in6_ifa_hold-incorrectly-for-dad-work.patch b/queue-4.11/ipv6-fix-calling-in6_ifa_hold-incorrectly-for-dad-work.patch
new file mode 100644 (file)
index 0000000..6737ce8
--- /dev/null
@@ -0,0 +1,64 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Xin Long <lucien.xin@gmail.com>
+Date: Thu, 15 Jun 2017 16:33:58 +0800
+Subject: ipv6: fix calling in6_ifa_hold incorrectly for dad work
+
+From: Xin Long <lucien.xin@gmail.com>
+
+
+[ Upstream commit f8a894b218138888542a5058d0e902378fd0d4ec ]
+
+Now when starting the dad work in addrconf_mod_dad_work, if the dad work
+is idle and queued, it needs to hold ifa.
+
+The problem is there's one gap in [1], during which if the pending dad work
+is removed elsewhere. It will miss to hold ifa, but the dad word is still
+idea and queue.
+
+        if (!delayed_work_pending(&ifp->dad_work))
+                in6_ifa_hold(ifp);
+                    <--------------[1]
+        mod_delayed_work(addrconf_wq, &ifp->dad_work, delay);
+
+An use-after-free issue can be caused by this.
+
+Chen Wei found this issue when WARN_ON(!hlist_unhashed(&ifp->addr_lst)) in
+net6_ifa_finish_destroy was hit because of it.
+
+As Hannes' suggestion, this patch is to fix it by holding ifa first in
+addrconf_mod_dad_work, then calling mod_delayed_work and putting ifa if
+the dad_work is already in queue.
+
+Note that this patch did not choose to fix it with:
+
+  if (!mod_delayed_work(delay))
+          in6_ifa_hold(ifp);
+
+As with it, when delay == 0, dad_work would be scheduled immediately, all
+addrconf_mod_dad_work(0) callings had to be moved under ifp->lock.
+
+Reported-by: Wei Chen <weichen@redhat.com>
+Suggested-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/addrconf.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -328,9 +328,9 @@ static void addrconf_mod_rs_timer(struct
+ static void addrconf_mod_dad_work(struct inet6_ifaddr *ifp,
+                                  unsigned long delay)
+ {
+-      if (!delayed_work_pending(&ifp->dad_work))
+-              in6_ifa_hold(ifp);
+-      mod_delayed_work(addrconf_wq, &ifp->dad_work, delay);
++      in6_ifa_hold(ifp);
++      if (mod_delayed_work(addrconf_wq, &ifp->dad_work, delay))
++              in6_ifa_put(ifp);
+ }
+ static int snmp6_alloc_dev(struct inet6_dev *idev)
diff --git a/queue-4.11/mac80211-free-netdev-on-dev_alloc_name-error.patch b/queue-4.11/mac80211-free-netdev-on-dev_alloc_name-error.patch
new file mode 100644 (file)
index 0000000..42e5f8b
--- /dev/null
@@ -0,0 +1,33 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Fri, 9 Jun 2017 21:33:09 +0200
+Subject: mac80211: free netdev on dev_alloc_name() error
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+
+[ Upstream commit c7a61cba71fd151cc7d9ebe53a090e0e61eeebf3 ]
+
+The change to remove free_netdev() from ieee80211_if_free()
+erroneously didn't add the necessary free_netdev() for when
+ieee80211_if_free() is called directly in one place, rather
+than as the priv_destructor. Add the missing call.
+
+Fixes: cf124db566e6 ("net: Fix inconsistent teardown and release of private netdev state.")
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mac80211/iface.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -1810,6 +1810,7 @@ int ieee80211_if_add(struct ieee80211_lo
+               ret = dev_alloc_name(ndev, ndev->name);
+               if (ret < 0) {
+                       ieee80211_if_free(ndev);
++                      free_netdev(ndev);
+                       return ret;
+               }
diff --git a/queue-4.11/net-8021q-fix-one-possible-panic-caused-by-bug_on-in-free_netdev.patch b/queue-4.11/net-8021q-fix-one-possible-panic-caused-by-bug_on-in-free_netdev.patch
new file mode 100644 (file)
index 0000000..f973a27
--- /dev/null
@@ -0,0 +1,73 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Gao Feng <gfree.wind@vip.163.com>
+Date: Fri, 16 Jun 2017 15:00:02 +0800
+Subject: net: 8021q: Fix one possible panic caused by BUG_ON in free_netdev
+
+From: Gao Feng <gfree.wind@vip.163.com>
+
+
+[ Upstream commit 9745e362add89432d2c951272a99b0a5fe4348a9 ]
+
+The register_vlan_device would invoke free_netdev directly, when
+register_vlan_dev failed. It would trigger the BUG_ON in free_netdev
+if the dev was already registered. In this case, the netdev would be
+freed in netdev_run_todo later.
+
+So add one condition check now. Only when dev is not registered, then
+free it directly.
+
+The following is the part coredump when netdev_upper_dev_link failed
+in register_vlan_dev. I removed the lines which are too long.
+
+[  411.237457] ------------[ cut here ]------------
+[  411.237458] kernel BUG at net/core/dev.c:7998!
+[  411.237484] invalid opcode: 0000 [#1] SMP
+[  411.237705]  [last unloaded: 8021q]
+[  411.237718] CPU: 1 PID: 12845 Comm: vconfig Tainted: G            E   4.12.0-rc5+ #6
+[  411.237737] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/02/2015
+[  411.237764] task: ffff9cbeb6685580 task.stack: ffffa7d2807d8000
+[  411.237782] RIP: 0010:free_netdev+0x116/0x120
+[  411.237794] RSP: 0018:ffffa7d2807dbdb0 EFLAGS: 00010297
+[  411.237808] RAX: 0000000000000002 RBX: ffff9cbeb6ba8fd8 RCX: 0000000000001878
+[  411.237826] RDX: 0000000000000001 RSI: 0000000000000282 RDI: 0000000000000000
+[  411.237844] RBP: ffffa7d2807dbdc8 R08: 0002986100029841 R09: 0002982100029801
+[  411.237861] R10: 0004000100029980 R11: 0004000100029980 R12: ffff9cbeb6ba9000
+[  411.238761] R13: ffff9cbeb6ba9060 R14: ffff9cbe60f1a000 R15: ffff9cbeb6ba9000
+[  411.239518] FS:  00007fb690d81700(0000) GS:ffff9cbebb640000(0000) knlGS:0000000000000000
+[  411.239949] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[  411.240454] CR2: 00007f7115624000 CR3: 0000000077cdf000 CR4: 00000000003406e0
+[  411.240936] Call Trace:
+[  411.241462]  vlan_ioctl_handler+0x3f1/0x400 [8021q]
+[  411.241910]  sock_ioctl+0x18b/0x2c0
+[  411.242394]  do_vfs_ioctl+0xa1/0x5d0
+[  411.242853]  ? sock_alloc_file+0xa6/0x130
+[  411.243465]  SyS_ioctl+0x79/0x90
+[  411.243900]  entry_SYSCALL_64_fastpath+0x1e/0xa9
+[  411.244425] RIP: 0033:0x7fb69089a357
+[  411.244863] RSP: 002b:00007ffcd04e0fc8 EFLAGS: 00000202 ORIG_RAX: 0000000000000010
+[  411.245445] RAX: ffffffffffffffda RBX: 00007ffcd04e2884 RCX: 00007fb69089a357
+[  411.245903] RDX: 00007ffcd04e0fd0 RSI: 0000000000008983 RDI: 0000000000000003
+[  411.246527] RBP: 00007ffcd04e0fd0 R08: 0000000000000000 R09: 1999999999999999
+[  411.246976] R10: 000000000000053f R11: 0000000000000202 R12: 0000000000000004
+[  411.247414] R13: 00007ffcd04e1128 R14: 00007ffcd04e2888 R15: 0000000000000001
+[  411.249129] RIP: free_netdev+0x116/0x120 RSP: ffffa7d2807dbdb0
+
+Signed-off-by: Gao Feng <gfree.wind@vip.163.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/8021q/vlan.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/8021q/vlan.c
++++ b/net/8021q/vlan.c
+@@ -277,7 +277,8 @@ static int register_vlan_device(struct n
+       return 0;
+ out_free_newdev:
+-      free_netdev(new_dev);
++      if (new_dev->reg_state == NETREG_UNINITIALIZED)
++              free_netdev(new_dev);
+       return err;
+ }
diff --git a/queue-4.11/net-caif-fix-a-sleep-in-atomic-bug-in-cfpkt_create_pfx.patch b/queue-4.11/net-caif-fix-a-sleep-in-atomic-bug-in-cfpkt_create_pfx.patch
new file mode 100644 (file)
index 0000000..6d0801a
--- /dev/null
@@ -0,0 +1,50 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Jia-Ju Bai <baijiaju1990@163.com>
+Date: Sat, 10 Jun 2017 16:49:39 +0800
+Subject: net: caif: Fix a sleep-in-atomic bug in cfpkt_create_pfx
+
+From: Jia-Ju Bai <baijiaju1990@163.com>
+
+
+[ Upstream commit f146e872eb12ebbe92d8e583b2637e0741440db3 ]
+
+The kernel may sleep under a rcu read lock in cfpkt_create_pfx, and the
+function call path is:
+cfcnfg_linkup_rsp (acquire the lock by rcu_read_lock)
+  cfctrl_linkdown_req
+    cfpkt_create
+      cfpkt_create_pfx
+        alloc_skb(GFP_KERNEL) --> may sleep
+cfserl_receive (acquire the lock by rcu_read_lock)
+  cfpkt_split
+    cfpkt_create_pfx
+      alloc_skb(GFP_KERNEL) --> may sleep
+
+There is "in_interrupt" in cfpkt_create_pfx to decide use "GFP_KERNEL" or
+"GFP_ATOMIC". In this situation, "GFP_KERNEL" is used because the function
+is called under a rcu read lock, instead in interrupt.
+
+To fix it, only "GFP_ATOMIC" is used in cfpkt_create_pfx.
+
+Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/caif/cfpkt_skbuff.c |    6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+--- a/net/caif/cfpkt_skbuff.c
++++ b/net/caif/cfpkt_skbuff.c
+@@ -81,11 +81,7 @@ static struct cfpkt *cfpkt_create_pfx(u1
+ {
+       struct sk_buff *skb;
+-      if (likely(in_interrupt()))
+-              skb = alloc_skb(len + pfx, GFP_ATOMIC);
+-      else
+-              skb = alloc_skb(len + pfx, GFP_KERNEL);
+-
++      skb = alloc_skb(len + pfx, GFP_ATOMIC);
+       if (unlikely(skb == NULL))
+               return NULL;
diff --git a/queue-4.11/net-don-t-call-strlen-on-non-terminated-string-in-dev_set_alias.patch b/queue-4.11/net-don-t-call-strlen-on-non-terminated-string-in-dev_set_alias.patch
new file mode 100644 (file)
index 0000000..0eb6cc1
--- /dev/null
@@ -0,0 +1,34 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Alexander Potapenko <glider@google.com>
+Date: Tue, 6 Jun 2017 15:56:54 +0200
+Subject: net: don't call strlen on non-terminated string in dev_set_alias()
+
+From: Alexander Potapenko <glider@google.com>
+
+
+[ Upstream commit c28294b941232931fbd714099798eb7aa7e865d7 ]
+
+KMSAN reported a use of uninitialized memory in dev_set_alias(),
+which was caused by calling strlcpy() (which in turn called strlen())
+on the user-supplied non-terminated string.
+
+Signed-off-by: Alexander Potapenko <glider@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/dev.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -1251,8 +1251,9 @@ int dev_set_alias(struct net_device *dev
+       if (!new_ifalias)
+               return -ENOMEM;
+       dev->ifalias = new_ifalias;
++      memcpy(dev->ifalias, alias, len);
++      dev->ifalias[len] = 0;
+-      strlcpy(dev->ifalias, alias, len+1);
+       return len;
+ }
diff --git a/queue-4.11/net-don-t-global-icmp-rate-limit-packets-originating-from-loopback.patch b/queue-4.11/net-don-t-global-icmp-rate-limit-packets-originating-from-loopback.patch
new file mode 100644 (file)
index 0000000..4a9c6d4
--- /dev/null
@@ -0,0 +1,66 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Jesper Dangaard Brouer <brouer@redhat.com>
+Date: Wed, 14 Jun 2017 13:27:37 +0200
+Subject: net: don't global ICMP rate limit packets originating from loopback
+
+From: Jesper Dangaard Brouer <brouer@redhat.com>
+
+
+[ Upstream commit 849a44de91636c24cea799cb8ad8c36433feb913 ]
+
+Florian Weimer seems to have a glibc test-case which requires that
+loopback interfaces does not get ICMP ratelimited.  This was broken by
+commit c0303efeab73 ("net: reduce cycles spend on ICMP replies that
+gets rate limited").
+
+An ICMP response will usually be routed back-out the same incoming
+interface.  Thus, take advantage of this and skip global ICMP
+ratelimit when the incoming device is loopback.  In the unlikely event
+that the outgoing it not loopback, due to strange routing policy
+rules, ICMP rate limiting still works via peer ratelimiting via
+icmpv4_xrlim_allow().  Thus, we should still comply with RFC1812
+(section 4.3.2.8 "Rate Limiting").
+
+This seems to fix the reproducer given by Florian.  While still
+avoiding to perform expensive and unneeded outgoing route lookup for
+rate limited packets (in the non-loopback case).
+
+Fixes: c0303efeab73 ("net: reduce cycles spend on ICMP replies that gets rate limited")
+Reported-by: Florian Weimer <fweimer@redhat.com>
+Reported-by: "H.J. Lu" <hjl.tools@gmail.com>
+Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/icmp.c |    8 ++++++--
+ net/ipv6/icmp.c |    2 +-
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -674,8 +674,12 @@ void icmp_send(struct sk_buff *skb_in, i
+       /* Needed by both icmp_global_allow and icmp_xmit_lock */
+       local_bh_disable();
+-      /* Check global sysctl_icmp_msgs_per_sec ratelimit */
+-      if (!icmpv4_global_allow(net, type, code))
++      /* Check global sysctl_icmp_msgs_per_sec ratelimit, unless
++       * incoming dev is loopback.  If outgoing dev change to not be
++       * loopback, then peer ratelimit still work (in icmpv4_xrlim_allow)
++       */
++      if (!(skb_in->dev && (skb_in->dev->flags&IFF_LOOPBACK)) &&
++            !icmpv4_global_allow(net, type, code))
+               goto out_bh_enable;
+       sk = icmp_xmit_lock(net);
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -491,7 +491,7 @@ static void icmp6_send(struct sk_buff *s
+       local_bh_disable();
+       /* Check global sysctl_icmp_msgs_per_sec ratelimit */
+-      if (!icmpv6_global_allow(type))
++      if (!(skb->dev->flags&IFF_LOOPBACK) && !icmpv6_global_allow(type))
+               goto out_bh_enable;
+       mip6_addr_swap(skb);
diff --git a/queue-4.11/net-fix-inconsistent-teardown-and-release-of-private-netdev-state.patch b/queue-4.11/net-fix-inconsistent-teardown-and-release-of-private-netdev-state.patch
new file mode 100644 (file)
index 0000000..492d35b
--- /dev/null
@@ -0,0 +1,1115 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: "David S. Miller" <davem@davemloft.net>
+Date: Mon, 8 May 2017 12:52:56 -0400
+Subject: net: Fix inconsistent teardown and release of private netdev state.
+
+From: "David S. Miller" <davem@davemloft.net>
+
+
+[ Upstream commit cf124db566e6b036b8bcbe8decbed740bdfac8c6 ]
+
+Network devices can allocate reasources and private memory using
+netdev_ops->ndo_init().  However, the release of these resources
+can occur in one of two different places.
+
+Either netdev_ops->ndo_uninit() or netdev->destructor().
+
+The decision of which operation frees the resources depends upon
+whether it is necessary for all netdev refs to be released before it
+is safe to perform the freeing.
+
+netdev_ops->ndo_uninit() presumably can occur right after the
+NETDEV_UNREGISTER notifier completes and the unicast and multicast
+address lists are flushed.
+
+netdev->destructor(), on the other hand, does not run until the
+netdev references all go away.
+
+Further complicating the situation is that netdev->destructor()
+almost universally does also a free_netdev().
+
+This creates a problem for the logic in register_netdevice().
+Because all callers of register_netdevice() manage the freeing
+of the netdev, and invoke free_netdev(dev) if register_netdevice()
+fails.
+
+If netdev_ops->ndo_init() succeeds, but something else fails inside
+of register_netdevice(), it does call ndo_ops->ndo_uninit().  But
+it is not able to invoke netdev->destructor().
+
+This is because netdev->destructor() will do a free_netdev() and
+then the caller of register_netdevice() will do the same.
+
+However, this means that the resources that would normally be released
+by netdev->destructor() will not be.
+
+Over the years drivers have added local hacks to deal with this, by
+invoking their destructor parts by hand when register_netdevice()
+fails.
+
+Many drivers do not try to deal with this, and instead we have leaks.
+
+Let's close this hole by formalizing the distinction between what
+private things need to be freed up by netdev->destructor() and whether
+the driver needs unregister_netdevice() to perform the free_netdev().
+
+netdev->priv_destructor() performs all actions to free up the private
+resources that used to be freed by netdev->destructor(), except for
+free_netdev().
+
+netdev->needs_free_netdev is a boolean that indicates whether
+free_netdev() should be done at the end of unregister_netdevice().
+
+Now, register_netdevice() can sanely release all resources after
+ndo_ops->ndo_init() succeeds, by invoking both ndo_ops->ndo_uninit()
+and netdev->priv_destructor().
+
+And at the end of unregister_netdevice(), we invoke
+netdev->priv_destructor() and optionally call free_netdev().
+
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/bonding/bond_main.c                             |    6 +++---
+ drivers/net/caif/caif_hsi.c                                 |    2 +-
+ drivers/net/caif/caif_serial.c                              |    2 +-
+ drivers/net/caif/caif_spi.c                                 |    2 +-
+ drivers/net/caif/caif_virtio.c                              |    2 +-
+ drivers/net/can/slcan.c                                     |    7 +++----
+ drivers/net/can/vcan.c                                      |    2 +-
+ drivers/net/dummy.c                                         |    4 ++--
+ drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c             |    2 +-
+ drivers/net/geneve.c                                        |    2 +-
+ drivers/net/gtp.c                                           |    2 +-
+ drivers/net/hamradio/6pack.c                                |    2 +-
+ drivers/net/hamradio/bpqether.c                             |    2 +-
+ drivers/net/ifb.c                                           |    4 ++--
+ drivers/net/ipvlan/ipvlan_main.c                            |    2 +-
+ drivers/net/loopback.c                                      |    4 ++--
+ drivers/net/macsec.c                                        |    4 ++--
+ drivers/net/macvlan.c                                       |    2 +-
+ drivers/net/nlmon.c                                         |    2 +-
+ drivers/net/slip/slip.c                                     |    7 +++----
+ drivers/net/team/team.c                                     |    4 ++--
+ drivers/net/tun.c                                           |    4 ++--
+ drivers/net/usb/cdc-phonet.c                                |    2 +-
+ drivers/net/veth.c                                          |    4 ++--
+ drivers/net/vrf.c                                           |    2 +-
+ drivers/net/vxlan.c                                         |    2 +-
+ drivers/net/wan/dlci.c                                      |    2 +-
+ drivers/net/wan/hdlc_fr.c                                   |    2 +-
+ drivers/net/wan/lapbether.c                                 |    2 +-
+ drivers/net/wireless/ath/ath6kl/main.c                      |    2 +-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c |    1 -
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c     |    3 ++-
+ drivers/net/wireless/intersil/hostap/hostap_main.c          |    2 +-
+ drivers/net/wireless/mac80211_hwsim.c                       |    2 +-
+ drivers/net/wireless/marvell/mwifiex/main.c                 |    2 +-
+ drivers/staging/rtl8188eu/os_dep/mon.c                      |    2 +-
+ drivers/usb/gadget/function/f_phonet.c                      |    2 +-
+ include/linux/netdevice.h                                   |    7 ++++---
+ net/8021q/vlan_dev.c                                        |    4 ++--
+ net/batman-adv/soft-interface.c                             |    5 ++---
+ net/bluetooth/6lowpan.c                                     |    2 +-
+ net/bridge/br_device.c                                      |    2 +-
+ net/caif/chnl_net.c                                         |    4 ++--
+ net/core/dev.c                                              |    8 ++++++--
+ net/hsr/hsr_device.c                                        |    4 ++--
+ net/ieee802154/6lowpan/core.c                               |    2 +-
+ net/ipv4/ip_tunnel.c                                        |    4 ++--
+ net/ipv4/ipmr.c                                             |    2 +-
+ net/ipv6/ip6_gre.c                                          |    9 +++++----
+ net/ipv6/ip6_tunnel.c                                       |    8 ++++----
+ net/ipv6/ip6_vti.c                                          |    8 ++++----
+ net/ipv6/ip6mr.c                                            |    2 +-
+ net/ipv6/sit.c                                              |    6 +++---
+ net/irda/irlan/irlan_eth.c                                  |    2 +-
+ net/l2tp/l2tp_eth.c                                         |    2 +-
+ net/mac80211/iface.c                                        |    6 +++---
+ net/mac802154/iface.c                                       |    7 +++----
+ net/openvswitch/vport-internal_dev.c                        |    4 ++--
+ net/phonet/pep-gprs.c                                       |    2 +-
+ 59 files changed, 102 insertions(+), 100 deletions(-)
+
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -4163,7 +4163,6 @@ static void bond_destructor(struct net_d
+       struct bonding *bond = netdev_priv(bond_dev);
+       if (bond->wq)
+               destroy_workqueue(bond->wq);
+-      free_netdev(bond_dev);
+ }
+ void bond_setup(struct net_device *bond_dev)
+@@ -4183,7 +4182,8 @@ void bond_setup(struct net_device *bond_
+       bond_dev->netdev_ops = &bond_netdev_ops;
+       bond_dev->ethtool_ops = &bond_ethtool_ops;
+-      bond_dev->destructor = bond_destructor;
++      bond_dev->needs_free_netdev = true;
++      bond_dev->priv_destructor = bond_destructor;
+       SET_NETDEV_DEVTYPE(bond_dev, &bond_type);
+@@ -4689,7 +4689,7 @@ int bond_create(struct net *net, const c
+       rtnl_unlock();
+       if (res < 0)
+-              bond_destructor(bond_dev);
++              free_netdev(bond_dev);
+       return res;
+ }
+--- a/drivers/net/caif/caif_hsi.c
++++ b/drivers/net/caif/caif_hsi.c
+@@ -1121,7 +1121,7 @@ static void cfhsi_setup(struct net_devic
+       dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+       dev->mtu = CFHSI_MAX_CAIF_FRAME_SZ;
+       dev->priv_flags |= IFF_NO_QUEUE;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       dev->netdev_ops = &cfhsi_netdevops;
+       for (i = 0; i < CFHSI_PRIO_LAST; ++i)
+               skb_queue_head_init(&cfhsi->qhead[i]);
+--- a/drivers/net/caif/caif_serial.c
++++ b/drivers/net/caif/caif_serial.c
+@@ -428,7 +428,7 @@ static void caifdev_setup(struct net_dev
+       dev->flags = IFF_POINTOPOINT | IFF_NOARP;
+       dev->mtu = CAIF_MAX_MTU;
+       dev->priv_flags |= IFF_NO_QUEUE;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       skb_queue_head_init(&serdev->head);
+       serdev->common.link_select = CAIF_LINK_LOW_LATENCY;
+       serdev->common.use_frag = true;
+--- a/drivers/net/caif/caif_spi.c
++++ b/drivers/net/caif/caif_spi.c
+@@ -712,7 +712,7 @@ static void cfspi_setup(struct net_devic
+       dev->flags = IFF_NOARP | IFF_POINTOPOINT;
+       dev->priv_flags |= IFF_NO_QUEUE;
+       dev->mtu = SPI_MAX_PAYLOAD_SIZE;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       skb_queue_head_init(&cfspi->qhead);
+       skb_queue_head_init(&cfspi->chead);
+       cfspi->cfdev.link_select = CAIF_LINK_HIGH_BANDW;
+--- a/drivers/net/caif/caif_virtio.c
++++ b/drivers/net/caif/caif_virtio.c
+@@ -617,7 +617,7 @@ static void cfv_netdev_setup(struct net_
+       netdev->tx_queue_len = 100;
+       netdev->flags = IFF_POINTOPOINT | IFF_NOARP;
+       netdev->mtu = CFV_DEF_MTU_SIZE;
+-      netdev->destructor = free_netdev;
++      netdev->needs_free_netdev = true;
+ }
+ /* Create debugfs counters for the device */
+--- a/drivers/net/can/slcan.c
++++ b/drivers/net/can/slcan.c
+@@ -417,7 +417,7 @@ static int slc_open(struct net_device *d
+ static void slc_free_netdev(struct net_device *dev)
+ {
+       int i = dev->base_addr;
+-      free_netdev(dev);
++
+       slcan_devs[i] = NULL;
+ }
+@@ -436,7 +436,8 @@ static const struct net_device_ops slc_n
+ static void slc_setup(struct net_device *dev)
+ {
+       dev->netdev_ops         = &slc_netdev_ops;
+-      dev->destructor         = slc_free_netdev;
++      dev->needs_free_netdev  = true;
++      dev->priv_destructor    = slc_free_netdev;
+       dev->hard_header_len    = 0;
+       dev->addr_len           = 0;
+@@ -761,8 +762,6 @@ static void __exit slcan_exit(void)
+               if (sl->tty) {
+                       printk(KERN_ERR "%s: tty discipline still running\n",
+                              dev->name);
+-                      /* Intentionally leak the control block. */
+-                      dev->destructor = NULL;
+               }
+               unregister_netdev(dev);
+--- a/drivers/net/can/vcan.c
++++ b/drivers/net/can/vcan.c
+@@ -160,7 +160,7 @@ static void vcan_setup(struct net_device
+               dev->flags |= IFF_ECHO;
+       dev->netdev_ops         = &vcan_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+ }
+ static struct rtnl_link_ops vcan_link_ops __read_mostly = {
+--- a/drivers/net/dummy.c
++++ b/drivers/net/dummy.c
+@@ -313,7 +313,6 @@ static void dummy_free_netdev(struct net
+       struct dummy_priv *priv = netdev_priv(dev);
+       kfree(priv->vfinfo);
+-      free_netdev(dev);
+ }
+ static void dummy_setup(struct net_device *dev)
+@@ -323,7 +322,8 @@ static void dummy_setup(struct net_devic
+       /* Initialize the device structure. */
+       dev->netdev_ops = &dummy_netdev_ops;
+       dev->ethtool_ops = &dummy_ethtool_ops;
+-      dev->destructor = dummy_free_netdev;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = dummy_free_netdev;
+       /* Fill in device structure with ethernet-generic values. */
+       dev->flags |= IFF_NOARP;
+--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
++++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
+@@ -4530,7 +4530,7 @@ static void dummy_setup(struct net_devic
+       /* Initialize the device structure. */
+       dev->netdev_ops = &cxgb4_mgmt_netdev_ops;
+       dev->ethtool_ops = &cxgb4_mgmt_ethtool_ops;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+ }
+ static int config_mgmt_dev(struct pci_dev *pdev)
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -1007,7 +1007,7 @@ static void geneve_setup(struct net_devi
+       dev->netdev_ops = &geneve_netdev_ops;
+       dev->ethtool_ops = &geneve_ethtool_ops;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       SET_NETDEV_DEVTYPE(dev, &geneve_type);
+--- a/drivers/net/gtp.c
++++ b/drivers/net/gtp.c
+@@ -618,7 +618,7 @@ static const struct net_device_ops gtp_n
+ static void gtp_link_setup(struct net_device *dev)
+ {
+       dev->netdev_ops         = &gtp_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+       dev->hard_header_len = 0;
+       dev->addr_len = 0;
+--- a/drivers/net/hamradio/6pack.c
++++ b/drivers/net/hamradio/6pack.c
+@@ -311,7 +311,7 @@ static void sp_setup(struct net_device *
+ {
+       /* Finish setting up the DEVICE info. */
+       dev->netdev_ops         = &sp_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+       dev->mtu                = SIXP_MTU;
+       dev->hard_header_len    = AX25_MAX_HEADER_LEN;
+       dev->header_ops         = &ax25_header_ops;
+--- a/drivers/net/hamradio/bpqether.c
++++ b/drivers/net/hamradio/bpqether.c
+@@ -476,7 +476,7 @@ static const struct net_device_ops bpq_n
+ static void bpq_setup(struct net_device *dev)
+ {
+       dev->netdev_ops      = &bpq_netdev_ops;
+-      dev->destructor      = free_netdev;
++      dev->needs_free_netdev = true;
+       memcpy(dev->broadcast, &ax25_bcast, AX25_ADDR_LEN);
+       memcpy(dev->dev_addr,  &ax25_defaddr, AX25_ADDR_LEN);
+--- a/drivers/net/ifb.c
++++ b/drivers/net/ifb.c
+@@ -207,7 +207,6 @@ static void ifb_dev_free(struct net_devi
+               __skb_queue_purge(&txp->tq);
+       }
+       kfree(dp->tx_private);
+-      free_netdev(dev);
+ }
+ static void ifb_setup(struct net_device *dev)
+@@ -230,7 +229,8 @@ static void ifb_setup(struct net_device
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+       netif_keep_dst(dev);
+       eth_hw_addr_random(dev);
+-      dev->destructor = ifb_dev_free;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = ifb_dev_free;
+ }
+ static netdev_tx_t ifb_xmit(struct sk_buff *skb, struct net_device *dev)
+--- a/drivers/net/ipvlan/ipvlan_main.c
++++ b/drivers/net/ipvlan/ipvlan_main.c
+@@ -621,7 +621,7 @@ void ipvlan_link_setup(struct net_device
+       dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+       dev->priv_flags |= IFF_UNICAST_FLT | IFF_NO_QUEUE;
+       dev->netdev_ops = &ipvlan_netdev_ops;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       dev->header_ops = &ipvlan_header_ops;
+       dev->ethtool_ops = &ipvlan_ethtool_ops;
+ }
+--- a/drivers/net/loopback.c
++++ b/drivers/net/loopback.c
+@@ -145,7 +145,6 @@ static void loopback_dev_free(struct net
+ {
+       dev_net(dev)->loopback_dev = NULL;
+       free_percpu(dev->lstats);
+-      free_netdev(dev);
+ }
+ static const struct net_device_ops loopback_ops = {
+@@ -183,7 +182,8 @@ static void loopback_setup(struct net_de
+       dev->ethtool_ops        = &loopback_ethtool_ops;
+       dev->header_ops         = &eth_header_ops;
+       dev->netdev_ops         = &loopback_ops;
+-      dev->destructor         = loopback_dev_free;
++      dev->needs_free_netdev  = true;
++      dev->priv_destructor    = loopback_dev_free;
+ }
+ /* Setup and register the loopback device. */
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -2994,7 +2994,6 @@ static void macsec_free_netdev(struct ne
+       free_percpu(macsec->secy.tx_sc.stats);
+       dev_put(real_dev);
+-      free_netdev(dev);
+ }
+ static void macsec_setup(struct net_device *dev)
+@@ -3004,7 +3003,8 @@ static void macsec_setup(struct net_devi
+       dev->max_mtu = ETH_MAX_MTU;
+       dev->priv_flags |= IFF_NO_QUEUE;
+       dev->netdev_ops = &macsec_netdev_ops;
+-      dev->destructor = macsec_free_netdev;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = macsec_free_netdev;
+       SET_NETDEV_DEVTYPE(dev, &macsec_type);
+       eth_zero_addr(dev->broadcast);
+--- a/drivers/net/macvlan.c
++++ b/drivers/net/macvlan.c
+@@ -1089,7 +1089,7 @@ void macvlan_common_setup(struct net_dev
+       netif_keep_dst(dev);
+       dev->priv_flags        |= IFF_UNICAST_FLT;
+       dev->netdev_ops         = &macvlan_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+       dev->header_ops         = &macvlan_hard_header_ops;
+       dev->ethtool_ops        = &macvlan_ethtool_ops;
+ }
+--- a/drivers/net/nlmon.c
++++ b/drivers/net/nlmon.c
+@@ -113,7 +113,7 @@ static void nlmon_setup(struct net_devic
+       dev->netdev_ops = &nlmon_ops;
+       dev->ethtool_ops = &nlmon_ethtool_ops;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       dev->features = NETIF_F_SG | NETIF_F_FRAGLIST |
+                       NETIF_F_HIGHDMA | NETIF_F_LLTX;
+--- a/drivers/net/slip/slip.c
++++ b/drivers/net/slip/slip.c
+@@ -629,7 +629,7 @@ static void sl_uninit(struct net_device
+ static void sl_free_netdev(struct net_device *dev)
+ {
+       int i = dev->base_addr;
+-      free_netdev(dev);
++
+       slip_devs[i] = NULL;
+ }
+@@ -651,7 +651,8 @@ static const struct net_device_ops sl_ne
+ static void sl_setup(struct net_device *dev)
+ {
+       dev->netdev_ops         = &sl_netdev_ops;
+-      dev->destructor         = sl_free_netdev;
++      dev->needs_free_netdev  = true;
++      dev->priv_destructor    = sl_free_netdev;
+       dev->hard_header_len    = 0;
+       dev->addr_len           = 0;
+@@ -1369,8 +1370,6 @@ static void __exit slip_exit(void)
+               if (sl->tty) {
+                       printk(KERN_ERR "%s: tty discipline still running\n",
+                              dev->name);
+-                      /* Intentionally leak the control block. */
+-                      dev->destructor = NULL;
+               }
+               unregister_netdev(dev);
+--- a/drivers/net/team/team.c
++++ b/drivers/net/team/team.c
+@@ -1643,7 +1643,6 @@ static void team_destructor(struct net_d
+       struct team *team = netdev_priv(dev);
+       free_percpu(team->pcpu_stats);
+-      free_netdev(dev);
+ }
+ static int team_open(struct net_device *dev)
+@@ -2079,7 +2078,8 @@ static void team_setup(struct net_device
+       dev->netdev_ops = &team_netdev_ops;
+       dev->ethtool_ops = &team_ethtool_ops;
+-      dev->destructor = team_destructor;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = team_destructor;
+       dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_TX_SKB_SHARING);
+       dev->priv_flags |= IFF_NO_QUEUE;
+       dev->priv_flags |= IFF_TEAM;
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -1560,7 +1560,6 @@ static void tun_free_netdev(struct net_d
+       free_percpu(tun->pcpu_stats);
+       tun_flow_uninit(tun);
+       security_tun_dev_free_security(tun->security);
+-      free_netdev(dev);
+ }
+ static void tun_setup(struct net_device *dev)
+@@ -1571,7 +1570,8 @@ static void tun_setup(struct net_device
+       tun->group = INVALID_GID;
+       dev->ethtool_ops = &tun_ethtool_ops;
+-      dev->destructor = tun_free_netdev;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = tun_free_netdev;
+       /* We prefer our own queue length */
+       dev->tx_queue_len = TUN_READQ_SIZE;
+ }
+--- a/drivers/net/usb/cdc-phonet.c
++++ b/drivers/net/usb/cdc-phonet.c
+@@ -298,7 +298,7 @@ static void usbpn_setup(struct net_devic
+       dev->addr_len           = 1;
+       dev->tx_queue_len       = 3;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+ }
+ /*
+--- a/drivers/net/veth.c
++++ b/drivers/net/veth.c
+@@ -227,7 +227,6 @@ static int veth_dev_init(struct net_devi
+ static void veth_dev_free(struct net_device *dev)
+ {
+       free_percpu(dev->vstats);
+-      free_netdev(dev);
+ }
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+@@ -322,7 +321,8 @@ static void veth_setup(struct net_device
+                              NETIF_F_HW_VLAN_STAG_TX |
+                              NETIF_F_HW_VLAN_CTAG_RX |
+                              NETIF_F_HW_VLAN_STAG_RX);
+-      dev->destructor = veth_dev_free;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = veth_dev_free;
+       dev->max_mtu = ETH_MAX_MTU;
+       dev->hw_features = VETH_FEATURES;
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -1206,7 +1206,7 @@ static void vrf_setup(struct net_device
+       dev->netdev_ops = &vrf_netdev_ops;
+       dev->l3mdev_ops = &vrf_l3mdev_ops;
+       dev->ethtool_ops = &vrf_ethtool_ops;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       /* Fill in device structure with ethernet-generic values. */
+       eth_hw_addr_random(dev);
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -2607,7 +2607,7 @@ static void vxlan_setup(struct net_devic
+       eth_hw_addr_random(dev);
+       ether_setup(dev);
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       SET_NETDEV_DEVTYPE(dev, &vxlan_type);
+       dev->features   |= NETIF_F_LLTX;
+--- a/drivers/net/wan/dlci.c
++++ b/drivers/net/wan/dlci.c
+@@ -475,7 +475,7 @@ static void dlci_setup(struct net_device
+       dev->flags              = 0;
+       dev->header_ops         = &dlci_header_ops;
+       dev->netdev_ops         = &dlci_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+       dlp->receive            = dlci_receive;
+--- a/drivers/net/wan/hdlc_fr.c
++++ b/drivers/net/wan/hdlc_fr.c
+@@ -1106,7 +1106,7 @@ static int fr_add_pvc(struct net_device
+               return -EIO;
+       }
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       *get_dev_p(pvc, type) = dev;
+       if (!used) {
+               state(hdlc)->dce_changed = 1;
+--- a/drivers/net/wan/lapbether.c
++++ b/drivers/net/wan/lapbether.c
+@@ -306,7 +306,7 @@ static const struct net_device_ops lapbe
+ static void lapbeth_setup(struct net_device *dev)
+ {
+       dev->netdev_ops      = &lapbeth_netdev_ops;
+-      dev->destructor      = free_netdev;
++      dev->needs_free_netdev = true;
+       dev->type            = ARPHRD_X25;
+       dev->hard_header_len = 3;
+       dev->mtu             = 1000;
+--- a/drivers/net/wireless/ath/ath6kl/main.c
++++ b/drivers/net/wireless/ath/ath6kl/main.c
+@@ -1287,7 +1287,7 @@ void init_netdev(struct net_device *dev)
+       struct ath6kl *ar = ath6kl_priv(dev);
+       dev->netdev_ops = &ath6kl_netdev_ops;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
+       dev->needed_headroom = ETH_HLEN;
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -5209,7 +5209,6 @@ void brcmf_cfg80211_free_netdev(struct n
+       if (vif)
+               brcmf_free_vif(vif);
+-      free_netdev(ndev);
+ }
+ static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -652,7 +652,8 @@ struct brcmf_if *brcmf_add_if(struct brc
+               if (!ndev)
+                       return ERR_PTR(-ENOMEM);
+-              ndev->destructor = brcmf_cfg80211_free_netdev;
++              ndev->needs_free_netdev = true;
++              ndev->priv_destructor = brcmf_cfg80211_free_netdev;
+               ifp = netdev_priv(ndev);
+               ifp->ndev = ndev;
+               /* store mapping ifidx to bsscfgidx */
+--- a/drivers/net/wireless/intersil/hostap/hostap_main.c
++++ b/drivers/net/wireless/intersil/hostap/hostap_main.c
+@@ -73,7 +73,7 @@ struct net_device * hostap_add_interface
+       dev->mem_end = mdev->mem_end;
+       hostap_setup_dev(dev, local, type);
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       sprintf(dev->name, "%s%s", prefix, name);
+       if (!rtnl_locked)
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -2807,7 +2807,7 @@ static const struct net_device_ops hwsim
+ static void hwsim_mon_setup(struct net_device *dev)
+ {
+       dev->netdev_ops = &hwsim_netdev_ops;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       ether_setup(dev);
+       dev->priv_flags |= IFF_NO_QUEUE;
+       dev->type = ARPHRD_IEEE80211_RADIOTAP;
+--- a/drivers/net/wireless/marvell/mwifiex/main.c
++++ b/drivers/net/wireless/marvell/mwifiex/main.c
+@@ -1277,7 +1277,7 @@ void mwifiex_init_priv_params(struct mwi
+                             struct net_device *dev)
+ {
+       dev->netdev_ops = &mwifiex_netdev_ops;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       /* Initialize private structure */
+       priv->current_key_index = 0;
+       priv->media_connected = false;
+--- a/drivers/staging/rtl8188eu/os_dep/mon.c
++++ b/drivers/staging/rtl8188eu/os_dep/mon.c
+@@ -152,7 +152,7 @@ static const struct net_device_ops mon_n
+ static void mon_setup(struct net_device *dev)
+ {
+       dev->netdev_ops = &mon_netdev_ops;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       ether_setup(dev);
+       dev->priv_flags |= IFF_NO_QUEUE;
+       dev->type = ARPHRD_IEEE80211;
+--- a/drivers/usb/gadget/function/f_phonet.c
++++ b/drivers/usb/gadget/function/f_phonet.c
+@@ -281,7 +281,7 @@ static void pn_net_setup(struct net_devi
+       dev->tx_queue_len       = 1;
+       dev->netdev_ops         = &pn_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+       dev->header_ops         = &phonet_header_ops;
+ }
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -1581,8 +1581,8 @@ enum netdev_priv_flags {
+  *    @rtnl_link_state:       This enum represents the phases of creating
+  *                            a new link
+  *
+- *    @destructor:            Called from unregister,
+- *                            can be used to call free_netdev
++ *    @needs_free_netdev:     Should unregister perform free_netdev?
++ *    @priv_destructor:       Called from unregister
+  *    @npinfo:                XXX: need comments on this one
+  *    @nd_net:                Network namespace this network device is inside
+  *
+@@ -1838,7 +1838,8 @@ struct net_device {
+               RTNL_LINK_INITIALIZING,
+       } rtnl_link_state:16;
+-      void (*destructor)(struct net_device *dev);
++      bool needs_free_netdev;
++      void (*priv_destructor)(struct net_device *dev);
+ #ifdef CONFIG_NETPOLL
+       struct netpoll_info __rcu       *npinfo;
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -807,7 +807,6 @@ static void vlan_dev_free(struct net_dev
+       free_percpu(vlan->vlan_pcpu_stats);
+       vlan->vlan_pcpu_stats = NULL;
+-      free_netdev(dev);
+ }
+ void vlan_setup(struct net_device *dev)
+@@ -820,7 +819,8 @@ void vlan_setup(struct net_device *dev)
+       netif_keep_dst(dev);
+       dev->netdev_ops         = &vlan_netdev_ops;
+-      dev->destructor         = vlan_dev_free;
++      dev->needs_free_netdev  = true;
++      dev->priv_destructor    = vlan_dev_free;
+       dev->ethtool_ops        = &vlan_ethtool_ops;
+       dev->min_mtu            = 0;
+--- a/net/batman-adv/soft-interface.c
++++ b/net/batman-adv/soft-interface.c
+@@ -961,8 +961,6 @@ static void batadv_softif_free(struct ne
+        * netdev and its private data (bat_priv)
+        */
+       rcu_barrier();
+-
+-      free_netdev(dev);
+ }
+ /**
+@@ -976,7 +974,8 @@ static void batadv_softif_init_early(str
+       ether_setup(dev);
+       dev->netdev_ops = &batadv_netdev_ops;
+-      dev->destructor = batadv_softif_free;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = batadv_softif_free;
+       dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_NETNS_LOCAL;
+       dev->priv_flags |= IFF_NO_QUEUE;
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -653,7 +653,7 @@ static void netdev_setup(struct net_devi
+       dev->netdev_ops         = &netdev_ops;
+       dev->header_ops         = &header_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+ }
+ static struct device_type bt_type = {
+--- a/net/bridge/br_device.c
++++ b/net/bridge/br_device.c
+@@ -379,7 +379,7 @@ void br_dev_setup(struct net_device *dev
+       ether_setup(dev);
+       dev->netdev_ops = &br_netdev_ops;
+-      dev->destructor = free_netdev;
++      dev->needs_free_netdev = true;
+       dev->ethtool_ops = &br_ethtool_ops;
+       SET_NETDEV_DEVTYPE(dev, &br_type);
+       dev->priv_flags = IFF_EBRIDGE | IFF_NO_QUEUE;
+--- a/net/caif/chnl_net.c
++++ b/net/caif/chnl_net.c
+@@ -392,14 +392,14 @@ static void chnl_net_destructor(struct n
+ {
+       struct chnl_net *priv = netdev_priv(dev);
+       caif_free_client(&priv->chnl);
+-      free_netdev(dev);
+ }
+ static void ipcaif_net_setup(struct net_device *dev)
+ {
+       struct chnl_net *priv;
+       dev->netdev_ops = &netdev_ops;
+-      dev->destructor = chnl_net_destructor;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = chnl_net_destructor;
+       dev->flags |= IFF_NOARP;
+       dev->flags |= IFF_POINTOPOINT;
+       dev->mtu = GPRS_PDP_MTU;
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -7346,6 +7346,8 @@ out:
+ err_uninit:
+       if (dev->netdev_ops->ndo_uninit)
+               dev->netdev_ops->ndo_uninit(dev);
++      if (dev->priv_destructor)
++              dev->priv_destructor(dev);
+       goto out;
+ }
+ EXPORT_SYMBOL(register_netdevice);
+@@ -7553,8 +7555,10 @@ void netdev_run_todo(void)
+               WARN_ON(rcu_access_pointer(dev->ip6_ptr));
+               WARN_ON(dev->dn_ptr);
+-              if (dev->destructor)
+-                      dev->destructor(dev);
++              if (dev->priv_destructor)
++                      dev->priv_destructor(dev);
++              if (dev->needs_free_netdev)
++                      free_netdev(dev);
+               /* Report a network device has been unregistered */
+               rtnl_lock();
+--- a/net/hsr/hsr_device.c
++++ b/net/hsr/hsr_device.c
+@@ -378,7 +378,6 @@ static void hsr_dev_destroy(struct net_d
+       del_timer_sync(&hsr->announce_timer);
+       synchronize_rcu();
+-      free_netdev(hsr_dev);
+ }
+ static const struct net_device_ops hsr_device_ops = {
+@@ -404,7 +403,8 @@ void hsr_dev_setup(struct net_device *de
+       SET_NETDEV_DEVTYPE(dev, &hsr_type);
+       dev->priv_flags |= IFF_NO_QUEUE;
+-      dev->destructor = hsr_dev_destroy;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = hsr_dev_destroy;
+       dev->hw_features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA |
+                          NETIF_F_GSO_MASK | NETIF_F_HW_CSUM |
+--- a/net/ieee802154/6lowpan/core.c
++++ b/net/ieee802154/6lowpan/core.c
+@@ -107,7 +107,7 @@ static void lowpan_setup(struct net_devi
+       ldev->netdev_ops        = &lowpan_netdev_ops;
+       ldev->header_ops        = &lowpan_header_ops;
+-      ldev->destructor        = free_netdev;
++      ldev->needs_free_netdev = true;
+       ldev->features          |= NETIF_F_NETNS_LOCAL;
+ }
+--- a/net/ipv4/ip_tunnel.c
++++ b/net/ipv4/ip_tunnel.c
+@@ -961,7 +961,6 @@ static void ip_tunnel_dev_free(struct ne
+       gro_cells_destroy(&tunnel->gro_cells);
+       dst_cache_destroy(&tunnel->dst_cache);
+       free_percpu(dev->tstats);
+-      free_netdev(dev);
+ }
+ void ip_tunnel_dellink(struct net_device *dev, struct list_head *head)
+@@ -1148,7 +1147,8 @@ int ip_tunnel_init(struct net_device *de
+       struct iphdr *iph = &tunnel->parms.iph;
+       int err;
+-      dev->destructor = ip_tunnel_dev_free;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = ip_tunnel_dev_free;
+       dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
+       if (!dev->tstats)
+               return -ENOMEM;
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -501,7 +501,7 @@ static void reg_vif_setup(struct net_dev
+       dev->mtu                = ETH_DATA_LEN - sizeof(struct iphdr) - 8;
+       dev->flags              = IFF_NOARP;
+       dev->netdev_ops         = &reg_vif_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+       dev->features           |= NETIF_F_NETNS_LOCAL;
+ }
+--- a/net/ipv6/ip6_gre.c
++++ b/net/ipv6/ip6_gre.c
+@@ -986,13 +986,13 @@ static void ip6gre_dev_free(struct net_d
+       dst_cache_destroy(&t->dst_cache);
+       free_percpu(dev->tstats);
+-      free_netdev(dev);
+ }
+ static void ip6gre_tunnel_setup(struct net_device *dev)
+ {
+       dev->netdev_ops = &ip6gre_netdev_ops;
+-      dev->destructor = ip6gre_dev_free;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = ip6gre_dev_free;
+       dev->type = ARPHRD_IP6GRE;
+@@ -1143,7 +1143,7 @@ static int __net_init ip6gre_init_net(st
+       return 0;
+ err_reg_dev:
+-      ip6gre_dev_free(ign->fb_tunnel_dev);
++      free_netdev(ign->fb_tunnel_dev);
+ err_alloc_dev:
+       return err;
+ }
+@@ -1292,7 +1292,8 @@ static void ip6gre_tap_setup(struct net_
+       ether_setup(dev);
+       dev->netdev_ops = &ip6gre_tap_netdev_ops;
+-      dev->destructor = ip6gre_dev_free;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = ip6gre_dev_free;
+       dev->features |= NETIF_F_NETNS_LOCAL;
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -254,7 +254,6 @@ static void ip6_dev_free(struct net_devi
+       gro_cells_destroy(&t->gro_cells);
+       dst_cache_destroy(&t->dst_cache);
+       free_percpu(dev->tstats);
+-      free_netdev(dev);
+ }
+ static int ip6_tnl_create2(struct net_device *dev)
+@@ -322,7 +321,7 @@ static struct ip6_tnl *ip6_tnl_create(st
+       return t;
+ failed_free:
+-      ip6_dev_free(dev);
++      free_netdev(dev);
+ failed:
+       return ERR_PTR(err);
+ }
+@@ -1772,7 +1771,8 @@ static const struct net_device_ops ip6_t
+ static void ip6_tnl_dev_setup(struct net_device *dev)
+ {
+       dev->netdev_ops = &ip6_tnl_netdev_ops;
+-      dev->destructor = ip6_dev_free;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = ip6_dev_free;
+       dev->type = ARPHRD_TUNNEL6;
+       dev->flags |= IFF_NOARP;
+@@ -2211,7 +2211,7 @@ static int __net_init ip6_tnl_init_net(s
+       return 0;
+ err_register:
+-      ip6_dev_free(ip6n->fb_tnl_dev);
++      free_netdev(ip6n->fb_tnl_dev);
+ err_alloc_dev:
+       return err;
+ }
+--- a/net/ipv6/ip6_vti.c
++++ b/net/ipv6/ip6_vti.c
+@@ -180,7 +180,6 @@ vti6_tnl_unlink(struct vti6_net *ip6n, s
+ static void vti6_dev_free(struct net_device *dev)
+ {
+       free_percpu(dev->tstats);
+-      free_netdev(dev);
+ }
+ static int vti6_tnl_create2(struct net_device *dev)
+@@ -235,7 +234,7 @@ static struct ip6_tnl *vti6_tnl_create(s
+       return t;
+ failed_free:
+-      vti6_dev_free(dev);
++      free_netdev(dev);
+ failed:
+       return NULL;
+ }
+@@ -841,7 +840,8 @@ static const struct net_device_ops vti6_
+ static void vti6_dev_setup(struct net_device *dev)
+ {
+       dev->netdev_ops = &vti6_netdev_ops;
+-      dev->destructor = vti6_dev_free;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = vti6_dev_free;
+       dev->type = ARPHRD_TUNNEL6;
+       dev->hard_header_len = LL_MAX_HEADER + sizeof(struct ipv6hdr);
+@@ -1092,7 +1092,7 @@ static int __net_init vti6_init_net(stru
+       return 0;
+ err_register:
+-      vti6_dev_free(ip6n->fb_tnl_dev);
++      free_netdev(ip6n->fb_tnl_dev);
+ err_alloc_dev:
+       return err;
+ }
+--- a/net/ipv6/ip6mr.c
++++ b/net/ipv6/ip6mr.c
+@@ -733,7 +733,7 @@ static void reg_vif_setup(struct net_dev
+       dev->mtu                = 1500 - sizeof(struct ipv6hdr) - 8;
+       dev->flags              = IFF_NOARP;
+       dev->netdev_ops         = &reg_vif_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+       dev->features           |= NETIF_F_NETNS_LOCAL;
+ }
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -265,7 +265,7 @@ static struct ip_tunnel *ipip6_tunnel_lo
+       return nt;
+ failed_free:
+-      ipip6_dev_free(dev);
++      free_netdev(dev);
+ failed:
+       return NULL;
+ }
+@@ -1333,7 +1333,6 @@ static void ipip6_dev_free(struct net_de
+       dst_cache_destroy(&tunnel->dst_cache);
+       free_percpu(dev->tstats);
+-      free_netdev(dev);
+ }
+ #define SIT_FEATURES (NETIF_F_SG         | \
+@@ -1348,7 +1347,8 @@ static void ipip6_tunnel_setup(struct ne
+       int t_hlen = tunnel->hlen + sizeof(struct iphdr);
+       dev->netdev_ops         = &ipip6_netdev_ops;
+-      dev->destructor         = ipip6_dev_free;
++      dev->needs_free_netdev  = true;
++      dev->priv_destructor    = ipip6_dev_free;
+       dev->type               = ARPHRD_SIT;
+       dev->hard_header_len    = LL_MAX_HEADER + t_hlen;
+--- a/net/irda/irlan/irlan_eth.c
++++ b/net/irda/irlan/irlan_eth.c
+@@ -65,7 +65,7 @@ static void irlan_eth_setup(struct net_d
+       ether_setup(dev);
+       dev->netdev_ops         = &irlan_eth_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+       dev->min_mtu            = 0;
+       dev->max_mtu            = ETH_MAX_MTU;
+--- a/net/l2tp/l2tp_eth.c
++++ b/net/l2tp/l2tp_eth.c
+@@ -133,7 +133,7 @@ static void l2tp_eth_dev_setup(struct ne
+       dev->priv_flags         &= ~IFF_TX_SKB_SHARING;
+       dev->features           |= NETIF_F_LLTX;
+       dev->netdev_ops         = &l2tp_eth_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+ }
+ static void l2tp_eth_dev_recv(struct l2tp_session *session, struct sk_buff *skb, int data_len)
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -1198,7 +1198,6 @@ static const struct net_device_ops ieee8
+ static void ieee80211_if_free(struct net_device *dev)
+ {
+       free_percpu(dev->tstats);
+-      free_netdev(dev);
+ }
+ static void ieee80211_if_setup(struct net_device *dev)
+@@ -1206,7 +1205,8 @@ static void ieee80211_if_setup(struct ne
+       ether_setup(dev);
+       dev->priv_flags &= ~IFF_TX_SKB_SHARING;
+       dev->netdev_ops = &ieee80211_dataif_ops;
+-      dev->destructor = ieee80211_if_free;
++      dev->needs_free_netdev = true;
++      dev->priv_destructor = ieee80211_if_free;
+ }
+ static void ieee80211_if_setup_no_queue(struct net_device *dev)
+@@ -1899,7 +1899,7 @@ int ieee80211_if_add(struct ieee80211_lo
+               ret = register_netdevice(ndev);
+               if (ret) {
+-                      ieee80211_if_free(ndev);
++                      free_netdev(ndev);
+                       return ret;
+               }
+       }
+--- a/net/mac802154/iface.c
++++ b/net/mac802154/iface.c
+@@ -526,8 +526,6 @@ static void mac802154_wpan_free(struct n
+       struct ieee802154_sub_if_data *sdata = IEEE802154_DEV_TO_SUB_IF(dev);
+       mac802154_llsec_destroy(&sdata->sec);
+-
+-      free_netdev(dev);
+ }
+ static void ieee802154_if_setup(struct net_device *dev)
+@@ -593,7 +591,8 @@ ieee802154_setup_sdata(struct ieee802154
+                                       sdata->dev->dev_addr);
+               sdata->dev->header_ops = &mac802154_header_ops;
+-              sdata->dev->destructor = mac802154_wpan_free;
++              sdata->dev->needs_free_netdev = true;
++              sdata->dev->priv_destructor = mac802154_wpan_free;
+               sdata->dev->netdev_ops = &mac802154_wpan_ops;
+               sdata->dev->ml_priv = &mac802154_mlme_wpan;
+               wpan_dev->promiscuous_mode = false;
+@@ -608,7 +607,7 @@ ieee802154_setup_sdata(struct ieee802154
+               break;
+       case NL802154_IFTYPE_MONITOR:
+-              sdata->dev->destructor = free_netdev;
++              sdata->dev->needs_free_netdev = true;
+               sdata->dev->netdev_ops = &mac802154_monitor_ops;
+               wpan_dev->promiscuous_mode = true;
+               break;
+--- a/net/openvswitch/vport-internal_dev.c
++++ b/net/openvswitch/vport-internal_dev.c
+@@ -94,7 +94,6 @@ static void internal_dev_destructor(stru
+       struct vport *vport = ovs_internal_dev_get_vport(dev);
+       ovs_vport_free(vport);
+-      free_netdev(dev);
+ }
+ static void
+@@ -156,7 +155,8 @@ static void do_setup(struct net_device *
+       netdev->priv_flags &= ~IFF_TX_SKB_SHARING;
+       netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE | IFF_OPENVSWITCH |
+                             IFF_PHONY_HEADROOM | IFF_NO_QUEUE;
+-      netdev->destructor = internal_dev_destructor;
++      netdev->needs_free_netdev = true;
++      netdev->priv_destructor = internal_dev_destructor;
+       netdev->ethtool_ops = &internal_dev_ethtool_ops;
+       netdev->rtnl_link_ops = &internal_dev_link_ops;
+--- a/net/phonet/pep-gprs.c
++++ b/net/phonet/pep-gprs.c
+@@ -236,7 +236,7 @@ static void gprs_setup(struct net_device
+       dev->tx_queue_len       = 10;
+       dev->netdev_ops         = &gprs_netdev_ops;
+-      dev->destructor         = free_netdev;
++      dev->needs_free_netdev  = true;
+ }
+ /*
diff --git a/queue-4.11/net-ipv6-release-route-when-device-is-unregistering.patch b/queue-4.11/net-ipv6-release-route-when-device-is-unregistering.patch
new file mode 100644 (file)
index 0000000..39f9297
--- /dev/null
@@ -0,0 +1,65 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: David Ahern <dsahern@gmail.com>
+Date: Wed, 7 Jun 2017 12:26:23 -0600
+Subject: net: ipv6: Release route when device is unregistering
+
+From: David Ahern <dsahern@gmail.com>
+
+
+[ Upstream commit 8397ed36b7c585f8d3e06c431f4137309124f78f ]
+
+Roopa reported attempts to delete a bond device that is referenced in a
+multipath route is hanging:
+
+$ ifdown bond2    # ifupdown2 command that deletes virtual devices
+unregister_netdevice: waiting for bond2 to become free. Usage count = 2
+
+Steps to reproduce:
+    echo 1 > /proc/sys/net/ipv6/conf/all/ignore_routes_with_linkdown
+    ip link add dev bond12 type bond
+    ip link add dev bond13 type bond
+    ip addr add 2001:db8:2::0/64 dev bond12
+    ip addr add 2001:db8:3::0/64 dev bond13
+    ip route add 2001:db8:33::0/64 nexthop via 2001:db8:2::2 nexthop via 2001:db8:3::2
+    ip link del dev bond12
+    ip link del dev bond13
+
+The root cause is the recent change to keep routes on a linkdown. Update
+the check to detect when the device is unregistering and release the
+route for that case.
+
+Fixes: a1a22c12060e4 ("net: ipv6: Keep nexthop of multipath route on admin down")
+Reported-by: Roopa Prabhu <roopa@cumulusnetworks.com>
+Signed-off-by: David Ahern <dsahern@gmail.com>
+Acked-by: Roopa Prabhu <roopa@cumulusnetworks.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/linux/netdevice.h |    5 +++++
+ net/ipv6/route.c          |    1 +
+ 2 files changed, 6 insertions(+)
+
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -4232,6 +4232,11 @@ static inline const char *netdev_name(co
+       return dev->name;
+ }
++static inline bool netdev_unregistering(const struct net_device *dev)
++{
++      return dev->reg_state == NETREG_UNREGISTERING;
++}
++
+ static inline const char *netdev_reg_state(const struct net_device *dev)
+ {
+       switch (dev->reg_state) {
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -2804,6 +2804,7 @@ static int fib6_ifdown(struct rt6_info *
+       if ((rt->dst.dev == dev || !dev) &&
+           rt != adn->net->ipv6.ip6_null_entry &&
+           (rt->rt6i_nsiblings == 0 ||
++           (dev && netdev_unregistering(dev)) ||
+            !rt->rt6i_idev->cnf.ignore_routes_with_linkdown))
+               return -1;
diff --git a/queue-4.11/net-mlx5-enable-4k-uar-only-when-page-size-is-bigger-than-4k.patch b/queue-4.11/net-mlx5-enable-4k-uar-only-when-page-size-is-bigger-than-4k.patch
new file mode 100644 (file)
index 0000000..104c266
--- /dev/null
@@ -0,0 +1,38 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Majd Dibbiny <majd@mellanox.com>
+Date: Sun, 28 May 2017 14:47:56 +0300
+Subject: net/mlx5: Enable 4K UAR only when page size is bigger than 4K
+
+From: Majd Dibbiny <majd@mellanox.com>
+
+
+[ Upstream commit 91828bd89940e8145f91751a015bc11bc486aad0 ]
+
+When the page size isn't bigger than 4K, there is no added value of enabling 4K
+UAR feature in the Firmware.
+
+Modified the condition of enabling the 4K UAR accordingly.
+
+Fixes: f502d834950a ("net/mlx5: Activate support for 4K UARs")
+Signed-off-by: Majd Dibbiny <majd@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/main.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -537,8 +537,10 @@ static int handle_hca_cap(struct mlx5_co
+       /* disable cmdif checksum */
+       MLX5_SET(cmd_hca_cap, set_hca_cap, cmdif_checksum, 0);
+-      /* If the HCA supports 4K UARs use it */
+-      if (MLX5_CAP_GEN_MAX(dev, uar_4k))
++      /* Enable 4K UAR only when HCA supports it and page size is bigger
++       * than 4K.
++       */
++      if (MLX5_CAP_GEN_MAX(dev, uar_4k) && PAGE_SIZE > 4096)
+               MLX5_SET(cmd_hca_cap, set_hca_cap, uar_4k, 1);
+       MLX5_SET(cmd_hca_cap, set_hca_cap, log_uar_page_sz, PAGE_SHIFT - 12);
diff --git a/queue-4.11/net-mlx5-remove-several-module-events-out-of-ethtool-stats.patch b/queue-4.11/net-mlx5-remove-several-module-events-out-of-ethtool-stats.patch
new file mode 100644 (file)
index 0000000..431e28d
--- /dev/null
@@ -0,0 +1,56 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Huy Nguyen <huyn@mellanox.com>
+Date: Mon, 8 May 2017 11:46:50 -0500
+Subject: net/mlx5: Remove several module events out of ethtool stats
+
+From: Huy Nguyen <huyn@mellanox.com>
+
+
+[ Upstream commit f729860a177d097ac44321fb2f7d927a0c54c5a3 ]
+
+Remove the following module event counters out of ethtool stats. The
+reason for removing these event counters is that these events do not
+occur without techinician's intervention.
+  module_pwr_budget_exd
+  module_long_range
+  module_no_eeprom
+  module_enforce_part
+  module_unknown_id
+  module_unknown_status
+  module_plug
+
+Fixes: bedb7c909c19 ("net/mlx5e: Add port module event counters to ethtool stats")
+Signed-off-by: Huy Nguyen <huyn@mellanox.com>
+Reviewed 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_stats.h |   11 ++---------
+ 1 file changed, 2 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.h
+@@ -417,20 +417,13 @@ struct mlx5e_stats {
+ };
+ static const struct counter_desc mlx5e_pme_status_desc[] = {
+-      { "module_plug", 0 },
+       { "module_unplug", 8 },
+ };
+ static const struct counter_desc mlx5e_pme_error_desc[] = {
+-      { "module_pwr_budget_exd", 0 },  /* power budget exceed */
+-      { "module_long_range", 8 },      /* long range for non MLNX cable */
+-      { "module_bus_stuck", 16 },      /* bus stuck (I2C or data shorted) */
+-      { "module_no_eeprom", 24 },      /* no eeprom/retry time out */
+-      { "module_enforce_part", 32 },   /* enforce part number list */
+-      { "module_unknown_id", 40 },     /* unknown identifier */
+-      { "module_high_temp", 48 },      /* high temperature */
++      { "module_bus_stuck", 16 },       /* bus stuck (I2C or data shorted) */
++      { "module_high_temp", 48 },       /* high temperature */
+       { "module_bad_shorted", 56 },    /* bad or shorted cable/module */
+-      { "module_unknown_status", 64 },
+ };
+ #endif /* __MLX5_EN_STATS_H__ */
diff --git a/queue-4.11/net-mlx5-wait-for-fw-readiness-before-initializing-command-interface.patch b/queue-4.11/net-mlx5-wait-for-fw-readiness-before-initializing-command-interface.patch
new file mode 100644 (file)
index 0000000..0015713
--- /dev/null
@@ -0,0 +1,56 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Eli Cohen <eli@mellanox.com>
+Date: Thu, 8 Jun 2017 11:33:16 -0500
+Subject: net/mlx5: Wait for FW readiness before initializing command interface
+
+From: Eli Cohen <eli@mellanox.com>
+
+
+[ Upstream commit 6c780a0267b8a1075f40b39851132eeaefefcff5 ]
+
+Before attempting to initialize the command interface we must wait till
+the fw_initializing bit is clear.
+
+If we fail to meet this condition the hardware will drop our
+configuration, specifically the descriptors page address.  This scenario
+can happen when the firmware is still executing an FLR flow and did not
+finish yet so the driver needs to wait for that to finish.
+
+Fixes: e3297246c2c8 ('net/mlx5_core: Wait for FW readiness on startup')
+Signed-off-by: Eli Cohen <eli@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/main.c |   14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c
+@@ -175,8 +175,9 @@ static struct mlx5_profile profile[] = {
+       },
+ };
+-#define FW_INIT_TIMEOUT_MILI  2000
+-#define FW_INIT_WAIT_MS               2
++#define FW_INIT_TIMEOUT_MILI          2000
++#define FW_INIT_WAIT_MS                       2
++#define FW_PRE_INIT_TIMEOUT_MILI      10000
+ static int wait_fw_init(struct mlx5_core_dev *dev, u32 max_wait_mili)
+ {
+@@ -1021,6 +1022,15 @@ static int mlx5_load_one(struct mlx5_cor
+        */
+       dev->state = MLX5_DEVICE_STATE_UP;
++      /* wait for firmware to accept initialization segments configurations
++       */
++      err = wait_fw_init(dev, FW_PRE_INIT_TIMEOUT_MILI);
++      if (err) {
++              dev_err(&dev->pdev->dev, "Firmware over %d MS in pre-initializing state, aborting\n",
++                      FW_PRE_INIT_TIMEOUT_MILI);
++              goto out;
++      }
++
+       err = mlx5_cmd_init(dev);
+       if (err) {
+               dev_err(&pdev->dev, "Failed initializing command interface, aborting\n");
diff --git a/queue-4.11/net-mlx5e-added-bw-check-for-dim-decision-mechanism.patch b/queue-4.11/net-mlx5e-added-bw-check-for-dim-decision-mechanism.patch
new file mode 100644 (file)
index 0000000..c41bcd9
--- /dev/null
@@ -0,0 +1,130 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Tal Gilboa <talgi@mellanox.com>
+Date: Mon, 15 May 2017 14:13:16 +0300
+Subject: net/mlx5e: Added BW check for DIM decision mechanism
+
+From: Tal Gilboa <talgi@mellanox.com>
+
+
+[ Upstream commit c3164d2fc48fd4fa0477ab658b644559c3fe9073 ]
+
+DIM (Dynamically-tuned Interrupt Moderation) is a mechanism designed for
+changing the channel interrupt moderation values in order to reduce CPU
+overhead for all traffic types.
+Until now only interrupt and packet rate were sampled.
+We found a scenario on which we get a false indication since a change in
+DIM caused more aggregation and reduced packet rate while increasing BW.
+
+We now regard a change as succesfull iff:
+current_BW > (prev_BW + threshold) or
+current_BW ~= prev_BW and current_PR > (prev_PR + threshold) or
+current_BW ~= prev_BW and current_PR ~= prev_PR and
+    current_IR < (prev_IR - threshold)
+Where BW = Bandwidth, PR = Packet rate and IR = Interrupt rate
+
+Improvements (ConnectX-4Lx 25GbE, single RX queue, LRO off)
+    --------------------------------------------------
+    packet size | before[Mb/s] | after[Mb/s] | gain  |
+    2B          | 343.4        | 359.4       |  4.5% |
+    16B         | 2739.7       | 2814.8      |  2.7% |
+    64B         | 9739         | 10185.3     |  4.5% |
+
+Fixes: cb3c7fd4f839 ("net/mlx5e: Support adaptive RX coalescing")
+Signed-off-by: Tal Gilboa <talgi@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.h       |    2 +
+ drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c |   41 +++++++++++----------
+ 2 files changed, 24 insertions(+), 19 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -313,12 +313,14 @@ struct mlx5e_dma_info {
+ struct mlx5e_rx_am_stats {
+       int ppms; /* packets per msec */
++      int bpms; /* bytes per msec */
+       int epms; /* events per msec */
+ };
+ struct mlx5e_rx_am_sample {
+       ktime_t         time;
+       unsigned int    pkt_ctr;
++      unsigned int    byte_ctr;
+       u16             event_ctr;
+ };
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
+@@ -183,28 +183,27 @@ static void mlx5e_am_exit_parking(struct
+       mlx5e_am_step(am);
+ }
++#define IS_SIGNIFICANT_DIFF(val, ref) \
++      (((100 * abs((val) - (ref))) / (ref)) > 10) /* more than 10% difference */
++
+ static int mlx5e_am_stats_compare(struct mlx5e_rx_am_stats *curr,
+                                 struct mlx5e_rx_am_stats *prev)
+ {
+-      int diff;
+-
+-      if (!prev->ppms)
+-              return curr->ppms ? MLX5E_AM_STATS_BETTER :
+-                                  MLX5E_AM_STATS_SAME;
+-
+-      diff = curr->ppms - prev->ppms;
+-      if (((100 * abs(diff)) / prev->ppms) > 10) /* more than 10% diff */
+-              return (diff > 0) ? MLX5E_AM_STATS_BETTER :
+-                                  MLX5E_AM_STATS_WORSE;
+-
+-      if (!prev->epms)
+-              return curr->epms ? MLX5E_AM_STATS_WORSE :
++      if (!prev->bpms)
++              return curr->bpms ? MLX5E_AM_STATS_BETTER :
+                                   MLX5E_AM_STATS_SAME;
+-      diff = curr->epms - prev->epms;
+-      if (((100 * abs(diff)) / prev->epms) > 10) /* more than 10% diff */
+-              return (diff < 0) ? MLX5E_AM_STATS_BETTER :
+-                                  MLX5E_AM_STATS_WORSE;
++      if (IS_SIGNIFICANT_DIFF(curr->bpms, prev->bpms))
++              return (curr->bpms > prev->bpms) ? MLX5E_AM_STATS_BETTER :
++                                                 MLX5E_AM_STATS_WORSE;
++
++      if (IS_SIGNIFICANT_DIFF(curr->ppms, prev->ppms))
++              return (curr->ppms > prev->ppms) ? MLX5E_AM_STATS_BETTER :
++                                                 MLX5E_AM_STATS_WORSE;
++
++      if (IS_SIGNIFICANT_DIFF(curr->epms, prev->epms))
++              return (curr->epms < prev->epms) ? MLX5E_AM_STATS_BETTER :
++                                                 MLX5E_AM_STATS_WORSE;
+       return MLX5E_AM_STATS_SAME;
+ }
+@@ -266,6 +265,7 @@ static void mlx5e_am_sample(struct mlx5e
+ {
+       s->time      = ktime_get();
+       s->pkt_ctr   = rq->stats.packets;
++      s->byte_ctr  = rq->stats.bytes;
+       s->event_ctr = rq->cq.event_ctr;
+ }
+@@ -278,12 +278,15 @@ static void mlx5e_am_calc_stats(struct m
+       /* u32 holds up to 71 minutes, should be enough */
+       u32 delta_us = ktime_us_delta(end->time, start->time);
+       unsigned int npkts = end->pkt_ctr - start->pkt_ctr;
++      unsigned int nbytes = end->byte_ctr - start->byte_ctr;
+       if (!delta_us)
+               return;
+-      curr_stats->ppms =            (npkts * USEC_PER_MSEC) / delta_us;
+-      curr_stats->epms = (MLX5E_AM_NEVENTS * USEC_PER_MSEC) / delta_us;
++      curr_stats->ppms = DIV_ROUND_UP(npkts * USEC_PER_MSEC, delta_us);
++      curr_stats->bpms = DIV_ROUND_UP(nbytes * USEC_PER_MSEC, delta_us);
++      curr_stats->epms = DIV_ROUND_UP(MLX5E_AM_NEVENTS * USEC_PER_MSEC,
++                                      delta_us);
+ }
+ void mlx5e_rx_am_work(struct work_struct *work)
diff --git a/queue-4.11/net-mlx5e-avoid-doing-a-cleanup-call-if-the-profile-doesn-t-have-it.patch b/queue-4.11/net-mlx5e-avoid-doing-a-cleanup-call-if-the-profile-doesn-t-have-it.patch
new file mode 100644 (file)
index 0000000..fce264a
--- /dev/null
@@ -0,0 +1,38 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Or Gerlitz <ogerlitz@mellanox.com>
+Date: Thu, 15 Jun 2017 20:08:32 +0300
+Subject: net/mlx5e: Avoid doing a cleanup call if the profile doesn't have it
+
+From: Or Gerlitz <ogerlitz@mellanox.com>
+
+
+[ Upstream commit 31ac93386d135a6c96de9c8bab406f5ccabf5a4d ]
+
+The error flow of mlx5e_create_netdev calls the cleanup call
+of the given profile without checking if it exists, fix that.
+
+Currently the VF reps don't register that callback and we crash
+if getting into error -- can be reproduced by the user doing ctrl^C
+while attempting to change the sriov mode from legacy to switchdev.
+
+Fixes: 26e59d8077a3 '(net/mlx5e: Implement mlx5e interface attach/detach callbacks')
+Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
+Reported-by: Sabrina Dubroca <sdubroca@redhat.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 |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+@@ -3885,7 +3885,8 @@ struct net_device *mlx5e_create_netdev(s
+       return netdev;
+ err_cleanup_nic:
+-      profile->cleanup(priv);
++      if (profile->cleanup)
++              profile->cleanup(priv);
+       free_netdev(netdev);
+       return NULL;
diff --git a/queue-4.11/net-mlx5e-fix-min-inline-value-for-vf-rep-sqs.patch b/queue-4.11/net-mlx5e-fix-min-inline-value-for-vf-rep-sqs.patch
new file mode 100644 (file)
index 0000000..b177035
--- /dev/null
@@ -0,0 +1,38 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Chris Mi <chrism@mellanox.com>
+Date: Tue, 16 May 2017 07:07:11 -0400
+Subject: net/mlx5e: Fix min inline value for VF rep SQs
+
+From: Chris Mi <chrism@mellanox.com>
+
+
+[ Upstream commit 5f195c2c5cba60241004146cd12d71451d6b0fc4 ]
+
+The offending commit only changed the code path for PF/VF, but it
+didn't take care of VF representors. As a result, since
+params->tx_min_inline_mode for VF representors is kzalloced to 0
+(MLX5_INLINE_MODE_NONE), all VF reps SQs were set to that mode.
+
+This actually works on CX5 by default but broke CX4. Fix that by
+adding a call to query the min inline mode from the VF rep build up code.
+
+Fixes: a6f402e49901 ("net/mlx5e: Tx, no inline copy on ConnectX-5")
+Signed-off-by: Chris Mi <chrism@mellanox.com>
+Reviewed-by: Or Gerlitz <ogerlitz@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_rep.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+@@ -424,6 +424,8 @@ static void mlx5e_build_rep_netdev_priv(
+       priv->params.lro_wqe_sz            =
+               MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
++      mlx5_query_min_inline(mdev, &priv->params.tx_min_inline_mode);
++
+       priv->mdev                         = mdev;
+       priv->netdev                       = netdev;
+       priv->params.num_channels          = profile->max_nch(mdev);
diff --git a/queue-4.11/net-mlx5e-fix-timestamping-capabilities-reporting.patch b/queue-4.11/net-mlx5e-fix-timestamping-capabilities-reporting.patch
new file mode 100644 (file)
index 0000000..4be5c6d
--- /dev/null
@@ -0,0 +1,40 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Maor Dickman <maord@mellanox.com>
+Date: Thu, 18 May 2017 15:15:08 +0300
+Subject: net/mlx5e: Fix timestamping capabilities reporting
+
+From: Maor Dickman <maord@mellanox.com>
+
+
+[ Upstream commit f0b381178b01b831f9907d72f467d6443afdea67 ]
+
+Misuse of (BIT) macro caused to report wrong flags for
+"Hardware Transmit Timestamp Modes" and "Hardware Receive
+Filter Modes"
+
+Fixes: ef9814deafd0 ('net/mlx5e: Add HW timestamping (TS) support')
+Signed-off-by: Maor Dickman <maord@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_ethtool.c |    8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+@@ -1205,11 +1205,11 @@ static int mlx5e_get_ts_info(struct net_
+                                SOF_TIMESTAMPING_RX_HARDWARE |
+                                SOF_TIMESTAMPING_RAW_HARDWARE;
+-      info->tx_types = (BIT(1) << HWTSTAMP_TX_OFF) |
+-                       (BIT(1) << HWTSTAMP_TX_ON);
++      info->tx_types = BIT(HWTSTAMP_TX_OFF) |
++                       BIT(HWTSTAMP_TX_ON);
+-      info->rx_filters = (BIT(1) << HWTSTAMP_FILTER_NONE) |
+-                         (BIT(1) << HWTSTAMP_FILTER_ALL);
++      info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) |
++                         BIT(HWTSTAMP_FILTER_ALL);
+       return 0;
+ }
diff --git a/queue-4.11/net-mlx5e-fix-wrong-indications-in-dim-due-to-counter-wraparound.patch b/queue-4.11/net-mlx5e-fix-wrong-indications-in-dim-due-to-counter-wraparound.patch
new file mode 100644 (file)
index 0000000..72def76
--- /dev/null
@@ -0,0 +1,87 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Tal Gilboa <talgi@mellanox.com>
+Date: Mon, 29 May 2017 17:02:55 +0300
+Subject: net/mlx5e: Fix wrong indications in DIM due to counter wraparound
+
+From: Tal Gilboa <talgi@mellanox.com>
+
+
+[ Upstream commit 53acd76ce571e3b71f9205f2d49ab285a9f1aad8 ]
+
+DIM (Dynamically-tuned Interrupt Moderation) is a mechanism designed for
+changing the channel interrupt moderation values in order to reduce CPU
+overhead for all traffic types.
+Each iteration of the algorithm, DIM calculates the difference in
+throughput, packet rate and interrupt rate from last iteration in order
+to make a decision. DIM relies on counters for each metric. When these
+counters get to their type's max value they wraparound. In this case
+the delta between 'end' and 'start' samples is negative and when
+translated to unsigned integers - very high. This results in a false
+indication to the algorithm and might result in a wrong decision.
+
+The fix calculates the 'distance' between 'end' and 'start' samples in a
+cyclic way around the relevant type's max value. It can also be viewed as
+an absolute value around the type's max value instead of around 0.
+
+Testing show higher stability in DIM profile selection and no wraparound
+issues.
+
+Fixes: cb3c7fd4f839 ("net/mlx5e: Support adaptive RX coalescing")
+Signed-off-by: Tal Gilboa <talgi@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.h       |    8 ++++----
+ drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c |   10 +++++++---
+ 2 files changed, 11 insertions(+), 7 deletions(-)
+
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en.h
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en.h
+@@ -318,10 +318,10 @@ struct mlx5e_rx_am_stats {
+ };
+ struct mlx5e_rx_am_sample {
+-      ktime_t         time;
+-      unsigned int    pkt_ctr;
+-      unsigned int    byte_ctr;
+-      u16             event_ctr;
++      ktime_t time;
++      u32     pkt_ctr;
++      u32     byte_ctr;
++      u16     event_ctr;
+ };
+ struct mlx5e_rx_am { /* Adaptive Moderation */
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx_am.c
+@@ -270,6 +270,8 @@ static void mlx5e_am_sample(struct mlx5e
+ }
+ #define MLX5E_AM_NEVENTS 64
++#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
++#define BIT_GAP(bits, end, start) ((((end) - (start)) + BIT_ULL(bits)) & (BIT_ULL(bits) - 1))
+ static void mlx5e_am_calc_stats(struct mlx5e_rx_am_sample *start,
+                               struct mlx5e_rx_am_sample *end,
+@@ -277,8 +279,9 @@ static void mlx5e_am_calc_stats(struct m
+ {
+       /* u32 holds up to 71 minutes, should be enough */
+       u32 delta_us = ktime_us_delta(end->time, start->time);
+-      unsigned int npkts = end->pkt_ctr - start->pkt_ctr;
+-      unsigned int nbytes = end->byte_ctr - start->byte_ctr;
++      u32 npkts = BIT_GAP(BITS_PER_TYPE(u32), end->pkt_ctr, start->pkt_ctr);
++      u32 nbytes = BIT_GAP(BITS_PER_TYPE(u32), end->byte_ctr,
++                           start->byte_ctr);
+       if (!delta_us)
+               return;
+@@ -311,7 +314,8 @@ void mlx5e_rx_am(struct mlx5e_rq *rq)
+       switch (am->state) {
+       case MLX5E_AM_MEASURE_IN_PROGRESS:
+-              nevents = rq->cq.event_ctr - am->start_sample.event_ctr;
++              nevents = BIT_GAP(BITS_PER_TYPE(u16), rq->cq.event_ctr,
++                                am->start_sample.event_ctr);
+               if (nevents < MLX5E_AM_NEVENTS)
+                       break;
+               mlx5e_am_sample(rq, &end_sample);
diff --git a/queue-4.11/net-s390-fix-up-for-fix-inconsistent-teardown-and-release-of-private-netdev-state.patch b/queue-4.11/net-s390-fix-up-for-fix-inconsistent-teardown-and-release-of-private-netdev-state.patch
new file mode 100644 (file)
index 0000000..fe44b9c
--- /dev/null
@@ -0,0 +1,37 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Stephen Rothwell <sfr@canb.auug.org.au>
+Date: Thu, 8 Jun 2017 19:06:29 +1000
+Subject: net: s390: fix up for "Fix inconsistent teardown and release of private netdev state"
+
+From: Stephen Rothwell <sfr@canb.auug.org.au>
+
+
+[ Upstream commit cd1997f6c11483da819a7719aa013093b8003743 ]
+
+Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/s390/net/netiucv.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/s390/net/netiucv.c
++++ b/drivers/s390/net/netiucv.c
+@@ -1954,7 +1954,6 @@ static void netiucv_free_netdevice(struc
+               privptr->conn = NULL; privptr->fsm = NULL;
+               /* privptr gets freed by free_netdev() */
+       }
+-      free_netdev(dev);
+ }
+ /**
+@@ -1972,7 +1971,8 @@ static void netiucv_setup_netdevice(stru
+       dev->mtu                 = NETIUCV_MTU_DEFAULT;
+       dev->min_mtu             = 576;
+       dev->max_mtu             = NETIUCV_MTU_MAX;
+-      dev->destructor          = netiucv_free_netdevice;
++      dev->needs_free_netdev   = true;
++      dev->priv_destructor     = netiucv_free_netdevice;
+       dev->hard_header_len     = NETIUCV_HDRLEN;
+       dev->addr_len            = 0;
+       dev->type                = ARPHRD_SLIP;
diff --git a/queue-4.11/net-tipc-fix-a-sleep-in-atomic-bug-in-tipc_msg_reverse.patch b/queue-4.11/net-tipc-fix-a-sleep-in-atomic-bug-in-tipc_msg_reverse.patch
new file mode 100644 (file)
index 0000000..bb4d76c
--- /dev/null
@@ -0,0 +1,44 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Jia-Ju Bai <baijiaju1990@163.com>
+Date: Sat, 10 Jun 2017 17:03:35 +0800
+Subject: net: tipc: Fix a sleep-in-atomic bug in tipc_msg_reverse
+
+From: Jia-Ju Bai <baijiaju1990@163.com>
+
+
+[ Upstream commit 343eba69c6968190d8654b857aea952fed9a6749 ]
+
+The kernel may sleep under a rcu read lock in tipc_msg_reverse, and the
+function call path is:
+tipc_l2_rcv_msg (acquire the lock by rcu_read_lock)
+  tipc_rcv
+    tipc_sk_rcv
+      tipc_msg_reverse
+        pskb_expand_head(GFP_KERNEL) --> may sleep
+tipc_node_broadcast
+  tipc_node_xmit_skb
+    tipc_node_xmit
+      tipc_sk_rcv
+        tipc_msg_reverse
+          pskb_expand_head(GFP_KERNEL) --> may sleep
+
+To fix it, "GFP_KERNEL" is replaced with "GFP_ATOMIC".
+
+Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/tipc/msg.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/tipc/msg.c
++++ b/net/tipc/msg.c
+@@ -508,7 +508,7 @@ bool tipc_msg_reverse(u32 own_node,  str
+       }
+       if (skb_cloned(_skb) &&
+-          pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_KERNEL))
++          pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC))
+               goto exit;
+       /* Now reverse the concerned fields */
diff --git a/queue-4.11/net-vrf-make-add_fib_rules-per-network-namespace-flag.patch b/queue-4.11/net-vrf-make-add_fib_rules-per-network-namespace-flag.patch
new file mode 100644 (file)
index 0000000..96ed197
--- /dev/null
@@ -0,0 +1,110 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: David Ahern <dsahern@gmail.com>
+Date: Thu, 8 Jun 2017 11:31:11 -0600
+Subject: net: vrf: Make add_fib_rules per network namespace flag
+
+From: David Ahern <dsahern@gmail.com>
+
+
+[ Upstream commit 097d3c9508dc58286344e4a22b300098cf0c1566 ]
+
+Commit 1aa6c4f6b8cd8 ("net: vrf: Add l3mdev rules on first device create")
+adds the l3mdev FIB rule the first time a VRF device is created. However,
+it only creates the rule once and only in the namespace the first device
+is created - which may not be init_net. Fix by using the net_generic
+capability to make the add_fib_rules flag per network namespace.
+
+Fixes: 1aa6c4f6b8cd8 ("net: vrf: Add l3mdev rules on first device create")
+Reported-by: Petr Machata <petrm@mellanox.com>
+Signed-off-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 |   36 ++++++++++++++++++++++++++++++++----
+ 1 file changed, 32 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/vrf.c
++++ b/drivers/net/vrf.c
+@@ -36,12 +36,14 @@
+ #include <net/addrconf.h>
+ #include <net/l3mdev.h>
+ #include <net/fib_rules.h>
++#include <net/netns/generic.h>
+ #define DRV_NAME      "vrf"
+ #define DRV_VERSION   "1.0"
+ #define FIB_RULE_PREF  1000       /* default preference for FIB rules */
+-static bool add_fib_rules = true;
++
++static unsigned int vrf_net_id;
+ struct net_vrf {
+       struct rtable __rcu     *rth;
+@@ -1252,6 +1254,8 @@ static int vrf_newlink(struct net *src_n
+                      struct nlattr *tb[], struct nlattr *data[])
+ {
+       struct net_vrf *vrf = netdev_priv(dev);
++      bool *add_fib_rules;
++      struct net *net;
+       int err;
+       if (!data || !data[IFLA_VRF_TABLE])
+@@ -1267,13 +1271,15 @@ static int vrf_newlink(struct net *src_n
+       if (err)
+               goto out;
+-      if (add_fib_rules) {
++      net = dev_net(dev);
++      add_fib_rules = net_generic(net, vrf_net_id);
++      if (*add_fib_rules) {
+               err = vrf_add_fib_rules(dev);
+               if (err) {
+                       unregister_netdevice(dev);
+                       goto out;
+               }
+-              add_fib_rules = false;
++              *add_fib_rules = false;
+       }
+ out:
+@@ -1356,16 +1362,38 @@ static struct notifier_block vrf_notifie
+       .notifier_call = vrf_device_event,
+ };
++/* Initialize per network namespace state */
++static int __net_init vrf_netns_init(struct net *net)
++{
++      bool *add_fib_rules = net_generic(net, vrf_net_id);
++
++      *add_fib_rules = true;
++
++      return 0;
++}
++
++static struct pernet_operations vrf_net_ops __net_initdata = {
++      .init = vrf_netns_init,
++      .id   = &vrf_net_id,
++      .size = sizeof(bool),
++};
++
+ static int __init vrf_init_module(void)
+ {
+       int rc;
+       register_netdevice_notifier(&vrf_notifier_block);
+-      rc = rtnl_link_register(&vrf_link_ops);
++      rc = register_pernet_subsys(&vrf_net_ops);
+       if (rc < 0)
+               goto error;
++      rc = rtnl_link_register(&vrf_link_ops);
++      if (rc < 0) {
++              unregister_pernet_subsys(&vrf_net_ops);
++              goto error;
++      }
++
+       return 0;
+ error:
diff --git a/queue-4.11/net-zero-ifla_vf_info-in-rtnl_fill_vfinfo.patch b/queue-4.11/net-zero-ifla_vf_info-in-rtnl_fill_vfinfo.patch
new file mode 100644 (file)
index 0000000..9fd8d67
--- /dev/null
@@ -0,0 +1,42 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: "Mintz, Yuval" <Yuval.Mintz@cavium.com>
+Date: Wed, 7 Jun 2017 21:00:33 +0300
+Subject: net: Zero ifla_vf_info in rtnl_fill_vfinfo()
+
+From: "Mintz, Yuval" <Yuval.Mintz@cavium.com>
+
+
+[ Upstream commit 0eed9cf58446b28b233388b7f224cbca268b6986 ]
+
+Some of the structure's fields are not initialized by the
+rtnetlink. If driver doesn't set those in ndo_get_vf_config(),
+they'd leak memory to user.
+
+Signed-off-by: Yuval Mintz <Yuval.Mintz@cavium.com>
+CC: Michal Schmidt <mschmidt@redhat.com>
+Reviewed-by: Greg Rose <gvrose8192@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/rtnetlink.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -1127,6 +1127,8 @@ static noinline_for_stack int rtnl_fill_
+       struct ifla_vf_mac vf_mac;
+       struct ifla_vf_info ivi;
++      memset(&ivi, 0, sizeof(ivi));
++
+       /* Not all SR-IOV capable drivers support the
+        * spoofcheck and "RSS query enable" query.  Preset to
+        * -1 so the user space tool can detect that the driver
+@@ -1135,7 +1137,6 @@ static noinline_for_stack int rtnl_fill_
+       ivi.spoofchk = -1;
+       ivi.rss_query_en = -1;
+       ivi.trusted = -1;
+-      memset(ivi.mac, 0, sizeof(ivi.mac));
+       /* The default value for VF link state is "auto"
+        * IFLA_VF_LINK_STATE_AUTO which equals zero
+        */
diff --git a/queue-4.11/proc-snmp6-use-correct-type-in-memset.patch b/queue-4.11/proc-snmp6-use-correct-type-in-memset.patch
new file mode 100644 (file)
index 0000000..06dc418
--- /dev/null
@@ -0,0 +1,32 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Christian Perle <christian.perle@secunet.com>
+Date: Mon, 12 Jun 2017 10:06:57 +0200
+Subject: proc: snmp6: Use correct type in memset
+
+From: Christian Perle <christian.perle@secunet.com>
+
+
+[ Upstream commit 3500cd73dff48f28f4ba80c171c4c80034d40f76 ]
+
+Reading /proc/net/snmp6 yields bogus values on 32 bit kernels.
+Use "u64" instead of "unsigned long" in sizeof().
+
+Fixes: 4a4857b1c81e ("proc: Reduce cache miss in snmp6_seq_show")
+Signed-off-by: Christian Perle <christian.perle@secunet.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/proc.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ipv6/proc.c
++++ b/net/ipv6/proc.c
+@@ -219,7 +219,7 @@ static void snmp6_seq_show_item64(struct
+       u64 buff64[SNMP_MIB_MAX];
+       int i;
+-      memset(buff64, 0, sizeof(unsigned long) * SNMP_MIB_MAX);
++      memset(buff64, 0, sizeof(u64) * SNMP_MIB_MAX);
+       snmp_get_cpu_field64_batch(buff64, itemlist, mib, syncpoff);
+       for (i = 0; itemlist[i].name; i++)
diff --git a/queue-4.11/qmi_wwan-new-telewell-and-sierra-device-ids.patch b/queue-4.11/qmi_wwan-new-telewell-and-sierra-device-ids.patch
new file mode 100644 (file)
index 0000000..61d22bd
--- /dev/null
@@ -0,0 +1,43 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Bjørn Mork <bjorn@mork.no>
+Date: Tue, 13 Jun 2017 19:10:18 +0200
+Subject: qmi_wwan: new Telewell and Sierra device IDs
+
+From: Bjørn Mork <bjorn@mork.no>
+
+
+[ Upstream commit 60cfe1eaccb8af598ebe1bdc44e157ea30fcdd81 ]
+
+A new Sierra Wireless EM7305 device ID used in a Toshiba laptop,
+and two Longcheer device IDs entries used by Telewell TW-3G HSPA+
+branded modems.
+
+Reported-by: Petr Kloc <petr_kloc@yahoo.com>
+Reported-by: Teemu Likonen <tlikonen@iki.fi>
+Signed-off-by: Bjørn Mork <bjorn@mork.no>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/qmi_wwan.c |    4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -898,6 +898,8 @@ static const struct usb_device_id produc
+       {QMI_FIXED_INTF(0x1199, 0x9056, 8)},    /* Sierra Wireless Modem */
+       {QMI_FIXED_INTF(0x1199, 0x9057, 8)},
+       {QMI_FIXED_INTF(0x1199, 0x9061, 8)},    /* Sierra Wireless Modem */
++      {QMI_FIXED_INTF(0x1199, 0x9063, 8)},    /* Sierra Wireless EM7305 */
++      {QMI_FIXED_INTF(0x1199, 0x9063, 10)},   /* Sierra Wireless EM7305 */
+       {QMI_FIXED_INTF(0x1199, 0x9071, 8)},    /* Sierra Wireless MC74xx */
+       {QMI_FIXED_INTF(0x1199, 0x9071, 10)},   /* Sierra Wireless MC74xx */
+       {QMI_FIXED_INTF(0x1199, 0x9079, 8)},    /* Sierra Wireless EM74xx */
+@@ -912,6 +914,8 @@ static const struct usb_device_id produc
+       {QMI_FIXED_INTF(0x1bc7, 0x1100, 3)},    /* Telit ME910 */
+       {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)},    /* Telit LE920 */
+       {QMI_QUIRK_SET_DTR(0x1bc7, 0x1201, 2)}, /* Telit LE920, LE920A4 */
++      {QMI_FIXED_INTF(0x1c9e, 0x9801, 3)},    /* Telewell TW-3G HSPA+ */
++      {QMI_FIXED_INTF(0x1c9e, 0x9803, 4)},    /* Telewell TW-3G HSPA+ */
+       {QMI_FIXED_INTF(0x1c9e, 0x9b01, 3)},    /* XS Stick W100-2 from 4G Systems */
+       {QMI_FIXED_INTF(0x0b3c, 0xc000, 4)},    /* Olivetti Olicard 100 */
+       {QMI_FIXED_INTF(0x0b3c, 0xc001, 4)},    /* Olivetti Olicard 120 */
diff --git a/queue-4.11/rtnetlink-add-ifla_group-to-ifla_policy.patch b/queue-4.11/rtnetlink-add-ifla_group-to-ifla_policy.patch
new file mode 100644 (file)
index 0000000..0ba8d0f
--- /dev/null
@@ -0,0 +1,42 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Serhey Popovych <serhe.popovych@gmail.com>
+Date: Tue, 20 Jun 2017 14:35:23 +0300
+Subject: rtnetlink: add IFLA_GROUP to ifla_policy
+
+From: Serhey Popovych <serhe.popovych@gmail.com>
+
+
+[ Upstream commit db833d40ad3263b2ee3b59a1ba168bb3cfed8137 ]
+
+Network interface groups support added while ago, however
+there is no IFLA_GROUP attribute description in policy
+and netlink message size calculations until now.
+
+Add IFLA_GROUP attribute to the policy.
+
+Fixes: cbda10fa97d7 ("net_device: add support for network device groups")
+Signed-off-by: Serhey Popovych <serhe.popovych@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/core/rtnetlink.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -934,6 +934,7 @@ static noinline size_t if_nlmsg_size(con
+              + nla_total_size(1) /* IFLA_LINKMODE */
+              + nla_total_size(4) /* IFLA_CARRIER_CHANGES */
+              + nla_total_size(4) /* IFLA_LINK_NETNSID */
++             + nla_total_size(4) /* IFLA_GROUP */
+              + nla_total_size(ext_filter_mask
+                               & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */
+              + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */
+@@ -1462,6 +1463,7 @@ static const struct nla_policy ifla_poli
+       [IFLA_LINK_NETNSID]     = { .type = NLA_S32 },
+       [IFLA_PROTO_DOWN]       = { .type = NLA_U8 },
+       [IFLA_XDP]              = { .type = NLA_NESTED },
++      [IFLA_GROUP]            = { .type = NLA_U32 },
+ };
+ static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
diff --git a/queue-4.11/sctp-disable-bh-in-sctp_for_each_endpoint.patch b/queue-4.11/sctp-disable-bh-in-sctp_for_each_endpoint.patch
new file mode 100644 (file)
index 0000000..5ab8e98
--- /dev/null
@@ -0,0 +1,49 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Xin Long <lucien.xin@gmail.com>
+Date: Sat, 10 Jun 2017 14:48:14 +0800
+Subject: sctp: disable BH in sctp_for_each_endpoint
+
+From: Xin Long <lucien.xin@gmail.com>
+
+
+[ Upstream commit 581409dacc9176b0de1f6c4ca8d66e13aa8e1b29 ]
+
+Now sctp holds read_lock when foreach sctp_ep_hashtable without disabling
+BH. If CPU schedules to another thread A at this moment, the thread A may
+be trying to hold the write_lock with disabling BH.
+
+As BH is disabled and CPU cannot schedule back to the thread holding the
+read_lock, while the thread A keeps waiting for the read_lock. A dead
+lock would be triggered by this.
+
+This patch is to fix this dead lock by calling read_lock_bh instead to
+disable BH when holding the read_lock in sctp_for_each_endpoint.
+
+Fixes: 626d16f50f39 ("sctp: export some apis or variables for sctp_diag and reuse some for proc")
+Reported-by: Xiumei Mu <xmu@redhat.com>
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/socket.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -4586,13 +4586,13 @@ int sctp_for_each_endpoint(int (*cb)(str
+       for (head = sctp_ep_hashtable; hash < sctp_ep_hashsize;
+            hash++, head++) {
+-              read_lock(&head->lock);
++              read_lock_bh(&head->lock);
+               sctp_for_each_hentry(epb, &head->chain) {
+                       err = cb(sctp_ep(epb), p);
+                       if (err)
+                               break;
+               }
+-              read_unlock(&head->lock);
++              read_unlock_bh(&head->lock);
+       }
+       return err;
diff --git a/queue-4.11/sctp-return-next-obj-by-passing-pos-1-into-sctp_transport_get_idx.patch b/queue-4.11/sctp-return-next-obj-by-passing-pos-1-into-sctp_transport_get_idx.patch
new file mode 100644 (file)
index 0000000..7320197
--- /dev/null
@@ -0,0 +1,46 @@
+From foo@baz Thu Jun 29 18:58:00 CEST 2017
+From: Xin Long <lucien.xin@gmail.com>
+Date: Thu, 15 Jun 2017 17:49:08 +0800
+Subject: sctp: return next obj by passing pos + 1 into sctp_transport_get_idx
+
+From: Xin Long <lucien.xin@gmail.com>
+
+
+[ Upstream commit 988c7322116970696211e902b468aefec95b6ec4 ]
+
+In sctp_for_each_transport, pos is used to save how many objs it has
+dumped. Now it gets the last obj by sctp_transport_get_idx, then gets
+the next obj by sctp_transport_get_next.
+
+The issue is that in the meanwhile if some objs in transport hashtable
+are removed and the objs nums are less than pos, sctp_transport_get_idx
+would return NULL and hti.walker.tbl is NULL as well. At this moment
+it should stop hti, instead of continue getting the next obj. Or it
+would cause a NULL pointer dereference in sctp_transport_get_next.
+
+This patch is to pass pos + 1 into sctp_transport_get_idx to get the
+next obj directly, even if pos > objs nums, it would return NULL and
+stop hti.
+
+Fixes: 626d16f50f39 ("sctp: export some apis or variables for sctp_diag and reuse some for proc")
+Signed-off-by: Xin Long <lucien.xin@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/sctp/socket.c |    5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -4630,9 +4630,8 @@ int sctp_for_each_transport(int (*cb)(st
+       if (err)
+               return err;
+-      sctp_transport_get_idx(net, &hti, pos);
+-      obj = sctp_transport_get_next(net, &hti);
+-      for (; obj && !IS_ERR(obj); obj = sctp_transport_get_next(net, &hti)) {
++      obj = sctp_transport_get_idx(net, &hti, pos + 1);
++      for (; !IS_ERR_OR_NULL(obj); obj = sctp_transport_get_next(net, &hti)) {
+               struct sctp_transport *transport = obj;
+               if (!sctp_transport_hold(transport))
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..dde3dc4fd97fe289161b17db5fe95f82a165bd80 100644 (file)
@@ -0,0 +1,32 @@
+net-don-t-call-strlen-on-non-terminated-string-in-dev_set_alias.patch
+net-fix-inconsistent-teardown-and-release-of-private-netdev-state.patch
+net-s390-fix-up-for-fix-inconsistent-teardown-and-release-of-private-netdev-state.patch
+mac80211-free-netdev-on-dev_alloc_name-error.patch
+decnet-dn_rtmsg-improve-input-length-sanitization-in-dnrmg_receive_user_skb.patch
+net-zero-ifla_vf_info-in-rtnl_fill_vfinfo.patch
+net-ipv6-release-route-when-device-is-unregistering.patch
+net-vrf-make-add_fib_rules-per-network-namespace-flag.patch
+af_unix-add-sockaddr-length-checks-before-accessing-sa_family-in-bind-and-connect-handlers.patch
+fix-an-intermittent-pr_emerg-warning-about-lo-becoming-free.patch
+sctp-disable-bh-in-sctp_for_each_endpoint.patch
+net-caif-fix-a-sleep-in-atomic-bug-in-cfpkt_create_pfx.patch
+net-tipc-fix-a-sleep-in-atomic-bug-in-tipc_msg_reverse.patch
+net-mlx5-remove-several-module-events-out-of-ethtool-stats.patch
+net-mlx5e-added-bw-check-for-dim-decision-mechanism.patch
+net-mlx5e-fix-wrong-indications-in-dim-due-to-counter-wraparound.patch
+net-mlx5-enable-4k-uar-only-when-page-size-is-bigger-than-4k.patch
+proc-snmp6-use-correct-type-in-memset.patch
+igmp-acquire-pmc-lock-for-ip_mc_clear_src.patch
+igmp-add-a-missing-spin_lock_init.patch
+qmi_wwan-new-telewell-and-sierra-device-ids.patch
+net-don-t-global-icmp-rate-limit-packets-originating-from-loopback.patch
+ipv6-fix-calling-in6_ifa_hold-incorrectly-for-dad-work.patch
+sctp-return-next-obj-by-passing-pos-1-into-sctp_transport_get_idx.patch
+net-mlx5e-fix-min-inline-value-for-vf-rep-sqs.patch
+net-mlx5e-avoid-doing-a-cleanup-call-if-the-profile-doesn-t-have-it.patch
+net-mlx5-wait-for-fw-readiness-before-initializing-command-interface.patch
+net-mlx5e-fix-timestamping-capabilities-reporting.patch
+decnet-always-not-take-dst-__refcnt-when-inserting-dst-into-hash-table.patch
+net-8021q-fix-one-possible-panic-caused-by-bug_on-in-free_netdev.patch
+ipv6-do-not-leak-throw-route-references.patch
+rtnetlink-add-ifla_group-to-ifla_policy.patch