wg-quick: auto MTU discovery

Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2017-04-24 05:01:16 +02:00
parent 83223f8e4c
commit 13db708a0f
2 changed files with 28 additions and 1 deletions

View file

@ -22,7 +22,7 @@ suitable for a few common use cases.
Use \fIup\fP to add and set up an interface, and use \fIdown\fP to tear down and remove
an interface. Running \fIup\fP adds a WireGuard interface, brings up the interface with the
supplied IP addresses, sets up routes, and optionally runs pre/post up scripts. Running \fIdown\fP
supplied IP addresses, sets up mtu and routes, and optionally runs pre/post up scripts. Running \fIdown\fP
optionally saves the current configuration, removes the WireGuard interface, and optionally
runs pre/post down scripts.
@ -65,6 +65,10 @@ which are handled by this tool:
Address \(em a comma-separated list of ip (v4 or v6) addresses (optionally with CIDR masks)
to be assigned to the interface. May be specified multiple times.
.IP \(bu
MTU \(em if not specified, the MTU is automatically determined from the endpoint addresses
or the system default route, which is usually a sane choice. However, to manually specify
an MTU to override this automatic discovery, this value may be specified explicitly.
.IP \(bu
PreUp, PostUp, PreDown, PostDown \(em script snippets which will be executed by
.BR bash (1)
before/after setting up/tearing down the interface, most commonly used

View file

@ -13,6 +13,7 @@ export PATH="${SELF%/*}:$PATH"
WG_CONFIG=""
INTERFACE=""
ADDRESSES=( )
MTU=""
PRE_UP=""
POST_UP=""
PRE_DOWN=""
@ -39,6 +40,7 @@ parse_options() {
if [[ $interface_section -eq 1 ]]; then
case "$key" in
Address) ADDRESSES+=( ${value//,/ } ); continue ;;
MTU) MTU="$value"; continue ;;
PreUp) PRE_UP="$value"; continue ;;
PreDown) PRE_DOWN="$value"; continue ;;
PostUp) POST_UP="$value"; continue ;;
@ -108,6 +110,25 @@ add_addr() {
cmd ip address add "$1" dev "$INTERFACE"
}
set_mtu() {
local mtu=0 endpoint output
if [[ -n $MTU ]]; then
cmd ip link set mtu "$MTU" dev "$INTERFACE"
return
fi
while read -r _ endpoint; do
[[ $endpoint =~ ^([a-z0-9:.]+):[0-9]+$ ]] || continue
output="$(ip route get "${BASH_REMATCH[1]}" || true)"
[[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
done < <(wg show "$INTERFACE" endpoints)
if [[ $mtu -eq 0 ]]; then
read -r output < <(ip route show default || true) || true
[[ ( $output =~ mtu\ ([0-9]+) || ( $output =~ dev\ ([^ ]+) && $(ip link show dev "${BASH_REMATCH[1]}") =~ mtu\ ([0-9]+) ) ) && ${BASH_REMATCH[1]} -gt $mtu ]] && mtu="${BASH_REMATCH[1]}"
fi
[[ $mtu -gt 0 ]] || mtu=1500
cmd ip link set mtu $(( mtu - 80 )) dev "$INTERFACE"
}
add_route() {
if [[ $1 == 0.0.0.0/0 || $1 == ::/0 ]]; then
add_default "$1"
@ -146,6 +167,7 @@ save_config() {
for address in ${BASH_REMATCH[1]}; do
new_config+="Address = $address"$'\n'
done
[[ -n $MTU && $(ip link show dev "$INTERFACE") =~ mtu\ ([0-9]+) ]] && new_config+="MTU = ${BASH_REMATCH[1]}"$'\n'
[[ $SAVE_CONFIG -eq 0 ]] || new_config+=$'SaveConfig = true\n'
[[ -z $PRE_UP ]] || new_config+="PreUp = $PRE_UP"$'\n'
[[ -z $POST_UP ]] || new_config+="PostUp = $POST_UP"$'\n'
@ -200,6 +222,7 @@ cmd_up() {
for i in "${ADDRESSES[@]}"; do
add_addr "$i"
done
set_mtu
up_if
for i in $(wg show "$INTERFACE" allowed-ips | grep -Po '(?<=[\t ])[0-9.:/a-f]+' | sort -nr -k 2 -t /); do
[[ $(ip route get "$i" 2>/dev/null) == *dev\ $INTERFACE\ * ]] || add_route "$i"