--- wg-quick.orig +++ wg-quick @@ -24,6 +24,7 @@ SAVE_CONFIG=0 CONFIG_FILE="" PROGRAM="${0##*/}" ARGS=( "$@" ) +NETNS="" @@ -68,6 +69,20 @@ "$@" } +ensure_netns() { + [[ -z $NETNS ]] && return 0 + if [[ ! -e /run/netns/$NETNS ]]; then + cmd ip netns add "$NETNS" + fi +} + +move_to_netns() { + [[ -z $NETNS ]] && return 0 + cmd ip link set "$INTERFACE" netns "$NETNS" +} + die() { echo "$PROGRAM: $*" >&2 exit 1 @@ -169,11 +184,23 @@ local proto=-4 [[ $1 == *:* ]] && proto=-6 - cmd ip $proto route add "$1" dev "$INTERFACE" table "$TABLE" + + if [[ -n $NETNS ]]; then + cmd ip -n "$NETNS" $proto route add "$1" dev "$INTERFACE" table "$TABLE" + else + cmd ip $proto route add "$1" dev "$INTERFACE" table "$TABLE" + fi elif [[ $1 == */0 ]]; then add_default "$1" else - [[ -n $(ip $proto route show dev "$INTERFACE" match "$1" 2>/dev/null) ]] || cmd ip $proto route add "$1" dev "$INTERFACE" + if [[ -n $NETNS ]]; then + [[ -n $(ip -n "$NETNS" $proto route show dev "$INTERFACE" match "$1" 2>/dev/null) ]] || cmd ip -n "$NETNS" $proto route add "$1" dev "$INTERFACE" + else + [[ -n $(ip $proto route show dev "$INTERFACE" match "$1" 2>/dev/null) ]] || cmd ip $proto route add "$1" dev "$INTERFACE" + fi fi } @@ -267,8 +294,18 @@ HAVE_SET_DNS=0 set_dns() { [[ ${#DNS[@]} -gt 0 ]] || return 0 + if [[ -n $NETNS ]]; then + local netns_resolv_dir="/etc/netns/$NETNS" + cmd mkdir -p "$netns_resolv_dir" + { printf 'nameserver %s\n' "${DNS[@]}" + [[ ${#DNS_SEARCH[@]} -eq 0 ]] || printf 'search %s\n' "${DNS_SEARCH[*]}" + } | cmd tee "$netns_resolv_dir/resolv.conf" > /dev/null + else { printf 'nameserver %s\n' "${DNS[@]}" [[ ${#DNS_SEARCH[@]} -eq 0 ]] || printf 'search %s\n' "${DNS_SEARCH[*]}" } | cmd resolvconf -a "$(resolvconf_iface_prefix)$INTERFACE" -m 0 -x + fi HAVE_SET_DNS=1 } @@ -276,6 +313,11 @@ unset_dns() { [[ ${#DNS[@]} -gt 0 ]] || return 0 + if [[ -n $NETNS ]]; then + local netns_resolv="/etc/netns/$NETNS/resolv.conf" + [[ -f $netns_resolv ]] && cmd rm -f "$netns_resolv" + return 0 + fi cmd resolvconf -d "$(resolvconf_iface_prefix)$INTERFACE" -f } @@ -431,7 +473,7 @@ cmd_usage() { cat >&2 <<-_EOF - Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ] + Usage: $PROGRAM [ up | down | save | strip ] [ CONFIG_FILE | INTERFACE ] [ NETNS ] CONFIG_FILE is a configuration file, whose filename is the interface name followed by \`.conf'. Otherwise, INTERFACE is an interface name, with @@ -462,9 +504,11 @@ cmd_up() { local i [[ -z $(ip link show dev "$INTERFACE" 2>/dev/null) ]] || die "\`$INTERFACE' already exists" + ensure_netns trap 'del_if; exit' INT TERM EXIT add_if execute_hooks "${PRE_UP[@]}" + move_to_netns set_config for i in "${ADDRESSES[@]}"; do add_addr "$i" @@ -503,16 +547,28 @@ if [[ $# -eq 1 && ( $1 == --help || $1 == -h || $1 == help ) ]]; then cmd_usage elif [[ $# -eq 2 && $1 == up ]]; then + auto_su + parse_options "$2" + cmd_up +elif [[ $# -eq 3 && $1 == up ]]; then auto_su parse_options "$2" + NETNS="$3" cmd_up elif [[ $# -eq 2 && $1 == down ]]; then + auto_su + parse_options "$2" + cmd_down +elif [[ $# -eq 3 && $1 == down ]]; then auto_su parse_options "$2" + NETNS="$3" cmd_down elif [[ $# -eq 2 && $1 == save ]]; then auto_su parse_options "$2" cmd_save elif [[ $# -eq 2 && $1 == strip ]]; then + auto_su parse_options "$2" cmd_strip else