]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.16-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Mar 2022 12:29:57 +0000 (13:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Mar 2022 12:29:57 +0000 (13:29 +0100)
added patches:
batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch
batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch
batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch
net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch
net-ipa-add-an-interconnect-dependency.patch
net-ipa-fix-a-build-dependency.patch
net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch
net-smc-fix-connection-leak.patch
net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch
net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch

queue-5.16/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch [new file with mode: 0644]
queue-5.16/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch [new file with mode: 0644]
queue-5.16/batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch [new file with mode: 0644]
queue-5.16/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch [new file with mode: 0644]
queue-5.16/net-ipa-add-an-interconnect-dependency.patch [new file with mode: 0644]
queue-5.16/net-ipa-fix-a-build-dependency.patch [new file with mode: 0644]
queue-5.16/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch [new file with mode: 0644]
queue-5.16/net-smc-fix-connection-leak.patch [new file with mode: 0644]
queue-5.16/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch [new file with mode: 0644]
queue-5.16/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch [new file with mode: 0644]
queue-5.16/series

diff --git a/queue-5.16/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch b/queue-5.16/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch
new file mode 100644 (file)
index 0000000..6015f5d
--- /dev/null
@@ -0,0 +1,95 @@
+From 6c1f41afc1dbe59d9d3c8bb0d80b749c119aa334 Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Sun, 27 Feb 2022 23:23:49 +0100
+Subject: batman-adv: Don't expect inter-netns unique iflink indices
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 6c1f41afc1dbe59d9d3c8bb0d80b749c119aa334 upstream.
+
+The ifindex doesn't have to be unique for multiple network namespaces on
+the same machine.
+
+  $ ip netns add test1
+  $ ip -net test1 link add dummy1 type dummy
+  $ ip netns add test2
+  $ ip -net test2 link add dummy2 type dummy
+
+  $ ip -net test1 link show dev dummy1
+  6: dummy1: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
+      link/ether 96:81:55:1e:dd:85 brd ff:ff:ff:ff:ff:ff
+  $ ip -net test2 link show dev dummy2
+  6: dummy2: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
+      link/ether 5a:3c:af:35:07:c3 brd ff:ff:ff:ff:ff:ff
+
+But the batman-adv code to walk through the various layers of virtual
+interfaces uses this assumption because dev_get_iflink handles it
+internally and doesn't return the actual netns of the iflink. And
+dev_get_iflink only documents the situation where ifindex == iflink for
+physical devices.
+
+But only checking for dev->netdev_ops->ndo_get_iflink is also not an option
+because ipoib_get_iflink implements it even when it sometimes returns an
+iflink != ifindex and sometimes iflink == ifindex. The caller must
+therefore make sure itself to check both netns and iflink + ifindex for
+equality. Only when they are equal, a "physical" interface was detected
+which should stop the traversal. On the other hand, vxcan_get_iflink can
+also return 0 in case there was currently no valid peer. In this case, it
+is still necessary to stop.
+
+Fixes: b7eddd0b3950 ("batman-adv: prevent using any virtual device created on batman-adv as hard-interface")
+Fixes: 5ed4a460a1d3 ("batman-adv: additional checks for virtual interfaces on top of WiFi")
+Reported-by: Sabrina Dubroca <sd@queasysnail.net>
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/hard-interface.c |   19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -157,13 +157,15 @@ static bool batadv_is_on_batman_iface(co
+               return true;
+       iflink = dev_get_iflink(net_dev);
+-
+-      /* no more parents..stop recursion */
+-      if (iflink == 0 || iflink == net_dev->ifindex)
++      if (iflink == 0)
+               return false;
+       parent_net = batadv_getlink_net(net_dev, net);
++      /* iflink to itself, most likely physical device */
++      if (net == parent_net && iflink == net_dev->ifindex)
++              return false;
++
+       /* recurse over the parent device */
+       parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
+       /* if we got a NULL parent_dev there is something broken.. */
+@@ -223,8 +225,7 @@ static struct net_device *batadv_get_rea
+               return NULL;
+       iflink = dev_get_iflink(netdev);
+-
+-      if (netdev->ifindex == iflink) {
++      if (iflink == 0) {
+               dev_hold(netdev);
+               return netdev;
+       }
+@@ -235,6 +236,14 @@ static struct net_device *batadv_get_rea
+       net = dev_net(hard_iface->soft_iface);
+       real_net = batadv_getlink_net(netdev, net);
++
++      /* iflink to itself, most likely physical device */
++      if (net == real_net && netdev->ifindex == iflink) {
++              real_netdev = netdev;
++              dev_hold(real_netdev);
++              goto out;
++      }
++
+       real_netdev = dev_get_by_index(real_net, iflink);
+ out:
diff --git a/queue-5.16/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch b/queue-5.16/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch
new file mode 100644 (file)
index 0000000..0b1ca8c
--- /dev/null
@@ -0,0 +1,53 @@
+From 690bb6fb64f5dc7437317153902573ecad67593d Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 28 Feb 2022 00:01:24 +0100
+Subject: batman-adv: Request iflink once in batadv-on-batadv check
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 690bb6fb64f5dc7437317153902573ecad67593d upstream.
+
+There is no need to call dev_get_iflink multiple times for the same
+net_device in batadv_is_on_batman_iface. And since some of the
+.ndo_get_iflink callbacks are dynamic (for example via RCUs like in
+vxcan_get_iflink), it could easily happen that the returned values are not
+stable. The pre-checks before __dev_get_by_index are then of course bogus.
+
+Fixes: b7eddd0b3950 ("batman-adv: prevent using any virtual device created on batman-adv as hard-interface")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/hard-interface.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -149,22 +149,23 @@ static bool batadv_is_on_batman_iface(co
+       struct net *net = dev_net(net_dev);
+       struct net_device *parent_dev;
+       struct net *parent_net;
++      int iflink;
+       bool ret;
+       /* check if this is a batman-adv mesh interface */
+       if (batadv_softif_is_valid(net_dev))
+               return true;
++      iflink = dev_get_iflink(net_dev);
++
+       /* no more parents..stop recursion */
+-      if (dev_get_iflink(net_dev) == 0 ||
+-          dev_get_iflink(net_dev) == net_dev->ifindex)
++      if (iflink == 0 || iflink == net_dev->ifindex)
+               return false;
+       parent_net = batadv_getlink_net(net_dev, net);
+       /* recurse over the parent device */
+-      parent_dev = __dev_get_by_index((struct net *)parent_net,
+-                                      dev_get_iflink(net_dev));
++      parent_dev = __dev_get_by_index((struct net *)parent_net, iflink);
+       /* if we got a NULL parent_dev there is something broken.. */
+       if (!parent_dev) {
+               pr_err("Cannot find parent device\n");
diff --git a/queue-5.16/batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch b/queue-5.16/batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch
new file mode 100644 (file)
index 0000000..cb700ba
--- /dev/null
@@ -0,0 +1,55 @@
+From 6116ba09423f7d140f0460be6a1644dceaad00da Mon Sep 17 00:00:00 2001
+From: Sven Eckelmann <sven@narfation.org>
+Date: Mon, 28 Feb 2022 00:01:24 +0100
+Subject: batman-adv: Request iflink once in batadv_get_real_netdevice
+
+From: Sven Eckelmann <sven@narfation.org>
+
+commit 6116ba09423f7d140f0460be6a1644dceaad00da upstream.
+
+There is no need to call dev_get_iflink multiple times for the same
+net_device in batadv_get_real_netdevice. And since some of the
+ndo_get_iflink callbacks are dynamic (for example via RCUs like in
+vxcan_get_iflink), it could easily happen that the returned values are not
+stable. The pre-checks before __dev_get_by_index are then of course bogus.
+
+Fixes: 5ed4a460a1d3 ("batman-adv: additional checks for virtual interfaces on top of WiFi")
+Signed-off-by: Sven Eckelmann <sven@narfation.org>
+Signed-off-by: Simon Wunderlich <sw@simonwunderlich.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/batman-adv/hard-interface.c |    9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+--- a/net/batman-adv/hard-interface.c
++++ b/net/batman-adv/hard-interface.c
+@@ -215,14 +215,16 @@ static struct net_device *batadv_get_rea
+       struct net_device *real_netdev = NULL;
+       struct net *real_net;
+       struct net *net;
+-      int ifindex;
++      int iflink;
+       ASSERT_RTNL();
+       if (!netdev)
+               return NULL;
+-      if (netdev->ifindex == dev_get_iflink(netdev)) {
++      iflink = dev_get_iflink(netdev);
++
++      if (netdev->ifindex == iflink) {
+               dev_hold(netdev);
+               return netdev;
+       }
+@@ -232,9 +234,8 @@ static struct net_device *batadv_get_rea
+               goto out;
+       net = dev_net(hard_iface->soft_iface);
+-      ifindex = dev_get_iflink(netdev);
+       real_net = batadv_getlink_net(netdev, net);
+-      real_netdev = dev_get_by_index(real_net, ifindex);
++      real_netdev = dev_get_by_index(real_net, iflink);
+ out:
+       batadv_hardif_put(hard_iface);
diff --git a/queue-5.16/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch b/queue-5.16/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch
new file mode 100644 (file)
index 0000000..36f36ca
--- /dev/null
@@ -0,0 +1,101 @@
+From 91b0383fef06f20b847fa9e4f0e3054ead0b1a1b Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Thu, 24 Feb 2022 18:01:54 +0200
+Subject: net: dcb: flush lingering app table entries for unregistered devices
+
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+
+commit 91b0383fef06f20b847fa9e4f0e3054ead0b1a1b upstream.
+
+If I'm not mistaken (and I don't think I am), the way in which the
+dcbnl_ops work is that drivers call dcb_ieee_setapp() and this populates
+the application table with dynamically allocated struct dcb_app_type
+entries that are kept in the module-global dcb_app_list.
+
+However, nobody keeps exact track of these entries, and although
+dcb_ieee_delapp() is supposed to remove them, nobody does so when the
+interface goes away (example: driver unbinds from device). So the
+dcb_app_list will contain lingering entries with an ifindex that no
+longer matches any device in dcb_app_lookup().
+
+Reclaim the lost memory by listening for the NETDEV_UNREGISTER event and
+flushing the app table entries of interfaces that are now gone.
+
+In fact something like this used to be done as part of the initial
+commit (blamed below), but it was done in dcbnl_exit() -> dcb_flushapp(),
+essentially at module_exit time. That became dead code after commit
+7a6b6f515f77 ("DCB: fix kconfig option") which essentially merged
+"tristate config DCB" and "bool config DCBNL" into a single "bool config
+DCB", so net/dcb/dcbnl.c could not be built as a module anymore.
+
+Commit 36b9ad8084bd ("net/dcb: make dcbnl.c explicitly non-modular")
+recognized this and deleted dcbnl_exit() and dcb_flushapp() altogether,
+leaving us with the version we have today.
+
+Since flushing application table entries can and should be done as soon
+as the netdevice disappears, fundamentally the commit that is to blame
+is the one that introduced the design of this API.
+
+Fixes: 9ab933ab2cc8 ("dcbnl: add appliction tlv handlers")
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/dcb/dcbnl.c |   44 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+--- a/net/dcb/dcbnl.c
++++ b/net/dcb/dcbnl.c
+@@ -2073,8 +2073,52 @@ u8 dcb_ieee_getapp_default_prio_mask(con
+ }
+ EXPORT_SYMBOL(dcb_ieee_getapp_default_prio_mask);
++static void dcbnl_flush_dev(struct net_device *dev)
++{
++      struct dcb_app_type *itr, *tmp;
++
++      spin_lock(&dcb_lock);
++
++      list_for_each_entry_safe(itr, tmp, &dcb_app_list, list) {
++              if (itr->ifindex == dev->ifindex) {
++                      list_del(&itr->list);
++                      kfree(itr);
++              }
++      }
++
++      spin_unlock(&dcb_lock);
++}
++
++static int dcbnl_netdevice_event(struct notifier_block *nb,
++                               unsigned long event, void *ptr)
++{
++      struct net_device *dev = netdev_notifier_info_to_dev(ptr);
++
++      switch (event) {
++      case NETDEV_UNREGISTER:
++              if (!dev->dcbnl_ops)
++                      return NOTIFY_DONE;
++
++              dcbnl_flush_dev(dev);
++
++              return NOTIFY_OK;
++      default:
++              return NOTIFY_DONE;
++      }
++}
++
++static struct notifier_block dcbnl_nb __read_mostly = {
++      .notifier_call  = dcbnl_netdevice_event,
++};
++
+ static int __init dcbnl_init(void)
+ {
++      int err;
++
++      err = register_netdevice_notifier(&dcbnl_nb);
++      if (err)
++              return err;
++
+       rtnl_register(PF_UNSPEC, RTM_GETDCB, dcb_doit, NULL, 0);
+       rtnl_register(PF_UNSPEC, RTM_SETDCB, dcb_doit, NULL, 0);
diff --git a/queue-5.16/net-ipa-add-an-interconnect-dependency.patch b/queue-5.16/net-ipa-add-an-interconnect-dependency.patch
new file mode 100644 (file)
index 0000000..750ea9f
--- /dev/null
@@ -0,0 +1,36 @@
+From 1dba41c9d2e2dc94b543394974f63d55aa195bfe Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@linaro.org>
+Date: Tue, 1 Mar 2022 05:34:40 -0600
+Subject: net: ipa: add an interconnect dependency
+
+From: Alex Elder <elder@linaro.org>
+
+commit 1dba41c9d2e2dc94b543394974f63d55aa195bfe upstream.
+
+In order to function, the IPA driver very clearly requires the
+interconnect framework to be enabled in the kernel configuration.
+State that dependency in the Kconfig file.
+
+This became a problem when CONFIG_COMPILE_TEST support was added.
+Non-Qualcomm platforms won't necessarily enable CONFIG_INTERCONNECT.
+
+Reported-by: kernel test robot <lkp@intel.com>
+Fixes: 38a4066f593c5 ("net: ipa: support COMPILE_TEST")
+Signed-off-by: Alex Elder <elder@linaro.org>
+Link: https://lore.kernel.org/r/20220301113440.257916-1-elder@linaro.org
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ipa/Kconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ipa/Kconfig
++++ b/drivers/net/ipa/Kconfig
+@@ -2,6 +2,7 @@ config QCOM_IPA
+       tristate "Qualcomm IPA support"
+       depends on NET && QCOM_SMEM
+       depends on ARCH_QCOM || COMPILE_TEST
++      depends on INTERCONNECT
+       depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST)
+       depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n
+       select QCOM_MDT_LOADER if ARCH_QCOM
diff --git a/queue-5.16/net-ipa-fix-a-build-dependency.patch b/queue-5.16/net-ipa-fix-a-build-dependency.patch
new file mode 100644 (file)
index 0000000..a2aca07
--- /dev/null
@@ -0,0 +1,42 @@
+From caef14b7530c065fb85d54492768fa48fdb5093e Mon Sep 17 00:00:00 2001
+From: Alex Elder <elder@linaro.org>
+Date: Fri, 25 Feb 2022 14:15:30 -0600
+Subject: net: ipa: fix a build dependency
+
+From: Alex Elder <elder@linaro.org>
+
+commit caef14b7530c065fb85d54492768fa48fdb5093e upstream.
+
+An IPA build problem arose in the linux-next tree the other day.
+The problem is that a recent commit adds a new dependency on some
+code, and the Kconfig file for IPA doesn't reflect that dependency.
+As a result, some configurations can fail to build (particularly
+when COMPILE_TEST is enabled).
+
+The recent patch adds calls to qmp_get(), qmp_put(), and qmp_send(),
+and those are built based on the QCOM_AOSS_QMP config option.  If
+that symbol is not defined, stubs are defined, so we just need to
+ensure QCOM_AOSS_QMP is compatible with QCOM_IPA, or it's not
+defined.
+
+Reported-by: Randy Dunlap <rdunlap@infradead.org>
+Fixes: 34a081761e4e3 ("net: ipa: request IPA register values be retained")
+Signed-off-by: Alex Elder <elder@linaro.org>
+Tested-by: Randy Dunlap <rdunlap@infradead.org>
+Acked-by: Randy Dunlap <rdunlap@infradead.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/ipa/Kconfig |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/ipa/Kconfig
++++ b/drivers/net/ipa/Kconfig
+@@ -3,6 +3,7 @@ config QCOM_IPA
+       depends on NET && QCOM_SMEM
+       depends on ARCH_QCOM || COMPILE_TEST
+       depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST)
++      depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n
+       select QCOM_MDT_LOADER if ARCH_QCOM
+       select QCOM_SCM
+       select QCOM_QMI_HELPERS
diff --git a/queue-5.16/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch b/queue-5.16/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch
new file mode 100644 (file)
index 0000000..ed43c3b
--- /dev/null
@@ -0,0 +1,93 @@
+From 9995b408f17ff8c7f11bc725c8aa225ba3a63b1c Mon Sep 17 00:00:00 2001
+From: "j.nixdorf@avm.de" <j.nixdorf@avm.de>
+Date: Thu, 24 Feb 2022 10:06:49 +0100
+Subject: net: ipv6: ensure we call ipv6_mc_down() at most once
+
+From: j.nixdorf@avm.de <j.nixdorf@avm.de>
+
+commit 9995b408f17ff8c7f11bc725c8aa225ba3a63b1c upstream.
+
+There are two reasons for addrconf_notify() to be called with NETDEV_DOWN:
+either the network device is actually going down, or IPv6 was disabled
+on the interface.
+
+If either of them stays down while the other is toggled, we repeatedly
+call the code for NETDEV_DOWN, including ipv6_mc_down(), while never
+calling the corresponding ipv6_mc_up() in between. This will cause a
+new entry in idev->mc_tomb to be allocated for each multicast group
+the interface is subscribed to, which in turn leaks one struct ifmcaddr6
+per nontrivial multicast group the interface is subscribed to.
+
+The following reproducer will leak at least $n objects:
+
+ip addr add ff2e::4242/32 dev eth0 autojoin
+sysctl -w net.ipv6.conf.eth0.disable_ipv6=1
+for i in $(seq 1 $n); do
+       ip link set up eth0; ip link set down eth0
+done
+
+Joining groups with IPV6_ADD_MEMBERSHIP (unprivileged) or setting the
+sysctl net.ipv6.conf.eth0.forwarding to 1 (=> subscribing to ff02::2)
+can also be used to create a nontrivial idev->mc_list, which will the
+leak objects with the right up-down-sequence.
+
+Based on both sources for NETDEV_DOWN events the interface IPv6 state
+should be considered:
+
+ - not ready if the network interface is not ready OR IPv6 is disabled
+   for it
+ - ready if the network interface is ready AND IPv6 is enabled for it
+
+The functions ipv6_mc_up() and ipv6_down() should only be run when this
+state changes.
+
+Implement this by remembering when the IPv6 state is ready, and only
+run ipv6_mc_down() if it actually changed from ready to not ready.
+
+The other direction (not ready -> ready) already works correctly, as:
+
+ - the interface notification triggered codepath for NETDEV_UP /
+   NETDEV_CHANGE returns early if ipv6 is disabled, and
+ - the disable_ipv6=0 triggered codepath skips fully initializing the
+   interface as long as addrconf_link_ready(dev) returns false
+ - calling ipv6_mc_up() repeatedly does not leak anything
+
+Fixes: 3ce62a84d53c ("ipv6: exit early in addrconf_notify() if IPv6 is disabled")
+Signed-off-by: Johannes Nixdorf <j.nixdorf@avm.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv6/addrconf.c |    8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -3732,6 +3732,7 @@ static int addrconf_ifdown(struct net_de
+       struct inet6_dev *idev;
+       struct inet6_ifaddr *ifa, *tmp;
+       bool keep_addr = false;
++      bool was_ready;
+       int state, i;
+       ASSERT_RTNL();
+@@ -3797,7 +3798,10 @@ restart:
+       addrconf_del_rs_timer(idev);
+-      /* Step 2: clear flags for stateless addrconf */
++      /* Step 2: clear flags for stateless addrconf, repeated down
++       *         detection
++       */
++      was_ready = idev->if_flags & IF_READY;
+       if (!unregister)
+               idev->if_flags &= ~(IF_RS_SENT|IF_RA_RCVD|IF_READY);
+@@ -3871,7 +3875,7 @@ restart:
+       if (unregister) {
+               ipv6_ac_destroy_dev(idev);
+               ipv6_mc_destroy_dev(idev);
+-      } else {
++      } else if (was_ready) {
+               ipv6_mc_down(idev);
+       }
diff --git a/queue-5.16/net-smc-fix-connection-leak.patch b/queue-5.16/net-smc-fix-connection-leak.patch
new file mode 100644 (file)
index 0000000..2295724
--- /dev/null
@@ -0,0 +1,85 @@
+From 9f1c50cf39167ff71dc5953a3234f3f6eeb8fcb5 Mon Sep 17 00:00:00 2001
+From: "D. Wythe" <alibuda@linux.alibaba.com>
+Date: Thu, 24 Feb 2022 23:26:19 +0800
+Subject: net/smc: fix connection leak
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+commit 9f1c50cf39167ff71dc5953a3234f3f6eeb8fcb5 upstream.
+
+There's a potential leak issue under following execution sequence :
+
+smc_release                            smc_connect_work
+if (sk->sk_state == SMC_INIT)
+                                       send_clc_confirim
+       tcp_abort();
+                                       ...
+                                       sk.sk_state = SMC_ACTIVE
+smc_close_active
+switch(sk->sk_state) {
+...
+case SMC_ACTIVE:
+       smc_close_final()
+       // then wait peer closed
+
+Unfortunately, tcp_abort() may discard CLC CONFIRM messages that are
+still in the tcp send buffer, in which case our connection token cannot
+be delivered to the server side, which means that we cannot get a
+passive close message at all. Therefore, it is impossible for the to be
+disconnected at all.
+
+This patch tries a very simple way to avoid this issue, once the state
+has changed to SMC_ACTIVE after tcp_abort(), we can actively abort the
+smc connection, considering that the state is SMC_INIT before
+tcp_abort(), abandoning the complete disconnection process should not
+cause too much problem.
+
+In fact, this problem may exist as long as the CLC CONFIRM message is
+not received by the server. Whether a timer should be added after
+smc_close_final() needs to be discussed in the future. But even so, this
+patch provides a faster release for connection in above case, it should
+also be valuable.
+
+Fixes: 39f41f367b08 ("net/smc: common release code for non-accepted sockets")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Acked-by: Karsten Graul <kgraul@linux.ibm.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/smc/af_smc.c |   10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+--- a/net/smc/af_smc.c
++++ b/net/smc/af_smc.c
+@@ -183,7 +183,7 @@ static int smc_release(struct socket *so
+ {
+       struct sock *sk = sock->sk;
+       struct smc_sock *smc;
+-      int rc = 0;
++      int old_state, rc = 0;
+       if (!sk)
+               goto out;
+@@ -191,8 +191,10 @@ static int smc_release(struct socket *so
+       sock_hold(sk); /* sock_put below */
+       smc = smc_sk(sk);
++      old_state = sk->sk_state;
++
+       /* cleanup for a dangling non-blocking connect */
+-      if (smc->connect_nonblock && sk->sk_state == SMC_INIT)
++      if (smc->connect_nonblock && old_state == SMC_INIT)
+               tcp_abort(smc->clcsock->sk, ECONNABORTED);
+       if (cancel_work_sync(&smc->connect_work))
+@@ -206,6 +208,10 @@ static int smc_release(struct socket *so
+       else
+               lock_sock(sk);
++      if (old_state == SMC_INIT && sk->sk_state == SMC_ACTIVE &&
++          !smc->use_fallback)
++              smc_close_active_abort(smc);
++
+       rc = __smc_release(smc);
+       /* detach socket */
diff --git a/queue-5.16/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch b/queue-5.16/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch
new file mode 100644 (file)
index 0000000..918cc23
--- /dev/null
@@ -0,0 +1,40 @@
+From 4940a1fdf31c39f0806ac831cde333134862030b Mon Sep 17 00:00:00 2001
+From: "D. Wythe" <alibuda@linux.alibaba.com>
+Date: Wed, 2 Mar 2022 21:25:12 +0800
+Subject: net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error cause by server
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+commit 4940a1fdf31c39f0806ac831cde333134862030b upstream.
+
+The problem of SMC_CLC_DECL_ERR_REGRMB on the server is very clear.
+Based on the fact that whether a new SMC connection can be accepted or
+not depends on not only the limit of conn nums, but also the available
+entries of rtoken. Since the rtoken release is trigger by peer, while
+the conn nums is decrease by local, tons of thing can happen in this
+time difference.
+
+This only thing that needs to be mentioned is that now all connection
+creations are completely protected by smc_server_lgr_pending lock, it's
+enough to check only the available entries in rtokens_used_mask.
+
+Fixes: cd6851f30386 ("smc: remote memory buffers (RMBs)")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/smc/smc_core.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -1783,7 +1783,8 @@ int smc_conn_create(struct smc_sock *smc
+                   (ini->smcd_version == SMC_V2 ||
+                    lgr->vlan_id == ini->vlan_id) &&
+                   (role == SMC_CLNT || ini->is_smcd ||
+-                   lgr->conns_num < SMC_RMBS_PER_LGR_MAX)) {
++                  (lgr->conns_num < SMC_RMBS_PER_LGR_MAX &&
++                    !bitmap_full(lgr->rtokens_used_mask, SMC_RMBS_PER_LGR_MAX)))) {
+                       /* link group found */
+                       ini->first_contact_local = 0;
+                       conn->lgr = lgr;
diff --git a/queue-5.16/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch b/queue-5.16/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch
new file mode 100644 (file)
index 0000000..adbe08b
--- /dev/null
@@ -0,0 +1,47 @@
+From 0537f0a2151375dcf90c1bbfda6a0aaf57164e89 Mon Sep 17 00:00:00 2001
+From: "D. Wythe" <alibuda@linux.alibaba.com>
+Date: Wed, 2 Mar 2022 21:25:11 +0800
+Subject: net/smc: fix unexpected SMC_CLC_DECL_ERR_REGRMB error generated by client
+
+From: D. Wythe <alibuda@linux.alibaba.com>
+
+commit 0537f0a2151375dcf90c1bbfda6a0aaf57164e89 upstream.
+
+The main reason for this unexpected SMC_CLC_DECL_ERR_REGRMB in client
+dues to following execution sequence:
+
+Server Conn A:           Server Conn B:                        Client Conn B:
+
+smc_lgr_unregister_conn
+                        smc_lgr_register_conn
+                        smc_clc_send_accept     ->
+                                                        smc_rtoken_add
+smcr_buf_unuse
+               ->              Client Conn A:
+                               smc_rtoken_delete
+
+smc_lgr_unregister_conn() makes current link available to assigned to new
+incoming connection, while smcr_buf_unuse() has not executed yet, which
+means that smc_rtoken_add may fail because of insufficient rtoken_entry,
+reversing their execution order will avoid this problem.
+
+Fixes: 3e034725c0d8 ("net/smc: common functions for RMBs and send buffers")
+Signed-off-by: D. Wythe <alibuda@linux.alibaba.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/smc/smc_core.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/smc/smc_core.c
++++ b/net/smc/smc_core.c
+@@ -1132,8 +1132,8 @@ void smc_conn_free(struct smc_connection
+                       cancel_work_sync(&conn->abort_work);
+       }
+       if (!list_empty(&lgr->list)) {
+-              smc_lgr_unregister_conn(conn);
+               smc_buf_unuse(conn, lgr); /* allow buffer reuse */
++              smc_lgr_unregister_conn(conn);
+       }
+       if (!lgr->conns_num)
index e295a58129923cda9fe3a3cdd734c0a19f984c20..d5e2aa04dbe6d4b78dae068d25d17791b8f45fe8 100644 (file)
@@ -73,3 +73,13 @@ net-fix-up-skbs-delta_truesize-in-udp-gro-frag_list.patch
 netfilter-nf_queue-don-t-assume-sk-is-full-socket.patch
 netfilter-nf_queue-fix-possible-use-after-free.patch
 netfilter-nf_queue-handle-socket-prefetch.patch
+batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch
+batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch
+batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch
+net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch
+net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch
+net-ipa-fix-a-build-dependency.patch
+net-ipa-add-an-interconnect-dependency.patch
+net-smc-fix-connection-leak.patch
+net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch
+net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch