From 3692297595ab60b38ff61df2a0bfa381b68edc41 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 31 Jul 2026 20:41:05 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=A5=20Sync=202026-07-31=2020:41:05?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dae/Makefile | 6 +- daed/Makefile | 6 +- luci-app-daede/Makefile | 2 +- .../luci-static/resources/view/daede/dae.js | 1 + .../resources/view/daede/styles.js | 6 +- luci-app-easytier/Makefile | 2 +- luci-app-easytier/root/etc/init.d/easytier | 25 +-- .../root/usr/share/easytier/firewall.sh | 4 +- luci-app-passwall/Makefile | 2 +- .../cbi/passwall/client/node_subscribe.lua | 3 + .../passwall/client/node_subscribe_config.lua | 2 - .../usr/share/passwall/clash_subconverter.lua | 15 +- .../share/passwall/helper_chinadns_add.lua | 11 +- luci-app-qemu-vms/Makefile | 2 +- .../resources/view/qemu-vms/passthrough.js | 52 +++++- .../root/usr/libexec/rpcd/luci.qemu-vms | 15 ++ .../share/rpcd/acl.d/luci-app-qemu-vms.json | 2 + qemu-vms/Makefile | 2 +- qemu-vms/root/etc/init.d/qemu-vms | 175 +++++++++++++----- teleproxy/Makefile | 6 +- 20 files changed, 253 insertions(+), 86 deletions(-) diff --git a/dae/Makefile b/dae/Makefile index 56f665cc7..98179fa33 100644 --- a/dae/Makefile +++ b/dae/Makefile @@ -5,10 +5,10 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dae -PKG_VERSION:=2026.07.30 -PKG_RELEASE:=25 +PKG_VERSION:=2026.07.31 +PKG_RELEASE:=26 -PKG_SOURCE:=dae-src-2026.07.30-305922fc343d.tar.gz +PKG_SOURCE:=dae-src-2026.07.31-31ea28be65b6.tar.gz PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/dae-src PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_HASH:=skip diff --git a/daed/Makefile b/daed/Makefile index 80abeb8a3..2d95c4d2c 100644 --- a/daed/Makefile +++ b/daed/Makefile @@ -5,10 +5,10 @@ include $(TOPDIR)/rules.mk PKG_NAME:=daed -PKG_VERSION:=2026.07.30 -PKG_RELEASE:=33 +PKG_VERSION:=2026.07.31 +PKG_RELEASE:=34 -PKG_SOURCE:=daed-src-2026.07.30-6066c5d691b3.tar.gz +PKG_SOURCE:=daed-src-2026.07.31-fe4d294559c7.tar.gz PKG_SOURCE_URL:=https://github.com/kenzok8/openwrt-daede/releases/download/daed-src PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) PKG_HASH:=skip diff --git a/luci-app-daede/Makefile b/luci-app-daede/Makefile index ac0791b61..bba0bb62c 100644 --- a/luci-app-daede/Makefile +++ b/luci-app-daede/Makefile @@ -6,7 +6,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-daede PKG_VERSION:=1.14.7 -PKG_RELEASE:=36 +PKG_RELEASE:=37 PKG_MAINTAINER:=kenzok8 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME) diff --git a/luci-app-daede/htdocs/luci-static/resources/view/daede/dae.js b/luci-app-daede/htdocs/luci-static/resources/view/daede/dae.js index 2eb1e78c1..03e851401 100644 --- a/luci-app-daede/htdocs/luci-static/resources/view/daede/dae.js +++ b/luci-app-daede/htdocs/luci-static/resources/view/daede/dae.js @@ -574,6 +574,7 @@ function renderDaeEditor() { const textarea = E('textarea', { 'class': 'dd-editor dd-editor-hl', 'spellcheck': 'false', + 'wrap': 'off', 'placeholder': _('dae config file is empty. Click "Load default config" to start, or paste your config here.') }, ''); const hlCode = E('code', {}); diff --git a/luci-app-daede/htdocs/luci-static/resources/view/daede/styles.js b/luci-app-daede/htdocs/luci-static/resources/view/daede/styles.js index 7dd3eac83..954bde6cc 100644 --- a/luci-app-daede/htdocs/luci-static/resources/view/daede/styles.js +++ b/luci-app-daede/htdocs/luci-static/resources/view/daede/styles.js @@ -104,7 +104,7 @@ const CSS = [ both share identical box metrics so glyphs line up; the textarea stays the real editor (caret, selection, insert-at-cursor, jump-to-line all native) */ '.dd-edit-wrap{position:relative}', - '.dd-edit-wrap .dd-editor,.dd-edit-wrap .dd-hl{margin:0;padding:10px 12px;border-width:1px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono",monospace;font-size:12px;line-height:1.5;letter-spacing:0;tab-size:4;white-space:pre-wrap;word-break:break-word;box-sizing:border-box}', + '.dd-edit-wrap .dd-editor,.dd-edit-wrap .dd-hl{margin:0;padding:10px 12px;border-width:1px;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono",monospace;font-size:12px;line-height:1.5;letter-spacing:0;tab-size:4;white-space:pre;word-break:normal;overflow-x:auto;box-sizing:border-box}', '.dd-edit-wrap .dd-hl{position:absolute;inset:0;margin:0;overflow:hidden;border:1px solid transparent;border-radius:6px 6px 0 0;pointer-events:none;background:#f6f8fa;color:#3b4252;z-index:1}', /* reset Argon's code{background:var(--lighter)} so the overlay inherits the pre background uniformly — otherwise a dark pre shows as side bars. @@ -117,9 +117,9 @@ const CSS = [ it ghosts over the highlight pre underneath */ '.dd-edit-wrap .dd-editor-hl::selection{background:rgba(56,134,161,.25);color:transparent}', '@media screen and (max-device-width:600px){.dd-edit-wrap .dd-editor,.dd-edit-wrap .dd-hl,.dd-edit-wrap .dd-hl code{font-size:16px}}', - '.dh-c{color:#8a919a;font-style:italic}', + '.dh-c{color:#8a919a}', '.dh-s{color:#2a8a4a}', - '.dh-k{color:#9a3fb5;font-weight:600}', + '.dh-k{color:#9a3fb5}', '.dh-f{color:#2f7288}', '.dh-o{color:#c2772a}', '.dh-g{color:#b0226a}', diff --git a/luci-app-easytier/Makefile b/luci-app-easytier/Makefile index 11f43369c..24732eefc 100644 --- a/luci-app-easytier/Makefile +++ b/luci-app-easytier/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk -include $(dir $(lastword $(MAKEFILE_LIST)))../version.mk PKG_VERSION:=$(or $(EASYTIER_VERSION),2.6.4) -PKG_RELEASE:=12 +PKG_RELEASE:=13 LUCI_TITLE:=LuCI support for EasyTier LUCI_DEPENDS:=+kmod-tun +easytier +luci-compat diff --git a/luci-app-easytier/root/etc/init.d/easytier b/luci-app-easytier/root/etc/init.d/easytier index d0c016ede..86cf72d46 100755 --- a/luci-app-easytier/root/etc/init.d/easytier +++ b/luci-app-easytier/root/etc/init.d/easytier @@ -626,17 +626,20 @@ EOF procd_set_param respawn procd_close_instance - if [ ! -z "$socks_port" ] ; then - echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 添加防火墙规则 easytier_socks5 放行端口 ${socks_port} " >>/tmp/easytier.log - uci -q delete firewall.easytier_socks5 - uci set firewall.easytier_socks5=rule - uci set firewall.easytier_socks5.name="easytier_socks5" - uci set firewall.easytier_socks5.target="ACCEPT" - uci set firewall.easytier_socks5.src="wan" - uci set firewall.easytier_socks5.proto="tcp" - uci set firewall.easytier_socks5.dest_port="$socks_port" - uci set firewall.easytier_socks5.enabled="1" - fi + # 不再自动放行 SOCKS5 端口到 WAN —— 无认证 SOCKS5 代理暴露给公网有严重安全风险 + # 如需公网访问,请手动在 LuCI 防火墙页面添加规则 + # 如需恢复自动放行,去掉下面各行行首的 # 即可 + # if [ ! -z "$socks_port" ] ; then + # echo "$(date '+%Y-%m-%d %H:%M:%S') easytier : 添加防火墙规则 easytier_socks5 放行端口 ${socks_port} " >>/tmp/easytier.log + # uci -q delete firewall.easytier_socks5 + # uci set firewall.easytier_socks5=rule + # uci set firewall.easytier_socks5.name="easytier_socks5" + # uci set firewall.easytier_socks5.target="ACCEPT" + # uci set firewall.easytier_socks5.src="wan" + # uci set firewall.easytier_socks5.proto="tcp" + # uci set firewall.easytier_socks5.dest_port="$socks_port" + # uci set firewall.easytier_socks5.enabled="1" + # fi if [ "$listenermode" = "ON" ] || [ "$etcmd" = "web" ] ; then if [ -z "$tcp_port" ] && [ -z "$ws_port" ] && [ -z "$wss_port" ] && [ -z "$wg_port" ] ; then tcp_port="11010" diff --git a/luci-app-easytier/root/usr/share/easytier/firewall.sh b/luci-app-easytier/root/usr/share/easytier/firewall.sh index 3de8bc36d..7758fbdc8 100755 --- a/luci-app-easytier/root/usr/share/easytier/firewall.sh +++ b/luci-app-easytier/root/usr/share/easytier/firewall.sh @@ -36,7 +36,9 @@ set_firewall_rules() { [ -n "$wss_port" ] && add_firewall_rule "easytier_wss" "tcp" "$wss_port" "EasyTier WSS" [ -n "$wg_port" ] && add_firewall_rule "easytier_wg" "udp" "$wg_port" "EasyTier WG" [ -n "$quic_port" ] && add_firewall_rule "easytier_quic" "tcp udp" "$quic_port" "EasyTier QUIC" - [ -n "$socks_port" ] && add_firewall_rule "easytier_socks5" "tcp" "$socks_port" "EasyTier SOCKS5" + # 不再自动放行 SOCKS5 端口到 WAN —— 无认证 SOCKS5 代理暴露给公网有严重安全风险 + # 如需恢复自动放行,去掉下面一行行首的 # 即可 + # [ -n "$socks_port" ] && add_firewall_rule "easytier_socks5" "tcp" "$socks_port" "EasyTier SOCKS5" } # 设置网络接口 diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile index 6294fa741..b8c0f4b08 100644 --- a/luci-app-passwall/Makefile +++ b/luci-app-passwall/Makefile @@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall PKG_VERSION:=26.7.24 -PKG_RELEASE:=197 +PKG_RELEASE:=198 PKG_PO_VERSION:=$(PKG_VERSION) PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua index 276f28131..5d8ad73d8 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua @@ -139,6 +139,9 @@ s.extedit = api.url("node_subscribe_config", "%s") function s.create(e, t) m.no_commit = true local id = TypedSection.create(e, t) + uci:set(appname, id, "hysteria_up_mbps", "100") + uci:set(appname, id, "hysteria_down_mbps", "100") + api.uci_save(uci, appname) luci.http.redirect(e.extedit:format(id)) end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua index 98e52f7e1..aa8215bc4 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua @@ -221,11 +221,9 @@ if #hysteria2_type > 0 then o = s:option(Value, "hysteria_up_mbps", "Hy/Hy2 " .. translate("Max upload Mbps")) o.datatype = "uinteger" - o.default = "100" o = s:option(Value, "hysteria_down_mbps", "Hy/Hy2 " .. translate("Max download Mbps")) o.datatype = "uinteger" - o.default = "100" end o = s:option(Flag, "boot_update", translate("Update Once on Boot"), translate("Updates the subscription the first time PassWall runs automatically after each system boot.")) diff --git a/luci-app-passwall/root/usr/share/passwall/clash_subconverter.lua b/luci-app-passwall/root/usr/share/passwall/clash_subconverter.lua index bc6ec4215..fd85c367b 100644 --- a/luci-app-passwall/root/usr/share/passwall/clash_subconverter.lua +++ b/luci-app-passwall/root/usr/share/passwall/clash_subconverter.lua @@ -7,6 +7,8 @@ local urlencode = api.UrlEncode local base64 = api.base64Encode local json = api.jsonc +local domain_redir = {} + local function host_format(host) if not host then return "" end local str = host:match("%[(.-)%]") or host @@ -162,7 +164,7 @@ local function build_common(node) local d = opts["download-settings"] local ds = {} - if d.server then ds.address = d.server end + if d.server then ds.address = domain_redir[d.server] or d.server end if d.port then ds.port = d.port end ds.network = "xhttp" @@ -507,6 +509,8 @@ local function encode_node(node) local t = node.type + node.server = domain_redir[node.server] or node.server + if t == "vless" then return encode_vless(node) elseif t == "trojan" then return encode_trojan(node) elseif t == "vmess" then return encode_vmess(node) @@ -531,6 +535,15 @@ function parseClashNode(raw, remark) api.log('检测到 Clash 订阅,正在进行转换 ...') + -- Some airports use hosts domain redirect to disguise the real node domain name. + for k, v in pairs(data.hosts or {}) do + if type(k) == "string" and type(v) == "string" then + if api.datatypes.hostname(k) and api.datatypes.hostname(v) then + domain_redir[k] = v + end + end + end + local links = {} for _, node in ipairs(data.proxies) do local err, link = encode_node(node) diff --git a/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua b/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua index 7ab88d6e3..f26535a60 100644 --- a/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua +++ b/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua @@ -330,11 +330,16 @@ end --中国列表 if CHNLIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then if CHNLIST == "direct" then + local sets = { + setflag .. "psw_chn", + setflag .. "psw_chn6" + } + local suffix = (NFTFLAG == "1") and "_static" or "" tmp_lines = { "chnlist-file " .. RULES_PATH .. "/chnlist", - "ipset-name4 " .. setflag .. "psw_chn", - "ipset-name6 " .. setflag .. "psw_chn6", - "add-tagchn-ip", + "ipset-name4 " .. setflag .. "psw_chn" .. suffix, + "ipset-name6 " .. setflag .. "psw_chn6" .. suffix, + "add-tagchn-ip" .. ((NFTFLAG == "1") and (" " .. table.concat(sets, ",")) or ""), "chnlist-first" } merge_array(config_lines, tmp_lines) diff --git a/luci-app-qemu-vms/Makefile b/luci-app-qemu-vms/Makefile index 84e78d698..95b1878df 100644 --- a/luci-app-qemu-vms/Makefile +++ b/luci-app-qemu-vms/Makefile @@ -4,7 +4,7 @@ LUCI_TITLE:=Web UI for QEMU Virtual Machine Simple (VMS) LUCI_DEPENDS:=@TARGET_x86_64 +qemu-vms +ttyd +usbutils +pciutils PKG_LICENSE:=GPLv3 PKG_VERSION:=0.0.1 -PKG_RELEASE:=8 +PKG_RELEASE:=9 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/luci-app-qemu-vms/htdocs/luci-static/resources/view/qemu-vms/passthrough.js b/luci-app-qemu-vms/htdocs/luci-static/resources/view/qemu-vms/passthrough.js index 65e5e67d0..a34e7d4f8 100644 --- a/luci-app-qemu-vms/htdocs/luci-static/resources/view/qemu-vms/passthrough.js +++ b/luci-app-qemu-vms/htdocs/luci-static/resources/view/qemu-vms/passthrough.js @@ -11,6 +11,18 @@ var callListHardware = rpc.declare({ params: [] }); +var callReleasePci = rpc.declare({ + object: 'luci.qemu-vms', + method: 'release_pci', + params: ['section_name'] +}); + +var callReleaseUsb = rpc.declare({ + object: 'luci.qemu-vms', + method: 'release_usb', + params: ['section_name'] +}); + return view.extend({ load: function() { return Promise.all([ @@ -33,7 +45,19 @@ return view.extend({ }); return found; }, - + /* + pciOwner: function(addr) { + var section = this.findPciSection(addr); + if (!section) + return null; + var owner = null; + uci.sections('qemu-vms', 'vm').forEach(function(vm) { + if (vm.pci_passthrough === section) + owner = vm['.name']; + }); + return owner; + }, + */ pciOwners: function(addr) { var section = this.findPciSection(addr); if (!section) @@ -175,9 +199,14 @@ return view.extend({ E('button', { 'class': 'btn cbi-button-negative', 'click': function() { - uci.remove('qemu-vms', section); - self.cleanupVmReferences('pci_passthrough', section); - return uci.save().then(function() { + return callReleasePci(section).catch(function(err) { + ui.addNotification(null, E('p', + _('Warning: could not rebind device to its original driver: ') + err.message), 'warning'); + }).then(function() { + uci.remove('qemu-vms', section); + self.cleanupVmReferences('pci_passthrough', section); + return uci.save(); + }).then(function() { ui.hideModal(); ui.addNotification(null, E('p', _('Passthrough removed for %s.').format(addr)), 'info'); self.updateView(); @@ -286,9 +315,14 @@ return view.extend({ E('button', { 'class': 'btn cbi-button-negative', 'click': function() { - uci.remove('qemu-vms', section); - self.cleanupVmReferences('usb_passthrough', section); - return uci.save().then(function() { + return callReleaseUsb(section).catch(function(err) { + ui.addNotification(null, E('p', + _('Warning: could not rebind device to its original driver: ') + err.message), 'warning'); + }).then(function() { + uci.remove('qemu-vms', section); + self.cleanupVmReferences('usb_passthrough', section); + return uci.save(); + }).then(function() { ui.hideModal(); ui.addNotification(null, E('p', _('Passthrough removed.')), 'info'); self.updateView(); @@ -305,10 +339,12 @@ return view.extend({ var self = this; var rows = devices.map(function(dev) { var section = self.findPciSection(dev.addr); + //var owner = self.pciOwner(dev.addr); var owners = self.pciOwners(dev.addr); var owner = owners.length ? owners.join(', ') : null; var passthroughStatus = section ? _('Active
Section: %s').format(section) : _('Not passthrough'); if (owner) passthroughStatus += ' ' + _('
Host: %s').format(owner); + var actionButton; if (section) { @@ -417,7 +453,7 @@ return view.extend({ renderContent: function(data) { var hw = data[0]; var self = this; - + var description = E('div', { 'class': 'cbi-section' }, [ E('h2', {}, _('Hardware Passthrough')), E('p', { 'class': 'cbi-section-descr' }, diff --git a/luci-app-qemu-vms/root/usr/libexec/rpcd/luci.qemu-vms b/luci-app-qemu-vms/root/usr/libexec/rpcd/luci.qemu-vms index bc8e5fdd2..65cb7917b 100755 --- a/luci-app-qemu-vms/root/usr/libexec/rpcd/luci.qemu-vms +++ b/luci-app-qemu-vms/root/usr/libexec/rpcd/luci.qemu-vms @@ -314,6 +314,8 @@ case "$1" in "list_hardware": { }, "list_machines": { }, "list_net_drivers": { }, + "release_pci": { "section_name": "" }, + "release_usb": { "section_name": "" }, "delete_vm": { "vm_name": "" } }' ;; @@ -324,6 +326,7 @@ case "$1" in json_get_var lines lines json_get_var offset offset json_get_var data data + json_get_var section_name section_name case "$2" in status) @@ -403,6 +406,18 @@ case "$1" in json_close_array json_dump ;; + release_pci) + /etc/init.d/qemu-vms release_pci_passthrough "$section_name" >/dev/null 2>&1 + json_init + json_add_boolean "success" 1 + json_dump + ;; + release_usb) + /etc/init.d/qemu-vms release_usb_passthrough "$section_name" >/dev/null 2>&1 + json_init + json_add_boolean "success" 1 + json_dump + ;; delete_vm) stop_vm_instance "$vm_name" console_close "$vm_name" >/dev/null diff --git a/luci-app-qemu-vms/root/usr/share/rpcd/acl.d/luci-app-qemu-vms.json b/luci-app-qemu-vms/root/usr/share/rpcd/acl.d/luci-app-qemu-vms.json index a85167061..bcf814ad4 100644 --- a/luci-app-qemu-vms/root/usr/share/rpcd/acl.d/luci-app-qemu-vms.json +++ b/luci-app-qemu-vms/root/usr/share/rpcd/acl.d/luci-app-qemu-vms.json @@ -22,6 +22,8 @@ "list_machines", "list_cpus", "list_net_drivers", + "release_pci", + "release_usb", "delete_vm" ] }, diff --git a/qemu-vms/Makefile b/qemu-vms/Makefile index 5529ffc2d..293c88c48 100644 --- a/qemu-vms/Makefile +++ b/qemu-vms/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=qemu-vms PKG_VERSION:=0.0.1 -PKG_RELEASE:=8 +PKG_RELEASE:=9 PKG_MAINTAINER:=Konstantine Shevlakov include $(INCLUDE_DIR)/package.mk diff --git a/qemu-vms/root/etc/init.d/qemu-vms b/qemu-vms/root/etc/init.d/qemu-vms index 487672d10..6fbbefd02 100755 --- a/qemu-vms/root/etc/init.d/qemu-vms +++ b/qemu-vms/root/etc/init.d/qemu-vms @@ -119,6 +119,8 @@ _add_pci() { local dev_name="$(basename "$dev")" local current_driver="$(basename "$(readlink -f "$dev/driver" 2>/dev/null)" 2>/dev/null)" if [ -n "$current_driver" ] && [ "$current_driver" != "vfio-pci" ]; then + local orig_file="$STATUS_DIR/pci-orig-driver-$dev_name" + [ -f "$orig_file" ] || echo "$current_driver" > "$orig_file" echo -n "$dev_name" > "$dev/driver/unbind" 2>/dev/null host_log "$cfg" "PCI: unbound $dev_name from $current_driver" fi @@ -137,26 +139,6 @@ _add_pci() { fi } -#_unbind_usb_host() { -# local usbcfg="$1" -# local vendor_id product_id -# config_get vendor_id "$usbcfg" vendor_id -# config_get product_id "$usbcfg" product_id -# [ -n "$vendor_id" ] && [ -n "$product_id" ] || return 0 -# for dev in /sys/bus/usb/devices/*; do -# if [ -f "$dev/idVendor" ] && [ -f "$dev/idProduct" ]; then -# local v=$(cat "$dev/idVendor") p=$(cat "$dev/idProduct") -# if [ "$v" = "$vendor_id" ] && [ "$p" = "$product_id" ]; then -# if [ -L "$dev/driver" ]; then -# local driver_path=$(readlink -f "$dev/driver") -# local driver_name=$(basename "$driver_path") -# echo -n "$(basename "$dev")" > "$driver_path/unbind" 2>/dev/null -# fi -# fi -# fi -# done -#} - _unbind_usb_host() { local usbcfg="$1" local vendor_id product_id @@ -190,6 +172,68 @@ _unbind_usb_host() { done } +_release_usb_node() { + # Rebind a single sysfs usb node (device or interface) to whatever + # driver it was recorded as being on before we ever touched it. + local node="$1" + local orig_file="$STATUS_DIR/usb-orig-driver-$node" + + [ -f "$orig_file" ] || return 0 + local orig_driver + orig_driver="$(cat "$orig_file")" + + if [ -n "$orig_driver" ] && [ -e "/sys/bus/usb/drivers/$orig_driver" ]; then + echo -n "$node" > "/sys/bus/usb/drivers/$orig_driver/bind" 2>/dev/null + if [ -L "/sys/bus/usb/devices/$node/driver" ] && \ + [ "$(basename "$(readlink -f "/sys/bus/usb/devices/$node/driver")")" = "$orig_driver" ]; then + logger -t qemu-vms "release_usb: restored $node to $orig_driver" + else + logger -t qemu-vms "WARNING: release_usb: failed to rebind $node to $orig_driver" + fi + fi + rm -f "$orig_file" +} + +release_usb() { + # Usage: release_usb + local vendor_id="$1" + local product_id="$2" + + [ -n "$vendor_id" ] && [ -n "$product_id" ] || { + logger -t qemu-vms "release_usb: vendor_id/product_id required" + return 1 + } + + for dev in /sys/bus/usb/devices/*; do + [ -f "$dev/idVendor" ] && [ -f "$dev/idProduct" ] || continue + local v=$(cat "$dev/idVendor") p=$(cat "$dev/idProduct") + [ "$v" = "$vendor_id" ] && [ "$p" = "$product_id" ] || continue + + local devname=$(basename "$dev") + _release_usb_node "$devname" + + for iface in /sys/bus/usb/devices/"$devname":*; do + [ -e "$iface" ] || continue + _release_usb_node "$(basename "$iface")" + done + done +} + +release_usb_passthrough() { + # Usage: release_usb_passthrough + local section="$1" + config_load qemu-vms + local vendor_id product_id + config_get vendor_id "$section" vendor_id + config_get product_id "$section" product_id + if [ -z "$vendor_id" ] || [ -z "$product_id" ]; then + logger -t qemu-vms "release_usb_passthrough: section '$section' has no vendor_id/product_id" + return 1 + fi + release_usb "$vendor_id" "$product_id" +} + + build_customargs() { local cfg="$1" custom_opts="" @@ -288,29 +332,6 @@ start_vm() { build_customargs "$cfg" build_diskargs "$cfg" "$image" - #local pci_id="" vendor_id="" pci_opts="" - #if [ -n "$pci_passthrough" ]; then - # config_get pci_id "$pci_passthrough" pci_id - # config_get vendor_id "$pci_passthrough" vendor_id - # if [ -n "$vendor_id" ] && [ -n "$pci_id" ]; then - # if [ -e "/sys/bus/pci/devices/0000:$pci_id/driver" ]; then - # local current_driver - # current_driver="$(basename "$(readlink -f "/sys/bus/pci/devices/0000:$pci_id/driver" 2>/dev/null)" 2>/dev/null)" - # host_log "$cfg" "PCI passthrough: $pci_id already bound to driver '$current_driver'" - # else - # echo "$vendor_id" > /sys/bus/pci/drivers/vfio-pci/new_id 2>/dev/null - # if [ -e "/sys/bus/pci/devices/0000:$pci_id/driver" ]; then - # host_log "$cfg" "PCI passthrough: bound $pci_id (vendor/device $vendor_id) to vfio-pci" - # else - # host_log "$cfg" "WARNING: PCI passthrough: failed to bind $pci_id to vfio-pci - check IOMMU/BIOS settings" - # fi - # fi - # pci_opts="-device vfio-pci,host=$pci_id" - # else - # host_log "$cfg" "WARNING: pci_passthrough='$pci_passthrough' is set but its pci_id/vendor_id are incomplete - skipping passthrough" - # fi - #fi - local pci_opts="" config_list_foreach "$cfg" pci_passthrough _add_pci @@ -369,6 +390,74 @@ start_vm() { # connects for the duration of the minicom session. } +release_pci() { + # Usage: release_pci + local pci_id="$1" + [ -n "$pci_id" ] || { + logger -t qemu-vms "release_pci: pci_id required" + return 1 + } + + local pci_path="/sys/bus/pci/devices/0000:$pci_id" + local iommu_group="" + [ -L "$pci_path/iommu_group" ] && iommu_group="$(basename "$(readlink -f "$pci_path/iommu_group")")" + + if [ -z "$iommu_group" ]; then + logger -t qemu-vms "release_pci: cannot determine IOMMU group for $pci_id" + return 1 + fi + + for dev in /sys/kernel/iommu_groups/$iommu_group/devices/*; do + local dev_name="$(basename "$dev")" + local current_driver="$(basename "$(readlink -f "$dev/driver" 2>/dev/null)" 2>/dev/null)" + + if [ "$current_driver" != "vfio-pci" ]; then + logger -t qemu-vms "release_pci: $dev_name is not bound to vfio-pci (currently '$current_driver'), skipping" + continue + fi + + echo -n "" > "$dev/driver_override" 2>/dev/null + echo -n "$dev_name" > "$dev/driver/unbind" 2>/dev/null + + local orig_file="$STATUS_DIR/pci-orig-driver-$dev_name" + if [ -f "$orig_file" ]; then + local orig_driver + orig_driver="$(cat "$orig_file")" + if [ -n "$orig_driver" ] && [ -e "/sys/bus/pci/drivers/$orig_driver" ]; then + echo -n "$dev_name" > "/sys/bus/pci/drivers/$orig_driver/bind" 2>/dev/null + if [ -e "$dev/driver" ] && [ "$(basename "$(readlink -f "$dev/driver")")" = "$orig_driver" ]; then + logger -t qemu-vms "release_pci: restored $dev_name to $orig_driver" + else + logger -t qemu-vms "WARNING: release_pci: failed to rebind $dev_name to $orig_driver" + logger -t qemu-vms "WARNING: release_pci: will need reoot host to bind original driver $$orig_driver" + fi + fi + rm -f "$orig_file" + else + logger -t qemu-vms "release_pci: no recorded original driver for $dev_name, left unbound" + fi + done +} + +release_pci_passthrough() { + # Usage: release_pci_passthrough + local section="$1" + config_load qemu-vms + local pci_id + config_get pci_id "$section" pci_id + if [ -z "$pci_id" ]; then + logger -t qemu-vms "release_pci_passthrough: section '$section' has no pci_id" + return 1 + fi + release_pci "$pci_id" +} + + +EXTRA_COMMANDS="release_pci_passthrough release_usb_passthrough" +EXTRA_HELP=" release_pci_passthrough
Unbind a PCI device from vfio-pci and restore its original driver + release_usb_passthrough
Unbind a USB device from passthrough use and restore its original driver" + + start_service() { config_load qemu-vms if [ -n "$1" ]; then diff --git a/teleproxy/Makefile b/teleproxy/Makefile index 9d1ac9915..aaaaa9e32 100644 --- a/teleproxy/Makefile +++ b/teleproxy/Makefile @@ -1,8 +1,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=teleproxy -PKG_VERSION:=4.15.0 -PKG_RELEASE:=21 +PKG_VERSION:=4.16.0 +PKG_RELEASE:=22 PKG_MAINTAINER:=Kosntantine Shevlakov PKG_LICENSE:=GPLv2 @@ -10,7 +10,7 @@ PKG_LICENSE_FILES:=LICENSE PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/teleproxy/teleproxy.git -PKG_SOURCE_VERSION:=8cb4c57116dab588de6cd7509e65f8b6b6d31936 +PKG_SOURCE_VERSION:=d5342b5983dee738ee94d66f77ff27ea24932755 PKG_SOURCE_SUBDIR:=$(PKG_NAME) PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz