Implement iptables forward manager core

This commit is contained in:
2026-04-17 09:36:40 +08:00
parent d1a5392476
commit 28960eee03
20 changed files with 2047 additions and 0 deletions

76
tests/test_rules_unit.sh Normal file
View File

@@ -0,0 +1,76 @@
#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
# shellcheck source=tests/lib/assert.sh
source "${ROOT_DIR}/tests/lib/assert.sh"
status_of() {
set +e
"$@" >/dev/null 2>&1
local rc=$?
set -e
printf '%s\n' "${rc}"
}
TMP_DIR=$(mktemp -d)
trap 'rm -rf "${TMP_DIR}"' EXIT
export IPF_STORAGE_DIR="${TMP_DIR}/storage"
export IPF_STORAGE_DB="${IPF_STORAGE_DIR}/rules.db"
export IPF_LOCK_FILE="${IPF_STORAGE_DIR}/.lock"
export IPTABLES_MOCK_DIR="${TMP_DIR}/iptables-mock"
export IPTABLES_MOCK_LOG="${TMP_DIR}/iptables.log"
export IPTABLES_BIN="${ROOT_DIR}/tests/mocks/iptables"
export IP6TABLES_BIN="${ROOT_DIR}/tests/mocks/ip6tables"
export IPTABLES_SAVE_BIN="${ROOT_DIR}/tests/mocks/iptables-save"
export IP6TABLES_SAVE_BIN="${ROOT_DIR}/tests/mocks/ip6tables-save"
export NETFILTER_PERSISTENT_BIN="${ROOT_DIR}/tests/mocks/persist-mock.sh"
export PERSIST_MOCK_LOG="${TMP_DIR}/persist.log"
# shellcheck source=lib/common.sh
source "${ROOT_DIR}/lib/common.sh"
# shellcheck source=lib/storage.sh
source "${ROOT_DIR}/lib/storage.sh"
# shellcheck source=lib/persist.sh
source "${ROOT_DIR}/lib/persist.sh"
# shellcheck source=lib/iptables_ops.sh
source "${ROOT_DIR}/lib/iptables_ops.sh"
# shellcheck source=lib/rules_mgr.sh
source "${ROOT_DIR}/lib/rules_mgr.sh"
reset_mock_state() {
rm -rf "${IPTABLES_MOCK_DIR}" "${IPF_STORAGE_DIR}"
mkdir -p "${IPTABLES_MOCK_DIR}" "${IPF_STORAGE_DIR}"
: >"${IPTABLES_MOCK_LOG}"
: >"${PERSIST_MOCK_LOG}"
unset IPTABLES_MOCK_FAIL_ON_N || true
storage_init
}
reset_mock_state
uuid_v4=$(cmd_add_batch tcp 8080 127.0.0.1 80 4 'web service')
assert_eq '1' "$(storage_count)" 'cmd_add_batch should persist one rule'
assert_eq '3' "$(grep -Ec '^iptables ' "${IPTABLES_MOCK_LOG}")" 'tcp/ipv4 add should emit three iptables commands'
assert_contains "$(storage_get "${uuid_v4}")" "uuid=${uuid_v4}" 'stored line should contain generated uuid'
assert_eq '1' "$(grep -Ec 'persist-mock\.sh save' "${PERSIST_MOCK_LOG}")" 'successful add should trigger persist_save'
assert_contains "$(ipt_find_by_uuid "${uuid_v4}")" "MGMT:${uuid_v4}" 'ipt_find_by_uuid should locate saved mock rules'
reset_mock_state
uuid_both=$(cmd_add_batch both 5353 '127.0.0.1,::1' 53 both 'dual stack dns')
add_count=$(grep -Ec '^(iptables|ip6tables) ' "${IPTABLES_MOCK_LOG}")
assert_eq '12' "${add_count}" 'both/both add should emit twelve commands'
cmd_delete_uuid "${uuid_both}"
del_count=$(grep -Ec ' -D ' "${IPTABLES_MOCK_LOG}")
assert_eq '12' "${del_count}" 'deleting both/both rule should emit twelve delete commands'
assert_eq '0' "$(storage_count)" 'cmd_delete_uuid should remove rule from storage'
reset_mock_state
export IPTABLES_MOCK_FAIL_ON_N=2
assert_eq '1' "$(status_of cmd_add_batch tcp 9000 127.0.0.1 90 4 'rollback')" 'cmd_add_batch should fail when iptables mock injects an error'
assert_eq '0' "$(storage_count)" 'failed add should not persist storage'
assert_contains "$(cat "${IPTABLES_MOCK_LOG}")" ' -D ' 'failed add should trigger rollback deletes'
assert_eq '0' "$(wc -l < "${PERSIST_MOCK_LOG}")" 'failed add before persistence should not call persist_save'
pass 'test_rules_unit.sh'