Michal Humpula e2e68c8e81 simplify env
2026-03-01 08:20:24 +01:00
2026-02-15 17:36:08 +01:00
2026-03-01 07:40:32 +01:00
2026-02-15 17:36:08 +01:00
2026-03-01 08:20:24 +01:00
2026-02-15 17:36:08 +01:00
2026-03-01 07:28:56 +01:00
2026-02-15 17:36:08 +01:00
api
2026-02-16 07:23:36 +01:00
api
2026-02-16 07:23:36 +01:00
api
2026-02-16 07:23:36 +01:00
2026-02-15 17:36:08 +01:00
2026-03-01 07:28:56 +01:00
2026-03-01 07:28:56 +01:00
2026-03-01 07:40:32 +01:00
api
2026-02-16 07:23:36 +01:00

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

# 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 runtime
  • pnet - Packet networking
  • netlink-sys - Netlink kernel communication
  • anyhow - Error handling
  • log + env_logger - Logging
  • clap - Command line parsing

License

GPLv

Description
No description provided
Readme 121 KiB
Languages
Rust 88.7%
Shell 9.7%
Dockerfile 1.1%
Makefile 0.5%