4.5 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
API (Optional)
The route-switcher includes an optional HTTP REST API for monitoring and control.
Configuration
# Enable API
API_ENABLED=true
API_USERNAME=admin
API_PASSWORD_HASH=<bcrypt-hash>
API_PORT=8080
Endpoints
- GET /api/state - Returns current state and ping statistics
- POST /api/state - Manually set state (primary/secondary)
Example Response
{
"state": "Primary",
"primary_stats": {
"success_rate": 95.5,
"failures": 2,
"total_pings": 44,
"last_ping": "Ok"
},
"secondary_stats": {
"success_rate": 98.2,
"failures": 1,
"total_pings": 56,
"last_ping": "Ok"
},
"last_failover": "2024-02-15T10:30:00Z"
}
Dependencies
tokio- Async runtimepnet- Packet networkingnetlink-sys- Netlink kernel communicationanyhow- Error handlinglog+env_logger- Loggingclap- Command line parsing
License
GPLv