#!/usr/bin/env bash
set -euo pipefail
state=/run/cookbook-routing-lab
[[ $EUID -eq 0 && -f "$state/owned" ]] || { echo 'First run lab.sh connected with sudo.' >&2; exit 1; }
case "${1:-}" in
  show) cat "$state/fault"; exit 0 ;;
  inject)
    [[ ! -e "$state/fault" ]] || { echo 'Restore the previous fault first.' >&2; exit 1; }
    ip netns exec lr-app curl --noproxy '*' -fsS --max-time 3 http://10.20.0.10:8080/health >/dev/null
    kind=$(printf '%s\n' route return forward filter blackhole neighbor mtu | shuf -n 1)
    # Written before mutation so an interrupted injection can still be restored.
    printf '%s\n' "$kind" > "$state/fault"
    case "$kind" in
      route) ip -n lr-app route del 10.20.0.0/24 via 10.10.0.1 ;;
      return) ip -n lr-db route del 10.10.0.0/24 via 10.20.0.1 ;;
      forward) ip netns exec lr-router sysctl -qw net.ipv4.ip_forward=0 ;;
      filter)
        ip netns exec lr-router nft add table inet route_exam
        ip netns exec lr-router nft 'add chain inet route_exam forward { type filter hook forward priority -10; policy accept; }'
        ip netns exec lr-router nft add rule inet route_exam forward tcp dport 8080 counter drop ;;
      blackhole) ip -n lr-app route add blackhole 10.20.0.10/32 ;;
      neighbor) ip -n lr-app neigh replace 10.10.0.1 lladdr 02:de:ad:00:00:01 nud permanent dev eth0 ;;
      mtu)
        ip -n lr-router link set db0 mtu 1280
        ip -n lr-db link set eth0 mtu 1280
        ip netns exec lr-router nft add table ip route_exam
        ip netns exec lr-router nft 'add chain ip route_exam output { type filter hook output priority filter; policy accept; }'
        ip netns exec lr-router nft add rule ip route_exam output icmp type 3 icmp code 4 counter drop
        ip -n lr-app route flush cache ;;
    esac
    echo 'One fault injected. Diagnose HTTP, small ping and large DF ping before using show.' ;;
  restore)
    kind=$(cat "$state/fault")
    case "$kind" in
      route) ip -n lr-app route replace 10.20.0.0/24 via 10.10.0.1 ;;
      return) ip -n lr-db route replace 10.10.0.0/24 via 10.20.0.1 ;;
      forward) ip netns exec lr-router sysctl -qw net.ipv4.ip_forward=1 ;;
      filter) ip netns exec lr-router nft delete table inet route_exam ;;
      blackhole) ip -n lr-app route del blackhole 10.20.0.10/32 ;;
      neighbor) ip -n lr-app neigh del 10.10.0.1 dev eth0 ;;
      mtu)
        ip netns exec lr-router nft delete table ip route_exam
        ip -n lr-router link set db0 mtu 1500
        ip -n lr-db link set eth0 mtu 1500
        ip -n lr-app route flush cache ;;
      *) echo 'Invalid fault record'; exit 1 ;;
    esac
    rm "$state/fault"
    echo 'Restored; re-run HTTP and large ping verification.' ;;
  *) echo 'Usage: fault.sh inject|show|restore'; exit 2 ;;
esac
