Archived
Public Access
Make qdisc modes apply to active interfaces
This commit is contained in:
@@ -159,6 +159,8 @@ modinfo tcp_bbr 2>/dev/null | grep '^version:'
|
||||
/etc/sysctl.d/99-joeyblog.conf
|
||||
```
|
||||
|
||||
脚本不仅会写入 `net.core.default_qdisc`,还会尝试把当前默认路由出口网卡的 root qdisc 立即替换为所选算法,避免只对新建队列生效、当前网卡实际仍保持旧队列。
|
||||
|
||||
对于需要模块加载的队列算法,脚本会尝试加载对应 `sch_*` 模块,并在需要时写入:
|
||||
|
||||
```text
|
||||
|
||||
+109
-21
@@ -509,28 +509,123 @@ clear_network_optimizations() {
|
||||
load_qdisc_module() {
|
||||
local qdisc_name="$1"
|
||||
local module_name="sch_$qdisc_name"
|
||||
local previous_qdisc
|
||||
local applied_qdisc
|
||||
|
||||
previous_qdisc=$(sysctl -n net.core.default_qdisc 2>/dev/null || true)
|
||||
|
||||
if ! lsmod | grep -q "^${module_name//-/_}"; then
|
||||
sudo modprobe "$module_name" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
# 检查队列算法是否已可用(通过尝试读取当前可用的 qdisc)
|
||||
# 如果 sysctl 能成功设置,说明模块已存在
|
||||
if sudo sysctl -w net.core.default_qdisc="$qdisc_name" > /dev/null 2>&1; then
|
||||
# 恢复原设置
|
||||
sudo sysctl -w net.core.default_qdisc="$CURRENT_QDISC" > /dev/null 2>&1
|
||||
applied_qdisc=$(sysctl -n net.core.default_qdisc 2>/dev/null || true)
|
||||
if [[ -n "$previous_qdisc" ]]; then
|
||||
sudo sysctl -w net.core.default_qdisc="$previous_qdisc" > /dev/null 2>&1 || true
|
||||
fi
|
||||
if [[ "$applied_qdisc" == "$qdisc_name" ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 检查模块是否已加载
|
||||
if lsmod | grep -q "^${module_name//-/_}"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# 模块不存在,尝试加载
|
||||
echo -e "\033[36m正在加载内核模块 $module_name...\033[0m"
|
||||
if sudo modprobe "$module_name" 2>/dev/null; then
|
||||
echo -e "\033[1;32m✔ 模块 $module_name 加载成功\033[0m"
|
||||
if sudo sysctl -w net.core.default_qdisc="$qdisc_name" > /dev/null 2>&1; then
|
||||
applied_qdisc=$(sysctl -n net.core.default_qdisc 2>/dev/null || true)
|
||||
if [[ -n "$previous_qdisc" ]]; then
|
||||
sudo sysctl -w net.core.default_qdisc="$previous_qdisc" > /dev/null 2>&1 || true
|
||||
fi
|
||||
if [[ "$applied_qdisc" == "$qdisc_name" ]]; then
|
||||
echo -e "\033[1;32m✔ 队列算法 $qdisc_name 可用\033[0m"
|
||||
return 0
|
||||
else
|
||||
echo -e "\033[33m⚠ 模块 $module_name 加载失败,可能内核不支持\033[0m"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
echo -e "\033[33m⚠ 队列算法 $qdisc_name 不可用,可能当前内核缺少 $module_name\033[0m"
|
||||
return 1
|
||||
}
|
||||
|
||||
# 函数:确保可以操作当前网卡队列
|
||||
ensure_iproute2_tools() {
|
||||
if command -v ip > /dev/null 2>&1 && command -v tc > /dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e "\033[36m正在安装 iproute2,用于立即切换当前网卡队列算法...\033[0m"
|
||||
sudo apt-get update > /dev/null 2>&1 || true
|
||||
if sudo apt-get install -y iproute2 > /dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e "\033[33m⚠ iproute2 安装失败,当前网卡队列无法立即替换;仍会写入 default_qdisc。\033[0m"
|
||||
return 1
|
||||
}
|
||||
|
||||
# 函数:获取默认路由出口网卡
|
||||
get_default_route_interfaces() {
|
||||
{
|
||||
ip -o route show default 2>/dev/null || true
|
||||
ip -o -6 route show default 2>/dev/null || true
|
||||
} | awk '{for (i = 1; i <= NF; i++) if ($i == "dev") print $(i + 1)}' | sort -u
|
||||
}
|
||||
|
||||
# 函数:让当前默认出口网卡立即切换队列算法
|
||||
apply_qdisc_to_active_interfaces() {
|
||||
local qdisc_name="$1"
|
||||
local interfaces=()
|
||||
local iface
|
||||
local applied=0
|
||||
local failed=0
|
||||
|
||||
if ! ensure_iproute2_tools; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
while IFS= read -r iface; do
|
||||
[[ -n "$iface" ]] && interfaces+=("$iface")
|
||||
done < <(get_default_route_interfaces)
|
||||
|
||||
if [[ ${#interfaces[@]} -eq 0 ]]; then
|
||||
echo -e "\033[33m⚠ 未找到默认路由出口网卡,已仅设置 default_qdisc。\033[0m"
|
||||
return 0
|
||||
fi
|
||||
|
||||
for iface in "${interfaces[@]}"; do
|
||||
if sudo tc qdisc replace dev "$iface" root "$qdisc_name" 2>/dev/null; then
|
||||
echo -e "\033[1;32m✔ 当前网卡 $iface 已切换为 $qdisc_name\033[0m"
|
||||
applied=1
|
||||
else
|
||||
echo -e "\033[33m⚠ 当前网卡 $iface 切换 $qdisc_name 失败\033[0m"
|
||||
failed=1
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ "$applied" -eq 1 ]]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
[[ "$failed" -eq 1 ]] && return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# 函数:根据队列算法是否为模块,决定是否写入开机加载
|
||||
persist_qdisc_module() {
|
||||
local qdisc_name="$1"
|
||||
local module_name="sch_$qdisc_name"
|
||||
|
||||
if [[ "$qdisc_name" == "fq" ]]; then
|
||||
sudo rm -f "$MODULES_CONF"
|
||||
echo -e "\033[1;32m(☆^ー^☆) 更改已永久保存啦~\033[0m"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if modinfo "$module_name" > /dev/null 2>&1 || lsmod | grep -q "^${module_name//-/_}"; then
|
||||
echo "$module_name" | sudo tee "$MODULES_CONF" > /dev/null
|
||||
echo -e "\033[1;32m(☆^ー^☆) 更改已永久保存,模块 $module_name 将在开机时自动加载~\033[0m"
|
||||
else
|
||||
sudo rm -f "$MODULES_CONF"
|
||||
echo -e "\033[1;32m(☆^ー^☆) 更改已永久保存;$qdisc_name 可能为内置队列,无需写入模块加载配置~\033[0m"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -619,6 +714,7 @@ ask_to_save() {
|
||||
echo -e "\033[36m正在应用配置...\033[0m"
|
||||
sudo sysctl -w net.core.default_qdisc="$QDISC" > /dev/null 2>&1
|
||||
sudo sysctl -w net.ipv4.tcp_congestion_control="$ALGO" > /dev/null 2>&1
|
||||
apply_qdisc_to_active_interfaces "$QDISC" || return 1
|
||||
|
||||
# 验证是否生效
|
||||
NEW_QDISC=$(sysctl -n net.core.default_qdisc 2>/dev/null)
|
||||
@@ -644,15 +740,7 @@ ask_to_save() {
|
||||
echo "net.ipv4.tcp_congestion_control=$ALGO" | sudo tee -a "$SYSCTL_CONF" > /dev/null
|
||||
sudo sysctl --system > /dev/null 2>&1
|
||||
|
||||
# 配置模块开机自动加载(fq 和 fq_codel 是内置的不需要)
|
||||
if [[ "$QDISC" == "fq" || "$QDISC" == "fq_codel" ]]; then
|
||||
# fq 和 fq_codel 是内核内置的,删除旧的模块配置文件
|
||||
sudo rm -f "$MODULES_CONF"
|
||||
echo -e "\033[1;32m(☆^ー^☆) 更改已永久保存啦~\033[0m"
|
||||
else
|
||||
echo "sch_$QDISC" | sudo tee "$MODULES_CONF" > /dev/null
|
||||
echo -e "\033[1;32m(☆^ー^☆) 更改已永久保存,模块 sch_$QDISC 将在开机时自动加载~\033[0m"
|
||||
fi
|
||||
persist_qdisc_module "$QDISC"
|
||||
else
|
||||
echo -e "\033[33m(⌒_⌒;) 好吧,没有永久保存,重启后会恢复原设置呢~\033[0m"
|
||||
fi
|
||||
|
||||
@@ -22,6 +22,10 @@ apply_policy_config() {
|
||||
|
||||
scripts/config --enable NET_SCH_DEFAULT
|
||||
scripts/config --enable NET_SCH_FQ
|
||||
scripts/config --module NET_SCH_FQ_CODEL
|
||||
scripts/config --module NET_SCH_PIE
|
||||
scripts/config --module NET_SCH_FQ_PIE
|
||||
scripts/config --module NET_SCH_CAKE
|
||||
scripts/config --disable DEFAULT_FQ_CODEL
|
||||
scripts/config --disable DEFAULT_PFIFO_FAST
|
||||
scripts/config --enable DEFAULT_FQ
|
||||
@@ -89,6 +93,10 @@ validate_config() {
|
||||
require_config_line 'CONFIG_DEFAULT_BBR=y' 'CONFIG_DEFAULT_BBR is not enabled.'
|
||||
require_config_line 'CONFIG_DEFAULT_TCP_CONG="bbr"' 'CONFIG_DEFAULT_TCP_CONG is not bbr.'
|
||||
require_config_line 'CONFIG_NET_SCH_FQ=y' 'CONFIG_NET_SCH_FQ is not built in.'
|
||||
require_config_line 'CONFIG_NET_SCH_FQ_CODEL=m' 'CONFIG_NET_SCH_FQ_CODEL is not module-enabled.'
|
||||
require_config_line 'CONFIG_NET_SCH_PIE=m' 'CONFIG_NET_SCH_PIE is not module-enabled.'
|
||||
require_config_line 'CONFIG_NET_SCH_FQ_PIE=m' 'CONFIG_NET_SCH_FQ_PIE is not module-enabled.'
|
||||
require_config_line 'CONFIG_NET_SCH_CAKE=m' 'CONFIG_NET_SCH_CAKE is not module-enabled.'
|
||||
require_config_line 'CONFIG_NET_SCH_DEFAULT=y' 'CONFIG_NET_SCH_DEFAULT is not enabled.'
|
||||
require_config_line 'CONFIG_DEFAULT_FQ=y' 'CONFIG_DEFAULT_FQ is not enabled.'
|
||||
require_config_line 'CONFIG_DEFAULT_NET_SCH="fq"' 'CONFIG_DEFAULT_NET_SCH is not fq.'
|
||||
@@ -98,7 +106,7 @@ validate_config() {
|
||||
require_config_line 'CONFIG_IP_NF_FILTER=m' 'CONFIG_IP_NF_FILTER is not module-enabled.'
|
||||
require_config_line 'CONFIG_IP_NF_TARGET_MASQUERADE=m' 'CONFIG_IP_NF_TARGET_MASQUERADE is not module-enabled.'
|
||||
|
||||
grep -E 'CONFIG_(DEBUG_INFO_NONE|TCP_CONG_BBR|DEFAULT_BBR|DEFAULT_TCP_CONG|NET_SCH_DEFAULT|NET_SCH_FQ|DEFAULT_FQ|DEFAULT_NET_SCH|NETFILTER_XTABLES_LEGACY|IP_NF_IPTABLES_LEGACY|IP_NF_NAT|IP_NF_FILTER|IP_NF_TARGET_MASQUERADE|IP6_NF_IPTABLES_LEGACY|IP6_NF_NAT|IP6_NF_FILTER)=' .config
|
||||
grep -E 'CONFIG_(DEBUG_INFO_NONE|TCP_CONG_BBR|DEFAULT_BBR|DEFAULT_TCP_CONG|NET_SCH_DEFAULT|NET_SCH_FQ|NET_SCH_FQ_CODEL|NET_SCH_PIE|NET_SCH_FQ_PIE|NET_SCH_CAKE|DEFAULT_FQ|DEFAULT_NET_SCH|NETFILTER_XTABLES_LEGACY|IP_NF_IPTABLES_LEGACY|IP_NF_NAT|IP_NF_FILTER|IP_NF_TARGET_MASQUERADE|IP6_NF_IPTABLES_LEGACY|IP6_NF_NAT|IP6_NF_FILTER)=' .config
|
||||
}
|
||||
|
||||
case "$arch" in
|
||||
|
||||
Reference in New Issue
Block a user