File: switch.bash

package info (click to toggle)
mimic 0.7.0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,204 kB
  • sloc: ansic: 484,549; sh: 490; makefile: 268
file content (115 lines) | stat: -rwxr-xr-x 3,059 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#!/bin/bash

: "${TEST_NETWORK_ID:=mimicsw}"

br="br$TEST_NETWORK_ID"
netns=("$TEST_NETWORK_ID"{1..2})

veth=("veth$TEST_NETWORK_ID"{1..2})
veth_ipv4_range=169.254.100.0/24
veth_ipv4=(169.254.100.{1..2}/24)
veth_ipv6_range=fc10::/64
veth_ipv6=(fc10::{1..2}/64)

wg_port=(1100{1..2})
wg_ipv4_range=169.254.200.0/24
wg_ipv4=(169.254.200.{1..2}/24)
wg_ipv6_range=fc20::/64
wg_ipv6=(fc20::{1..2}/64)

_curdir=$(dirname $(realpath "${BASH_SOURCE[0]}"))
source "$_curdir/../util.bash"

switch_env_setup() {
  for _i in "$@"; do
    case "$_i" in
    --mtu=*) local mtu="${_i#*=}" ;;
    --no-offload) local no_offload=true ;;
    --wg) local wg=1 ;;
    --wg-v4) local wg_ip_kind=v4 ;;
    --wg-v6) local wg_ip_kind=v6 ;;
    --wg-mtu=*) local wg_mtu="${_i#*=}" ;;
    *) ;;
    esac
  done

  ip link add $br type bridge
  [ -z "$mtu" ] || ip link set $br mtu "$mtu"
  ip link set $br up

  for _i in {0..1}; do
    ip netns add ${netns[$_i]}
    ip link add ${veth[$_i]} type veth peer ${veth[$_i]} netns ${netns[$_i]}
    ip link set ${veth[$_i]} master $br

    ip -n ${netns[$_i]} addr add dev ${veth[$_i]} ${veth_ipv4[$_i]}
    ip -n ${netns[$_i]} addr add dev ${veth[$_i]} ${veth_ipv6[$_i]}
    [ "$no_offload" != true ] || ip netns exec ${netns[$_i]} ethtool -K ${veth[$_i]} tx off

    if [ -n "$mtu" ]; then
      ip link set ${veth[$_i]} mtu "$mtu"
      ip -n ${netns[$_i]} link set ${veth[$_i]} mtu "$mtu"
    fi

    ip link set ${veth[$_i]} up
    ip -n ${netns[$_i]} link set lo up
    ip -n ${netns[$_i]} link set ${veth[$_i]} up
  done

  if [ -n "$wg" ]; then
    local _priv_key=($(wg genkey) $(wg genkey))
    for _i in {0..1}; do
      ip -n ${netns[$_i]} link add wg-${veth[$_i]} type wireguard
      ip -n ${netns[$_i]} addr add dev wg-${veth[$_i]} ${wg_ipv4[$_i]}
      ip -n ${netns[$_i]} addr add dev wg-${veth[$_i]} ${wg_ipv6[$_i]}

      ip netns exec ${netns[$_i]} wg set wg-${veth[$_i]} \
        listen-port ${wg_port[$_i]} \
        private-key <(echo ${_priv_key[$_i]})

      for _j in {0..1}; do
        if [ $_i -eq $_j ]; then continue; fi
        local _endpoint
        if [ "$wg_ip_kind" = v6 ]; then
          _endpoint=\[$(strip_ip_cidr ${veth_ipv6[$_j]})\]
        else
          _endpoint=$(strip_ip_cidr ${veth_ipv4[$_j]})
        fi
        ip netns exec ${netns[$_i]} wg set wg-${veth[$_i]} \
          peer $(echo ${_priv_key[$_j]} | wg pubkey) \
          allowed-ips ${wg_ipv4_range},${wg_ipv6_range} \
          endpoint $_endpoint:${wg_port[$_j]}
      done

      [ -z "$wg_mtu" ] || ip -n ${netns[$_i]} link set wg-${veth[$_i]} mtu "$wg_mtu"
      ip -n ${netns[$_i]} link set wg-${veth[$_i]} up
    done
  fi
}

switch_env_cleanup() (
  set +e
  ip link del $br
  for _i in {0..1}; do
    ip netns del ${netns[$_i]}
    ip link del ${veth[$_i]} 2>/dev/null
  done
)

if [ "${BASH_SOURCE[0]}" = "$0" ]; then
  set -e
  case "$1" in
  setup)
    shift
    switch_env_setup $@
    ;;
  clean)
    shift
    switch_env_cleanup $@
    ;;
  *)
    >&2 echo "expected 'setup' or 'clean'"
    exit 1
    ;;
  esac
fi