mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 01:32:18 +02:00
164 lines
4.2 KiB
Bash
Executable File
164 lines
4.2 KiB
Bash
Executable File
#!/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.
|
|
|
|
#
|
|
# Use BGP+EVPN for VXLAN with CloudStack instead of Multicast
|
|
#
|
|
# The default 'modifyvxlan.sh' script from CloudStack uses Multicast instead of EVPN for VXLAN
|
|
# In order to use this script and thus utilize BGP+EVPN, symlink this file:
|
|
#
|
|
# cd /usr/share
|
|
# ln -s cloudstack-common/scripts/vm/network/vnet/modifyvxlan-evpn.sh modifyvxlan.sh
|
|
#
|
|
#
|
|
# CloudStack will not handle the BGP configuration nor communication, the operator of the hypervisor will
|
|
# need to configure the properly.
|
|
#
|
|
# Frrouting is recommend to be used on the hypervisor to establish BGP sessions with upstream routers and
|
|
# exchange BGP+EVPN information.
|
|
#
|
|
# More information about BGP and EVPN with FRR: https://vincent.bernat.ch/en/blog/2017-vxlan-bgp-evpn
|
|
#
|
|
|
|
DSTPORT=4789
|
|
|
|
# We bind our VXLAN tunnel IP(v4) on Loopback device 'lo'
|
|
DEV="lo"
|
|
|
|
usage() {
|
|
echo "Usage: $0: -o <op>(add | delete) -v <vxlan id> -p <pif> -b <bridge name> (-6)"
|
|
}
|
|
|
|
localAddr() {
|
|
local FAMILY=$1
|
|
|
|
if [[ -z "$FAMILY" || $FAMILY == "inet" ]]; then
|
|
ip -4 -o addr show scope global dev ${DEV} | awk 'NR==1 {gsub("/[0-9]+", "") ; print $4}'
|
|
fi
|
|
|
|
if [[ "$FAMILY" == "inet6" ]]; then
|
|
ip -6 -o addr show scope global dev ${DEV} | awk 'NR==1 {gsub("/[0-9]+", "") ; print $4}'
|
|
fi
|
|
}
|
|
|
|
addVxlan() {
|
|
local VNI=$1
|
|
local PIF=$2
|
|
local VXLAN_BR=$3
|
|
local FAMILY=$4
|
|
local VXLAN_DEV=vxlan${VNI}
|
|
local ADDR=$(localAddr ${FAMILY})
|
|
|
|
echo "local addr for VNI ${VNI} is ${ADDR}"
|
|
|
|
if [[ ! -d /sys/class/net/${VXLAN_DEV} ]]; then
|
|
ip -f ${FAMILY} link add ${VXLAN_DEV} type vxlan id ${VNI} local ${ADDR} dstport ${DSTPORT} nolearning
|
|
ip link set ${VXLAN_DEV} up
|
|
sysctl -qw net.ipv6.conf.${VXLAN_DEV}.disable_ipv6=1
|
|
fi
|
|
|
|
if [[ ! -d /sys/class/net/$VXLAN_BR ]]; then
|
|
ip link add name ${VXLAN_BR} type bridge
|
|
ip link set ${VXLAN_BR} up
|
|
sysctl -qw net.ipv6.conf.${VXLAN_BR}.disable_ipv6=1
|
|
fi
|
|
|
|
bridge link show|grep ${VXLAN_BR}|awk '{print $2}'|grep "^${VXLAN_DEV}\$" > /dev/null
|
|
if [[ $? -gt 0 ]]; then
|
|
ip link set ${VXLAN_DEV} master ${VXLAN_BR}
|
|
fi
|
|
}
|
|
|
|
deleteVxlan() {
|
|
local VNI=$1
|
|
local PIF=$2
|
|
local VXLAN_BR=$3
|
|
local FAMILY=$4
|
|
local VXLAN_DEV=vxlan${VNI}
|
|
|
|
ip link set ${VXLAN_DEV} nomaster
|
|
ip link delete ${VXLAN_DEV}
|
|
|
|
ip link set ${VXLAN_BR} down
|
|
ip link delete ${VXLAN_BR} type bridge
|
|
}
|
|
|
|
OP=
|
|
VNI=
|
|
FAMILY=inet
|
|
option=$@
|
|
|
|
while getopts 'o:v:p:b:6' OPTION
|
|
do
|
|
case $OPTION in
|
|
o) oflag=1
|
|
OP="$OPTARG"
|
|
;;
|
|
v) vflag=1
|
|
VNI="$OPTARG"
|
|
;;
|
|
p) pflag=1
|
|
PIF="$OPTARG"
|
|
;;
|
|
b) bflag=1
|
|
BRNAME="$OPTARG"
|
|
;;
|
|
6)
|
|
FAMILY=inet6
|
|
;;
|
|
?) usage
|
|
exit 2
|
|
;;
|
|
esac
|
|
done
|
|
|
|
if [[ "$oflag$vflag$pflag$bflag" != "1111" ]]; then
|
|
usage
|
|
exit 2
|
|
fi
|
|
|
|
lsmod|grep ^vxlan >& /dev/null
|
|
if [[ $? -gt 0 ]]; then
|
|
modprobe=`modprobe vxlan 2>&1`
|
|
if [[ $? -gt 0 ]]; then
|
|
echo "Failed to load vxlan kernel module: $modprobe"
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
|
|
#
|
|
# Add a lockfile to prevent this script from running twice on the same host
|
|
# this can cause a race condition
|
|
#
|
|
|
|
LOCKFILE=/var/run/cloud/vxlan.lock
|
|
|
|
(
|
|
flock -x -w 10 200 || exit 1
|
|
if [[ "$OP" == "add" ]]; then
|
|
addVxlan ${VNI} ${PIF} ${BRNAME} ${FAMILY}
|
|
|
|
if [[ $? -gt 0 ]]; then
|
|
exit 1
|
|
fi
|
|
elif [[ "$OP" == "delete" ]]; then
|
|
deleteVxlan ${VNI} ${PIF} ${BRNAME} ${FAMILY}
|
|
fi
|
|
) 200>${LOCKFILE}
|