Files
route-switcher/README.md
Michal Humpula 7d0392b703 cleanup docs
2026-03-01 07:40:32 +01:00

182 lines
4.5 KiB
Markdown

# 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
```
## API (Optional)
The route-switcher includes an optional HTTP REST API for monitoring and control.
### Configuration
```bash
# 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
```json
{
"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 runtime
- `pnet` - Packet networking
- `netlink-sys` - Netlink kernel communication
- `anyhow` - Error handling
- `log` + `env_logger` - Logging
- `clap` - Command line parsing
## License
GPLv