From a6b7ad4652f7a47fe21482ff97679ca3a2e6d7fb Mon Sep 17 00:00:00 2001 From: Paul Donald Date: Sat, 4 Apr 2026 19:12:54 +0200 Subject: [PATCH] luci-mod-network: check kernel for mptcp to display MPTCP options https://www.kernel.org/doc/html/v6.12/networking/mptcp-sysctl.html There may be user instances where mptcp was not compiled into the kernel or is an unloaded module, so gate the options behind the feature check. Closes #8522 Signed-off-by: Paul Donald --- .../luci-base/root/usr/share/rpcd/ucode/luci | 1 + .../resources/view/network/interfaces.js | 24 +++++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/modules/luci-base/root/usr/share/rpcd/ucode/luci b/modules/luci-base/root/usr/share/rpcd/ucode/luci index ca95ded897..b54011a84f 100644 --- a/modules/luci-base/root/usr/share/rpcd/ucode/luci +++ b/modules/luci-base/root/usr/share/rpcd/ucode/luci @@ -242,6 +242,7 @@ const methods = { ufpd: access('/usr/sbin/ufpd') == true, vrf: access('/sys/module/vrf/refcnt') == true, // vrf.ko is loaded netifd_vrf: false, + mptcp: access('/proc/sys/net/mptcp/enabled'), }; const wifi_features = [ diff --git a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js index 9fc453c38a..5fad6f343f 100644 --- a/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js +++ b/modules/luci-mod-network/htdocs/luci-static/resources/view/network/interfaces.js @@ -1216,14 +1216,16 @@ return view.extend({ o.datatype = 'uinteger'; o.placeholder = '0'; - o = nettools.replaceOption(s, 'advanced', form.RichListValue, 'multipath', _('Multi-Path TCP'), - _('Multi-Path TCP') + ' %s'.format('RFC8684').format('https://www.rfc-editor.org/rfc/rfc8684.html') + '
' + - _('For packets originating from this device, e.g. VPN.') ); - o.value('off', _('Off'), _('Disables this interface for MPTCP')); - o.value('on', _('On'), _('No special configuration')); - o.value('master', _('Master'), _('Sets default route for all traffic')); - o.value('backup', _('Backup'), _('Hot standby; use this interface; do not forward traffic until no other interface is available (faster)')); - o.value('handover', _('Handover'), _('Cold standby; Establish a connection only when no other interface is available (slower)')); + if (L.hasSystemFeature('mptcp')) { + o = nettools.replaceOption(s, 'advanced', form.RichListValue, 'multipath', _('Multi-Path TCP'), + _('Multi-Path TCP') + ' %s'.format('RFC8684').format('https://www.rfc-editor.org/rfc/rfc8684.html') + '
' + + _('For packets originating from this device, e.g. VPN.') ); + o.value('off', _('Off'), _('Disables this interface for MPTCP')); + o.value('on', _('On'), _('No special configuration')); + o.value('master', _('Master'), _('Sets default route for all traffic')); + o.value('backup', _('Backup'), _('Hot standby; use this interface; do not forward traffic until no other interface is available (faster)')); + o.value('handover', _('Handover'), _('Cold standby; Establish a connection only when no other interface is available (slower)')); + } o = nettools.replaceOption(s, 'advanced', form.Value, 'ip4table', _('Override IPv4 routing table')); o.datatype = 'or(uinteger, string)'; @@ -1774,8 +1776,10 @@ return view.extend({ _('This identifier is randomly generated the first time the device is booted.')); o.datatype = 'and(rangelength(6,260),hexstring)'; - o = s.option(form.Flag, 'multipath', _('Multi-Path TCP'), _('For packets originating from this device, e.g. VPN.')); - o.optional = true; + if (L.hasSystemFeature('mptcp')) { + o = s.option(form.Flag, 'multipath', _('Multi-Path TCP'), _('For packets originating from this device, e.g. VPN.')); + o.optional = true; + } const l3mdevhelp1 = _('%s services running on this device in the default VRF context (ie., not bound to any VRF device) shall work across all VRF domains.'); const l3mdevhelp2 = _('Off means VRF traffic will be handled exclusively by sockets bound to VRFs.');