From: Greg Kroah-Hartman Date: Sat, 5 Mar 2022 12:29:57 +0000 (+0100) Subject: 5.16-stable patches X-Git-Tag: v4.9.305~69 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5d7d629c2078390be3527538b8c6681dfb502d66;p=thirdparty%2Fkernel%2Fstable-queue.git 5.16-stable patches 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 --- 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 index 00000000000..6015f5d9a86 --- /dev/null +++ b/queue-5.16/batman-adv-don-t-expect-inter-netns-unique-iflink-indices.patch @@ -0,0 +1,95 @@ +From 6c1f41afc1dbe59d9d3c8bb0d80b749c119aa334 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Sun, 27 Feb 2022 23:23:49 +0100 +Subject: batman-adv: Don't expect inter-netns unique iflink indices + +From: Sven Eckelmann + +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: 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: 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 +Signed-off-by: Sven Eckelmann +Signed-off-by: Simon Wunderlich +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..0b1ca8c6abe --- /dev/null +++ b/queue-5.16/batman-adv-request-iflink-once-in-batadv-on-batadv-check.patch @@ -0,0 +1,53 @@ +From 690bb6fb64f5dc7437317153902573ecad67593d Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Mon, 28 Feb 2022 00:01:24 +0100 +Subject: batman-adv: Request iflink once in batadv-on-batadv check + +From: Sven Eckelmann + +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 +Signed-off-by: Simon Wunderlich +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..cb700ba21cc --- /dev/null +++ b/queue-5.16/batman-adv-request-iflink-once-in-batadv_get_real_netdevice.patch @@ -0,0 +1,55 @@ +From 6116ba09423f7d140f0460be6a1644dceaad00da Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Mon, 28 Feb 2022 00:01:24 +0100 +Subject: batman-adv: Request iflink once in batadv_get_real_netdevice + +From: Sven Eckelmann + +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 +Signed-off-by: Simon Wunderlich +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..36f36ca5117 --- /dev/null +++ b/queue-5.16/net-dcb-flush-lingering-app-table-entries-for-unregistered-devices.patch @@ -0,0 +1,101 @@ +From 91b0383fef06f20b847fa9e4f0e3054ead0b1a1b Mon Sep 17 00:00:00 2001 +From: Vladimir Oltean +Date: Thu, 24 Feb 2022 18:01:54 +0200 +Subject: net: dcb: flush lingering app table entries for unregistered devices + +From: Vladimir Oltean + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..750ea9f8fb1 --- /dev/null +++ b/queue-5.16/net-ipa-add-an-interconnect-dependency.patch @@ -0,0 +1,36 @@ +From 1dba41c9d2e2dc94b543394974f63d55aa195bfe Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Tue, 1 Mar 2022 05:34:40 -0600 +Subject: net: ipa: add an interconnect dependency + +From: Alex Elder + +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 +Fixes: 38a4066f593c5 ("net: ipa: support COMPILE_TEST") +Signed-off-by: Alex Elder +Link: https://lore.kernel.org/r/20220301113440.257916-1-elder@linaro.org +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..a2aca070cc2 --- /dev/null +++ b/queue-5.16/net-ipa-fix-a-build-dependency.patch @@ -0,0 +1,42 @@ +From caef14b7530c065fb85d54492768fa48fdb5093e Mon Sep 17 00:00:00 2001 +From: Alex Elder +Date: Fri, 25 Feb 2022 14:15:30 -0600 +Subject: net: ipa: fix a build dependency + +From: Alex Elder + +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 +Fixes: 34a081761e4e3 ("net: ipa: request IPA register values be retained") +Signed-off-by: Alex Elder +Tested-by: Randy Dunlap +Acked-by: Randy Dunlap +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..ed43c3b459a --- /dev/null +++ b/queue-5.16/net-ipv6-ensure-we-call-ipv6_mc_down-at-most-once.patch @@ -0,0 +1,93 @@ +From 9995b408f17ff8c7f11bc725c8aa225ba3a63b1c Mon Sep 17 00:00:00 2001 +From: "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 + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..2295724c3b1 --- /dev/null +++ b/queue-5.16/net-smc-fix-connection-leak.patch @@ -0,0 +1,85 @@ +From 9f1c50cf39167ff71dc5953a3234f3f6eeb8fcb5 Mon Sep 17 00:00:00 2001 +From: "D. Wythe" +Date: Thu, 24 Feb 2022 23:26:19 +0800 +Subject: net/smc: fix connection leak + +From: D. Wythe + +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 +Acked-by: Karsten Graul +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..918cc230686 --- /dev/null +++ b/queue-5.16/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-cause-by-server.patch @@ -0,0 +1,40 @@ +From 4940a1fdf31c39f0806ac831cde333134862030b Mon Sep 17 00:00:00 2001 +From: "D. Wythe" +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 + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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 index 00000000000..adbe08b5d94 --- /dev/null +++ b/queue-5.16/net-smc-fix-unexpected-smc_clc_decl_err_regrmb-error-generated-by-client.patch @@ -0,0 +1,47 @@ +From 0537f0a2151375dcf90c1bbfda6a0aaf57164e89 Mon Sep 17 00:00:00 2001 +From: "D. Wythe" +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 + +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 +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + 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) diff --git a/queue-5.16/series b/queue-5.16/series index e295a581299..d5e2aa04dbe 100644 --- a/queue-5.16/series +++ b/queue-5.16/series @@ -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