--- /dev/null
+From 3b4c22ea18b96e21a055a9e44652d873d7a567a7 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Mon, 31 Oct 2022 12:58:48 +0000
+Subject: [PATCH kronosnet] pmtud: Reset/restart pmtud when a node joins
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If a new node joins with a 'black hole' that sets the effective
+MTU to be less than the hardware MTU then it will fail to join.
+
+So this patch restarts the pMTU processes each time a new node
+joins so it has a chance to declare it's real MTU in time.
+
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ libknet/crypto.c | 2 +-
+ libknet/links.c | 4 ++++
+ libknet/threads_common.c | 28 ++++++++++++++++++++--------
+ libknet/threads_common.h | 2 +-
+ libknet/threads_pmtud.c | 2 +-
+ libknet/transport_udp.c | 2 +-
+ 6 files changed, 28 insertions(+), 12 deletions(-)
+
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 032a13e3..dc41aac8 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -144,7 +144,7 @@ static int crypto_use_config(
+ knet_h->sec_salt_size = 0;
+ }
+
+- force_pmtud_run(knet_h, KNET_SUB_CRYPTO, 1);
++ force_pmtud_run(knet_h, KNET_SUB_CRYPTO, 1, 0);
+
+ return 0;
+ }
+diff --git a/libknet/links.c b/libknet/links.c
+index 5ee86896..185f62e5 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -46,6 +46,10 @@ int _link_updown(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+
+ if (!connected) {
+ transport_link_is_down(knet_h, link);
++ } else {
++ /* Reset MTU in case new link can't use full line MTU */
++ log_info(knet_h, KNET_SUB_LINK, "Resetting MTU for link %u because host %u joined", link_id, host_id);
++ force_pmtud_run(knet_h, KNET_SUB_LINK, 1, 1);
+ }
+
+ if (lock_stats) {
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index bd847460..c7419861 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -37,13 +37,8 @@ int shutdown_in_progress(knet_handle_t knet_h)
+ return ret;
+ }
+
+-static int pmtud_reschedule(knet_handle_t knet_h)
++static int _pmtud_reschedule(knet_handle_t knet_h)
+ {
+- if (pthread_mutex_lock(&knet_h->pmtud_mutex) != 0) {
+- log_debug(knet_h, KNET_SUB_PMTUD, "Unable to get mutex lock");
+- return -1;
+- }
+-
+ if (knet_h->pmtud_running) {
+ knet_h->pmtud_abort = 1;
+
+@@ -51,9 +46,20 @@ static int pmtud_reschedule(knet_handle_t knet_h)
+ pthread_cond_signal(&knet_h->pmtud_cond);
+ }
+ }
++ return 0;
++}
+
++static int pmtud_reschedule(knet_handle_t knet_h)
++{
++ int res;
++
++ if (pthread_mutex_lock(&knet_h->pmtud_mutex) != 0) {
++ log_debug(knet_h, KNET_SUB_PMTUD, "Unable to get mutex lock");
++ return -1;
++ }
++ res = _pmtud_reschedule(knet_h);
+ pthread_mutex_unlock(&knet_h->pmtud_mutex);
+- return 0;
++ return res;
+ }
+
+ int get_global_wrlock(knet_handle_t knet_h)
+@@ -219,7 +225,7 @@ int wait_all_threads_status(knet_handle_t knet_h, uint8_t status)
+ return 0;
+ }
+
+-void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem, uint8_t reset_mtu)
++void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem, uint8_t reset_mtu, uint8_t force_restart)
+ {
+ if (reset_mtu) {
+ log_debug(knet_h, subsystem, "PMTUd has been reset to default");
+@@ -243,6 +249,12 @@ void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem, uint8_t reset_mtu)
+ log_debug(knet_h, subsystem, "Notifying PMTUd to rerun");
+ knet_h->pmtud_forcerun = 1;
+ }
++ } else {
++ if (force_restart) {
++ if (_pmtud_reschedule(knet_h) < 0) {
++ log_info(knet_h, KNET_SUB_PMTUD, "Unable to notify PMTUd to reschedule. A joining node may struggle to connect properly");
++ }
++ }
+ }
+ pthread_mutex_unlock(&knet_h->pmtud_mutex);
+ }
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index 057723a8..0d2e9b7e 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -51,6 +51,6 @@ int set_thread_flush_queue(knet_handle_t knet_h, uint8_t thread_id, uint8_t stat
+ int wait_all_threads_flush_queue(knet_handle_t knet_h);
+ int set_thread_status(knet_handle_t knet_h, uint8_t thread_id, uint8_t status);
+ int wait_all_threads_status(knet_handle_t knet_h, uint8_t status);
+-void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem, uint8_t reset_mtu);
++void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem, uint8_t reset_mtu, uint8_t force_restart);
+
+ #endif
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index ab1e435e..3bf99b86 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -761,7 +761,7 @@ int knet_handle_pmtud_set(knet_handle_t knet_h,
+
+ knet_h->manual_mtu = iface_mtu;
+
+- force_pmtud_run(knet_h, KNET_SUB_PMTUD, 0);
++ force_pmtud_run(knet_h, KNET_SUB_PMTUD, 0, 0);
+
+ pthread_rwlock_unlock(&knet_h->global_rwlock);
+
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index f0257997..2f158658 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -343,7 +343,7 @@ static int read_errs_from_sock(knet_handle_t knet_h, int sockfd)
+ pthread_mutex_unlock(&knet_h->kmtu_mutex);
+ }
+
+- force_pmtud_run(knet_h, KNET_SUB_TRANSP_UDP, 0);
++ force_pmtud_run(knet_h, KNET_SUB_TRANSP_UDP, 0, 0);
+ }
+ /*
+ * those errors are way too noisy
+--
+2.30.2
+