#!/usr/bin/env bash # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you 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. # modifyvxlan.sh -- adds and deletes VXLANs from a Routing Server # set -x ## TODO(VXLAN): MTU, IPv6 underlying usage() { printf "Usage: %s: -o (add | delete) -v -p -b \n" } addVxlan() { local vxlanId=$1 local pif=$2 local vxlanDev=vxlan$vxlanId local vxlanBr=$3 local mcastGrp="239.$(( ($vxlanId >> 16) % 256 )).$(( ($vxlanId >> 8) % 256 )).$(( $vxlanId % 256 ))" ## TODO(VXLAN): $brif (trafficlabel) should be passed from caller because we cannot assume 1:1 mapping between pif and brif. # lookup bridge interface local sysfs_dir=/sys/devices/virtual/net/ local brif=`find ${sysfs_dir}*/brif/ -name $pif | sed -e "s,$sysfs_dir,," | sed -e 's,/brif/.*$,,'` if [ "$brif " == " " ] then if [ -d "/sys/class/net/${pif}" ] then # if bridge is not found, but matches a pif, use it brif=$pif else printf "Failed to lookup bridge interface which includes pif: $pif." return 1 fi else # confirm ip address of $brif ip addr show $brif | grep -w inet if [ $? -gt 0 ] then printf "Failed to find vxlan multicast source ip address on brif: $brif." return 1 fi fi # mcast route ## TODO(VXLAN): Can we assume there're only one IP address which can be multicast src IP on the IF? ip route get $mcastGrp | grep -w "dev $brif" if [ $? -gt 0 ] then ip route add $mcastGrp/32 dev $brif if [ $? -gt 0 ] then printf "Failed to add vxlan multicast route on brif: $brif." return 1 fi fi if [ ! -d /sys/class/net/$vxlanDev ] then ip link add $vxlanDev type vxlan id $vxlanId group $mcastGrp ttl 10 dev $brif if [ $? -gt 0 ] then # race condition that someone already creates the vxlan if [ ! -d /sys/class/net/$vxlanDev ] then printf "Failed to create vxlan $vxlanId on brif: $brif." return 1 fi fi fi # is up? ip link show $vxlanDev | grep -w UP > /dev/null if [ $? -gt 0 ] then ip link set $vxlanDev up > /dev/null fi if [ ! -d /sys/class/net/$vxlanBr ] then brctl addbr $vxlanBr > /dev/null if [ $? -gt 0 ] then if [ ! -d /sys/class/net/$vxlanBr ] then printf "Failed to create br: $vxlanBr" return 2 fi fi brctl setfd $vxlanBr 0 fi #pif is eslaved into vxlanBr? ls /sys/class/net/$vxlanBr/brif/ | grep -w "$vxlanDev" > /dev/null if [ $? -gt 0 ] then brctl addif $vxlanBr $vxlanDev > /dev/null if [ $? -gt 0 ] then ls /sys/class/net/$vxlanBr/brif/ | grep -w "$vxlanDev" > /dev/null if [ $? -gt 0 ] then printf "Failed to add vxlan: $vxlanDev to $vxlanBr" return 3 fi fi fi # is vxlanBr up? ip link show $vxlanBr | grep -w UP > /dev/null if [ $? -gt 0 ] then ip link set $vxlanBr up fi return 0 } deleteVxlan() { local vxlanId=$1 local pif=$2 local vxlanDev=vxlan$vxlanId local vxlanBr=$3 local mcastGrp="239.$(( ($vxlanId >> 16) % 256 )).$(( ($vxlanId >> 8) % 256 )).$(( $vxlanId % 256 ))" local sysfs_dir=/sys/devices/virtual/net/ local brif=`find ${sysfs_dir}*/brif/ -name $pif | sed -e "s,$sysfs_dir,," | sed -e 's,/brif/.*$,,'` ip route del $mcastGrp/32 dev $brif ip link delete $vxlanDev if [ $? -gt 0 ] then printf "Failed to del vxlan: $vxlanId" printf "Continue..." fi ip link set $vxlanBr down if [ $? -gt 0 ] then return 1 fi brctl delbr $vxlanBr if [ $? -gt 0 ] then printf "Failed to del bridge $vxlanBr" return 1 fi return 0 } op= vxlanId= option=$@ while getopts 'o:v:p:b:' OPTION do case $OPTION in o) oflag=1 op="$OPTARG" ;; v) vflag=1 vxlanId="$OPTARG" ;; p) pflag=1 pif="$OPTARG" ;; b) bflag=1 brName="$OPTARG" ;; ?) usage exit 2 ;; esac done # Check that all arguments were passed in if [ "$oflag$vflag$pflag$bflag" != "1111" ] then usage exit 2 fi # Do we support Vxlan? lsmod|grep ^vxlan >& /dev/null if [ $? -gt 0 ] then modprobe=`modprobe vxlan 2>&1` if [ $? -gt 0 ] then printf "Failed to load vxlan kernel module: $modprobe" exit 1 fi fi if [ "$op" == "add" ] then # Add the vxlan addVxlan $vxlanId $pif $brName # If the add fails then return failure if [ $? -gt 0 ] then exit 1 fi else if [ "$op" == "delete" ] then # Delete the vxlan deleteVxlan $vxlanId $pif $brName # Always exit with success exit 0 fi fi