Commit ce15dda0 authored by Vitaly Lipatov's avatar Vitaly Lipatov

router: add BIRD2 config auto-generation from per-list tables

generate_bird_config() creates /etc/bird/route-tables.conf with protocol kernel blocks for each per-list routing table, tagged with BGP community (AS:table_num). Each kernel syncer gets its own BIRD table with a pipe to master4/master6. Uses 'learn' to import routes from external programs. Only runs if birdc is installed. Co-Authored-By: 's avatarClaude Opus 4.6 <noreply@anthropic.com>
parent 4a16d1c8
...@@ -17,6 +17,9 @@ ROUTES6_DIR=routes6.d ...@@ -17,6 +17,9 @@ ROUTES6_DIR=routes6.d
STATE_DIR=.state STATE_DIR=.state
HISTORY_SIZE=10 HISTORY_SIZE=10
BIRD_AS=65000
BIRD_CONF="/etc/bird/route-tables.conf"
FORCE= FORCE=
RESOLVE= RESOLVE=
SHOW= SHOW=
...@@ -661,6 +664,98 @@ cleanup_state() ...@@ -661,6 +664,98 @@ cleanup_state()
done done
} }
# --- Generate BIRD2 config for BGP route distribution ---
# Creates /etc/bird/route-tables.conf with protocol kernel blocks
# for each per-list routing table, tagged with BGP community = table number.
# Only runs if birdc is installed.
generate_bird_config()
{
command -v birdc >/dev/null 2>&1 || return 0
local tmp_conf=$(mktemp)
local seen=""
echo "# Auto-generated by route-update.sh — do not edit" > "$tmp_conf"
# IPv4 tables: each gets own BIRD table + pipe to master4
for state_dir in "$STATE_DIR/$ROUTES_DIR"/*/*/ ; do
[ -d "$state_dir" ] || continue
[ -f "$state_dir/table" ] || continue
local name=$(basename "$state_dir")
# Skip duplicates (same list in multiple groups shares table)
echo "$seen" | grep -q " ${name}4 " && continue
seen="$seen ${name}4 "
local table_num
read -r table_num < "$state_dir/table"
cat >> "$tmp_conf" <<EOF
ipv4 table t_${name}4;
protocol kernel k_${name}4 {
ipv4 { table t_${name}4; import filter { bgp_community.add(($BIRD_AS, $table_num)); accept; }; export none; };
kernel table $table_num;
scan time 30;
learn;
}
protocol pipe p_${name}4 {
table master4;
peer table t_${name}4;
import all;
export none;
}
EOF
done
# IPv6 tables: each gets own BIRD table + pipe to master6
for state_dir in "$STATE_DIR/$ROUTES6_DIR"/*/*/ ; do
[ -d "$state_dir" ] || continue
[ -f "$state_dir/table" ] || continue
local name=$(basename "$state_dir")
echo "$seen" | grep -q " ${name}6 " && continue
seen="$seen ${name}6 "
local table_num
read -r table_num < "$state_dir/table"
cat >> "$tmp_conf" <<EOF
ipv6 table t_${name}6;
protocol kernel k_${name}6 {
ipv6 { table t_${name}6; import filter { bgp_community.add(($BIRD_AS, $table_num)); accept; }; export none; };
kernel table $table_num;
scan time 30;
learn;
}
protocol pipe p_${name}6 {
table master6;
peer table t_${name}6;
import all;
export none;
}
EOF
done
if [ -n "$SHOW" ] ; then
log "Generated BIRD config ($BIRD_CONF):"
cat "$tmp_conf" >&2
rm -f "$tmp_conf"
return 0
fi
# Compare and replace only if changed
if [ -f "$BIRD_CONF" ] && diff -q "$tmp_conf" "$BIRD_CONF" >/dev/null 2>&1 ; then
vlog "BIRD config unchanged"
rm -f "$tmp_conf"
return 0
fi
mv "$tmp_conf" "$BIRD_CONF"
chmod 644 "$BIRD_CONF"
log "BIRD config updated: $BIRD_CONF"
birdc configure >/dev/null 2>&1 && log "BIRD reconfigured" || log "WARNING: birdc configure failed"
}
# --- Main --- # --- Main ---
[ -n "$SHOW" ] && log "Dry-run mode (no changes will be made)" [ -n "$SHOW" ] && log "Dry-run mode (no changes will be made)"
[ -n "$VERBOSE" ] && log "Verbose mode, state_dir=$STATE_DIR" [ -n "$VERBOSE" ] && log "Verbose mode, state_dir=$STATE_DIR"
...@@ -671,5 +766,6 @@ check_extra_dns ...@@ -671,5 +766,6 @@ check_extra_dns
process_routes "$ROUTES_DIR" get_ipv4_list_bulk "ip" "" process_routes "$ROUTES_DIR" get_ipv4_list_bulk "ip" ""
process_routes "$ROUTES6_DIR" get_ipv6_list_bulk "ip -6" " (v6)" process_routes "$ROUTES6_DIR" get_ipv6_list_bulk "ip -6" " (v6)"
cleanup_state cleanup_state
generate_bird_config
[ -n "$SHOW" ] || log "All done" [ -n "$SHOW" ] || log "All done"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment