blob: e5d5739ac129e1d0c2fdc8f2db8ae27f80e44584 [file] [log] [blame]
#!/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 <<EOF
Usage: $0 [options] command
Enable, disable or restart Open IoT SDK networking environment.
Options:
-h,--help Show this help
-n,--name <base_name> Open IoT SDK network base name <base_name - default is ARM>
-u,--user <user_name> Network user <user_name - default is current user>
-I,--Internet Add Internet connection support to network namespace <disabled by default>
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