# Copyright (c) 2018 # Released under the 2-clause BSD license. # shellcheck shell=sh disable=SC1008 veth_depend() { program ip } _config_vars="$_config_vars veth" # We need it because _exists() function seeks in /sys/class/net _netns_exists() { [ -e "/var/run/netns/$1" ] } #Creates the network namespace if it doesn't exist. If called with no arguments, does nothing #Arguments: # $1 - name of the namespace _create_ns() { vethrc=0 for _ns in "$@"; do if [ -z "$_ns" ]; then continue fi if ! _netns_exists "$_ns"; then ip netns add "$_ns" > /dev/null 2>&1 vethrc=$(($?+ vethrc)) fi done return $vethrc } #Brings a virtual interface up and takes network namespaces into account #Arguments: # $1 - name of the interface, required! # $2 - namespace _bring_peer_up() { if [ ! -z "$2" ]; then ip link set "$1" netns "$2" > /dev/null 2>&1 vethrc=$? ip netns exec "$2" ip link set dev "$1" up > /dev/null 2>&1 vethrc=$(($?+ vethrc)) return $vethrc fi ip link set dev "$1" up > /dev/null 2>&1 return $? } #Brings a virtual interface down and takes network namespaces into account #Arguments: # $1 - name of the interface, required! # $2 - namespace _bring_peer_down() { if [ ! -z "$2" ]; then ip netns exec "$2" ip link del dev "$1" > /dev/null 2>&1 return $? fi ip link del dev "$1" > /dev/null 2>&1 return $? } #Create and bring the veth pair up _create_peers() { local peer1 peer1="$(_get_array "veth_${IFVAR}_peer1")" local peer2 peer2="$(_get_array "veth_${IFVAR}_peer2")" for x in $peer1 $peer2; do if _exists "$x" ; then eerror "Interface $x already exists. Can't continue" return 1 fi done local netns1 netns1="$(_get_array "veth_${IFVAR}_ns1")" local netns2 netns2="$(_get_array "veth_${IFVAR}_ns2")" local vethrc if ! _create_ns "$netns1" "$netns2" then eerror "Can't create namespaces: $netns1 $netns2" return 1 fi ip link add "$peer1" type veth peer name "$peer2" > /dev/null 2>&1 || { eerror "Can't create veth peer $peer1 or $peer2" return 1 } if ! _bring_peer_up "$peer1" "$netns1" then eerror "Can't bring the veth peer $peer1 up" return 1 fi if ! _bring_peer_up "$peer2" "$netns2" then eerror "Can't bring the veth peer $peer2 up" return 1 fi return 0 } # Create peers and namespaces veth_pre_start() { local itype eval itype=\$type_${IFVAR} if [ "$itype" != "veth" ]; then return 0 fi local createveth eval createveth=\$veth_${IFVAR}_create if [ "$createveth" = "no" ]; then return 0 fi type ip >/dev/null 2>&1 || { eerror "iproute2 nor found, please install iproute2" return 1 } if ! _create_peers then return 1 fi return 0 } #Delete the veth pair #We don't delete namespaces because someone may use them for some purposes veth_post_stop() { local itype eval itype=\$type_${IFVAR} if [ "$itype" != "veth" ]; then return 0 fi local createveth eval createveth=\$veth_${IFVAR}_create if [ "$createveth" == "no" ]; then return 0 fi local peer1 peer1="$(_get_array "veth_${IFVAR}_peer1")" local netns1 netns1="$(_get_array "veth_${IFVAR}_ns1")" if ! _bring_peer_down "$peer1" "$netns1" then eerror "Can't delete the veth pair ${IFVAR}" eend 1 fi return 0 }