diff --git a/dockerd/Makefile b/dockerd/Makefile index 710ac25aa..a1fa6fb07 100644 --- a/dockerd/Makefile +++ b/dockerd/Makefile @@ -1,7 +1,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=dockerd -PKG_VERSION:=29.1.0 +PKG_VERSION:=29.1.1 PKG_RELEASE:=1 PKG_LICENSE:=Apache-2.0 PKG_LICENSE_FILES:=LICENSE diff --git a/luci-app-eqosplus/Makefile b/luci-app-eqosplus/Makefile index 6cc7478a3..91e501b72 100644 --- a/luci-app-eqosplus/Makefile +++ b/luci-app-eqosplus/Makefile @@ -1,6 +1,6 @@ # -# Copyright (C) 2006-2017 OpenWrt.org -# Copyright (C) 2022-2025 sirpdboy +# Copyright (C) 2006-2017 OpenWrt.org# +# Copyright (C) 2022-2025 sirpdboy herboy2008@gmail.com https://github.com/sirpdboy/luci-app-eqosplus # This is free software, licensed under the GNU General Public License v2. # See /LICENSE for more information. # @@ -14,11 +14,11 @@ PKG_LICENSE:=Apache-2.0 LUCI_TITLE:=LuCI support for eqosplus. LUCI_DESCRIPTION:=LuCI support for Easy eqosplus(Support speed limit based on IP address). -LUCI_DEPENDS:=+bash +tc +kmod-sched-core +kmod-ifb +kmod-sched +iptables-mod-filter +iptables-mod-nat-extra +LUCI_DEPENDS:=+ip-full +tc +nftables +bc +kmod-ifb LUCI_PKGARCH:=all -PKG_VERSION:=1.2.8 -PKG_RELEASE:=20250723 +PKG_VERSION:=1.3.0 +PKG_RELEASE:=20251128 PKG_MAINTAINER:=sirpdboy define Build/Compile diff --git a/luci-app-eqosplus/luasrc/model/cbi/eqosplus.lua b/luci-app-eqosplus/luasrc/model/cbi/eqosplus.lua index bbe054dbd..e2c020864 100644 --- a/luci-app-eqosplus/luasrc/model/cbi/eqosplus.lua +++ b/luci-app-eqosplus/luasrc/model/cbi/eqosplus.lua @@ -7,7 +7,7 @@ local ipc = require "luci.ip" local a, t, e a = Map("eqosplus", translate("Network speed limit")) -a.description = translate("Users can limit the network speed for uploading/downloading through MAC, IP.The speed unit is MB/second.")..translate("Suggested feedback:")..translate("GitHub @sirpdboy/luci-app-eqosplus ") +a.description = translate("Users can limit the network speed for uploading/downloading through MAC, IP, and IP segments (192.168.110.00-192.168.10.200). The speed unit is MB/second.")) a.template = "eqosplus/index" t = a:section(TypedSection, "eqosplus") diff --git a/luci-app-eqosplus/po/templates/eqosplus.pot b/luci-app-eqosplus/po/templates/eqosplus.pot new file mode 100644 index 000000000..151cee8db --- /dev/null +++ b/luci-app-eqosplus/po/templates/eqosplus.pot @@ -0,0 +1,61 @@ + +msgid "Eqosplus" +msgstr "" + +msgid "Network speed limit" +msgstr "" + +msgid "Running state" +msgstr "" + +msgid "Not running" +msgstr "" + +msgid "Running" +msgstr "" + +msgid "Users can limit the network speed for uploading/downloading through MAC, IP, and IP segments (192.168.110.00-192.168.10.200). The speed unit is MB/second." +msgstr "" + +msgid "MAC/IP" +msgstr "" + +msgid "Downloads" +msgstr "" + +msgid "Uploads" +msgstr "" + +msgid "Comment" +msgstr "" + +msgid "Upload bandwidth(Mbit/s)" +msgstr "" + +msgid "Download bandwidth(Mbit/s)" +msgstr "" + +msgid "Start control time" +msgstr "" + +msgid "Stop control time" +msgstr "" + +msgid "Week Day(1~7)" +msgstr "" + +msgid "Suggested feedback:" +msgstr "" + +msgid "Set the interface used for restriction, use pppoe-wan for dialing, use WAN hardware interface for DHCP mode (such as eth1), and use br-lan for bypass mode" +msgstr "" + +msgid "Rest Day" +msgstr "" + +msgid "Workday" +msgstr "" + +msgid "Automatic settings" +msgstr "" + diff --git a/luci-app-eqosplus/po/zh_Hans/eqosplus.po b/luci-app-eqosplus/po/zh_Hans/eqosplus.po index 0fa563938..840559fcb 100644 --- a/luci-app-eqosplus/po/zh_Hans/eqosplus.po +++ b/luci-app-eqosplus/po/zh_Hans/eqosplus.po @@ -14,8 +14,8 @@ msgstr "未运行" msgid "Running" msgstr "已运行" -msgid "Users can limit the network speed for uploading/downloading through MAC, IP.The speed unit is MB/second." -msgstr "可以通过MAC,IP限制用户上传/下载的网速。速度单位为 MB/秒 。" +msgid "Users can limit the network speed for uploading/downloading through MAC, IP, and IP segments (192.168.110.00-192.168.10.200). The speed unit is MB/second." +msgstr "用户可以通过MAC、IP、IP段(192.168.10.100-192.168.10.200),限制上传/下载的网络速度。速度单位为MB/秒。。" msgid "MAC/IP" msgstr "MAC/IP" diff --git a/luci-app-eqosplus/root/etc/config/eqosplus b/luci-app-eqosplus/root/etc/config/eqosplus index a0df9a3b9..722434ae1 100644 --- a/luci-app-eqosplus/root/etc/config/eqosplus +++ b/luci-app-eqosplus/root/etc/config/eqosplus @@ -11,11 +11,11 @@ config device option download '1' option timeend '23:55' option upload '1' - option mac '' + option mac '192.168.10.10' option enable '0' config device - option mac '192.168.10.10/24' + option mac '192.168.10.10-192.168.10.200' option timestart '00:00' option timeend '00:00' option week '0' diff --git a/luci-app-eqosplus/root/etc/hotplug.d/iface/10-eqosplus b/luci-app-eqosplus/root/etc/hotplug.d/iface/10-eqosplus new file mode 100644 index 000000000..91059ec8e --- /dev/null +++ b/luci-app-eqosplus/root/etc/hotplug.d/iface/10-eqosplus @@ -0,0 +1,5 @@ +#!/bin/sh +[ "$ACTION" = "ifup" ] && [ "$INTERFACE" = "wan" ] && { + sleep 5 + /etc/init.d/eqosplus restart +} \ No newline at end of file diff --git a/luci-app-eqosplus/root/usr/bin/eqosplus b/luci-app-eqosplus/root/usr/bin/eqosplus index 00318fdaa..721fafa0f 100644 --- a/luci-app-eqosplus/root/usr/bin/eqosplus +++ b/luci-app-eqosplus/root/usr/bin/eqosplus @@ -9,50 +9,32 @@ NAME=eqosplus IDLIST="/var/$NAME.idlist" LOCK="/var/lock/$NAME.lock" TMPID="/var/$NAME.tmpid" +LOG="/var/$NAME_log.log" +# idlist=`uci show $NAME | grep "enable='1'" | grep "device" | grep -oE '\[.*?\]' | grep -o '[0-9]' ` -# 获取网络接口配置 -if [ x$(uci get $NAME.@$NAME[0].ifname) = 'x1' ]; then + +if [ x$(uci get $NAME.@$NAME[0].ifname 2>/dev/null) = 'x1' ]; then ifname=$(uci -q get network.lan.ifname) [ "x$ifname" = "x" ] && ifname="device" || ifname="ifname" dev=$(uci -q get network.wan.$ifname) [ ! "$dev" ] && dev=br-lan else - dev=$(uci -q get $NAME.@$NAME[0].ifname) + dev=$(uci -q get $NAME.@$NAME[0].ifname 2>/dev/null) + [ ! "$dev" ] && dev=br-lan fi -# 工具路径 bin_nft=$(which nft) -bin_iptables=$(which iptables) -bin_ip6tables=$(which ip6tables) bin_tc=$(which tc) bin_ip=$(which ip) DEBUG=1 -# 检测nftables类型 nft_type() { if command -v nft >/dev/null; then nftables_ver="true" fi } -# 检测iptables类型 -ipt_type() { - if command -v iptables >/dev/null; then - iptables_ver="true" - fi -} - -# Debug functions - echo + run -dbg_iptables() { - [ "${DEBUG:-0}" -eq 0 ] || echo "DEBUG: iptables $*" - $bin_iptables "$*" -} - -dbg_ip6tables() { - [ "${DEBUG:-0}" -eq 0 ] || echo "DEBUG: ip6tables $*" - $bin_ip6tables "$*" -} - +# Debug functions dbg_nft() { [ "${DEBUG:-0}" -eq 0 ] || echo "DEBUG: nft $*" $bin_nft "$@" @@ -76,220 +58,173 @@ is_macaddr() { return $ret } +# 数值比较函数 +is_gt_zero() { + local value=$1 + # 使用bc进行浮点数比较 + echo "$value > 0" | bc -l 2>/dev/null | grep -q 1 +} + +# 转换为kbit +to_kbit() { + local mb=$1 + # MB/s 转 kbit/s: 1 MB/s = 8192 kbit/s + echo "scale=0; $mb * 8192 / 1" | bc 2>/dev/null || echo "0" +} + # Default commands -iptables="dbg_iptables" -ip6tables="dbg_ip6tables" tc="dbg_tc" ip="dbg_ip" -ipt="dbg_iptables" -ipt6="dbg_ip6tables" nft="dbg_nft" -# 检测防火墙类型 nft_type -ipt_type - -ipt(){ - $iptables $* - $ip6tables $* -} - -iptm(){ - $iptables "-t mangle $*" - $ip6tables "-t mangle $*" -} stop_qos() { - # 清理所有HTB队列 - for face in $(tc qdisc show | grep htb | awk '{print $5}'); do + for face in $(tc qdisc show 2>/dev/null | grep htb | awk '{print $5}'); do $tc qdisc del dev $face root 2>/dev/null done - # 清理特定设备的队列 $tc qdisc del dev ${dev} root 2>/dev/null $tc qdisc del dev ${dev}_ifb root 2>/dev/null $tc qdisc del dev ${dev} ingress 2>/dev/null - $ip link del dev ${dev}_ifb 2>/dev/null 2>&1 - - # 清理nftables规则 + $ip link del dev ${dev}_ifb 2>/dev/null 2>&1 + if [ -n "$nftables_ver" ]; then - $nft flush table inet ${NAME} 2>/dev/null $nft delete table inet ${NAME} 2>/dev/null - fi - - # 清理iptables标记规则 - if [ -n "$iptables_ver" ]; then - $iptables -t mangle -F ${NAME}_mark 2>/dev/null - $iptables -t mangle -X ${NAME}_mark 2>/dev/null - $ip6tables -t mangle -F ${NAME}_mark 2>/dev/null - $ip6tables -t mangle -X ${NAME}_mark 2>/dev/null + $nft delete table bridge ${NAME} 2>/dev/null fi - echo "" > "$IDLIST" + echo "" > "$IDLIST" 2>/dev/null } init_qosplus() { - # 加载内核模块 + insmod sch_htb 2>/dev/null insmod act_mirred 2>/dev/null insmod ifb 2>/dev/null + + $ip link del dev ${dev}_ifb 2>/dev/null + $ip link add dev ${dev}_ifb name ${dev}_ifb type ifb + $ip link set dev ${dev}_ifb up - # 创建IFB虚拟接口用于上传限速 - $ip link add dev ${dev}_ifb name ${dev}_ifb type ifb 2>/dev/null - $ip link set dev ${dev}_ifb up 2>/dev/null - - # 下载限速设置(原始接口) + $tc qdisc del dev ${dev} root 2>/dev/null $tc qdisc add dev ${dev} root handle 1:0 htb default 1 - $tc class add dev ${dev} parent 1:0 classid 1:1 htb rate 80gbit prio 0 quantum 1500 + $tc class add dev ${dev} parent 1:0 classid 1:1 htb rate 1000mbit ceil 1000mbit - # 上传限速设置(IFB接口) + $tc qdisc del dev ${dev}_ifb root 2>/dev/null $tc qdisc add dev ${dev}_ifb root handle 1:0 htb default 1 - $tc class add dev ${dev}_ifb parent 1:0 classid 1:1 htb rate 80gbit prio 0 quantum 1500 - - # 排除本地网络流量 + $tc class add dev ${dev}_ifb parent 1:0 classid 1:1 htb rate 1000mbit ceil 1000mbit lanipaddr=$(uci -q get network.lan.ipaddr 2>/dev/null | awk -F '.' '{print $1"."$2"."$3".0/24"}') - $tc filter add dev $dev parent 1:0 protocol ip prio 1 u32 match ip src "$lanipaddr" match ip dst "$lanipaddr" flowid 1:1 - $tc filter add dev ${dev}_ifb parent 1:0 protocol ip prio 1 u32 match ip src "$lanipaddr" match ip dst "$lanipaddr" flowid 1:1 - - # 设置入口流量重定向到IFB + if [ -n "$lanipaddr" ]; then + $tc filter add dev $dev parent 1:0 protocol ip prio 1 u32 match ip src "$lanipaddr" match ip dst "$lanipaddr" flowid 1:1 + $tc filter add dev ${dev}_ifb parent 1:0 protocol ip prio 1 u32 match ip src "$lanipaddr" match ip dst "$lanipaddr" flowid 1:1 + fi + $tc qdisc del dev ${dev} ingress 2>/dev/null $tc qdisc add dev ${dev} ingress $tc filter add dev ${dev} parent ffff: protocol all prio 2 u32 match u32 0 0 flowid 1:1 action mirred egress redirect dev ${dev}_ifb - - # 初始化nftables表 - if [ -n "$nftables_ver" ]; then - $nft add table inet ${NAME} 2>/dev/null - $nft add chain inet ${NAME} mark_traffic { type filter hook postrouting priority -150 \; } - fi - # 添加iptables标记规则(用于更精确的上传控制) - if [ -n "$iptables_ver" ]; then - $iptables -t mangle -N ${NAME}_mark 2>/dev/null - $iptables -t mangle -F ${NAME}_mark - $iptables -t mangle -A POSTROUTING -j ${NAME}_mark - $ip6tables -t mangle -N ${NAME}_mark 2>/dev/null - $ip6tables -t mangle -F ${NAME}_mark - $ip6tables -t mangle -A POSTROUTING -j ${NAME}_mark + if [ -n "$nftables_ver" ]; then + $nft delete table inet ${NAME} 2>/dev/null + $nft delete table bridge ${NAME} 2>/dev/null + + $nft add table inet ${NAME} + + $nft add chain inet ${NAME} mark_forward { type filter hook forward priority -200\; policy accept\; } + $nft add chain inet ${NAME} mark_output { type filter hook output priority -200\; policy accept\; } + $nft add chain inet ${NAME} mark_postrouting { type filter hook postrouting priority -200\; policy accept\; } fi + + return 0 } + del_id() { - id=$((id + 10)) + local list_id=$1 + id=$((list_id * 10 + 1000)) [ "${DEBUG:-0}" -eq 0 ] || echo "D: del_id $@ --$id --$mac" - - # 删除下载限速规则 - $tc qdisc del dev ${dev} parent 1:$id 2>/dev/null + $tc filter del dev ${dev} parent 1: handle 800::$(printf "%x" $id) 2>/dev/null $tc class del dev ${dev} parent 1:1 classid 1:$id 2>/dev/null - $tc filter del dev ${dev} pref $id 2>/dev/null - - # 删除上传限速规则 - $tc qdisc del dev ${dev}_ifb parent 1:$id 2>/dev/null + $tc filter del dev ${dev}_ifb parent 1: handle 800::$(printf "%x" $id) 2>/dev/null $tc class del dev ${dev}_ifb parent 1:1 classid 1:$id 2>/dev/null - $tc filter del dev ${dev}_ifb pref $id 2>/dev/null - - # 删除nftables/iptables标记规则 - mac=$(uci -q get $NAME.@device[$1].mac) - if is_macaddr "$mac"; then - - [ -n "$nftables_ver" ] && $nft delete rule inet ${NAME} mark_traffic ether saddr $mac counter 2>/dev/null - [ -n "$iptables_ver" ] && $iptables -t mangle -D ${NAME}_mark -m mac --mac-source $mac -j MARK --set-mark $id 2>/dev/null - else - [ -n "$nftables_ver" ] && $nft delete rule inet ${NAME} mark_traffic ip saddr $mac counter 2>/dev/null - [ -n "$iptables_ver" ] && $iptables -t mangle -D ${NAME}_mark -s $mac -j MARK --set-mark $id 2>/dev/null + mac=$(uci -q get $NAME.@device[$list_id].mac 2>/dev/null) + if [ -n "$nftables_ver" ] && [ -n "$mac" ]; then + if is_macaddr "$mac"; then + $nft delete rule inet ${NAME} mark_forward ether saddr $mac counter 2>/dev/null + $nft delete rule inet ${NAME} mark_output ether saddr $mac counter 2>/dev/null + $nft delete rule inet ${NAME} mark_postrouting ether saddr $mac counter 2>/dev/null + else + Z=$(echo $mac | awk -F '[/]' '{print $2}') + [ -n "$Z" ] && mac=$(echo $mac | awk -F '[/]' '{print $1}') || Z=32 + $nft delete rule inet ${NAME} mark_forward ip saddr $mac/$Z counter 2>/dev/null + $nft delete rule inet ${NAME} mark_output ip saddr $mac/$Z counter 2>/dev/null + $nft delete rule inet ${NAME} mark_postrouting ip saddr $mac/$Z counter 2>/dev/null + fi fi } add_mac() { - id=$((id + 10)) + local list_id=$1 + id=$((list_id * 10 + 1000)) M0=$(echo $mac | cut -d : -f 1)$(echo $mac | cut -d : -f 2) M1=$(echo $mac | cut -d : -f 3)$(echo $mac | cut -d : -f 4) M2=$(echo $mac | cut -d : -f 5)$(echo $mac | cut -d : -f 6) [ "${DEBUG:-0}" -eq 0 ] || echo "D: add_mac $@ --id:$id --mac:$mac M012--$M0-$M1-$M2" - - # 添加上传限速规则(使用IFB接口) - if [ "$UL" -gt 0 ]; then - # 添加nftables标记规则 - [ -n "$nftables_ver" ] && $nft add rule inet ${NAME} mark_traffic ether saddr $mac counter meta mark set $id - [ -n "$iptables_ver" ] && $iptables -t mangle -A ${NAME}_mark -m mac --mac-source $mac -j MARK --set-mark $id - # 添加TC限速规则 - $tc class add dev ${dev}_ifb parent 1:1 classid 1:$id htb rate "${UL}kbit" ceil "${UL}kbit" prio $id quantum 1500 - $tc qdisc add dev ${dev}_ifb parent 1:$id handle $id: sfq perturb 1 + + if is_gt_zero "$UL"; then + if [ -n "$nftables_ver" ]; then + $nft add rule inet ${NAME} mark_forward ether saddr $mac counter meta mark set $id + $nft add rule inet ${NAME} mark_output ether saddr $mac counter meta mark set $id + $nft add rule inet ${NAME} mark_postrouting ether saddr $mac counter meta mark set $id + fi + $tc class add dev ${dev}_ifb parent 1:1 classid 1:$id htb rate "${UL}kbit" ceil "${UL}kbit" prio $id burst 15k cburst 15k + $tc qdisc add dev ${dev}_ifb parent 1:$id handle ${id}: sfq perturb 10 + $tc filter add dev ${dev}_ifb parent 1: protocol ip prio $id handle $id fw flowid 1:$id - - # 原始MAC过滤 - $tc filter add dev ${dev}_ifb parent 1: protocol ip prio $(expr $id + 100) u32 \ + + $tc filter add dev ${dev}_ifb parent 1: protocol ip prio $((id + 100)) u32 \ match u16 0x0800 0xFFFF at -2 \ match u16 0x${M2} 0xFFFF at -4 \ match u32 0x${M0}${M1} 0xFFFFFFFF at -8 \ flowid 1:$id - elif [ "$UL" -eq 0 ]; then - $tc filter add dev ${dev}_ifb parent 1: protocol ip prio 5 u32 \ - match u16 0x0800 0xFFFF at -2 \ - match u16 0x${M2} 0xFFFF at -4 \ - match u32 0x${M0}${M1} 0xFFFFFFFF at -8 \ - flowid 1:1 fi - - # 添加下载限速规则 - if [ "$DL" -gt 0 ]; then - $tc class add dev ${dev} parent 1:1 classid 1:$id htb rate "${DL}kbit" ceil "${DL}kbit" prio $id quantum 1500 - $tc qdisc add dev ${dev} parent 1:$id handle $id: sfq perturb 1 + if is_gt_zero "$DL"; then + $tc class add dev ${dev} parent 1:1 classid 1:$id htb rate "${DL}kbit" ceil "${DL}kbit" prio $id burst 15k cburst 15k + $tc qdisc add dev ${dev} parent 1:$id handle ${id}: sfq perturb 10 + $tc filter add dev ${dev} parent 1: protocol ip prio $id u32 \ match u16 0x0800 0xFFFF at -2 \ match u32 0x${M1}${M2} 0xFFFFFFFF at -12 \ match u16 0x${M0} 0xFFFF at -14 \ flowid 1:$id - elif [ "$DL" -eq 0 ]; then - $tc filter add dev ${dev} parent 1: protocol ip prio 5 u32 \ - match u16 0x0800 0xFFFF at -2 \ - match u32 0x${M1}${M2} 0xFFFFFFFF at -12 \ - match u16 0x${M0} 0xFFFF at -14 \ - flowid 1:1 fi } add_ip() { - id=$((id + 10)) + local list_id=$1 + id=$((list_id * 10 + 1000)) [ "${DEBUG:-0}" -eq 0 ] || echo "D: add_ip $@ --$id --$mac" Z=$(echo $mac | awk -F '[/]' '{print $2}') [ -n "$Z" ] && mac=$(echo $mac | awk -F '[/]' '{print $1}') || Z=32 - - # 添加上传限速规则(使用IFB接口) - if [ "$UL" -gt 0 ]; then - # 添加nftables/iptables标记规则 + if is_gt_zero "$UL"; then if [ -n "$nftables_ver" ]; then - $nft add rule inet ${NAME} mark_traffic ip saddr $mac/$Z counter meta mark set $id + $nft add rule inet ${NAME} mark_forward ip saddr $mac/$Z counter meta mark set $id + $nft add rule inet ${NAME} mark_output ip saddr $mac/$Z counter meta mark set $id + $nft add rule inet ${NAME} mark_postrouting ip saddr $mac/$Z counter meta mark set $id fi - if [ -n "$iptables_ver" ]; then - $iptables -t mangle -A ${NAME}_mark -s $mac/$Z -j MARK --set-mark $id - fi - - # 添加TC限速规则 - $tc class add dev ${dev}_ifb parent 1:1 classid 1:$id htb rate "${UL}kbit" ceil "${UL}kbit" prio $id quantum 1500 - $tc qdisc add dev ${dev}_ifb parent 1:$id handle $id: sfq perturb 1 + $tc class add dev ${dev}_ifb parent 1:1 classid 1:$id htb rate "${UL}kbit" ceil "${UL}kbit" prio $id burst 15k cburst 15k + $tc qdisc add dev ${dev}_ifb parent 1:$id handle ${id}: sfq perturb 10 $tc filter add dev ${dev}_ifb parent 1: protocol ip prio $id handle $id fw flowid 1:$id - - # 原始IP过滤 - $tc filter add dev ${dev}_ifb parent 1:0 prio $(expr $id + 100) protocol ip u32 \ + $tc filter add dev ${dev}_ifb parent 1:0 prio $((id + 100)) protocol ip u32 \ match ip src "$mac"/"$Z" \ - classid 1:$id - elif [ "$UL" -eq 0 ]; then - $tc filter add dev ${dev}_ifb parent 1:0 prio 6 protocol ip u32 \ - match ip src "$mac"/"$Z" \ - classid 1:1 + flowid 1:$id fi - - # 添加下载限速规则 - if [ "$DL" -gt 0 ]; then - $tc class add dev ${dev} parent 1:1 classid 1:$id htb rate "${DL}kbit" ceil "${DL}kbit" prio $id quantum 1500 - $tc qdisc add dev ${dev} parent 1:$id handle $id: sfq perturb 1 + if is_gt_zero "$DL"; then + $tc class add dev ${dev} parent 1:1 classid 1:$id htb rate "${DL}kbit" ceil "${DL}kbit" prio $id burst 15k cburst 15k + $tc qdisc add dev ${dev} parent 1:$id handle ${id}: sfq perturb 10 $tc filter add dev ${dev} parent 1:0 prio $id protocol ip u32 \ match ip dst "$mac"/"$Z" \ - classid 1:$id - elif [ "$DL" -eq 0 ]; then - $tc filter add dev ${dev} parent 1:0 prio 6 protocol ip u32 \ - match ip dst "$mac"/"$Z" \ - classid 1:1 + flowid 1:$id fi } @@ -336,69 +271,109 @@ case "$crrun" in stop_qos ;; "start") + stop_qos > /dev/null 2>&1 + sleep 2 init_qosplus - idlist=$(uci show $NAME | grep "enable='1'" | grep "device" | grep -oE '\[.*?\]' | grep -o '[0-9]' | sed -e 's/^/!/g' -e 's/$/!/g' > $IDLIST; cat $IDLIST | sed -e 's/!//g') + idlist=$(uci show $NAME 2>/dev/null | grep "enable='1'" | grep "device" | grep -oE '\[.*?\]' | grep -o '[0-9]' | sort -nu | sed -e 's/^/!/g' -e 's/$/!/g' > $IDLIST; cat $IDLIST 2>/dev/null | sed -e 's/!//g') + if [ ! -s "$IDLIST" ]; then - stop_qos - return 1 + return 1 fi + device_count=0 for list in $(echo $idlist | sed -e 's/!//g'); do if check_list $list; then - mac=$(uci -q get $NAME.@device[$list].mac) - DL=$(uci -q get $NAME.@device[$list].download 2>/dev/null | awk '{print $1*1000/8}') - UL=$(uci -q get $NAME.@device[$list].upload 2>/dev/null | awk '{print $1*1000/8}') - if is_macaddr $mac; then - add_mac $list - else - add_ip $list + mac=$(uci -q get $NAME.@device[$list].mac 2>/dev/null) + download_mb=$(uci -q get $NAME.@device[$list].download 2>/dev/null) + upload_mb=$(uci -q get $NAME.@device[$list].upload 2>/dev/null) + comment=$(uci -q get $NAME.@device[$list].comment 2>/dev/null) + + # 转换为kbit + DL=$(to_kbit "$download_mb") + UL=$(to_kbit "$upload_mb") + + if [ -n "$mac" ]; then + if is_macaddr "$mac"; then + add_mac $list >>$LOG + echo "✅ MAC限速: $comment ($mac) - 下载:${download_mb}MB/s(${DL}kbit/s) 上传:${upload_mb}MB/s(${UL}kbit/s)" >>$LOG + else + add_ip $list >>$LOG + echo "✅ IP限速: $comment ($mac) - 下载:${download_mb}MB/s(${DL}kbit/s) 上传:${upload_mb}MB/s(${UL}kbit/s)" >>$LOG + fi + device_count=$((device_count + 1)) fi else - [ $(cat $IDLIST 2>/dev/null | grep "!${list}!" | wc -l) -gt 0 ] && { - del_id $list - sed -i "/!$list!/d" $IDLIST >/dev/null 2>&1 + [ -f "$IDLIST" ] && [ $(grep "!${list}!" "$IDLIST" 2>/dev/null | wc -l) -gt 0 ] && { + del_id $list >>$LOG + sed -i "/!$list!/d" "$IDLIST" >/dev/null 2>&1 + comment=$(uci -q get $NAME.@device[$list].comment 2>/dev/null) } fi done + echo "EQOSPLUS限速服务启动完成,共配置 $device_count 个设备" >>$LOG + echo "" + echo "当前限速状态:" >>$LOG + tc -s class show dev $dev | grep "rate" | head -5 >>$LOG + tc -s class show dev ${dev}_ifb | grep "rate" | head -5 >>$LOG + ;; "add") + echo "➕ 添加限速规则..." for list in $(echo $crid | sed -e 's/!//g' | sed 's/,/ /g'); do - mac=$(uci -q get $NAME.@device[$list].mac) - DL=$(uci -q get $NAME.@device[$list].download 2>/dev/null | awk '{print $1*1000/8}') - UL=$(uci -q get $NAME.@device[$list].upload 2>/dev/null | awk '{print $1*1000/8}') + mac=$(uci -q get $NAME.@device[$list].mac 2>/dev/null) + download_mb=$(uci -q get $NAME.@device[$list].download 2>/dev/null) + upload_mb=$(uci -q get $NAME.@device[$list].upload 2>/dev/null) + comment=$(uci -q get $NAME.@device[$list].comment 2>/dev/null) + DL=$(to_kbit "$download_mb") + UL=$(to_kbit "$upload_mb") + if is_macaddr $mac; then add_mac $list + echo "✅ 添加MAC限速: $comment ($mac)" >>$LOG else add_ip $list + echo "✅ 添加IP限速: $comment ($mac)" >>$LOG fi done ;; "del") for list in $(echo $crid | sed -e 's/!//g' | sed 's/,/ /g'); do + comment=$(uci -q get $NAME.@device[$list].comment 2>/dev/null) + mac=$(uci -q get $NAME.@device[$list].mac 2>/dev/null) del_id $list done ;; "status") - echo "### Statistics $dev ###" - echo "# qdiscs #" - tc -s qdisc show dev $dev - echo "# class #" - tc -s class show dev $dev - echo "# filter #" - tc -s filter show dev $dev root - tc -s filter show dev $dev parent 1: - echo "### Statistics ${dev}_ifb ###" - echo "# qdiscs #" - tc -s qdisc show dev ${dev}_ifb - echo "# class #" - tc -s class show dev ${dev}_ifb - echo "# filter #" - tc -s filter show dev ${dev}_ifb root - tc -s filter show dev ${dev}_ifb parent 1: - echo "### NFTables Rules ###" - nft list table inet ${NAME} 2>/dev/null - echo "### IPTables Rules ###" - iptables -t mangle -L ${NAME}_mark -n 2>/dev/null - ip6tables -t mangle -L ${NAME}_mark -n 2>/dev/null + echo "EQOSPLUS限速服务状态" + echo "### 网络接口: $dev ###" + echo "# 下载队列统计 #" + tc -s qdisc show dev $dev 2>/dev/null || echo "无下载队列" + echo "# 下载类统计 #" + tc -s class show dev $dev 2>/dev/null | grep -E "class htb|rate [0-9]" || echo "无下载类" + echo "# 下载过滤器 #" + tc -s filter show dev $dev parent 1: 2>/dev/null | head -10 || echo "无下载过滤器" + + echo "### 虚拟接口: ${dev}_ifb ###" + echo "# 上传队列统计 #" + tc -s qdisc show dev ${dev}_ifb 2>/dev/null || echo "无上传队列" + echo "# 上传类统计 #" + tc -s class show dev ${dev}_ifb 2>/dev/null | grep -E "class htb|rate [0-9]" || echo "无上传类" + echo "# 上传过滤器 #" + tc -s filter show dev ${dev}_ifb parent 1: 2>/dev/null | head -10 || echo "无上传过滤器" + + if [ -n "$nftables_ver" ]; then + echo "### NFTables规则 ###" + nft list table inet ${NAME} 2>/dev/null || echo "没有NFTables规则" + else + echo "NFTables不可用" + fi + + # 显示流量统计 + echo "### 流量统计 ###" + echo "下载流量:" + tc -s class show dev $dev 2>/dev/null | grep "Sent" | head -5 + echo "上传流量:" + tc -s class show dev ${dev}_ifb 2>/dev/null | grep "Sent" | head -5 ;; + esac \ No newline at end of file diff --git a/luci-app-nft-timecontrol/Makefile b/luci-app-nft-timecontrol/Makefile index 73216caac..cf0db5199 100644 --- a/luci-app-nft-timecontrol/Makefile +++ b/luci-app-nft-timecontrol/Makefile @@ -18,7 +18,7 @@ LUCI_DEPENDS:=+bc +nftables +bash LUCI_PKGARCH:=all PKG_VERSION:=3.1.5 -PKG_RELEASE:=20251127 +PKG_RELEASE:=20251129 PKG_MAINTAINER:=sirpdboy define Build/Compile diff --git a/luci-app-nft-timecontrol/root/usr/bin/timecontrol b/luci-app-nft-timecontrol/root/usr/bin/timecontrol index e2a8f3009..02ec7dedb 100644 --- a/luci-app-nft-timecontrol/root/usr/bin/timecontrol +++ b/luci-app-nft-timecontrol/root/usr/bin/timecontrol @@ -119,25 +119,16 @@ nft_set_exists() { nft list sets | grep -q "$table $set" } -nft_chain_exists() { - local table=$1 - local chain=$2 - nft list chain "$table" filter "$chain" 2>/dev/null >/dev/null -} - stop_timecontrol() { if [ -n "$nftables_ver" ]; then for chain in "ip" "bridge" "ip6"; do if nft_table_exists "$chain filter"; then - if nft_chain_exists "$chain" filter "$CHAIN"; then - nft flush chain "$chain" filter "$CHAIN" - fi - if nft_chain_exists "$chain" filter "forward_$CHAIN"; then - nft flush chain "$chain" filter "forward_$CHAIN" - fi - if nft_set_exists "$chain filter" "${list_name}_list"; then - nft delete set "$chain" filter "${list_name}_list" + nft flush chain "$chain" filter input + nft flush chain "$chain" filter forward + if nft_set_exists "$chain filter" "${list_type}_list"; then + nft delete set "$chain" filter "${list_type}_list" fi + nft delete table "$chain" filter fi done dbg "All nftables rules have been cleared." @@ -176,16 +167,16 @@ init_timecontrol() { nft add table "$chain" filter fi - if ! nft_set_exists "$chain filter" "${list_name}_list"; then - nft add set "$chain" filter "${list_name}_list" "{ type $addr_type; flags interval; }" + if ! nft_set_exists "$chain filter" "${list_type}_list"; then + nft add set "$chain" filter "${list_type}_list" "{ type $addr_type; }" fi - if ! nft_chain_exists "$chain" filter "$CHAIN"; then - nft add chain "$chain" filter "$CHAIN" "{ type filter hook input priority -100; }" + if ! nft list chain "$chain" filter input 2>/dev/null; then + nft add chain "$chain" filter input "{ type filter hook input priority -100; }" fi - if ! nft_chain_exists "$chain" filter "forward_$CHAIN"; then - nft add chain "$chain" filter "forward_$CHAIN" "{ type filter hook forward priority -100; }" + if ! nft list chain "$chain" filter forward 2>/dev/null; then + nft add chain "$chain" filter forward "{ type filter hook forward priority -100; }" fi done elif [ -n "$iptables_ver" ]; then @@ -235,24 +226,12 @@ timeadd() { esac if [ -n "$nftables_ver" ]; then - nft add element "$table" filter "${list_name}_list" "{ $target }" - - if [ "$list_name" = "blacklist" ]; then - nft flush chain "$table" filter "$CHAIN" - nft flush chain "$table" filter "forward_$CHAIN" - nft add rule "$table" filter "$CHAIN" "$saddr" @"${list_name}_list" drop - nft add rule "$table" filter "forward_$CHAIN" "$saddr" @"${list_name}_list" drop - - elif [ "$list_name" = "whitelist" ]; then - nft flush chain "$table" filter "$CHAIN" - nft flush chain "$table" filter "forward_$CHAIN" - nft add rule "$table" filter "$CHAIN" "$saddr" @"${list_name}_list" accept - nft add rule "$table" filter "$CHAIN" "$saddr" drop - nft add rule "$table" filter "forward_$CHAIN" "$saddr" @"${list_name}_list" accept - nft add rule "$table" filter "forward_$CHAIN" "$saddr" drop - fi - - dbg "Added $target to $list_name in table $table" + nft add element "$table" filter "${list_type}_list" "{ $target }" + nft add rule "$table" filter input "$daddr" @"${list_type}_list" drop 2>/dev/null + nft add rule "$table" filter input "$saddr" @"${list_type}_list" drop 2>/dev/null + nft add rule "$table" filter forward "$daddr" @"${list_type}_list" drop 2>/dev/null + nft add rule "$table" filter forward "$saddr" @"${list_type}_list" drop 2>/dev/null + dbg "Added $target to $list_type in table $table" else if ! ipset test "$ipset_name" "$target" 2>/dev/null; then @@ -280,8 +259,11 @@ timedel() { esac if [ -n "$nftables_ver" ]; then - nft delete element "$table" filter "${list_name}_list" "{ $target }" - dbg "Removed $target from $list_name in table $table" + nft delete element "$table" filter "${list_type}_list" "{ $target }" + nft delete rule "$table" filter input "$daddr" @"${list_type}_list" 2>/dev/null + nft delete rule "$table" filter input "$saddr" @"${list_type}_list" 2>/dev/null + nft delete rule "$table" filter forward "$daddr" @"${list_type}_list" 2>/dev/null + nft delete rule "$table" filter forward "$saddr" @"${list_type}_list" 2>/dev/null else ipset del "$ipset_name" "$target" 2>/dev/null dbg "Removed $target from ipset $ipset_name"