From 069d09339ca5f8930885faf3407bcc25cc9fae37 Mon Sep 17 00:00:00 2001 From: kaffa Date: Sat, 7 Feb 2026 08:44:14 +0900 Subject: [PATCH] Support direct IP/CIDR in whitelist add/del commands Previously whitelist only accepted named presets (cloudflare, aws, etc). Now `xdp-defense whitelist add 8.8.8.8/32` works directly for both IPv4 and IPv6 addresses, writing to the shared pinned BPF map. Co-Authored-By: Claude Opus 4.6 --- bin/xdp-defense | 47 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/bin/xdp-defense b/bin/xdp-defense index 5cd7113..328a65a 100755 --- a/bin/xdp-defense +++ b/bin/xdp-defense @@ -443,13 +443,56 @@ cmd_country_list() { cmd_whitelist_add() { local name=$1 - [ -z "$name" ] && { log_err "Usage: xdp-defense whitelist add "; exit 1; } + [ -z "$name" ] && { log_err "Usage: xdp-defense whitelist add "; exit 1; } + + # Direct IP/CIDR: contains a dot (IPv4) or colon (IPv6) with digits + if [[ "$name" =~ ^[0-9]+\.[0-9]+ ]] || [[ "$name" =~ ^[0-9a-fA-F]*: ]]; then + local map_name key_hex + if [[ "$name" == *":"* ]]; then + map_name="whitelist_v6" + key_hex=$(python3 -c "from ${COMMON_PY} import cidr_to_key_v6; print(cidr_to_key_v6('$name'))" 2>/dev/null) + else + map_name="whitelist_v4" + key_hex=$(python3 -c "from ${COMMON_PY} import cidr_to_key; print(cidr_to_key('$name'))" 2>/dev/null) + fi + [ -z "$key_hex" ] && { log_err "Invalid CIDR: $name"; exit 1; } + + local map_id + map_id=$(get_map_id "$map_name") + [ -z "$map_id" ] && { log_err "$map_name map not found. Is XDP loaded?"; exit 1; } + + bpftool map update id "$map_id" key hex $key_hex value hex 01 00 00 00 00 00 00 00 2>/dev/null + log_ok "Whitelisted: $name" + return + fi + python3 "$LIB_DIR/xdp_whitelist.py" add "$name" } cmd_whitelist_del() { local name=$1 - [ -z "$name" ] && { log_err "Usage: xdp-defense whitelist del "; exit 1; } + [ -z "$name" ] && { log_err "Usage: xdp-defense whitelist del "; exit 1; } + + # Direct IP/CIDR + if [[ "$name" =~ ^[0-9]+\.[0-9]+ ]] || [[ "$name" =~ ^[0-9a-fA-F]*: ]]; then + local map_name key_hex + if [[ "$name" == *":"* ]]; then + map_name="whitelist_v6" + key_hex=$(python3 -c "from ${COMMON_PY} import cidr_to_key_v6; print(cidr_to_key_v6('$name'))" 2>/dev/null) + else + map_name="whitelist_v4" + key_hex=$(python3 -c "from ${COMMON_PY} import cidr_to_key; print(cidr_to_key('$name'))" 2>/dev/null) + fi + [ -z "$key_hex" ] && { log_err "Invalid CIDR: $name"; exit 1; } + + local map_id + map_id=$(get_map_id "$map_name") + [ -z "$map_id" ] && { log_err "$map_name map not found"; exit 1; } + + bpftool map delete id "$map_id" key hex $key_hex 2>/dev/null && log_ok "Removed from whitelist: $name" + return + fi + python3 "$LIB_DIR/xdp_whitelist.py" del "$name" }