#!/bin/sh
# iptables 兼容包装：让 guest 用**爱快自己的** xtables-legacy-multi 去驱动爱快打过补丁的
# 宿主 netfilter。
#
# 为什么必须用爱快的工具链：爱快给内核 ip_tables 打了补丁（私有 fastid/ccnt/fcnt 列，
# 以及 APPMARK/IKQUEUE/FULLCONENAT 等 target）。**任何 stock iptables 连列一下表都做不到**
# —— 直接 `ERROR: 0 not a valid target` / `Aborted`。所以 guest 只能跑爱快自己的
# xtables-legacy-multi **连同它自己的 libxtables**；宿主把整套收集到 /usr/ikuai/compat。
#
# 两种落地方式，由**宿主 libc** 决定（宿主把结果写在 /usr/ikuai/compat/.hostlibc）：
#
#   musl  宿主（arm64 现役；x64 从 4.0.307/4.0.309 的非-Enterprise 构建起）
#         → 工具链与 guest 同 ABI，**直接原生运行**：省掉 chroot、CAP_SYS_CHROOT，
#           也不必随包再带一份 musl libc —— guest 自带的就是它的运行时。
#
#   uClibc 宿主（x64 4.0.306/4.0.308 以及所有 *_Enterprise_* 构建）
#         → 解释器 /lib/ld64-uClibc.so.0 本机没有，必须在 chroot 里跑，
#           才能让 loader 落在它 PT_INTERP 的硬编码路径上。
#
# ★ 本脚本与各 applet 符号链接是**构建期就烤进镜像**的（见 install-iptables-wrapper.sh），
#   运行期不写 /usr/sbin：userns 里容器 root 是宿主 uid 100000，对 lower 层 root 拥有的
#   /usr/sbin 没有 copy-up 权限（`Permission denied`），运行期现建符号链接会整层失效
#   —— 而症状是「容器一切正常、只是没有防火墙」。实测 M360X(arm64) 如此。
#
# APP 由 argv[0] 决定（多调用二进制按 basename 分派）。
APP=$(basename "$0")
N=/usr/ikuai/native   # 原生模式：compat 树的工作副本（可执行）
R=/usr/ikuai/chroot   # chroot 模式：带 libc 的完整根

# 列规则时要把爱快的私有列（ccnt/fcnt/fastid）与链策略后缀规整掉，
# 否则 LuCI 的 iptparser 会在解析时崩。
normalize() {
  awk '
    /^Chain / { sub(/ bytes[0-9]+ ccnts[0-9]+ fcnts/, " bytes"); print; next }
    /^num[[:space:]]+pkts[[:space:]]+bytes[[:space:]]+ccnt[[:space:]]+fcnt[[:space:]]+fastid[[:space:]]+/ {
      print $1,$2,$3,$7,$8,$9,$10,$11,$12,$13; next }
    /^[[:space:]]*[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+/ {
      printf "%s %s %s %s %s %s %s %s %s %s",$1,$2,$3,$7,$8,$9,$10,$11,$12,$13
      for (i=14;i<=NF;i++) printf " %s",$i; printf "\n"; next }
    /^[[:space:]]*pkts[[:space:]]+bytes[[:space:]]+ccnt[[:space:]]+fcnt[[:space:]]+fastid[[:space:]]+/ {
      print $1,$2,$6,$7,$8,$9,$10,$11,$12; next }
    /^[[:space:]]*[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+[0-9]+[[:space:]]+/ {
      printf "%s %s %s %s %s %s %s %s",$1,$2,$6,$7,$8,$9,$10,$11
      for (i=12;i<=NF;i++) printf " %s",$i; printf "\n"; next }
    { print }
  '
}

is_list=0
for a in "$@"; do
  case "$a" in -L|--list|*L*) is_list=1 ;; esac
done

# ① 原生：musl 宿主。库只指到 compat 树，不污染 guest 的默认搜索路径
#    （guest 自己的程序 —— 例如它自带的 fw3 —— 不该被我们的 libxtables 牵着走）。
if [ -x "$N/usr/sbin/xtables-legacy-multi" ]; then
  LD_LIBRARY_PATH="$N/usr/lib"
  export LD_LIBRARY_PATH
  XTABLES_LIBDIR="$N/usr/lib/iptables"
  export XTABLES_LIBDIR
  if [ "$is_list" = "1" ]; then
    "$N/usr/sbin/$APP" "$@" | normalize
    exit 0
  fi
  exec "$N/usr/sbin/$APP" "$@"
fi

# ② chroot：uClibc 宿主。解释器路径本机没有，只能连 libc 一起 chroot 进去跑。
if [ -x "$R/usr/sbin/xtables-legacy-multi" ]; then
  if [ "$is_list" = "1" ]; then
    chroot "$R" "/usr/sbin/$APP" "$@" | normalize
    exit 0
  fi
  exec chroot "$R" "/usr/sbin/$APP" "$@"
fi

# ③ 兜底：宿主没提供工具链（仅管理口模式等）。这里**没有** stock iptables 可用 ——
#    爱快内核打过补丁，任何 stock iptables 都会 Abort，装了也是白占体积。
#    明确报错，不要静默失败。
echo "iptables: compat toolchain missing (native=$N chroot=$R); host toolchain not collected" >&2
exit 1
