3.8 KiB
3.8 KiB
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:
- Async Pingers (
src/pinger.rs) - ICMP monitoring with explicit interface binding - Route Manager (
src/routing.rs) - Netlink-based route manipulation - 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
# 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:
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
# 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
# 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
# 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
# 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 runtimepnet- Packet networkingnetlink-sys- Netlink kernel communicationanyhow- Error handlinglog+env_logger- Loggingclap- Command line parsing
License
GPLv3