#!/bin/sh
# 内核性能优化验证脚本

echo "========================================="
echo "  iKuai内核性能优化验证"
echo "========================================="
echo ""

PASS=0
FAIL=0

check() {
    desc="$1"
    expect="$2"
    actual="$3"
    if echo "$actual" | grep -q "$expect"; then
        echo "[PASS] $desc"
        PASS=$((PASS+1))
    else
        echo "[FAIL] $desc (期望: $expect, 实际: $actual)"
        FAIL=$((FAIL+1))
    fi
}

echo "--- 1. HZ=1000 ---"
HZ=$(grep -E "^CONFIG_HZ=" /proc/config.gz 2>/dev/null | zcat 2>/dev/null || cat /sys/module/ */parameters 2>/dev/null)
# 用getconf
HZ=$(getconf CLK_TCK 2>/dev/null)
check "HZ=1000" "1000" "$HZ"

echo ""
echo "--- 2. PREEMPT模型 ---"
PREEMPT=$(uname -v 2>/dev/null)
check "PREEMPT_VOLUNTARY" "voluntary" "$(echo $PREEMPT | tr '[:upper:]' '[:lower:]')"
# 补充检查
cat /proc/version 2>/dev/null
grep -i preempt /proc/version 2>/dev/null

echo ""
echo "--- 3. TCP拥塞控制 ---"
CC=$(cat /proc/sys/net/ipv4/tcp_congestion_control 2>/dev/null)
check "BBR" "bbr" "$CC"
echo "可用算法: $(cat /proc/sys/net/ipv4/tcp_available_congestion_control 2>/dev/null)"

echo ""
echo "--- 4. CAKE qdisc ---"
CAKE=$(ls /lib/modules/$(uname -r)/kernel/net/sched/sch_cake.ko* 2>/dev/null || echo "not found")
# 如果是built-in检查
CAKE2=$(zcat /proc/config.gz 2>/dev/null | grep "CONFIG_NET_SCH_CAKE")
if [ -n "$CAKE2" ]; then
    check "CAKE编译" "=y" "$CAKE2"
else
    check "CAKE模块存在" "sch_cake" "$CAKE"
fi
# 看当前qdisc
echo "当前根qdisc:"
tc qdisc show dev eth0 2>/dev/null || tc qdisc show 2>/dev/null | head -5

echo ""
echo "--- 5. eBPF/BTF ---"
BTF=$(ls /sys/kernel/btf/vmlinux 2>/dev/null && echo "exists")
check "BTF" "exists" "$BTF"
BPF=$(cat /proc/sys/kernel/unprivileged_bpf_disabled 2>/dev/null)
echo "BPF syscalls: $(zcat /proc/config.gz 2>/dev/null | grep CONFIG_BPF_SYSCALL=y || echo 'check /proc/config.gz')"

echo ""
echo "--- 6. FTRACE ---"
FTRACE=$(cat /proc/sys/kernel/ftrace_enabled 2>/dev/null)
check "FTRACE可用" "1\|0" "$FTRACE"
echo "FTRACE默认关闭(0)，需要时echo 1 > /proc/sys/kernel/ftrace_enabled"
ls /sys/kernel/debug/tracing/events/ 2>/dev/null | head -5 && echo "tracing events可用"

echo ""
echo "--- 7. sysctl参数 ---"
BUDGET=$(cat /proc/sys/net/core/netdev_budget 2>/dev/null)
check "netdev_budget=3000" "3000" "$BUDGET"

BACKLOG=$(cat /proc/sys/net/core/netdev_max_backlog 2>/dev/null)
check "netdev_max_backlog=16384" "16384" "$BACKLOG"

GRO=$(cat /proc/sys/net/core/gro_normal_batch 2>/dev/null)
check "gro_normal_batch=64" "64" "$GRO"

RMEM=$(cat /proc/sys/net/core/rmem_max 2>/dev/null)
check "rmem_max=16777216" "16777216" "$RMEM"

WMEM=$(cat /proc/sys/net/core/wmem_max 2>/dev/null)
check "wmem_max=16777216" "16777216" "$WMEM"

CTMAX=$(cat /proc/sys/net/netfilter/nf_conntrack_max 2>/dev/null)
check "nf_conntrack_max=262144" "262144" "$CTMAX"

CTBUCKETS=$(cat /proc/sys/net/netfilter/nf_conntrack_buckets 2>/dev/null)
check "nf_conntrack_buckets=65536" "65536" "$CTBUCKETS"

HELPER=$(cat /proc/sys/net/netfilter/nf_conntrack_helper 2>/dev/null)
check "nf_conntrack_helper=0" "0" "$HELPER"

ECN=$(cat /proc/sys/net/ipv4/tcp_ecn 2>/dev/null)
check "tcp_ecn=1" "1" "$ECN"

echo ""
echo "--- 8. conntrack使用率 ---"
CTCOUNT=$(cat /proc/sys/net/netfilter/nf_conntrack_count 2>/dev/null)
echo "当前连接数: $CTCOUNT / $CTMAX ($(echo "scale=1; $CTCOUNT*100/$CTMAX" | bc 2>/dev/null || echo "N/A")%)"

echo ""
echo "--- 9. 软加速+QoS ---"
# 看FASTOFFLOAD链是否存在
FO=$(iptables -t mangle -L FASTOFFLOAD 2>/dev/null | head -3)
if [ -n "$FO" ]; then
    echo "[PASS] FASTOFFLOAD链存在"
    PASS=$((PASS+1))
    echo "$FO"
    # 看RETURN规则
    EMARK=$(iptables -t mangle -L FASTOFFLOAD 2>/dev/null | grep -c "emark")
    if [ "$EMARK" -gt 0 ]; then
        echo "[PASS] EMARK RETURN规则存在"
        PASS=$((PASS+1))
    else
        echo "[FAIL] EMARK RETURN规则不存在"
        FAIL=$((FAIL+1))
    fi
else
    echo "[SKIP] FASTOFFLOAD链不存在（软加速未开启）"
fi

echo ""
echo "--- 10. 网卡offload ---"
echo "eth0 offload:"
ethtool -k eth0 2>/dev/null | grep -E "generic-receive-offload|generic-segmentation|tcp-segmentation" | head -5

echo ""
echo "========================================="
echo "  结果: $PASS PASS, $FAIL FAIL"
echo "========================================="
