182 lines
4.5 KiB
Markdown
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 |