From 8ea5e07b9850174340718f1bcaff57cf45711155 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Mon, 31 May 2021 08:34:45 -0400 Subject: [PATCH 1/6] Script for setting up linux namespaces This will let developers run a controller and device on the same machines. --- scripts/tools/linux_ip_namespace_setup.sh | 194 ++++++++++++++++++++++ 1 file changed, 194 insertions(+) create mode 100755 scripts/tools/linux_ip_namespace_setup.sh diff --git a/scripts/tools/linux_ip_namespace_setup.sh b/scripts/tools/linux_ip_namespace_setup.sh new file mode 100755 index 00000000000000..1d3f71fcdb5fcb --- /dev/null +++ b/scripts/tools/linux_ip_namespace_setup.sh @@ -0,0 +1,194 @@ +#!/bin/bash + +NAMESPACE="MatterTester" +HOST_SIDE_IF_NAME="heth0" +NAMESPACE_SIDE_IF_NAME="neth0" +BRIDGE_NAME="nbridge" +BRIDGE_ADDR="192.168.4.50" +NAMESPACE_ADDR="192.168.4.45" +HOST_IPV6_ADDR=fc00::1 +BRIDGE_IPV6_ADDR=fc00::b +NAMESPACE_IPV6_ADDR=fc00::a + +function run_setup() { + # Create namespace. + ip netns add ${NAMESPACE} + + # Create two virtual interfaces and link them - one on host side, one on namespace side. + ip link add ${HOST_SIDE_IF_NAME} type veth peer name ${NAMESPACE_SIDE_IF_NAME} + + # Give the host a known IPv6 addr and set the host side up + ip -6 addr add ${HOST_IPV6_ADDR}/64 dev ${HOST_SIDE_IF_NAME} + ip link set ${HOST_SIDE_IF_NAME} up + + # Associate namespace IF with the namespace + ip link set ${NAMESPACE_SIDE_IF_NAME} netns ${NAMESPACE} + + # Give the namespace IF an address (something nothing else is using) and set it up + echo "Adding address for namespace IF" + ip netns exec ${NAMESPACE} ip -6 addr add ${NAMESPACE_IPV6_ADDR}/64 dev ${NAMESPACE_SIDE_IF_NAME} + ip netns exec ${NAMESPACE} ip link set dev ${NAMESPACE_SIDE_IF_NAME} up + + # Add a route to the namespace to go through the bridge + echo "Setting routes for namespace" + ip netns exec ${NAMESPACE} ip -6 route add default dev ${NAMESPACE_SIDE_IF_NAME} + + echo "Setup complete." +} + +function run_add_ipv4() { + # Give the namespace an IPv4 address + ip netns exec ${NAMESPACE} ip addr add ${NAMESPACE_ADDR}/24 dev ${NAMESPACE_SIDE_IF_NAME} + + # Add a bridge, give it an address (something nothing else is using) + echo "Setting up bridge" + ip link add name ${BRIDGE_NAME} type bridge + ip -6 addr add ${BRIDGE_IPV6_ADDR}/64 dev ${BRIDGE_NAME} + ip addr add ${BRIDGE_ADDR}/24 brd + dev ${BRIDGE_NAME} + + # For ipv6 and ipv4 to work together, need the bridge to ignore the ipv6 packets (DROP here means don't bridge) + ebtables-legacy -t broute -A BROUTING -p ipv6 -j DROP -i ${HOST_SIDE_IF_NAME} + ip link set ${BRIDGE_NAME} up + + # Connect the host side to the bridge, so now we have bridge <-> host_side_if <-> namespace_if + echo "Connecting host virtual IF to bridge" + ip link set ${HOST_SIDE_IF_NAME} master ${BRIDGE_NAME} + + #ip netns exec ${NAMESPACE} ip route add default via ${BRIDGE_ADDR} dev ${NAMESPACE_SIDE_IF_NAME} +} + +function run_cmd() { + # Start the app in the namespace + echo "Running $1 in namespace." + ip netns exec ${NAMESPACE} $1 +} + +function run_cleanup() { + # Deleting the namespace will remove the namespace and peer'd interfaces to + have_ebtables_legacy=$1 + ip netns delete ${NAMESPACE} + if ifconfig | grep ${BRIDGE_NAME}; then + if [ $have_ebtables_legacy = true ]; then + # Just try to drop the additional rule - it references our interface + # so if it's there, we added it. + ebtables-legacy -t broute -D BROUTING -p ipv6 -j DROP -i ${HOST_SIDE_IF_NAME} > /dev/null + fi + ip link delete dev ${BRIDGE_NAME} type bridge + fi +} + +function help() { + echo "Usage: $file_name [ options ... ]" + echo "" + + echo "This script is used to set up linux namespaces for Matter device testing." + echo "To use this script, set up a namespace then run the Matter device example" + echo "using the -r command. Run the controller in another terminal to send" + echo "commands to and from the device." + echo "" + echo "This script requires sudo for setup and requires access to ebtables-legacy" + echo "to set up dual ipv4/ipv6 namespaces. Defaults to ipv6 only." + echo "" + + echo "Options: + -h, --help Display this information. + -s, --setup Setup an IP namespace. Will run cleanup if namespace exists. + -4, --ipv4 Add ipv4 support. + -r, --run filename Run file in the namespace. Will setup namespace if required. + -c, --cleanup Delete namespace and routes +" +} + +declare setup=false +declare filename="" +declare run=false +declare cleanup=false +declare ipv4=false + +file_name=${0##*/} + +while (($#)); do + case $1 in + --help | -h) + help + exit 1 + ;; + --setup | -s) + setup=true + ;; + --run | -r) + run=true + filename=$2 + shift + ;; + --cleanup | -c) + cleanup=true + ;; + --ipv4 | -4) + ipv4=true + ;; + -*) + help + echo "Unknown Option \"$1\"" + exit 1 + ;; + esac + shift +done + +if [[ $EUID -ne 0 ]]; then + echo "You must run this script as root." + exit 1 +fi + +if ifconfig | grep "${HOST_SIDE_IF_NAME}"; then + issetup=true +else + issetup=false +fi + +if [ $setup = false ] && [ $run = false ] && [ $cleanup = false ]; then + echo "Must specify one or more of -s -r -c." + exit 1 +fi + +if command -v ebtables-legacy > /dev/null; then + have_ebtables_legacy=true +else + have_ebtables_legacy=false +fi + +if [ $ipv4 = true ] && [ $have_ebtables_legacy = false ]; then + echo "To set up namesapces with ipv4/ipv6 connectivity, ebtables-legacy" + echo "is required. To install please use:" + echo "apt-get install ebtables" + exit 1 +fi + +if [ $run = true ]; then + if [ $issetup = false ]; then + setup=true + fi +fi + +if [ $setup = true]; then + if [ $issetup = true ]; then + cleanup=true + fi +fi + +if [ $cleanup = true ]; then + run_cleanup $have_ebtables_legacy +fi + +if [ $setup = true ]; then + run_setup + if [ $ipv4 = true ]; then + run_add_ipv4 + fi +fi + +if [ $run = true ]; then + run_cmd $filename +fi + From 659e69e49e7e2992e328e8b178d1cda277ac732e Mon Sep 17 00:00:00 2001 From: C Freeman Date: Tue, 1 Jun 2021 19:46:37 -0400 Subject: [PATCH 2/6] Apply suggestions from code review Co-authored-by: Tennessee Carmel-Veilleux --- scripts/tools/linux_ip_namespace_setup.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/scripts/tools/linux_ip_namespace_setup.sh b/scripts/tools/linux_ip_namespace_setup.sh index 1d3f71fcdb5fcb..d90c8a200c82a7 100755 --- a/scripts/tools/linux_ip_namespace_setup.sh +++ b/scripts/tools/linux_ip_namespace_setup.sh @@ -137,7 +137,7 @@ while (($#)); do done if [[ $EUID -ne 0 ]]; then - echo "You must run this script as root." + echo "You must run this script with superuser privileges." exit 1 fi @@ -148,7 +148,7 @@ else fi if [ $setup = false ] && [ $run = false ] && [ $cleanup = false ]; then - echo "Must specify one or more of -s -r -c." + echo "Must specify one or more of -s, -r, -c." exit 1 fi @@ -159,9 +159,9 @@ else fi if [ $ipv4 = true ] && [ $have_ebtables_legacy = false ]; then - echo "To set up namesapces with ipv4/ipv6 connectivity, ebtables-legacy" - echo "is required. To install please use:" - echo "apt-get install ebtables" + echo "To set up namespaces with ipv4/ipv6 connectivity, ebtables-legacy" + echo "is required. For example, to install on machines using APT:" + echo "sudo apt-get install ebtables" exit 1 fi @@ -191,4 +191,3 @@ fi if [ $run = true ]; then run_cmd $filename fi - From 6631c679abba44cbb63d2d9e1e123f290e99a081 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Tue, 1 Jun 2021 19:49:48 -0400 Subject: [PATCH 3/6] reformatting. --- scripts/tools/linux_ip_namespace_setup.sh | 84 +++++++++++------------ 1 file changed, 42 insertions(+), 42 deletions(-) diff --git a/scripts/tools/linux_ip_namespace_setup.sh b/scripts/tools/linux_ip_namespace_setup.sh index d90c8a200c82a7..66f2aee4f489a2 100755 --- a/scripts/tools/linux_ip_namespace_setup.sh +++ b/scripts/tools/linux_ip_namespace_setup.sh @@ -71,26 +71,26 @@ function run_cleanup() { if [ $have_ebtables_legacy = true ]; then # Just try to drop the additional rule - it references our interface # so if it's there, we added it. - ebtables-legacy -t broute -D BROUTING -p ipv6 -j DROP -i ${HOST_SIDE_IF_NAME} > /dev/null + ebtables-legacy -t broute -D BROUTING -p ipv6 -j DROP -i ${HOST_SIDE_IF_NAME} >/dev/null fi ip link delete dev ${BRIDGE_NAME} type bridge fi } function help() { - echo "Usage: $file_name [ options ... ]" - echo "" - - echo "This script is used to set up linux namespaces for Matter device testing." - echo "To use this script, set up a namespace then run the Matter device example" - echo "using the -r command. Run the controller in another terminal to send" - echo "commands to and from the device." - echo "" - echo "This script requires sudo for setup and requires access to ebtables-legacy" - echo "to set up dual ipv4/ipv6 namespaces. Defaults to ipv6 only." - echo "" - - echo "Options: + echo "Usage: $file_name [ options ... ]" + echo "" + + echo "This script is used to set up linux namespaces for Matter device testing." + echo "To use this script, set up a namespace then run the Matter device example" + echo "using the -r command. Run the controller in another terminal to send" + echo "commands to and from the device." + echo "" + echo "This script requires sudo for setup and requires access to ebtables-legacy" + echo "to set up dual ipv4/ipv6 namespaces. Defaults to ipv6 only." + echo "" + + echo "Options: -h, --help Display this information. -s, --setup Setup an IP namespace. Will run cleanup if namespace exists. -4, --ipv4 Add ipv4 support. @@ -108,37 +108,37 @@ declare ipv4=false file_name=${0##*/} while (($#)); do - case $1 in - --help | -h) - help - exit 1 - ;; - --setup | -s) - setup=true - ;; - --run | -r) - run=true - filename=$2 - shift - ;; - --cleanup | -c) - cleanup=true - ;; - --ipv4 | -4) - ipv4=true - ;; - -*) - help - echo "Unknown Option \"$1\"" - exit 1 - ;; - esac + case $1 in + --help | -h) + help + exit 1 + ;; + --setup | -s) + setup=true + ;; + --run | -r) + run=true + filename=$2 shift + ;; + --cleanup | -c) + cleanup=true + ;; + --ipv4 | -4) + ipv4=true + ;; + -*) + help + echo "Unknown Option \"$1\"" + exit 1 + ;; + esac + shift done if [[ $EUID -ne 0 ]]; then - echo "You must run this script with superuser privileges." - exit 1 + echo "You must run this script with superuser privileges." + exit 1 fi if ifconfig | grep "${HOST_SIDE_IF_NAME}"; then @@ -152,7 +152,7 @@ if [ $setup = false ] && [ $run = false ] && [ $cleanup = false ]; then exit 1 fi -if command -v ebtables-legacy > /dev/null; then +if command -v ebtables-legacy >/dev/null; then have_ebtables_legacy=true else have_ebtables_legacy=false From e3a2a4108fd8572b2fd3d5fbb095fa30932081a3 Mon Sep 17 00:00:00 2001 From: Cecille Freeman Date: Tue, 1 Jun 2021 20:09:03 -0400 Subject: [PATCH 4/6] Add example and header. --- scripts/tools/linux_ip_namespace_setup.sh | 52 ++++++++++++++++++++--- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/scripts/tools/linux_ip_namespace_setup.sh b/scripts/tools/linux_ip_namespace_setup.sh index 66f2aee4f489a2..75167ed38e399e 100755 --- a/scripts/tools/linux_ip_namespace_setup.sh +++ b/scripts/tools/linux_ip_namespace_setup.sh @@ -1,4 +1,35 @@ -#!/bin/bash +#!/usr/bin/env bash +# +# +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# Description: +# This is a utility script that can be used by developers to do +# simulate a device and controller on the same linux machine. This +# script is not intended to be used in a testing framework as-is +# because it requires root access to set up network namespaces. +# +# To use this script, compile the required device example, and +# run inside the namespace using +# sudo /linux_ip_namespace_setup.sh -r +# +# The controller can then be started in a new terminal and will +# be able to communicate with the application as if it were on +# a separate network. +# NAMESPACE="MatterTester" HOST_SIDE_IF_NAME="heth0" @@ -81,10 +112,19 @@ function help() { echo "Usage: $file_name [ options ... ]" echo "" - echo "This script is used to set up linux namespaces for Matter device testing." - echo "To use this script, set up a namespace then run the Matter device example" - echo "using the -r command. Run the controller in another terminal to send" - echo "commands to and from the device." + echo "This script is used to set up linux namespaces for Matter device testing" + echo "between a controller and device on the same linux machine." + echo "" + echo "To use this script, run the device code in a namespace using the -r command" + echo "and a controller in a seperate terminal to simulate two devices communicating" + echo "across a network." + echo "Example:" + echo "--------" + echo "Terminal 1:" + echo "sudo /$file_name -r /" + echo "" + echo "Terminal 2:" + echo "/chip-device-ctrl" echo "" echo "This script requires sudo for setup and requires access to ebtables-legacy" echo "to set up dual ipv4/ipv6 namespaces. Defaults to ipv6 only." @@ -171,7 +211,7 @@ if [ $run = true ]; then fi fi -if [ $setup = true]; then +if [ $setup = true ]; then if [ $issetup = true ]; then cleanup=true fi From 96189869db334dc005b2037d86a67144a190a5be Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 2 Jun 2021 00:17:52 +0000 Subject: [PATCH 5/6] Restyled by shellharden --- scripts/tools/linux_ip_namespace_setup.sh | 68 +++++++++++------------ 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/scripts/tools/linux_ip_namespace_setup.sh b/scripts/tools/linux_ip_namespace_setup.sh index 75167ed38e399e..b5904e625dcb72 100755 --- a/scripts/tools/linux_ip_namespace_setup.sh +++ b/scripts/tools/linux_ip_namespace_setup.sh @@ -43,47 +43,47 @@ NAMESPACE_IPV6_ADDR=fc00::a function run_setup() { # Create namespace. - ip netns add ${NAMESPACE} + ip netns add "$NAMESPACE" # Create two virtual interfaces and link them - one on host side, one on namespace side. - ip link add ${HOST_SIDE_IF_NAME} type veth peer name ${NAMESPACE_SIDE_IF_NAME} + ip link add "$HOST_SIDE_IF_NAME" type veth peer name "$NAMESPACE_SIDE_IF_NAME" # Give the host a known IPv6 addr and set the host side up - ip -6 addr add ${HOST_IPV6_ADDR}/64 dev ${HOST_SIDE_IF_NAME} - ip link set ${HOST_SIDE_IF_NAME} up + ip -6 addr add "$HOST_IPV6_ADDR"/64 dev "$HOST_SIDE_IF_NAME" + ip link set "$HOST_SIDE_IF_NAME" up # Associate namespace IF with the namespace - ip link set ${NAMESPACE_SIDE_IF_NAME} netns ${NAMESPACE} + ip link set "$NAMESPACE_SIDE_IF_NAME" netns "$NAMESPACE" # Give the namespace IF an address (something nothing else is using) and set it up echo "Adding address for namespace IF" - ip netns exec ${NAMESPACE} ip -6 addr add ${NAMESPACE_IPV6_ADDR}/64 dev ${NAMESPACE_SIDE_IF_NAME} - ip netns exec ${NAMESPACE} ip link set dev ${NAMESPACE_SIDE_IF_NAME} up + ip netns exec "$NAMESPACE" ip -6 addr add "$NAMESPACE_IPV6_ADDR"/64 dev "$NAMESPACE_SIDE_IF_NAME" + ip netns exec "$NAMESPACE" ip link set dev "$NAMESPACE_SIDE_IF_NAME" up # Add a route to the namespace to go through the bridge echo "Setting routes for namespace" - ip netns exec ${NAMESPACE} ip -6 route add default dev ${NAMESPACE_SIDE_IF_NAME} + ip netns exec "$NAMESPACE" ip -6 route add default dev "$NAMESPACE_SIDE_IF_NAME" echo "Setup complete." } function run_add_ipv4() { # Give the namespace an IPv4 address - ip netns exec ${NAMESPACE} ip addr add ${NAMESPACE_ADDR}/24 dev ${NAMESPACE_SIDE_IF_NAME} + ip netns exec "$NAMESPACE" ip addr add "$NAMESPACE_ADDR"/24 dev "$NAMESPACE_SIDE_IF_NAME" # Add a bridge, give it an address (something nothing else is using) echo "Setting up bridge" - ip link add name ${BRIDGE_NAME} type bridge - ip -6 addr add ${BRIDGE_IPV6_ADDR}/64 dev ${BRIDGE_NAME} - ip addr add ${BRIDGE_ADDR}/24 brd + dev ${BRIDGE_NAME} + ip link add name "$BRIDGE_NAME" type bridge + ip -6 addr add "$BRIDGE_IPV6_ADDR"/64 dev "$BRIDGE_NAME" + ip addr add "$BRIDGE_ADDR"/24 brd + dev "$BRIDGE_NAME" # For ipv6 and ipv4 to work together, need the bridge to ignore the ipv6 packets (DROP here means don't bridge) - ebtables-legacy -t broute -A BROUTING -p ipv6 -j DROP -i ${HOST_SIDE_IF_NAME} - ip link set ${BRIDGE_NAME} up + ebtables-legacy -t broute -A BROUTING -p ipv6 -j DROP -i "$HOST_SIDE_IF_NAME" + ip link set "$BRIDGE_NAME" up # Connect the host side to the bridge, so now we have bridge <-> host_side_if <-> namespace_if echo "Connecting host virtual IF to bridge" - ip link set ${HOST_SIDE_IF_NAME} master ${BRIDGE_NAME} + ip link set "$HOST_SIDE_IF_NAME" master "$BRIDGE_NAME" #ip netns exec ${NAMESPACE} ip route add default via ${BRIDGE_ADDR} dev ${NAMESPACE_SIDE_IF_NAME} } @@ -91,20 +91,20 @@ function run_add_ipv4() { function run_cmd() { # Start the app in the namespace echo "Running $1 in namespace." - ip netns exec ${NAMESPACE} $1 + ip netns exec "$NAMESPACE" "$1" } function run_cleanup() { # Deleting the namespace will remove the namespace and peer'd interfaces to have_ebtables_legacy=$1 - ip netns delete ${NAMESPACE} - if ifconfig | grep ${BRIDGE_NAME}; then - if [ $have_ebtables_legacy = true ]; then + ip netns delete "$NAMESPACE" + if ifconfig | grep "$BRIDGE_NAME"; then + if [ "$have_ebtables_legacy" = true ]; then # Just try to drop the additional rule - it references our interface # so if it's there, we added it. - ebtables-legacy -t broute -D BROUTING -p ipv6 -j DROP -i ${HOST_SIDE_IF_NAME} >/dev/null + ebtables-legacy -t broute -D BROUTING -p ipv6 -j DROP -i "$HOST_SIDE_IF_NAME" >/dev/null fi - ip link delete dev ${BRIDGE_NAME} type bridge + ip link delete dev "$BRIDGE_NAME" type bridge fi } @@ -181,13 +181,13 @@ if [[ $EUID -ne 0 ]]; then exit 1 fi -if ifconfig | grep "${HOST_SIDE_IF_NAME}"; then +if ifconfig | grep "$HOST_SIDE_IF_NAME"; then issetup=true else issetup=false fi -if [ $setup = false ] && [ $run = false ] && [ $cleanup = false ]; then +if [ "$setup" = false ] && [ "$run" = false ] && [ "$cleanup" = false ]; then echo "Must specify one or more of -s, -r, -c." exit 1 fi @@ -198,36 +198,36 @@ else have_ebtables_legacy=false fi -if [ $ipv4 = true ] && [ $have_ebtables_legacy = false ]; then +if [ "$ipv4" = true ] && [ "$have_ebtables_legacy" = false ]; then echo "To set up namespaces with ipv4/ipv6 connectivity, ebtables-legacy" echo "is required. For example, to install on machines using APT:" echo "sudo apt-get install ebtables" exit 1 fi -if [ $run = true ]; then - if [ $issetup = false ]; then +if [ "$run" = true ]; then + if [ "$issetup" = false ]; then setup=true fi fi -if [ $setup = true ]; then - if [ $issetup = true ]; then +if [ "$setup" = true ]; then + if [ "$issetup" = true ]; then cleanup=true fi fi -if [ $cleanup = true ]; then - run_cleanup $have_ebtables_legacy +if [ "$cleanup" = true ]; then + run_cleanup "$have_ebtables_legacy" fi -if [ $setup = true ]; then +if [ "$setup" = true ]; then run_setup - if [ $ipv4 = true ]; then + if [ "$ipv4" = true ]; then run_add_ipv4 fi fi -if [ $run = true ]; then - run_cmd $filename +if [ "$run" = true ]; then + run_cmd "$filename" fi From 9217aeaf0dae0915e513ade61bfb94f7de7d510e Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 2 Jun 2021 00:17:53 +0000 Subject: [PATCH 6/6] Restyled by shfmt --- scripts/tools/linux_ip_namespace_setup.sh | 230 +++++++++++----------- 1 file changed, 115 insertions(+), 115 deletions(-) diff --git a/scripts/tools/linux_ip_namespace_setup.sh b/scripts/tools/linux_ip_namespace_setup.sh index b5904e625dcb72..1520efe1bc3368 100755 --- a/scripts/tools/linux_ip_namespace_setup.sh +++ b/scripts/tools/linux_ip_namespace_setup.sh @@ -42,95 +42,95 @@ BRIDGE_IPV6_ADDR=fc00::b NAMESPACE_IPV6_ADDR=fc00::a function run_setup() { - # Create namespace. - ip netns add "$NAMESPACE" + # Create namespace. + ip netns add "$NAMESPACE" - # Create two virtual interfaces and link them - one on host side, one on namespace side. - ip link add "$HOST_SIDE_IF_NAME" type veth peer name "$NAMESPACE_SIDE_IF_NAME" + # Create two virtual interfaces and link them - one on host side, one on namespace side. + ip link add "$HOST_SIDE_IF_NAME" type veth peer name "$NAMESPACE_SIDE_IF_NAME" - # Give the host a known IPv6 addr and set the host side up - ip -6 addr add "$HOST_IPV6_ADDR"/64 dev "$HOST_SIDE_IF_NAME" - ip link set "$HOST_SIDE_IF_NAME" up + # Give the host a known IPv6 addr and set the host side up + ip -6 addr add "$HOST_IPV6_ADDR"/64 dev "$HOST_SIDE_IF_NAME" + ip link set "$HOST_SIDE_IF_NAME" up - # Associate namespace IF with the namespace - ip link set "$NAMESPACE_SIDE_IF_NAME" netns "$NAMESPACE" + # Associate namespace IF with the namespace + ip link set "$NAMESPACE_SIDE_IF_NAME" netns "$NAMESPACE" - # Give the namespace IF an address (something nothing else is using) and set it up - echo "Adding address for namespace IF" - ip netns exec "$NAMESPACE" ip -6 addr add "$NAMESPACE_IPV6_ADDR"/64 dev "$NAMESPACE_SIDE_IF_NAME" - ip netns exec "$NAMESPACE" ip link set dev "$NAMESPACE_SIDE_IF_NAME" up + # Give the namespace IF an address (something nothing else is using) and set it up + echo "Adding address for namespace IF" + ip netns exec "$NAMESPACE" ip -6 addr add "$NAMESPACE_IPV6_ADDR"/64 dev "$NAMESPACE_SIDE_IF_NAME" + ip netns exec "$NAMESPACE" ip link set dev "$NAMESPACE_SIDE_IF_NAME" up - # Add a route to the namespace to go through the bridge - echo "Setting routes for namespace" - ip netns exec "$NAMESPACE" ip -6 route add default dev "$NAMESPACE_SIDE_IF_NAME" + # Add a route to the namespace to go through the bridge + echo "Setting routes for namespace" + ip netns exec "$NAMESPACE" ip -6 route add default dev "$NAMESPACE_SIDE_IF_NAME" - echo "Setup complete." + echo "Setup complete." } function run_add_ipv4() { - # Give the namespace an IPv4 address - ip netns exec "$NAMESPACE" ip addr add "$NAMESPACE_ADDR"/24 dev "$NAMESPACE_SIDE_IF_NAME" + # Give the namespace an IPv4 address + ip netns exec "$NAMESPACE" ip addr add "$NAMESPACE_ADDR"/24 dev "$NAMESPACE_SIDE_IF_NAME" - # Add a bridge, give it an address (something nothing else is using) - echo "Setting up bridge" - ip link add name "$BRIDGE_NAME" type bridge - ip -6 addr add "$BRIDGE_IPV6_ADDR"/64 dev "$BRIDGE_NAME" - ip addr add "$BRIDGE_ADDR"/24 brd + dev "$BRIDGE_NAME" + # Add a bridge, give it an address (something nothing else is using) + echo "Setting up bridge" + ip link add name "$BRIDGE_NAME" type bridge + ip -6 addr add "$BRIDGE_IPV6_ADDR"/64 dev "$BRIDGE_NAME" + ip addr add "$BRIDGE_ADDR"/24 brd + dev "$BRIDGE_NAME" - # For ipv6 and ipv4 to work together, need the bridge to ignore the ipv6 packets (DROP here means don't bridge) - ebtables-legacy -t broute -A BROUTING -p ipv6 -j DROP -i "$HOST_SIDE_IF_NAME" - ip link set "$BRIDGE_NAME" up + # For ipv6 and ipv4 to work together, need the bridge to ignore the ipv6 packets (DROP here means don't bridge) + ebtables-legacy -t broute -A BROUTING -p ipv6 -j DROP -i "$HOST_SIDE_IF_NAME" + ip link set "$BRIDGE_NAME" up - # Connect the host side to the bridge, so now we have bridge <-> host_side_if <-> namespace_if - echo "Connecting host virtual IF to bridge" - ip link set "$HOST_SIDE_IF_NAME" master "$BRIDGE_NAME" + # Connect the host side to the bridge, so now we have bridge <-> host_side_if <-> namespace_if + echo "Connecting host virtual IF to bridge" + ip link set "$HOST_SIDE_IF_NAME" master "$BRIDGE_NAME" - #ip netns exec ${NAMESPACE} ip route add default via ${BRIDGE_ADDR} dev ${NAMESPACE_SIDE_IF_NAME} + #ip netns exec ${NAMESPACE} ip route add default via ${BRIDGE_ADDR} dev ${NAMESPACE_SIDE_IF_NAME} } function run_cmd() { - # Start the app in the namespace - echo "Running $1 in namespace." - ip netns exec "$NAMESPACE" "$1" + # Start the app in the namespace + echo "Running $1 in namespace." + ip netns exec "$NAMESPACE" "$1" } function run_cleanup() { - # Deleting the namespace will remove the namespace and peer'd interfaces to - have_ebtables_legacy=$1 - ip netns delete "$NAMESPACE" - if ifconfig | grep "$BRIDGE_NAME"; then - if [ "$have_ebtables_legacy" = true ]; then - # Just try to drop the additional rule - it references our interface - # so if it's there, we added it. - ebtables-legacy -t broute -D BROUTING -p ipv6 -j DROP -i "$HOST_SIDE_IF_NAME" >/dev/null + # Deleting the namespace will remove the namespace and peer'd interfaces to + have_ebtables_legacy=$1 + ip netns delete "$NAMESPACE" + if ifconfig | grep "$BRIDGE_NAME"; then + if [ "$have_ebtables_legacy" = true ]; then + # Just try to drop the additional rule - it references our interface + # so if it's there, we added it. + ebtables-legacy -t broute -D BROUTING -p ipv6 -j DROP -i "$HOST_SIDE_IF_NAME" >/dev/null + fi + ip link delete dev "$BRIDGE_NAME" type bridge fi - ip link delete dev "$BRIDGE_NAME" type bridge - fi } function help() { - echo "Usage: $file_name [ options ... ]" - echo "" - - echo "This script is used to set up linux namespaces for Matter device testing" - echo "between a controller and device on the same linux machine." - echo "" - echo "To use this script, run the device code in a namespace using the -r command" - echo "and a controller in a seperate terminal to simulate two devices communicating" - echo "across a network." - echo "Example:" - echo "--------" - echo "Terminal 1:" - echo "sudo /$file_name -r /" - echo "" - echo "Terminal 2:" - echo "/chip-device-ctrl" - echo "" - echo "This script requires sudo for setup and requires access to ebtables-legacy" - echo "to set up dual ipv4/ipv6 namespaces. Defaults to ipv6 only." - echo "" - - echo "Options: + echo "Usage: $file_name [ options ... ]" + echo "" + + echo "This script is used to set up linux namespaces for Matter device testing" + echo "between a controller and device on the same linux machine." + echo "" + echo "To use this script, run the device code in a namespace using the -r command" + echo "and a controller in a seperate terminal to simulate two devices communicating" + echo "across a network." + echo "Example:" + echo "--------" + echo "Terminal 1:" + echo "sudo /$file_name -r /" + echo "" + echo "Terminal 2:" + echo "/chip-device-ctrl" + echo "" + echo "This script requires sudo for setup and requires access to ebtables-legacy" + echo "to set up dual ipv4/ipv6 namespaces. Defaults to ipv6 only." + echo "" + + echo "Options: -h, --help Display this information. -s, --setup Setup an IP namespace. Will run cleanup if namespace exists. -4, --ipv4 Add ipv4 support. @@ -148,86 +148,86 @@ declare ipv4=false file_name=${0##*/} while (($#)); do - case $1 in - --help | -h) - help - exit 1 - ;; - --setup | -s) - setup=true - ;; - --run | -r) - run=true - filename=$2 + case $1 in + --help | -h) + help + exit 1 + ;; + --setup | -s) + setup=true + ;; + --run | -r) + run=true + filename=$2 + shift + ;; + --cleanup | -c) + cleanup=true + ;; + --ipv4 | -4) + ipv4=true + ;; + -*) + help + echo "Unknown Option \"$1\"" + exit 1 + ;; + esac shift - ;; - --cleanup | -c) - cleanup=true - ;; - --ipv4 | -4) - ipv4=true - ;; - -*) - help - echo "Unknown Option \"$1\"" - exit 1 - ;; - esac - shift done if [[ $EUID -ne 0 ]]; then - echo "You must run this script with superuser privileges." - exit 1 + echo "You must run this script with superuser privileges." + exit 1 fi if ifconfig | grep "$HOST_SIDE_IF_NAME"; then - issetup=true + issetup=true else - issetup=false + issetup=false fi if [ "$setup" = false ] && [ "$run" = false ] && [ "$cleanup" = false ]; then - echo "Must specify one or more of -s, -r, -c." - exit 1 + echo "Must specify one or more of -s, -r, -c." + exit 1 fi if command -v ebtables-legacy >/dev/null; then - have_ebtables_legacy=true + have_ebtables_legacy=true else - have_ebtables_legacy=false + have_ebtables_legacy=false fi if [ "$ipv4" = true ] && [ "$have_ebtables_legacy" = false ]; then - echo "To set up namespaces with ipv4/ipv6 connectivity, ebtables-legacy" - echo "is required. For example, to install on machines using APT:" - echo "sudo apt-get install ebtables" - exit 1 + echo "To set up namespaces with ipv4/ipv6 connectivity, ebtables-legacy" + echo "is required. For example, to install on machines using APT:" + echo "sudo apt-get install ebtables" + exit 1 fi if [ "$run" = true ]; then - if [ "$issetup" = false ]; then - setup=true - fi + if [ "$issetup" = false ]; then + setup=true + fi fi if [ "$setup" = true ]; then - if [ "$issetup" = true ]; then - cleanup=true - fi + if [ "$issetup" = true ]; then + cleanup=true + fi fi if [ "$cleanup" = true ]; then - run_cleanup "$have_ebtables_legacy" + run_cleanup "$have_ebtables_legacy" fi if [ "$setup" = true ]; then - run_setup - if [ "$ipv4" = true ]; then - run_add_ipv4 - fi + run_setup + if [ "$ipv4" = true ]; then + run_add_ipv4 + fi fi if [ "$run" = true ]; then - run_cmd "$filename" + run_cmd "$filename" fi