#!/bin/bash # # Copyright (c) 2022 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. # # Enable/disable/restart Open IoT SDK networking environment. NAMESPACE_NAME="ns" HOST_SIDE_IF_NAME="hveth" NAMESPACE_SIDE_IF_NAME="nveth" TAP_TUN_INTERFACE_NAME="tap" BRIDGE_INTERFACE_NAME="br" HOST_IPV6_ADDR="fe00::1" NAMESPACE_IPV6_ADDR="fe00::2" HOST_IPV4_ADDR="10.200.1.1" NAMESPACE_IPV4_ADDR="10.200.1.2" NAME="ARM" INTERNET_ENABLE=false USER="$(id -u -n)" if [ "$EUID" -ne 0 ]; then echo "Run a script with root permissions" exit 1 fi function show_usage() { cat < Open IoT SDK network base name -u,--user Network user -I,--Internet Add Internet connection support to network namespace command: up down restart EOF } function net_ns_up() { # Enable IPv6 and IP-forwarding sysctl net.ipv6.conf.all.disable_ipv6=0 net.ipv4.conf.all.forwarding=1 net.ipv6.conf.all.forwarding=1 echo "Create $NAMESPACE_NAME network namespace" # Create namespace. ip netns add "$NAMESPACE_NAME" # Enable lo interface in namespace ip netns exec "$NAMESPACE_NAME" ip link set dev lo up echo "Adding $HOST_SIDE_IF_NAME veth with peer $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 echo "Set IP addresses $HOST_IPV4_ADDR/24 $HOST_IPV6_ADDR/64 to $HOST_SIDE_IF_NAME interface" ip addr add "$HOST_IPV4_ADDR"/24 dev "$HOST_SIDE_IF_NAME" ip -6 addr add "$HOST_IPV6_ADDR"/64 dev "$HOST_SIDE_IF_NAME" ip link set "$HOST_SIDE_IF_NAME" up echo "Adding $NAMESPACE_SIDE_IF_NAME veth to namespace $NAMESPACE_NAME" # Associate namespace IF with the namespace ip link set "$NAMESPACE_SIDE_IF_NAME" netns "$NAMESPACE_NAME" ip netns exec "$NAMESPACE_NAME" ip link set dev "$NAMESPACE_SIDE_IF_NAME" up echo "Create $TAP_TUN_INTERFACE_NAME TAP device" ip netns exec "$NAMESPACE_NAME" ip tuntap add dev "$TAP_TUN_INTERFACE_NAME" mode tap user "$USER" ip netns exec "$NAMESPACE_NAME" ifconfig "$TAP_TUN_INTERFACE_NAME" 0.0.0.0 promisc echo "Create $BRIDGE_INTERFACE_NAME bridge interface between $NAMESPACE_SIDE_IF_NAME and $TAP_TUN_INTERFACE_NAME" ip netns exec "$NAMESPACE_NAME" ip link add "$BRIDGE_INTERFACE_NAME" type bridge echo "Set IP addresses $NAMESPACE_IPV4_ADDR/24 $NAMESPACE_IPV6_ADDR/64 to $BRIDGE_INTERFACE_NAME bridge interface" ip netns exec "$NAMESPACE_NAME" ip -6 addr add "$NAMESPACE_IPV6_ADDR"/64 dev "$BRIDGE_INTERFACE_NAME" ip netns exec "$NAMESPACE_NAME" ip addr add "$NAMESPACE_IPV4_ADDR"/24 dev "$BRIDGE_INTERFACE_NAME" ip netns exec "$NAMESPACE_NAME" ip addr flush dev "$NAMESPACE_SIDE_IF_NAME" ip netns exec "$NAMESPACE_NAME" ip link set "$TAP_TUN_INTERFACE_NAME" master "$BRIDGE_INTERFACE_NAME" ip netns exec "$NAMESPACE_NAME" ip link set "$NAMESPACE_SIDE_IF_NAME" master "$BRIDGE_INTERFACE_NAME" ip netns exec "$NAMESPACE_NAME" ip link set dev "$BRIDGE_INTERFACE_NAME" up ip netns exec "$NAMESPACE_NAME" ip route add default via "$HOST_IPV4_ADDR" if "$INTERNET_ENABLE"; then echo "Set Internet connection to $NAMESPACE_NAME namespace" DEFAULT_ROUTE=$(route | grep '^default' | grep -o '[^ ]*$') echo "Default route interface $DEFAULT_ROUTE" # Enable masquerading of namespace IP address iptables -t nat -A POSTROUTING -s "$NAMESPACE_IPV4_ADDR"/24 -o "$DEFAULT_ROUTE" -j MASQUERADE iptables -A FORWARD -i "$DEFAULT_ROUTE" -o "$HOST_SIDE_IF_NAME" -j ACCEPT iptables -A FORWARD -o "$DEFAULT_ROUTE" -i "$HOST_SIDE_IF_NAME" -j ACCEPT fi echo "$NAMESPACE_NAME namespace configuration" ip netns exec "$NAMESPACE_NAME" ifconfig echo "Host configuration" ifconfig } function net_ns_down() { ip netns delete "$NAMESPACE_NAME" ip link delete dev "$HOST_SIDE_IF_NAME" echo "Host configuration" ifconfig } SHORT=n:,u:,I,h, LONG=name:,user:,Internet,help OPTS=$(getopt -n build --options "$SHORT" --longoptions "$LONG" -- "$@") eval set -- "$OPTS" while :; do case "$1" in -h | --help) show_usage exit 0 ;; -n | --name) NAME=$2 shift 2 ;; -u | --user) USER=$2 shift 2 ;; -I | --Internet) INTERNET_ENABLE=true shift ;; -* | --*) shift break ;; *) echo "Unexpected option: $1" show_usage exit 2 ;; esac done if [[ $# -lt 1 ]]; then show_usage >&2 exit 1 fi case "$1" in up | down | restart) COMMAND=$1 ;; *) echo "ERROR: Command $COMMAND not supported" show_usage exit 1 ;; esac NAMESPACE_NAME="$NAME$NAMESPACE_NAME" HOST_SIDE_IF_NAME="$NAME$HOST_SIDE_IF_NAME" NAMESPACE_SIDE_IF_NAME="$NAME$NAMESPACE_SIDE_IF_NAME" TAP_TUN_INTERFACE_NAME="$NAME$TAP_TUN_INTERFACE_NAME" BRIDGE_INTERFACE_NAME="$NAME$BRIDGE_INTERFACE_NAME" if [[ "$COMMAND" == *"down"* || "$COMMAND" == *"restart"* ]]; then net_ns_down fi if [[ "$COMMAND" == *"up"* || "$COMMAND" == *"restart"* ]]; then net_ns_up fi