From de36c400d4de910f0de7e503fcde43f3473cdda9 Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Wed, 2 Sep 2020 11:04:43 +0200 Subject: [PATCH 1/6] tapsetup: make output easier to parse Distinguish bridge creation from tap creation. --- dist/tools/tapsetup/tapsetup | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/tools/tapsetup/tapsetup b/dist/tools/tapsetup/tapsetup index 9328bc9fa670..02151d8b8f21 100755 --- a/dist/tools/tapsetup/tapsetup +++ b/dist/tools/tapsetup/tapsetup @@ -44,7 +44,7 @@ update_uplink() { } create_bridge() { - echo "creating ${BRNAME}" + echo "creating bridge ${BRNAME}" case "${PLATFORM}" in FreeBSD) From a9722dda7145fab1ecd0087b5b3bc140469d3ae5 Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Tue, 1 Sep 2020 13:22:40 +0200 Subject: [PATCH 2/6] tapsetup: add capability to list bridges --- dist/tools/tapsetup/tapsetup | 71 ++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/dist/tools/tapsetup/tapsetup b/dist/tools/tapsetup/tapsetup index 02151d8b8f21..05d7597ca0ae 100755 --- a/dist/tools/tapsetup/tapsetup +++ b/dist/tools/tapsetup/tapsetup @@ -17,6 +17,9 @@ usage() { echo "Options:" >&2 echo " -c [], --create []: Create tap interfaces (default: 2)" >&2 echo " -d, --delete: Delete all interface" >&2 + echo " -l , --list : If belongs to a bridge, list the bridge and" >&2 + echo " all interfaces that belong to it. If does " >&2 + echo" not belong to a bridge, just print ." >&2 echo " -b , --bridge : Give name for the bridge (default: tapbr)" >&2 echo " -t , --tap : Name base for the tap interfaces; the" >&2 echo " generated names will be x" >&2 @@ -148,6 +151,50 @@ create_tap() { esac } +get_master() { + IFACE=$1 + case "${PLATFORM}" in + Linux) + MASTER=$(ip link show ${IFACE} | grep -o "master \S\+" | cut -d' ' -f2) + ;; + FreeBSD|OSX) + for IF in $(ifconfig | grep -oiE "^[a-z0-9_-]+"); do + if ifconfig $IF | grep -q "member: $IFACE"; then + MASTER=${IF} + break + fi + done + ;; + *) + ;; + esac + if [ -z "$MASTER" ]; then + # IFACE is its own master + echo "$IFACE" + else + echo "$MASTER" + fi +} + +list_bridge() { + BRIDGE=$1 + echo "$BRIDGE:" + case "${PLATFORM}" in + Linux) + for IF in $(ls /sys/class/net/${BRIDGE}/brif); do + echo "- $IF" + done + ;; + FreeBSD|OSX) + for IF in $(ifconfig ${BRIDGE} | grep -oiE "member: .+ " | cut -d' ' -f2); do + echo "- $IF" + done + ;; + *) + ;; + esac +} + while true ; do case "$1" in -6) @@ -185,6 +232,20 @@ while true ; do fi COMMAND="delete" shift ;; + -l|--list) + if [ -n "${COMMAND}" ]; then + usage + exit 2 + fi + COMMAND="list" + case "$2" in + "") + usage + exit 2 ;; + *) + BRNAME="$2" + shift 2 ;; + esac ;; -h|--help) usage exit ;; @@ -213,13 +274,13 @@ while true ; do esac done -if [ -z "${SUDO_USER}" ]; then - echo 'Environment variable $SUDO_USER required; Please run with `sudo`' - exit 1 -fi if [ -z "${COMMAND}" ]; then COMMAND="create" fi +if [ -z "${SUDO_USER}" ] && [ "${COMMAND}" != "list" ]; then + echo 'Environment variable $SUDO_USER required; Please run with `sudo`' + exit 1 +fi case "$(uname -s)" in Darwin) PLATFORM="OSX" @@ -251,6 +312,8 @@ if [ "${COMMAND}" = 'create' ]; then elif [ "${COMMAND}" = 'delete' ]; then delete_bridge +elif [ "${COMMAND}" = 'list' ]; then + list_bridge $(get_master "$BRNAME") else echo 'unknown command' exit 1 From 0abe581e3e1f1d55b7b44428aed7ee3ec6de0a2a Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Tue, 1 Sep 2020 17:26:15 +0200 Subject: [PATCH 3/6] tapsetup: add capability to enable forwarding for bridge --- dist/tools/tapsetup/tapsetup | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/dist/tools/tapsetup/tapsetup b/dist/tools/tapsetup/tapsetup index 05d7597ca0ae..de339201211b 100755 --- a/dist/tools/tapsetup/tapsetup +++ b/dist/tools/tapsetup/tapsetup @@ -6,6 +6,7 @@ COMMAND="" BRNAME="tapbr0" TAPNAME="tap" DEACTIVATE_IPV6="" +ENABLE_FORWARDING=0 UPLINK="" usage() { @@ -20,6 +21,8 @@ usage() { echo " -l , --list : If belongs to a bridge, list the bridge and" >&2 echo " all interfaces that belong to it. If does " >&2 echo" not belong to a bridge, just print ." >&2 + echo " -f, --forwarding Enable forwarding system-wide on creation and " >&2 + echo " disable on deletion." >&2 echo " -b , --bridge : Give name for the bridge (default: tapbr)" >&2 echo " -t , --tap : Name base for the tap interfaces; the" >&2 echo " generated names will be x" >&2 @@ -46,6 +49,20 @@ update_uplink() { fi } +activate_forwarding() { + if [ ${ENABLE_FORWARDING} -eq 1 ]; then + case "${PLATFORM}" in + FreeBSD|OSX) + sysctl -w net.inet.ip.forwarding=1 || exit 1 ;; + Linux) + sysctl -w net.ipv6.conf.${BRNAME}.forwarding=1 || exit 1 + sysctl -w net.ipv6.conf.${BRNAME}.accept_ra=0 || exit 1 + sysctl -w net.ipv6.conf.all.forwarding=1 || exit 1 ;; + *) ;; + esac + fi +} + create_bridge() { echo "creating bridge ${BRNAME}" @@ -85,6 +102,20 @@ up_bridge() { esac } +deactivate_forwarding() { + if [ ${ENABLE_FORWARDING} -eq 1 ]; then + case "${PLATFORM}" in + FreeBSD|OSX) + sysctl -w net.inet.ip.forwarding=0 || exit 1 ;; + Linux) + sysctl -w net.ipv6.conf.${BRNAME}.forwarding=0 || exit 1 + sysctl -w net.ipv6.conf.${BRNAME}.accept_ra=1 || exit 1 + sysctl -w net.ipv6.conf.all.forwarding=0 || exit 1 ;; + *) ;; + esac + fi +} + delete_bridge() { echo "deleting ${BRNAME}" @@ -232,6 +263,9 @@ while true ; do fi COMMAND="delete" shift ;; + -f|--forwarding) + ENABLE_FORWARDING=1 + shift ;; -l|--list) if [ -n "${COMMAND}" ]; then usage @@ -308,9 +342,11 @@ if [ "${COMMAND}" = 'create' ]; then create_tap || exit 1 done + activate_forwarding || exit 1 up_bridge || exit 1 elif [ "${COMMAND}" = 'delete' ]; then + deactivate_forwarding || exit 1 delete_bridge elif [ "${COMMAND}" = 'list' ]; then list_bridge $(get_master "$BRNAME") From dbeb783b137066fcd0d9224f2274d5b721c1f044 Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Wed, 2 Sep 2020 10:33:01 +0200 Subject: [PATCH 4/6] tapsetup: add capability to add addresses to bridge --- dist/tools/tapsetup/tapsetup | 53 ++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/dist/tools/tapsetup/tapsetup b/dist/tools/tapsetup/tapsetup index de339201211b..b4c9cdb55e35 100755 --- a/dist/tools/tapsetup/tapsetup +++ b/dist/tools/tapsetup/tapsetup @@ -7,6 +7,7 @@ BRNAME="tapbr0" TAPNAME="tap" DEACTIVATE_IPV6="" ENABLE_FORWARDING=0 +DEFAULT_PREFIX_LEN=128 UPLINK="" usage() { @@ -21,6 +22,9 @@ usage() { echo " -l , --list : If belongs to a bridge, list the bridge and" >&2 echo " all interfaces that belong to it. If does " >&2 echo" not belong to a bridge, just print ." >&2 + echo " -a
[/], --address
[/]:" >&2 + echo " Address to add to the created bridge. Can be used" >&2 + echo " multiple times." >&2 echo " -f, --forwarding Enable forwarding system-wide on creation and " >&2 echo " disable on deletion." >&2 echo " -b , --bridge : Give name for the bridge (default: tapbr)" >&2 @@ -63,6 +67,25 @@ activate_forwarding() { fi } +add_ipv6_addrs() { + for a in ${BRIDGE_ADDRS}; do + address_addr=$(echo "${a}" | cut -d/ -f1) + prefix_len=$(echo "${a}" | cut -d/ -f2) + if [ "${a}" = "${prefix_len}" ]; then + # prefix length is not defined + prefix_len=${DEFAULT_PREFIX_LEN} + fi + case "${PLATFORM}" in + FreeBSD|OSX) + ifconfig ${BRNAME} inet6 ${address_addr} prefixlen ${prefix_len} || exit 1 + ;; + Linux) + ip address add ${address_addr}/${prefix_len} dev ${BRNAME} || exit 1 + ;; + esac + done +} + create_bridge() { echo "creating bridge ${BRNAME}" @@ -116,6 +139,25 @@ deactivate_forwarding() { fi } +del_ipv6_addrs() { + for a in ${BRIDGE_ADDRS}; do + address_addr=$(echo "${a}" | cut -d/ -f1) + prefix_len=$(echo "${a}" | cut -d/ -f2) + if [ "${a}" = "${prefix_len}" ]; then + # prefix length is not defined + prefix_len=${DEFAULT_PREFIX_LEN} + fi + case "${PLATFORM}" in + FreeBSD|OSX) + ifconfig ${BRNAME} inet6 ${address_addr} prefixlen ${prefix_len} delete || exit 1 + ;; + Linux) + ip address delete ${address_addr}/${prefix_len} dev ${BRNAME} || exit 1 + ;; + esac + done +} + delete_bridge() { echo "deleting ${BRNAME}" @@ -231,6 +273,15 @@ while true ; do -6) DEACTIVATE_IPV6=1 shift ;; + -a|--address) + # check if valid address + optional prefix length + if echo "$2" | grep -q "^[a-f0-9:]\+\(/[0-9]\+\)\?$"; then + BRIDGE_ADDRS="${BRIDGE_ADDRS} $2" + shift 2 + else + usage + exit 2 + fi ;; -b|--bridge) case "$2" in "") @@ -344,8 +395,10 @@ if [ "${COMMAND}" = 'create' ]; then activate_forwarding || exit 1 up_bridge || exit 1 + add_ipv6_addrs || exit 1 elif [ "${COMMAND}" = 'delete' ]; then + del_ipv6_addrs || exit 1 deactivate_forwarding || exit 1 delete_bridge elif [ "${COMMAND}" = 'list' ]; then From 29684af116b31293e1c289a469ef022e38bc3753 Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Wed, 2 Sep 2020 11:16:35 +0200 Subject: [PATCH 5/6] tapsetup: add capability to add routes to bridge --- dist/tools/tapsetup/tapsetup | 70 ++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/dist/tools/tapsetup/tapsetup b/dist/tools/tapsetup/tapsetup index b4c9cdb55e35..77a7d21a6e35 100755 --- a/dist/tools/tapsetup/tapsetup +++ b/dist/tools/tapsetup/tapsetup @@ -7,6 +7,8 @@ BRNAME="tapbr0" TAPNAME="tap" DEACTIVATE_IPV6="" ENABLE_FORWARDING=0 +BRIDGE_ADDRS="" +BRIDGE_ROUTES="" DEFAULT_PREFIX_LEN=128 UPLINK="" @@ -25,6 +27,9 @@ usage() { echo " -a
[/], --address
[/]:" >&2 echo " Address to add to the created bridge. Can be used" >&2 echo " multiple times." >&2 + echo " -r [/] , --route [/] :" >&2 + echo " Route to add to via the created bridge. Can be used" >&2 + echo " multiple times." >&2 echo " -f, --forwarding Enable forwarding system-wide on creation and " >&2 echo " disable on deletion." >&2 echo " -b , --bridge : Give name for the bridge (default: tapbr)" >&2 @@ -82,6 +87,31 @@ add_ipv6_addrs() { Linux) ip address add ${address_addr}/${prefix_len} dev ${BRNAME} || exit 1 ;; + *) ;; + esac + done +} + +add_ipv6_routes() { + for r in ${BRIDGE_ROUTES}; do + route=$(echo "${r}" | cut -d- -f1) + next_hop=$(echo "${r}" | cut -d- -f2) + route_prefix=$(echo "${route}" | cut -d/ -f1) + route_prefix_len=$(echo "${route}" | cut -d/ -f2) + if [ "${route}" = "${route_prefix_len}" ]; then + # prefix length is not defined + route_prefix_len=${DEFAULT_PREFIX_LEN} + fi + case "${PLATFORM}" in + FreeBSD|OSX) + route -6n add ${route_prefix} -interface ${BRNAME} \ + ${next_hop} || exit 1 + ;; + Linux) + ip route add ${route_prefix}/${route_prefix_len} \ + via ${next_hop} dev ${BRNAME} || exit 1 + ;; + *) ;; esac done } @@ -154,6 +184,31 @@ del_ipv6_addrs() { Linux) ip address delete ${address_addr}/${prefix_len} dev ${BRNAME} || exit 1 ;; + *) ;; + esac + done +} + +del_ipv6_routes() { + for r in ${BRIDGE_ROUTES}; do + route=$(echo "${r}" | cut -d- -f1) + next_hop=$(echo "${r}" | cut -d- -f2) + route_prefix=$(echo "${route}" | cut -d/ -f1) + route_prefix_len=$(echo "${route}" | cut -d/ -f2) + if [ "${route}" = "${route_prefix_len}" ]; then + # prefix length is not defined + route_prefix_len=${DEFAULT_PREFIX_LEN} + fi + case "${PLATFORM}" in + FreeBSD|OSX) + route -6 delete ${route_prefix}/${route_prefix_len} \ + -interface ${BRNAME} ${next_hop} || exit 1 + ;; + Linux) + ip route delete ${route_prefix}/${route_prefix_len} \ + via ${next_hop} dev ${BRNAME} || exit 1 + ;; + *) ;; esac done } @@ -334,6 +389,19 @@ while true ; do -h|--help) usage exit ;; + -r|--route) + # check if valid address + optional prefix length + if ! echo "$2" | grep -q "^[a-f0-9:]\+\(/[0-9]\+\)\?$"; then + usage + exit 2 + fi + # check if valid next hop + if ! echo "$3" | grep -q "^[a-f0-9:]\+$"; then + usage + exit 2 + fi + BRIDGE_ROUTES="${BRIDGE_ROUTES} $2-$3" + shift 3 ;; -u|--uplink) case "$2" in "") @@ -396,8 +464,10 @@ if [ "${COMMAND}" = 'create' ]; then activate_forwarding || exit 1 up_bridge || exit 1 add_ipv6_addrs || exit 1 + add_ipv6_routes || exit 1 elif [ "${COMMAND}" = 'delete' ]; then + del_ipv6_routes || exit 1 del_ipv6_addrs || exit 1 deactivate_forwarding || exit 1 delete_bridge From 5fea5fca6526057768b36b8712660fa8c1671946 Mon Sep 17 00:00:00 2001 From: "Martine S. Lenders" Date: Wed, 2 Sep 2020 11:24:05 +0200 Subject: [PATCH 6/6] tapsetup: FreeBSD/OSX: remove member TAPs of bridge explicitly --- dist/tools/tapsetup/tapsetup | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dist/tools/tapsetup/tapsetup b/dist/tools/tapsetup/tapsetup index 77a7d21a6e35..4e2e52e9b663 100755 --- a/dist/tools/tapsetup/tapsetup +++ b/dist/tools/tapsetup/tapsetup @@ -219,6 +219,9 @@ delete_bridge() { case "${PLATFORM}" in FreeBSD) sysctl net.link.tap.user_open=0 + for IF in $(ifconfig ${BRIDGE} | grep -oiE "member: .+ " | cut -d' ' -f2); do + ifconfig $IF destroy || exit 1 + done ifconfig ${BRNAME} destroy || exit 1 kldunload if_tap # unloading might fail due to dependencies kldunload if_bridge ;; @@ -236,6 +239,9 @@ delete_bridge() { update_uplink ${UPLINK} fi ;; OSX) + for IF in $(ifconfig ${BRIDGE} | grep -oiE "member: .+ " | cut -d' ' -f2); do + ifconfig $IF destroy || exit 1 + done ifconfig ${BRNAME} destroy || exit 1 ;; *) ;;