Files
NeoTachyon/tests/route_router_traffic.sh

138 lines
4.8 KiB
Bash

#!/usr/bin/env bash
set -eo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TACHYON_LIB="$ROOT_DIR/tachyon/files/usr/lib"
NFT_RUNTIME="$ROOT_DIR/tachyon/files/usr/lib/nft/apply.uc"
WORK_DIR="$(mktemp -d)"
NFT_LOG="$WORK_DIR/nft.log"
LOGGER_LOG="$WORK_DIR/logger.log"
export NFT_LOG LOGGER_LOG WORK_DIR
cleanup() {
rm -rf "$WORK_DIR"
}
trap cleanup EXIT
fail() {
printf 'FAIL: %s\n' "$1" >&2
printf 'nft log:\n' >&2
cat "$NFT_LOG" >&2 2>/dev/null || true
exit 1
}
assert_contains() {
local file="$1"
local expected="$2"
local label="$3"
grep -Fq "$expected" "$file" || fail "$label: expected '$expected'"
}
mkdir -p "$WORK_DIR/bin"
cat >"$WORK_DIR/bin/nft" <<NFT
#!/usr/bin/env bash
set -eo pipefail
{
printf 'nft'
for arg in "\$@"; do
printf '\t%s' "\$arg"
done
printf '\n'
} >> "\${NFT_LOG:?}"
if [ "\$#" -ge 5 ] && [ "\$1" = "flush" ] && [ "\$2" = "chain" ]; then
if [ ! -f "$WORK_DIR/chain_exists" ]; then
exit 1
fi
fi
if [ "\$#" -ge 5 ] && [ "\$1" = "add" ] && [ "\$2" = "chain" ]; then
touch "$WORK_DIR/chain_exists"
fi
if [ "\$#" -ge 5 ] && [ "\$1" = "delete" ] && [ "\$2" = "chain" ]; then
rm -f "$WORK_DIR/chain_exists"
fi
NFT
chmod 0755 "$WORK_DIR/bin/nft"
cat >"$WORK_DIR/bin/logger" <<'LOGGER'
#!/usr/bin/env bash
set -eo pipefail
printf 'logger\t%s\n' "$*" >> "${LOGGER_LOG:?}"
LOGGER
chmod 0755 "$WORK_DIR/bin/logger"
export PATH="$WORK_DIR/bin:$PATH"
nft_ucode() {
ucode -S -L "$TACHYON_LIB" "$NFT_RUNTIME" "$@"
}
# Test 1: Direct enable call
: > "$NFT_LOG"
rm -f "$WORK_DIR/chain_exists"
nft_ucode nft-enable-router-output-intercept TachyonTable localv4 0x00100000 1
assert_contains "$NFT_LOG" $'nft\tadd\tchain\tinet\tTachyonTable\toutput_redirect\t{ type nat hook output priority -100; policy accept; }' "enable: creates chain output_redirect"
assert_contains "$NFT_LOG" $'nft\tadd\trule\tinet\tTachyonTable\toutput_redirect\tct\tstatus\tdnat\treturn' "enable: ct status dnat return"
assert_contains "$NFT_LOG" $'nft\tadd\trule\tinet\tTachyonTable\toutput_redirect\tip\tdaddr\t@localv4\treturn' "enable: localv4 bypass"
assert_contains "$NFT_LOG" $'nft\tadd\trule\tinet\tTachyonTable\toutput_redirect\ttcp\tdport\t53\treturn' "enable: port 53 bypass"
assert_contains "$NFT_LOG" $'nft\tadd\trule\tinet\tTachyonTable\toutput_redirect\tudp\tdport\t123\treturn' "enable: exclude_ntp bypass"
assert_contains "$NFT_LOG" $'nft\tadd\trule\tinet\tTachyonTable\toutput_redirect\tmeta\tmark\t0x00100000\treturn' "enable: outbound_mark bypass"
assert_contains "$NFT_LOG" $'nft\tadd\trule\tinet\tTachyonTable\toutput_redirect\tmeta\tl4proto\ttcp\tcounter\tredirect\tto\t:1604' "enable: tcp redirect to 1604"
# Test 2: Direct disable call
: > "$NFT_LOG"
nft_ucode nft-disable-router-output-intercept TachyonTable
assert_contains "$NFT_LOG" $'nft\tdelete\tchain\tinet\tTachyonTable\toutput_redirect' "disable: deletes chain output_redirect"
# Test 3: Sync from UCI - when enabled
STATE_ENABLED="$WORK_DIR/enabled.state"
cat >"$STATE_ENABLED" <<'STATE'
tachyon.settings=settings
tachyon.settings.route_router_traffic=1
tachyon.settings.route_router_traffic_section=proxy_sec
tachyon.settings.exclude_ntp=1
tachyon.proxy_sec=section
tachyon.proxy_sec.enabled=1
tachyon.proxy_sec.routing_mode=proxy
tachyon.proxy_sec.mark=354
tachyon.proxy_sec.tproxy_port=10080
STATE
: > "$NFT_LOG"
rm -f "$WORK_DIR/chain_exists"
TACHYON_UCI_STATE_FILE="$STATE_ENABLED" nft_ucode nft-sync-router-output-intercept TachyonTable localv4 0x00100000
assert_contains "$NFT_LOG" $'nft\tadd\tchain\tinet\tTachyonTable\toutput_redirect\t{ type nat hook output priority -100; policy accept; }' "sync(enabled): creates chain"
assert_contains "$NFT_LOG" $'nft\tadd\trule\tinet\tTachyonTable\toutput_redirect\tmeta\tl4proto\ttcp\tcounter\tredirect\tto\t:1604' "sync(enabled): redirects to port"
# Test 4: Sync from UCI - when disabled
STATE_DISABLED="$WORK_DIR/disabled.state"
cat >"$STATE_DISABLED" <<'STATE'
tachyon.settings=settings
tachyon.settings.route_router_traffic=0
tachyon.settings.route_router_traffic_section=proxy_sec
tachyon.proxy_sec=section
tachyon.proxy_sec.enabled=1
tachyon.proxy_sec.routing_mode=proxy
tachyon.proxy_sec.mark=354
STATE
: > "$NFT_LOG"
TACHYON_UCI_STATE_FILE="$STATE_DISABLED" nft_ucode nft-sync-router-output-intercept TachyonTable localv4 0x00100000
assert_contains "$NFT_LOG" $'nft\tdelete\tchain\tinet\tTachyonTable\toutput_redirect' "sync(disabled): deletes chain"
# Test 5: Verify UCI setting loads route_router_traffic
CHECK_SETTINGS=$(TACHYON_UCI_STATE_FILE="$STATE_DISABLED" ucode -S -L "$TACHYON_LIB" -e '
let uci = require("core.uci");
let val = uci.get("tachyon.settings.route_router_traffic");
print("val=" + val);
')
if [ "$CHECK_SETTINGS" != "val=0" ]; then
fail "UCI route_router_traffic expected val=0, got '$CHECK_SETTINGS'"
fi
printf 'ALL TESTS PASSED for route_router_traffic\n'