diff --git a/luci-app-adguardhome/.official_channel b/luci-app-adguardhome/.official_channel index 8ab67f2e7..49f33a8c6 100644 --- a/luci-app-adguardhome/.official_channel +++ b/luci-app-adguardhome/.official_channel @@ -1 +1 @@ -snapshot +both diff --git a/luci-app-adguardhome/.official_version_release b/luci-app-adguardhome/.official_version_release index b2e9500a7..b10ae1e0f 100644 --- a/luci-app-adguardhome/.official_version_release +++ b/luci-app-adguardhome/.official_version_release @@ -1 +1 @@ -26.278.51687~be446e3 +26.278.68466~6e4d979 diff --git a/luci-app-fwlive/Makefile b/luci-app-fwlive/Makefile index a06edd105..bb3df9d3a 100644 --- a/luci-app-fwlive/Makefile +++ b/luci-app-fwlive/Makefile @@ -11,8 +11,8 @@ LUCI_DESCRIPTION:=Live firewall log table (firewall4/nft; iptables-tagged lines LUCI_DEPENDS:=+luci-base +logd +jsonfilter LUCI_PKGARCH:=all -PKG_VERSION:=0.1.51 -PKG_RELEASE:=62 +PKG_VERSION:=0.1.52 +PKG_RELEASE:=63 # Reproducible build: honor SOURCE_DATE_EPOCH from the build environment (set by docker-sdk.sh / CI). ifdef SOURCE_DATE_EPOCH diff --git a/luci-app-fwlive/README.md b/luci-app-fwlive/README.md index 4205a1115..428b76a52 100644 --- a/luci-app-fwlive/README.md +++ b/luci-app-fwlive/README.md @@ -29,7 +29,7 @@ LuCI **Firewall Live View** — client-side JS view polling `ubus fwlive poll` ( | `root/usr/libexec/fwlive-adaptive-cap.sh` | Layer 1 adaptive poll cap (sourced by `rpcd/fwlive`) | | `root/usr/libexec/fwlive-logging.sh` | WAN zone logging helpers | | `root/lib/upgrade/keep.d/luci-app-fwlive` | Keep `/etc/fwlive/` across sysupgrade | -| `/etc/fwlive/wan-log-baseline` | Written on first **Enable logging** (and best-effort on already-on enable with no baseline file, recording the current mask with fwlive's filter-log bit cleared); `prerm` restores it on uninstall. A successful disable/reload, including an already-disabled retry, drops the marker when no later fwlive toggle has taken ownership; this preserves operator changes to other log-mask bits, including staged edits. A disable commit race (`firewall_commit_raced`) is still reported as a failure, but a successful reload also retires the marker because it only tracks fwlive's own toggle. If logging is already off but the marker remains, Disable retries `/etc/init.d/firewall reload`; pending UCI changes return `firewall_changes_pending` without reloading, and reload failure returns `firewall_reload_failed` while retaining the marker. Lock, read, or generation mismatch also keeps it for uninstall recovery. Restore is skipped (file kept; `fwlive` syslog only) when there is no WAN zone, the lock is unavailable, firewall changes are pending, the commit does not verify, reload fails, or the value after reload does not match the baseline. Disable of a pre-existing/foreign log bit is not snapshotted, so uninstall will not restore that bit. | +| `/etc/fwlive/wan-log-baseline` | Written on first **Enable logging** (and best-effort on already-on enable with no baseline file, recording the current mask with fwlive's filter-log bit cleared); `prerm` restores it on uninstall. A raced Enable commit retains the marker for uninstall recovery because the committed value may have changed. A successful disable/reload, including an already-disabled retry, drops the marker when no later fwlive toggle has taken ownership; this preserves operator changes to other log-mask bits, including staged edits. A disable commit race (`firewall_commit_raced`) is still reported as a failure, but a successful reload also retires the marker because it only tracks fwlive's own toggle. If logging is already off but the marker remains, Disable retries `/etc/init.d/firewall reload`; pending UCI changes return `firewall_changes_pending` without reloading, and reload failure returns `firewall_reload_failed` while retaining the marker. Lock, read, or generation mismatch also keeps it for uninstall recovery. Restore is skipped (file kept; `fwlive` syslog only) when there is no WAN zone, the lock is unavailable, firewall changes are pending, the commit does not verify, reload fails, or the value after reload does not match the baseline. Disable of a pre-existing/foreign log bit is not snapshotted, so uninstall will not restore that bit. | | `root/usr/libexec/fwlive-log-filter.sh` | Server-side firewall-only filter (`isFirewallEvent` parity) | | `root/usr/libexec/fwlive-is-firewall-event.sh` | Shared filter logic (sourced by filter + tests) | | `root/usr/libexec/fwlive-is-firewall-event.awk` | **Generated** standalone classifier from `CLASSIFY_SPEC`; loaded by `fwlive-is-firewall-event.sh` | diff --git a/luci-app-fwlive/htdocs/luci-static/resources/fwlive/constants.js b/luci-app-fwlive/htdocs/luci-static/resources/fwlive/constants.js index 20fa5392e..f4a3b0f73 100644 --- a/luci-app-fwlive/htdocs/luci-static/resources/fwlive/constants.js +++ b/luci-app-fwlive/htdocs/luci-static/resources/fwlive/constants.js @@ -9,7 +9,7 @@ */ return baseclass.extend({ /* Keep in sync with openwrt-feed/luci-app-fwlive/Makefile PKG_VERSION. */ - APP_VERSION: '0.1.51', + APP_VERSION: '0.1.52', ROW_LIMIT_OPTIONS: [25, 50, 100, 250, 500, 1000, 2000], DEFAULT_ROW_LIMIT: 100, FETCH_MODE_OPTIONS: ['auto', 'manual'], diff --git a/luci-app-open-box/Makefile b/luci-app-open-box/Makefile index 0c49cd499..f2d9f56b7 100644 --- a/luci-app-open-box/Makefile +++ b/luci-app-open-box/Makefile @@ -1,8 +1,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-open-box -PKG_VERSION:=0.1.290 -PKG_RELEASE:=13 +PKG_VERSION:=0.1.291 +PKG_RELEASE:=14 PKG_MAINTAINER:=liandu2024 PKG_LICENSE:=GPL-3.0-or-later diff --git a/luci-app-sqm-autorate/root/usr/share/rpcd/acl.d/luci-app-sqm.json b/luci-app-sqm-autorate/root/usr/share/rpcd/acl.d/luci-app-sqm.json index 810d91b83..1100c6338 100644 --- a/luci-app-sqm-autorate/root/usr/share/rpcd/acl.d/luci-app-sqm.json +++ b/luci-app-sqm-autorate/root/usr/share/rpcd/acl.d/luci-app-sqm.json @@ -4,19 +4,24 @@ "read": { "file": { "/var/run/sqm/available_qdiscs": [ "list" ], - "/usr/lib/sqm/*.qos.help": [ "read" ], + "/usr/lib/sqm/*.qos.help": [ "read" ] + }, + "uci": [ "sqm" ], + "ubus": { + "file": [ "read", "list" ] + } + }, + "write": { + "file": { "/etc/init.d/sqm enable" : [ "exec" ], "/etc/init.d/sqm start" : [ "exec" ], "/etc/init.d/sqm-autorate enable" : [ "exec" ], "/etc/init.d/sqm-autorate start" : [ "exec" ] }, - "uci": [ "sqm" ], "ubus": { - "file": [ "read", "list" ], + "file": [ "exec" ], "luci": [ "setInitAction" ] - } - }, - "write": { + }, "uci": [ "sqm" ] } } diff --git a/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js b/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js index 76add6a93..1ae831791 100644 --- a/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js +++ b/luci-mod-network/htdocs/luci-static/resources/view/network/wireless.js @@ -483,6 +483,8 @@ function formatConfigEncryption(enc) { if (enc == '' || enc == 'none') return _('None'); + if (enc == 'owe') + return 'OWE'; if (enc == 'psk2' || enc.indexOf('psk2+') == 0) return 'WPA2-PSK'; if (enc == 'psk' || enc.indexOf('psk+') == 0) @@ -509,12 +511,43 @@ function formatConfigEncryption(enc) { return enc; } +// Keep an incompatible saved value visible as invalid, never silently replace it. +function restrictQca6GHzChoices(option, getBand, allowed, message) { + let widget, section; + const update = function() { + if (!widget) + return; + widget.querySelectorAll('option').forEach(choice => { + const incompatible = getBand() == '6g' && !allowed.includes(choice.value); + choice.disabled = incompatible; + choice.hidden = incompatible && !choice.selected; + }); + }; + option.renderWidget = function(section_id, option_index, cfgvalue) { + section = section_id; + widget = form.ListValue.prototype.renderWidget.call(this, section_id, option_index, cfgvalue); + widget.addEventListener('change', update); + update(); + return widget; + }; + option.validate = function(section_id, value) { + return getBand() != '6g' || allowed.includes(value) || message; + }; + return function() { + update(); + if (widget) + option.triggerValidation(section); + }; +} + function getConfigEncryptionValue(section_id, hwtype) { const enc = String(uci.get('wireless', section_id, 'encryption') || ''); const sae = uci.get('wireless', section_id, 'sae'); if (enc == 'wep') return 'wep-open'; + if (isQcaWifiHwtype(hwtype) && uci.get('wireless', section_id, 'owe') == '1') + return 'owe'; if (isQcaWifiHwtype(hwtype) && sae == '1') { if (enc == 'psk2' || enc.indexOf('psk2+') == 0) @@ -548,12 +581,18 @@ function getConfigCipherValue(section_id, hwtype) { } function getDisplayEncryption(radioNet) { + const hwtype = uci.get('wireless', radioNet.getWifiDeviceName(), 'type'); + const configured = getConfigEncryptionValue(radioNet.getName(), hwtype); + // The QCA iwinfo backend reports OWE as WPA2-PSK. + if (isQcaWifiHwtype(hwtype) && configured == 'owe') + return formatConfigEncryption(configured); + const encryption = radioNet.getActiveEncryption(); if (encryption && encryption != '-') return encryption; - return formatConfigEncryption(getConfigEncryptionValue(radioNet.getName(), uci.get('wireless', radioNet.getWifiDeviceName(), 'type'))); + return formatConfigEncryption(configured); } function getDisplayBSSID(radioNet) { @@ -2240,6 +2279,11 @@ var CBIWifiFrequencyValue = form.Value.extend({ E('br', { 'style': 'clear:left' }) ]); + elem.addEventListener('change', () => { + if (this.onBandChange) + this.onBandChange(); + }); + return this.setInitialValues(section_id, elem, cfgvalue); }, @@ -2782,6 +2826,15 @@ return view.extend({ * Mode/Band/Channel/Width controls in the modal. */ o.ucisection = radioNet.getWifiDeviceName(); + const frequencyOption = o; + const getSecurityBand = function() { + const device = radioNet.getWifiDeviceName(); + const field = frequencyOption.map.findElement('data-field', frequencyOption.cbid(device)); + const band = field && field.querySelector('select.band'); + return band ? band.value : getConfiguredBand(hwtype, + uci.get('wireless', device, 'hwmode'), uci.get('wireless', device, 'channel'), + uci.get('wireless', device, 'band'), uci.get('wireless', device, 'htmode')); + }; if (hwtype == 'mac80211' || isQcaWifiHwtype(hwtype)) { o = ss.taboption('general', CBIWifiTxPowerValue, 'txpower', _('Maximum transmit power'), _('Specifies the maximum transmit power the wireless radio may use. Depending on regulatory requirements and wireless usage, the actual transmit power may be reduced by the driver.')); @@ -3227,6 +3280,15 @@ return view.extend({ c = 'ccmp'; if (isQcaWifiHwtype(hwtype)) { + if (e == 'owe') { + stored_e = 'ccmp'; + uci.set('wireless', section_id, 'owe', '1'); + uci.set('wireless', section_id, 'ieee80211w', '2'); + uci.unset('wireless', section_id, 'key'); + } + else { + uci.unset('wireless', section_id, 'owe'); + } if (e == 'sae-mixed') { stored_e = 'psk2'; uci.set('wireless', section_id, 'sae', '1'); @@ -3246,6 +3308,7 @@ return view.extend({ }; o = ss.taboption('encryption', form.ListValue, 'cipher', _('Cipher')); + const cipherOption = o; o.depends('encryption', 'wpa'); o.depends('encryption', 'wpa2'); o.depends('encryption', 'wpa3'); @@ -3448,6 +3511,17 @@ return view.extend({ encr.value(crypto_mode[0], '%s (%s)'.format(crypto_mode[1], security_level)); }); + if (isQcaWifiHwtype(hwtype)) { + const updateEncryption = restrictQca6GHzChoices(encr, getSecurityBand, + ['sae', 'owe'], _('6 GHz requires WPA3-SAE or OWE.')); + const updateCipher = restrictQca6GHzChoices(cipherOption, getSecurityBand, + ['auto', 'ccmp', 'ccmp256', 'gcmp', 'gcmp256'], _('TKIP is not supported on 6 GHz.')); + frequencyOption.onBandChange = function() { + updateEncryption(); + updateCipher(); + }; + } + // QR Code o = ss.taboption('encryption', form.DummyValue, '_qrops', _('QR Code'), _('SSID and passwords with URIencoded sequences (e.g. %20) may not work.')); diff --git a/shunt/Makefile b/shunt/Makefile index 38096448b..983d63929 100644 --- a/shunt/Makefile +++ b/shunt/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=shunt PKG_VERSION:=0.1.11 -PKG_RELEASE:=6 +PKG_RELEASE:=7 PKG_LICENSE:=GPL-3.0-or-later PKG_LICENSE_FILES:= PKG_MAINTAINER:=Dirk Brenken diff --git a/shunt/src/netifd.uc b/shunt/src/netifd.uc index f4d758d21..36c53ca02 100644 --- a/shunt/src/netifd.uc +++ b/shunt/src/netifd.uc @@ -9,9 +9,10 @@ function nexthop(entry, fam) { let dflt = (fam == 4) ? '0.0.0.0' : '::'; - for (let r in (entry?.route ?? [])) - if (r?.target == dflt && r?.mask == 0 && length(r?.nexthop ?? '')) + for (let r in (entry?.route ?? [])) { + if (r?.target == dflt && r?.mask == 0 && length(r?.nexthop ?? '') && r.nexthop != dflt) return r.nexthop; + } return null; }