update 2025-11-29 00:30:54

This commit is contained in:
kenzok8
2025-11-29 00:30:54 +08:00
parent 707976f536
commit 70848822de
10 changed files with 278 additions and 255 deletions

View File

@@ -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

View File

@@ -1,6 +1,6 @@
#
# Copyright (C) 2006-2017 OpenWrt.org
# Copyright (C) 2022-2025 sirpdboy <herboy2008@gmail.com>
# 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 <herboy2008@gmail.com>
define Build/Compile

View File

@@ -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("<a href=\'https://github.com/sirpdboy/luci-app-eqosplus.git' target=\'_blank\'>GitHub @sirpdboy/luci-app-eqosplus </a>")
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")

View File

@@ -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 ""

View File

@@ -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 "可以通过MACIP限制用户上传/下载的网。速度单位为<font color=\"red\"><b> MB/秒 </b></font>。"
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"

View File

@@ -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'

View File

@@ -0,0 +1,5 @@
#!/bin/sh
[ "$ACTION" = "ifup" ] && [ "$INTERFACE" = "wan" ] && {
sleep 5
/etc/init.d/eqosplus restart
}

View File

@@ -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

View File

@@ -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 <herboy2008@gmail.com>
define Build/Compile

View File

@@ -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"