# Route-Switcher A Linux-based network failover system written in Rust that automatically switches routing between dual network interfaces based on connectivity monitoring. ## Overview Route-Switcher monitors connectivity to specified IP addresses via multiple network interfaces and automatically manages routing tables to ensure network redundancy. When the primary interface fails, it seamlessly switches to a secondary interface, and automatically fails back when the primary connection is restored. ## Architecture Route-Switcher consists of three main components: 1. **Async Pingers** (`src/pinger.rs`) - ICMP monitoring with explicit interface binding 2. **Route Manager** (`src/routing.rs`) - Netlink-based route manipulation 3. **State Machine** (`src/main.rs`) - Failover logic with anti-flapping protection ### State Machine ``` Boot → Primary: After 10 seconds of sampling Primary → Fallback: After 3 consecutive failures AND secondary is healthy Fallback → Primary: After 60 seconds of stable primary connectivity ``` ### Route Management Strategy - **Primary route**: metric 10 (default priority) - **Secondary route**: metric 20 (lower priority) - **Failover route**: metric 5 (highest priority, added only during failover) The system maintains both base routes continuously and adds/removes the failover route as needed. ## Key Features - **Dual Interface Monitoring**: Simultaneous ping testing via both network interfaces - **Automatic Failover**: Switches to secondary interface after 3 consecutive ping failures - **Smart Failback**: Returns to primary interface after 1 minute of stable connectivity - **Anti-Flapping**: Prevents frequent switching between interfaces - **Edge Case Handling**: Won't switch if secondary interface is also down - **Netlink Integration**: Direct kernel communication for route management - **Async Architecture**: Non-blocking monitoring and management ## Requirements - Linux operating system - Rust 2024 edition - Two network interfaces with internet connectivity - Root privileges for route manipulation - Netlink kernel support ## Configuration ### Network Setup Example ```bash # Primary interface eth0: 192.168.1.10/24, gateway 192.168.1.1 # Secondary interface eth1: 192.168.2.10/24, gateway 192.168.2.1 ``` ### Application Configuration The application is configured through command-line arguments: ```bash sudo cargo run -- \ --primary-interface eth0 \ --secondary-interface eth1 \ --primary-gateway 192.168.1.1 \ --secondary-gateway 192.168.2.1 \ --ping-target 8.8.8.8 ``` ## Usage ### Basic Usage ```bash # Run with default settings sudo cargo run # Run with custom configuration sudo cargo run -- \ --primary-interface eth0 \ --secondary-interface eth1 \ --primary-gateway 192.168.1.1 \ --secondary-gateway 192.168.2.1 ``` ### Development ```bash # Build cargo build # Run tests cargo test # Run with debug logging RUST_LOG=debug sudo cargo run # Run with custom log level RUST_LOG=info sudo cargo run ``` ## Testing ### Quick Test ```bash # Start test environment podman-compose up -d # Run automated failover test ./scripts/test-failover.sh # View logs podman-compose logs -f route-switcher # Stop environment podman-compose down ``` ### Manual Testing ```bash # Test primary connectivity podman-compose exec route-switcher ping -c 3 -I eth0 192.168.202.100 # Test secondary connectivity podman-compose exec route-switcher ping -c 3 -I eth1 192.168.202.100 # Simulate primary router failure podman-compose exec primary-router ip link set eth0 down # Check routing table podman-compose exec route-switcher ip route show ``` ## Dependencies - `tokio` - Async runtime - `pnet` - Packet networking - `netlink-sys` - Netlink kernel communication - `anyhow` - Error handling - `log` + `env_logger` - Logging - `clap` - Command line parsing ## License GPLv3