Skip to content

Instantly share code, notes, and snippets.

@raspi
Created August 14, 2022 16:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save raspi/7d0d2f876002566da309a0f4fdfd5c19 to your computer and use it in GitHub Desktop.
Save raspi/7d0d2f876002566da309a0f4fdfd5c19 to your computer and use it in GitHub Desktop.
Setup Linux namespace network with virtual bridge
#!/bin/bash
# (C) Pekka Järvinen 2022
# Name for bridge which virtual namespaces will use to communicate with each other
BRIDGENAME="gamebr0"
# Prefix for network
NETPREFIX="192.168.255."
# Starting IP (NETPREFIX + this)
let STARTIP=10
# How many virtual player namespaces to create
# 4 is good for 2 x 2 screen
let PLAYERCOUNT=4
# Old cleanup
if [[ -d "/sys/class/net/$BRIDGENAME" ]]
then
ip link del dev $BRIDGENAME
fi
while read NS; do
ip netns delete $NS
done < <(ip netns list | grep "^player" )
# Remove player* interfaces
find /sys/class/net -maxdepth 1 -iname "player*" -printf "%f\n" | xargs -I{} ip link del dev {}
# Setup
echo "Setting up bridge $BRIDGENAME"
ip link add $BRIDGENAME type bridge
ip addr add ${NETPREFIX}1/24 dev $BRIDGENAME
ip link set $BRIDGENAME up
echo ""
let PIP=$STARTIP
for (( i=0; i<=$PLAYERCOUNT; i++ )) do
echo "Setting up player #$i network namespace..."
echo " Adding namespace: player$i"
ip netns add player$i
# Bring lo up
ip netns exec player$i ip link set lo up
echo " Adding virtual ethernet device player${i}eth and TAP player${i}tap0"
ip link add player${i}eth type veth peer name player${i}tap0
ip link set player${i}tap0 up
echo " Attaching player${i}tap0 to $BRIDGENAME"
ip link set player${i}tap0 master $BRIDGENAME
echo " Moving player${i}eth to namespace player$i"
ip link set player${i}eth netns player$i
echo " Setting IP address to ${NETPREFIX}${PIP}/24"
ip netns exec player$i ip address add "${NETPREFIX}${PIP}/24" dev player${i}eth
((PIP=PIP+1))
# Bring veth up
ip netns exec player$i ip link set player${i}eth up
# Show address to user
ip netns exec player$i ip addr show player${i}eth
echo "-----------------------------------------"
done
echo ""
echo "Testing network with ping..."
for (( i=0; i<=$PLAYERCOUNT; i++ )) do
let NStoBErr=0
let BtoNSErr=0
# Ping bridge from namespace
ip netns exec player$i ping -q -n -c1 ${NETPREFIX}1 > /dev/null || NStoBErr=1
# Ping namespace from bridge
ping -I $BRIDGENAME -q -n -c1 ${NETPREFIX}$(expr $STARTIP + $i) > /dev/null || BtoNSErr=1
if [ $NStoBErr -eq 1 ]
then
echo "!! Failed to ping ${NETPREFIX}1 ($BRIDGENAME) from NS player$i. Please check your firewall and IP forwarding kernel settings."
exit 1
fi
if [ $BtoNSErr -eq 1 ]
then
echo "!! Failed to ping ${NETPREFIX}$(expr $STARTIP + $i) (NS player$i) from $BRIDGENAME. Please check your firewall and IP forwarding kernel settings."
exit 1
fi
done
echo "Player network added successfully!"
echo ""
echo "Bridge:"
ip addr show $BRIDGENAME
echo ""
echo "Done."
echo ""
echo "Test that namespace networking works with:"
echo " ping -I $BRIDGENAME ${NETPREFIX}1"
echo " ping -I $BRIDGENAME ${NETPREFIX}$STARTIP"
echo " ping -I $BRIDGENAME ${NETPREFIX}$(expr $STARTIP + 1)"
echo " sudo ip netns exec player1 ping ${NETPREFIX}1"
echo " sudo ip netns exec player2 ping ${NETPREFIX}1"
echo " sudo ip netns exec player1 ping ${NETPREFIX}$(expr $STARTIP + 1)"
echo " sudo ip netns exec player2 ping ${NETPREFIX}$STARTIP"
echo ""
echo "Show namespaces with:"
echo " ip netns"
echo ""
echo "Delete networks and namespaces after use (or just reboot):"
for (( i=0; i<=$PLAYERCOUNT; i++ )) do
echo " sudo ip netns delete player${i}"
#echo "sudo ip link del dev player${i}tap0"
done
echo "sudo ip link del dev $BRIDGENAME"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment