wg-quick: account for specified fwmark in auto routing mode

If we're doing automatic routing with default routes, but the config has
also specified an explicit fwmark, then use that explicit fwmark, even
if it's conflicting, since the administrator has explicitly opted into
using it. Also, when shutting down the interface, we only now remove the
fancy rules if we're in automatic routing mode with default routes.

Suggested-by: Luis Ressel <aranea@aixah.de>
Reported-by: Saeid Akbari <saeidscorp@yahoo.com>
Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com>
This commit is contained in:
Jason A. Donenfeld 2018-04-14 02:34:28 +02:00
parent cd19f54970
commit 81879fe346
1 changed files with 23 additions and 19 deletions

View File

@ -87,20 +87,17 @@ add_if() {
} }
del_if() { del_if() {
local fwmark local table
[[ $HAVE_SET_DNS -eq 0 ]] || unset_dns [[ $HAVE_SET_DNS -eq 0 ]] || unset_dns
fwmark="$(wg show "$INTERFACE" fwmark)" if [[ -z $TABLE || $TABLE == auto ]] && get_fwmark table && [[ $(wg show "$INTERFACE" allowed-ips) =~ /0(\ |$'\n'|$) ]]; then
DEFAULT_TABLE=0 while [[ $(ip -4 rule show) == *"lookup $table"* ]]; do
[[ $fwmark != off ]] && DEFAULT_TABLE=$(( fwmark )) cmd ip -4 rule delete table $table
if [[ $DEFAULT_TABLE -ne 0 ]]; then
while [[ $(ip -4 rule show) == *"lookup $DEFAULT_TABLE"* ]]; do
cmd ip -4 rule delete table $DEFAULT_TABLE
done done
while [[ $(ip -4 rule show) == *"from all lookup main suppress_prefixlength 0"* ]]; do while [[ $(ip -4 rule show) == *"from all lookup main suppress_prefixlength 0"* ]]; do
cmd ip -4 rule delete table main suppress_prefixlength 0 cmd ip -4 rule delete table main suppress_prefixlength 0
done done
while [[ $(ip -6 rule show) == *"lookup $DEFAULT_TABLE"* ]]; do while [[ $(ip -6 rule show) == *"lookup $table"* ]]; do
cmd ip -6 rule delete table $DEFAULT_TABLE cmd ip -6 rule delete table $table
done done
while [[ $(ip -6 rule show) == *"from all lookup main suppress_prefixlength 0"* ]]; do while [[ $(ip -6 rule show) == *"from all lookup main suppress_prefixlength 0"* ]]; do
cmd ip -6 rule delete table main suppress_prefixlength 0 cmd ip -6 rule delete table main suppress_prefixlength 0
@ -169,21 +166,28 @@ add_route() {
fi fi
} }
DEFAULT_TABLE= get_fwmark() {
local fwmark
fwmark="$(wg show "$INTERFACE" fwmark)" || return 1
[[ -n $fwmark && $fwmark != off ]] || return 1
printf -v "$1" "%d" "$fwmark"
return 0
}
add_default() { add_default() {
if [[ -z $DEFAULT_TABLE ]]; then local table proto key value
DEFAULT_TABLE=51820 if ! get_fwmark table; then
while [[ -n $(ip -4 route show table $DEFAULT_TABLE) || -n $(ip -6 route show table $DEFAULT_TABLE) ]]; do table=51820
((DEFAULT_TABLE++)) while [[ -n $(ip -4 route show table $table) || -n $(ip -6 route show table $table) ]]; do
((table++))
done done
cmd wg set "$INTERFACE" fwmark $table
fi fi
local proto=-4 proto=-4
[[ $1 == *:* ]] && proto=-6 [[ $1 == *:* ]] && proto=-6
cmd wg set "$INTERFACE" fwmark $DEFAULT_TABLE cmd ip $proto route add "$1" dev "$INTERFACE" table $table
cmd ip $proto route add "$1" dev "$INTERFACE" table $DEFAULT_TABLE cmd ip $proto rule add not fwmark $table table $table
cmd ip $proto rule add not fwmark $DEFAULT_TABLE table $DEFAULT_TABLE
cmd ip $proto rule add table main suppress_prefixlength 0 cmd ip $proto rule add table main suppress_prefixlength 0
local key value
while read -r key _ value; do while read -r key _ value; do
[[ $value -eq 1 ]] && sysctl -q "$key=2" [[ $value -eq 1 ]] && sysctl -q "$key=2"
done < <(sysctl -a -r '^net\.ipv4.conf\.[^ .=]+\.rp_filter$') done < <(sysctl -a -r '^net\.ipv4.conf\.[^ .=]+\.rp_filter$')