1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
|
#!/bin/bash
# Save trace setting
_XTRACE_BAGPIPE_BGP=$(set +o | grep xtrace)
set -o xtrace
# Pre-install gobgp requirements
function pre_install_gobgp {
# Install go language and configure environment variables
install_package golang-go
export GOPATH=${GOPATH:-$DEST/go}
if [[ ! -d $GOPATH ]]; then
mkdir -p $GOPATH
fi
}
# Install gobgp
function install_gobgp {
# we install from binary, because compiling from source requires golang-1.7 which is not in ubuntu xenial
mkdir -p $GOPATH/bin
cd $GOPATH/bin
wget $GOBGP_RELEASE -qO - | tar xz
}
# Set config files, create data dirs, etc
function configure_bagpipe {
# Put config files in ``/etc/bagpipe-bgp`` for everyone to find
if [[ ! -d $BAGPIPE_CONF_DIR ]]; then
sudo mkdir -p $BAGPIPE_CONF_DIR
fi
sudo chown $STACK_USER $BAGPIPE_CONF_DIR
# place rootwrap config files
# this is done here so that these files are in place, even when
# bagpipe-bgp is not configured, specifically for the functional and
# fullstack gate jobs
BAGPIPE_BGP_RW_CONF=/etc/bagpipe-bgp/rootwrap.conf
BAGPIPE_BGP_RW_D=/etc/bagpipe-bgp/rootwrap.d
sudo install -o root -g root -m 644 $NETWORKING_BAGPIPE_DIR/etc/bagpipe-bgp/rootwrap.conf $BAGPIPE_BGP_RW_CONF
sudo install -d -o root -m 755 $BAGPIPE_BGP_RW_D/
sudo install -o root -m 644 $NETWORKING_BAGPIPE_DIR/etc/bagpipe-bgp/rootwrap.d/* $BAGPIPE_BGP_RW_D/
sudo sed -e "s:^filters_path=.*$:filters_path=$BAGPIPE_BGP_RW_D:" -i $BAGPIPE_BGP_RW_CONF
sudo sed -e 's:^exec_dirs=\(.*\)$:exec_dirs=\1,/usr/local/bin:' -i $BAGPIPE_BGP_RW_CONF
# Specify ``rootwrap.conf`` as first parameter to neutron-rootwrap
ROOTWRAP_SUDOER_CMD="$NEUTRON_ROOTWRAP $BAGPIPE_BGP_RW_CONF *"
ROOTWRAP_DAEMON_SUDOER_CMD="$NEUTRON_ROOTWRAP-daemon $BAGPIPE_BGP_RW_CONF"
# configure sudo to allow bagpipe-bgp rootwrap config
TEMPFILE=`mktemp`
echo "$STACK_USER ALL=(root) NOPASSWD: $ROOTWRAP_SUDOER_CMD" >$TEMPFILE
echo "$STACK_USER ALL=(root) NOPASSWD: $ROOTWRAP_DAEMON_SUDOER_CMD" >>$TEMPFILE
chmod 0440 $TEMPFILE
sudo chown root:root $TEMPFILE
sudo mv $TEMPFILE /etc/sudoers.d/bagpipe-rootwrap
if is_service_enabled neutron-bagpipe-bgp; then
# build the config file from scratch
create_bagpipe_conf
fi
}
# Create a new bgp.conf file
function create_bagpipe_conf {
# (Re)create ``bgp.conf``
cp -p $NETWORKING_BAGPIPE_DIR/etc/bagpipe-bgp/bgp.conf.template $BAGPIPE_CONF
# build config
iniset $BAGPIPE_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
iniset $BAGPIPE_CONF BGP local_address ${BAGPIPE_HOST_IP:-$HOST_IP}
if [[ $BAGPIPE_BGP_PEERS == "-" ]]; then
iniset $BAGPIPE_CONF BGP peers ""
else
iniset $BAGPIPE_CONF BGP peers "$BAGPIPE_BGP_PEERS"
fi
iniset $BAGPIPE_CONF API host $BAGPIPE_SERVICE_HOST
iniset $BAGPIPE_CONF API port $BAGPIPE_SERVICE_PORT
iniset $BAGPIPE_CONF DATAPLANE_DRIVER_IPVPN dataplane_driver ${BAGPIPE_DATAPLANE_DRIVER_IPVPN:-dummy}
iniset $BAGPIPE_CONF DATAPLANE_DRIVER_IPVPN mpls_interface $BAGPIPE_MPLS_IFACE
iniset $BAGPIPE_CONF DATAPLANE_DRIVER_IPVPN ovs_bridge $BAGPIPE_MPLS_BR
iniset $BAGPIPE_CONF DATAPLANE_DRIVER_EVPN dataplane_driver ${BAGPIPE_DATAPLANE_DRIVER_EVPN:-dummy}
iniset $BAGPIPE_CONF DATAPLANE_DRIVER_IPVPN arp_responder ${BAGPIPE_ARP_RESPONDER:-False}
iniset $BAGPIPE_CONF DATAPLANE_DRIVER_IPVPN proxy_arp ${BAGPIPE_PROXY_ARP:-False}
BAGPIPE_BGP_RW_COMMAND="sudo $NEUTRON_ROOTWRAP $BAGPIPE_BGP_RW_CONF"
BAGPIPE_BGP_RW_DAEMON_COMMAND="sudo $NEUTRON_ROOTWRAP-daemon $BAGPIPE_BGP_RW_CONF"
iniset $BAGPIPE_CONF common root_helper "$BAGPIPE_BGP_RW_COMMAND"
iniset $BAGPIPE_CONF common root_helper_daemon "$BAGPIPE_BGP_RW_DAEMON_COMMAND"
setup_logging $BAGPIPE_CONF
}
# Initialize databases, etc.
function init_bagpipe {
if [[ $BAGPIPE_DATAPLANE_DRIVER_IPVPN == *"MPLSOVSDataplaneDriver"* || $BAGPIPE_DATAPLANE_DRIVER_IPVPN == "ovs" ]]; then
init_bagpipe_ovsmpls
else
echo "IP VPN driver not OVS, let's not init OVS MPLS bridge (driver is '$BAGPIPE_DATAPLANE_DRIVER_IPVPN')"
fi
}
function init_bagpipe_ovsmpls {
BAGPIPE_BR_RESET_SCRIPT=$(mktemp /var/tmp/bagpipe-bgp-br-reset.XXXXX)
:> $BAGPIPE_BR_RESET_SCRIPT
if [ -n "$BAGPIPE_MPLS_IFACE" ]; then
cat >> $BAGPIPE_BR_RESET_SCRIPT <<EOF
echo "Setting up $BAGPIPE_MPLS_BR OVS bridge based on current $BAGPIPE_MPLS_IFACE settings"
MPLS_IFACE_IP=\`ip addr show $BAGPIPE_MPLS_IFACE | grep 'inet ' | awk '{ print \$2 }'\`
if [ -z "\$MPLS_IFACE_IP" ]; then
echo "Failure retrieving IP config of BaGPipe MPLS interface ($BAGPIPE_MPLS_IFACE): perhaps $BAGPIPE_MPLS_BR was configured already ?"
echo "Try to setup $BAGPIPE_MPLS_IFACE before trying again.."
return -1
fi
if [ "\`ip route | grep default | awk '{ print \$5 }'\`" == "$BAGPIPE_MPLS_IFACE" ]; then
GW_IP=\`ip route | grep default | awk '{ print \$3 }'\`
fi
#echo "adding bridge $BAGPIPE_MPLS_BR with interface $BAGPIPE_MPLS_IFACE"
sudo ip addr flush dev $BAGPIPE_MPLS_IFACE
sudo ovs-vsctl del-br $BAGPIPE_MPLS_BR || true
sudo ovs-vsctl --may-exist add-br $BAGPIPE_MPLS_BR -- set-fail-mode $BAGPIPE_MPLS_BR secure
sudo ovs-vsctl --may-exist add-port $BAGPIPE_MPLS_BR $BAGPIPE_MPLS_IFACE
# when devstack is ran in a VM deployed on openstack, by default, openstac
# will forbid this VM to use another MAC address than the one it has allocated
# use a port with the same MAC as the one used by BAGPIPE_MPLS_IFACE
MAC=\`ip link show dev $BAGPIPE_MPLS_IFACE | grep link/ether | awk '{ print \$2 }'\`
sudo ip link set dev $BAGPIPE_MPLS_BR address \$MAC
#echo "setting ip and port on $BAGPIPE_MPLS_BR"
sudo ip addr add \$MPLS_IFACE_IP dev $BAGPIPE_MPLS_BR
sudo ip link set $BAGPIPE_MPLS_BR up
if [ -n "\$GW_IP" ]; then
#echo "adding route to $\GW_IP"
sudo ip route add default via \$GW_IP
fi
# map traffic to/from the bagpipe port from/to the physical interface,
# traffic from the phy interface only goes to internal port as a last
# resort (if it did not match an MPLS rule)
BAGPIPE_MPLS_IFACE_PORT_NUMBER=\`sudo ovs-ofctl show $BAGPIPE_MPLS_BR | grep "($BAGPIPE_MPLS_IFACE)" | awk '-F(' '{print \$1}' | tr -d ' '\`
BAGPIPE_INTERNAL_PORT_NUMBER=\`sudo ovs-ofctl show $BAGPIPE_MPLS_BR | grep "($BAGPIPE_MPLS_BR)" | awk '-F(' '{print \$1}' | tr -d ' '\`
sudo ovs-ofctl add-flow $BAGPIPE_MPLS_BR priority=0,in_port=\$BAGPIPE_MPLS_IFACE_PORT_NUMBER,action=output:\$BAGPIPE_INTERNAL_PORT_NUMBER
sudo ovs-ofctl add-flow $BAGPIPE_MPLS_BR in_port=\$BAGPIPE_INTERNAL_PORT_NUMBER,action=output:\$BAGPIPE_MPLS_IFACE_PORT_NUMBER
EOF
else
cat >> $BAGPIPE_BR_RESET_SCRIPT <<EOF
sudo ovs-vsctl del-br $BAGPIPE_MPLS_BR || true
sudo ovs-vsctl --may-exist add-br $BAGPIPE_MPLS_BR -- set-fail-mode $BAGPIPE_MPLS_BR secure
EOF
fi
source $BAGPIPE_BR_RESET_SCRIPT
}
# Start the BGP component
function start_bagpipe_bgp {
if is_service_enabled neutron-bagpipe-bgp ; then
run_process neutron-bagpipe-bgp "${NEUTRON_BIN_DIR}/bagpipe-bgp"
run_process neutron-bagpipe-bgp-lg "/bin/sh -c 'while true; do date ; sleep 10; bagpipe-looking-glass -r vpns instances ; echo --------------------------------------------------; done'"
echo "Waiting for bagpipe-bgp to start..."
if ! wait_for_service $SERVICE_TIMEOUT http://$BAGPIPE_SERVICE_HOST:$BAGPIPE_SERVICE_PORT; then
die $LINENO "bagpipe-bgp did not start"
fi
fi
}
# Start the FakeRR component
function start_bagpipe_fakerr {
if is_service_enabled neutron-bagpipe-fakerr ; then
run_process neutron-bagpipe-fakerr "echo 'from networking_bagpipe.bagpipe_bgp.fakerr import application' | sudo twistd -n -y /dev/stdin"
fi
}
function start_bagpipe {
start_bagpipe_bgp
start_bagpipe_fakerr
}
function stop_bagpipe_bgp {
stop_process neutron-bagpipe-bgp
}
function stop_bagpipe_fakerr {
stop_process neutron-bagpipe-fakerr
}
# Stop running processes
function stop_bagpipe {
stop_bagpipe_bgp
stop_bagpipe_fakerr
}
# Remove residual data files, anything left over from previous runs that a
# clean run would need to clean up
function cleanup_bagpipe {
if is_service_enabled neutron-bagpipe-bgp ; then
sudo bagpipe-bgp-cleanup
MPLS_IFACE_IP=`ip addr show $BAGPIPE_INTERNAL_PORT | grep 'inet ' | awk '{ print $2 }'`
GW_IP=`ip route | grep default | awk '{ print $3 }'`
sudo ovs-vsctl del-br $BAGPIPE_MPLS_BR
sudo ip addr add $MPLS_IFACE_IP dev $BAGPIPE_MPLS_IFACE
sudo ip route add default via $GW_IP
fi
}
if [[ "$1" == "source" ]]; then
# no-op
:
elif [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
if is_service_enabled gobgp ; then
echo_summary "Installing golang package"
pre_install_gobgp
fi
elif [[ "$1" == "stack" && "$2" == "install" ]]; then
if is_service_enabled gobgp ; then
echo_summary "Installing GoBGP"
install_gobgp
fi
elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
echo_summary "Configuring Bagpipe"
configure_bagpipe
# Initializing before neutron starts is needed, so that we can move the single interface in br-mpls
init_bagpipe
elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
echo_summary "Starting Bagpipe"
start_bagpipe
fi
if [[ "$1" == "unstack" ]]; then
echo_summary "Stopping Bagpipe"
stop_bagpipe
cleanup_bagpipe
fi
if [[ "$1" == "clean" ]]; then
cleanup_bagpipe
fi
# restore xtrace state
${_XTRACE_BAGPIPE_BGP}
|