|
@@ -2,100 +2,457 @@
|
|
|
|
|
|
# Public domain, not copyrighted..
|
|
|
|
|
|
-NUM=8
|
|
|
+set -u
|
|
|
+
|
|
|
+# number of bgpd instances, not more than 255 at this point. At least 3 are
|
|
|
+# needed to connect in a ring.
|
|
|
+NUM=7
|
|
|
+
|
|
|
+# The NUM peers can be connected in a ring topology.
|
|
|
+#
|
|
|
+# This sets the proportion of other peers that each peer should be
|
|
|
+# configured to connect to E.g., 20 means each BGP instance will peer with
|
|
|
+# 20% of the other peers before and after it in the ring. So 10% of the
|
|
|
+# peers prior to this instance in the ring, and 10% of the following peers.
|
|
|
+# 100 should lead to a full-mesh, for an odd total number of peers.
|
|
|
+#
|
|
|
+# A value of 1 will result in each instance having at least 2 peers in the ring.
|
|
|
+#
|
|
|
+# A value of 0 will disable creating a ring, in which case the only peers
|
|
|
+# configured will be those in the EXPEERS list.
|
|
|
+PEERPROP=100
|
|
|
+
|
|
|
+# number of routes each BGP instance should advertise
|
|
|
+ADV=10
|
|
|
+# First octet to use for the IPv4 advertisements. The advertisements
|
|
|
+# will be /32s under this /8. E.g. ADVPREF=10 will mean
|
|
|
+# 10.x.y.z/32's are advertised.
|
|
|
+ADVPREF=10
|
|
|
+
|
|
|
+# Base VTY port to allocate Quagga telnet vtys from. VTYBASE+ID will be
|
|
|
+# the port.
|
|
|
VTYBASE=2610
|
|
|
-ASBASE=64560
|
|
|
-BGPD=/path/to/bgpd
|
|
|
+# Base ASN to allocate ASNs to instances.
|
|
|
+ASBASE=64500
|
|
|
PREFIX=192.168.145.
|
|
|
#PREFIX=3ffe:123:456::
|
|
|
ADDRPLEN=32
|
|
|
CONFBASE=/tmp
|
|
|
PIDBASE=/var/run/quagga
|
|
|
-CHOWNSTR=quagga:quagga
|
|
|
-
|
|
|
-for H in `seq 1 ${NUM}` ; do
|
|
|
- CONF="${CONFBASE}"/bgpd${H}.conf
|
|
|
- ADDR=${PREFIX}${H}
|
|
|
-
|
|
|
- if [ ! -e "$CONF" ] ; then
|
|
|
- # This sets up a ring of bgpd peerings
|
|
|
- NEXT=$(( ($H % ${NUM}) + 1 ))
|
|
|
- PREV=$(( (($H + $NUM - 2) % ${NUM}) + 1 ))
|
|
|
- NEXT2=$(( (($H+1) % ${NUM}) + 1 ))
|
|
|
- PREV2=$(( (($H + $NUM - 3) % ${NUM}) + 1 ))
|
|
|
- NEXTADDR="${PREFIX}${NEXT}"
|
|
|
- NEXTAS=$((${ASBASE} + $NEXT))
|
|
|
- PREVADDR="${PREFIX}${PREV}"
|
|
|
- PREVAS=$((${ASBASE} + $PREV))
|
|
|
- NEXT2ADDR="${PREFIX}${NEXT2}"
|
|
|
- NEXT2AS=$((${ASBASE} + $NEXT2))
|
|
|
- PREV2ADDR="${PREFIX}${PREV2}"
|
|
|
- PREV2AS=$((${ASBASE} + $PREV2))
|
|
|
- ASN=$((64560+${H}))
|
|
|
+USER=quagga
|
|
|
+GROUP=quagga
|
|
|
+
|
|
|
+# MRAI to specify, where an implementation supports it.
|
|
|
+MRAI=1
|
|
|
+# Connect retry timer
|
|
|
+CONNECTRETRY=1
|
|
|
+
|
|
|
+# The binary locations for BGP instances.
|
|
|
+declare -A BGP_BINS=(
|
|
|
+ [quagga]=/usr/sbin/bgpd
|
|
|
+ [bird]=/usr/sbin/bird
|
|
|
+ [birdgit]=/home/paul/code/bird/bird
|
|
|
+ [quaggagit]=/home/paul/code/quagga/bgpd/bgpd
|
|
|
+ [exabgp]=/home/paul/code/exabgp/sbin/exabgp
|
|
|
+)
|
|
|
+
|
|
|
+# Configuration generation functions for the BGP instances.
|
|
|
+declare -A BGP_CONFIGGEN=(
|
|
|
+ [quagga]=quagga_config
|
|
|
+ [quaggagit]=quagga_config
|
|
|
+ [bird]=bird_config
|
|
|
+ [birdgit]=bird_config
|
|
|
+ [exabgp]=exabgp_config
|
|
|
+)
|
|
|
+
|
|
|
+# Launch functions for the BGP instances.
|
|
|
+declare -A BGP_LAUNCH=(
|
|
|
+ [quagga]=quagga_launch
|
|
|
+ [quaggagit]=quagga_launch
|
|
|
+ [bird]=bird_launch
|
|
|
+ [birdgit]=bird_launch
|
|
|
+ [quaggagit]=quagga_launch
|
|
|
+ [exabgp]=exabgp_launch
|
|
|
+)
|
|
|
+
|
|
|
+# the instances to run, in the order they should appear in the ring
|
|
|
+# (repeated over until there are $NUM instances). The value must exist as a
|
|
|
+# key into the above two arrays.
|
|
|
+declare -a BGP_INSTANCES=(
|
|
|
+ quagga
|
|
|
+ bird
|
|
|
+ quaggagit
|
|
|
+ exabgp
|
|
|
+)
|
|
|
+
|
|
|
+# Peers to configure, that are external to this script. One list of IPs, with
|
|
|
+# corresponding list of their ASes.
|
|
|
+#
|
|
|
+# e.g.:
|
|
|
+#EXPEERS=(192.168.147.{1..10})
|
|
|
+#EXPEERASES=($(seq $((ASBASE+11)) $(($ASBASE+20))))
|
|
|
+
|
|
|
+EXPEERS=()
|
|
|
+EXPEERASES=()
|
|
|
+
|
|
|
+############################################################################
|
|
|
+# Can override any of the above from a supplied file with declarations
|
|
|
+CONFWRITE=Y
|
|
|
+if [ $# -gt 0 ] ; then
|
|
|
+ echo "multiple-bgpd.sh: sourcing config from $1"
|
|
|
+ [ -f "$1" ] && . "$1"
|
|
|
+
|
|
|
+ # keep config, if exists
|
|
|
+ [ $# -gt 1 ] && [ "$2" = "k" ] && CONFWRITE=N
|
|
|
+fi
|
|
|
+
|
|
|
+############################################################################
|
|
|
+# Internal variables.
|
|
|
+
|
|
|
+# Number of peers for each instance to peer with
|
|
|
+PEERNUM=$(( ($NUM-1) * $PEERPROP / 100 ))
|
|
|
+[ "$PEERNUM" -gt $(($NUM-1)) ] && PEERNUM=$(($NUM-1))
|
|
|
+
|
|
|
+# the 'range', i.e. how many of the previous and next peers in the ring to
|
|
|
+# connect to
|
|
|
+PEERRANGE=$(( $PEERNUM/2 ))
|
|
|
+[ "$PEERPROP" -gt 0 -a "$NUM" -ge 3 -a "$PEERRANGE" -le 0 ] && PEERRANGE=1
|
|
|
+
|
|
|
+# and a convenience expansion
|
|
|
+PEEREXP=""
|
|
|
+if [ "$PEERRANGE" -gt 0 ]; then
|
|
|
+ PEEREXP=($(seq -${PEERRANGE} ${PEERRANGE}))
|
|
|
+ # dont need 0
|
|
|
+ unset PEEREXP[PEERRANGE]
|
|
|
+fi
|
|
|
+
|
|
|
+#echo ${PEEREXP[@]}
|
|
|
+
|
|
|
+############################################################################
|
|
|
+## helpers
|
|
|
+
|
|
|
+# translate instance ID to its address.
|
|
|
+id2addr () {
|
|
|
+ local ID=$1
|
|
|
+ echo ${PREFIX}${ID}
|
|
|
+}
|
|
|
+
|
|
|
+# return the ID of a peer, in terms of an offset on the given instance's ID.
|
|
|
+#
|
|
|
+# E.g., given an ID of 1 and an offset of -1, if there are 10 instances overall,
|
|
|
+# this will return 10.
|
|
|
+peeridoff () {
|
|
|
+ local ID=$1
|
|
|
+ local OFF=$2
|
|
|
+ echo $(( (($ID + $OFF - 1 + $NUM) % $NUM) + 1 ))
|
|
|
+}
|
|
|
+
|
|
|
+# return IPv4 address to advertise, for given instance ID and number.
|
|
|
+advipaddr () {
|
|
|
+ local ID=$1
|
|
|
+ local N=$2
|
|
|
+ echo "$ADVPREF.$(( ($N >> 16) %256 )).$(( ($N >> 8) % 256 )).$(( $N % 256 ))"
|
|
|
+}
|
|
|
+
|
|
|
+############################################################################
|
|
|
+# launch functions
|
|
|
+#
|
|
|
+# do not daemonise, so that all launched instances can be killed by killing
|
|
|
+# the script.
|
|
|
+#
|
|
|
+
|
|
|
+quagga_launch () {
|
|
|
+ local ID=$1
|
|
|
+ local ASN=$2
|
|
|
+ local ADDR=$3
|
|
|
+ local BIN=$4
|
|
|
+ local CONF=$5
|
|
|
+ ${BIN} -i "${PIDBASE}"/bgpd${ID}.pid \
|
|
|
+ -l ${ADDR} \
|
|
|
+ -f "${CONF}" \
|
|
|
+ -u $USER -g $GROUP \
|
|
|
+ -P $((${VTYBASE}+${ID}))
|
|
|
+}
|
|
|
+
|
|
|
+exabgp_launch () {
|
|
|
+ local ID=$1
|
|
|
+ local ASN=$2
|
|
|
+ local ADDR=$3
|
|
|
+ local BIN=$4
|
|
|
+ local CONF=$5
|
|
|
+
|
|
|
+ env exabgp.api.file="${PIDBASE}"/exabgp${ID}.ctl \
|
|
|
+ exabgp.daemon.pid="${PIDBASE}"/bgpd${ID}.pid \
|
|
|
+ exabgp.daemon.daemonize=false \
|
|
|
+ exabgp.tcp.bind=${ADDR} \
|
|
|
+ exabgp.log.enable=false \
|
|
|
+ exabgp.daemon.user=quagga \
|
|
|
+ ${BIN} ${CONF}
|
|
|
+}
|
|
|
+
|
|
|
+bird_launch () {
|
|
|
+ local ID=$1
|
|
|
+ local ASN=$2
|
|
|
+ local ADDR=$3
|
|
|
+ local BIN=$4
|
|
|
+ local CONF=$5
|
|
|
+ ${BIN} -P "${PIDBASE}"/bird${ID}.pid \
|
|
|
+ -c "${CONF}" \
|
|
|
+ -s "${PIDBASE}"/bird${ID}.ctl \
|
|
|
+ -f
|
|
|
+}
|
|
|
+
|
|
|
+#######################################################################
|
|
|
+#
|
|
|
+# functions to write the configuration for instances
|
|
|
+#
|
|
|
+
|
|
|
+exabgp_config () {
|
|
|
+ local ID=$1
|
|
|
+ local ASN=$2
|
|
|
+ local ADDR=$3
|
|
|
+
|
|
|
+ local N
|
|
|
+ local P
|
|
|
+
|
|
|
+ cat <<- EOF
|
|
|
+ group default {
|
|
|
+ local-address $ADDR;
|
|
|
+ local-as $ASN;
|
|
|
+ router-id $ADDR;
|
|
|
+
|
|
|
+ capability {
|
|
|
+ asn4 enable;
|
|
|
+ }
|
|
|
+ EOF
|
|
|
+
|
|
|
+ for N in $(seq 1 $ADV) ; do
|
|
|
+ echo " static {"
|
|
|
+ echo " route `advipaddr $ID $N`/32 {"
|
|
|
+ echo " next-hop $ADDR;"
|
|
|
+ echo " }"
|
|
|
+ echo " }"
|
|
|
+ done
|
|
|
+
|
|
|
+ for P in ${PEEREXP[@]}; do
|
|
|
+ [ "$P" -eq 0 ] && continue;
|
|
|
+
|
|
|
+ #local PID=$(( (($ID + $P - 1 + $NUM) % $NUM) + 1 ))
|
|
|
+ local PID=`peeridoff $ID $P`
|
|
|
+ #local PADDR="${PREFIX}${PID}"
|
|
|
+ local PADDR=`id2addr $PID`
|
|
|
+ local PAS=$((${ASBASE} + $PID))
|
|
|
|
|
|
- # Edit config to suit.
|
|
|
- cat > "$CONF" <<- EOF
|
|
|
- password whatever
|
|
|
- service advanced-vty
|
|
|
- !
|
|
|
- router bgp ${ASN}
|
|
|
- bgp router-id ${ADDR}
|
|
|
- maximum-paths 32
|
|
|
- bgp bestpath as-path multipath-relax
|
|
|
- network 10.${H}.1.0/24 pathlimit 1
|
|
|
- network 10.${H}.2.0/24 pathlimit 2
|
|
|
- network 10.${H}.3.0/24 pathlimit 3
|
|
|
- network 10.${H}.0.0/24
|
|
|
- neighbor default peer-group
|
|
|
- neighbor default update-source ${ADDR}
|
|
|
- neighbor default capability orf prefix-list both
|
|
|
- neighbor default soft-reconfiguration inbound
|
|
|
- neighbor default route-map test out
|
|
|
- neighbor ${NEXTADDR} remote-as ${NEXTAS}
|
|
|
- neighbor ${NEXTADDR} peer-group default
|
|
|
- neighbor ${PREVADDR} remote-as ${PREVAS}
|
|
|
- neighbor ${PREVADDR} peer-group default
|
|
|
- neighbor ${NEXT2ADDR} remote-as ${NEXT2AS}
|
|
|
- neighbor ${NEXT2ADDR} peer-group default
|
|
|
- neighbor ${PREV2ADDR} remote-as ${PREV2AS}
|
|
|
- neighbor ${PREV2ADDR} peer-group default
|
|
|
- !
|
|
|
- address-family ipv6
|
|
|
- network 3ffe:${H}::/48
|
|
|
- network 3ffe:${H}:1::/48 pathlimit 1
|
|
|
- network 3ffe:${H}:2::/48 pathlimit 3
|
|
|
- network 3ffe:${H}:3::/48 pathlimit 3
|
|
|
- neighbor default activate
|
|
|
- neighbor default capability orf prefix-list both
|
|
|
- neighbor default default-originate
|
|
|
- neighbor default route-map test out
|
|
|
- neighbor ${NEXTADDR} peer-group default
|
|
|
- neighbor ${PREVADDR} peer-group default
|
|
|
- neighbor ${NEXT2ADDR} peer-group default
|
|
|
- neighbor ${PREV2ADDR} peer-group default
|
|
|
- exit-address-family
|
|
|
- !
|
|
|
- ! bgpd still has problems with extcommunity rt/soo
|
|
|
- route-map test permit 10
|
|
|
- set extcommunity rt ${ASN}:1
|
|
|
- set extcommunity soo ${ASN}:2
|
|
|
- set community ${ASN}:1
|
|
|
- !
|
|
|
- line vty
|
|
|
- exec-timeout 0 0
|
|
|
- !
|
|
|
- end
|
|
|
- EOF
|
|
|
- chown ${CHOWNSTR} "$CONF"
|
|
|
+ echo " neighbor $PADDR {"
|
|
|
+ #echo " local-address $ADDR;"
|
|
|
+ #echo " local-as $ASN;"
|
|
|
+ #echo " graceful-restart;"
|
|
|
+ #echo " router-id $ADDR;"
|
|
|
+ echo " peer-as $PAS;"
|
|
|
+ echo " }"
|
|
|
+ done
|
|
|
+
|
|
|
+ for P in ${!EXPEERS[@]}; do
|
|
|
+ echo " neighbor ${EXPEERS[$P]} {"
|
|
|
+ echo " peer-as ${EXPEERASES[$P]};"
|
|
|
+ echo " }"
|
|
|
+ done
|
|
|
+
|
|
|
+ cat <<- EOF
|
|
|
+ }
|
|
|
+ EOF
|
|
|
+}
|
|
|
+
|
|
|
+quagga_config () {
|
|
|
+ local ID=$1
|
|
|
+ local ASN=$2
|
|
|
+ local ADDR=$3
|
|
|
+
|
|
|
+ local N
|
|
|
+ local P
|
|
|
+
|
|
|
+ # Edit config to suit.
|
|
|
+ cat <<- EOF
|
|
|
+ password foo
|
|
|
+ service advanced-vty
|
|
|
+ !
|
|
|
+ router bgp ${ASN}
|
|
|
+ bgp router-id ${ADDR}
|
|
|
+ !maximum-paths 32
|
|
|
+ !bgp bestpath as-path multipath-relax
|
|
|
+ EOF
|
|
|
+
|
|
|
+ for N in $(seq 1 $ADV) ; do
|
|
|
+ echo " network `advipaddr $ID $N`/32"
|
|
|
+ done
|
|
|
+
|
|
|
+ cat <<- EOF
|
|
|
+ neighbor default peer-group
|
|
|
+ neighbor default update-source ${ADDR}
|
|
|
+ neighbor default capability orf prefix-list both
|
|
|
+ !neighbor default soft-reconfiguration inbound
|
|
|
+ neighbor default advertisement-interval $MRAI
|
|
|
+ neighbor default timers connect $CONNECTRETRY
|
|
|
+ neighbor default route-map test out
|
|
|
+ EOF
|
|
|
+
|
|
|
+ for P in ${PEEREXP[@]}; do
|
|
|
+ [ "$P" -eq 0 ] && continue;
|
|
|
+
|
|
|
+ local PID=`peeridoff $ID $P`
|
|
|
+ local PADDR=`id2addr $PID`
|
|
|
+ local PAS=$((${ASBASE} + $PID))
|
|
|
+ echo " neighbor ${PADDR} remote-as ${PAS}"
|
|
|
+ echo " neighbor ${PADDR} peer-group default"
|
|
|
+ done
|
|
|
+
|
|
|
+ for P in ${!EXPEERS[@]}; do
|
|
|
+ echo " neighbor ${EXPEERS[$P]} remote-as ${EXPEERASES[$P]}"
|
|
|
+ echo " neighbor ${EXPEERS[$P]} peer-group default"
|
|
|
+ done
|
|
|
+
|
|
|
+ cat <<- EOF
|
|
|
+ !
|
|
|
+ address-family ipv6
|
|
|
+ network 3ffe:${ID}::/48
|
|
|
+ network 3ffe:${ID}:1::/48 pathlimit 1
|
|
|
+ network 3ffe:${ID}:2::/48 pathlimit 3
|
|
|
+ network 3ffe:${ID}:3::/48 pathlimit 3
|
|
|
+ neighbor default activate
|
|
|
+ neighbor default capability orf prefix-list both
|
|
|
+ neighbor default default-originate
|
|
|
+ neighbor default route-map test out
|
|
|
+ EOF
|
|
|
+
|
|
|
+ for P in ${PEEREXP[@]}; do
|
|
|
+ [ "$P" -eq 0 ] && continue;
|
|
|
+
|
|
|
+ local PID=`peeridoff $ID $P`
|
|
|
+ local PADDR=`id2addr $PID`
|
|
|
+ local PAS=$((${ASBASE} + $PID))
|
|
|
+ echo " neighbor ${PADDR} peer-group default"
|
|
|
+ done
|
|
|
+
|
|
|
+ cat <<- EOF
|
|
|
+ exit-address-family
|
|
|
+ !
|
|
|
+ ! bgpd still has problems with extcommunity rt/soo
|
|
|
+ route-map test permit 10
|
|
|
+ set extcommunity rt ${ASN}:1
|
|
|
+ set extcommunity soo ${ASN}:2
|
|
|
+ set community ${ASN}:1
|
|
|
+ !
|
|
|
+ line vty
|
|
|
+ exec-timeout 0 0
|
|
|
+ !
|
|
|
+ end
|
|
|
+ EOF
|
|
|
+}
|
|
|
+
|
|
|
+bird_config () {
|
|
|
+ local ID=$1
|
|
|
+ local ASN=$2
|
|
|
+ local ADDR=$3
|
|
|
+
|
|
|
+ cat <<- EOF
|
|
|
+ #log "/var/log/bird.log" all;
|
|
|
+ #debug protocols all;
|
|
|
+
|
|
|
+ # Override router ID
|
|
|
+ router id ${ADDR};
|
|
|
+ listen bgp address ${ADDR};
|
|
|
+
|
|
|
+ protocol kernel { device routes; import all; }
|
|
|
+ protocol device { import all; }
|
|
|
+
|
|
|
+ function avoid_martians()
|
|
|
+ prefix set martians;
|
|
|
+ {
|
|
|
+ martians = [
|
|
|
+ 224.0.0.0/4+, 240.0.0.0/4+
|
|
|
+ ];
|
|
|
+
|
|
|
+ # Avoid RFC1918 and similar networks
|
|
|
+ if net ~ martians then return false;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ filter import_filter
|
|
|
+ {
|
|
|
+ if ! (avoid_martians()) then reject;
|
|
|
+ accept;
|
|
|
+ }
|
|
|
+
|
|
|
+ filter set_comm
|
|
|
+ {
|
|
|
+ bgp_community.add ((${ASN}, 1));
|
|
|
+ accept;
|
|
|
+ }
|
|
|
+
|
|
|
+ template bgp peer_conf {
|
|
|
+ local as ${ASN};
|
|
|
+ source address ${ADDR};
|
|
|
+ import filter import_filter;
|
|
|
+ export filter set_comm;
|
|
|
+ multihop;
|
|
|
+ }
|
|
|
+ EOF
|
|
|
+
|
|
|
+ local P;
|
|
|
+
|
|
|
+ for P in ${PEEREXP[@]}; do
|
|
|
+ [ "$P" -eq 0 ] && continue;
|
|
|
+
|
|
|
+ local PID=`peeridoff $ID $P`
|
|
|
+ local PADDR=`id2addr $PID`
|
|
|
+ local PAS=$((${ASBASE} + $PID))
|
|
|
+ echo "protocol bgp from peer_conf {"
|
|
|
+ echo " neighbor ${PADDR} as ${PAS};"
|
|
|
+ echo "}"
|
|
|
+ done
|
|
|
+
|
|
|
+ for P in ${!EXPEERS[@]}; do
|
|
|
+ echo "protocol bgp from peer_conf {"
|
|
|
+ echo " neighbor ${EXPEERS[$P]} as ${EXPEERASES[$P]};"
|
|
|
+ echo "}"
|
|
|
+ done
|
|
|
+
|
|
|
+
|
|
|
+ for N in $(seq 1 $ADV) ; do
|
|
|
+ echo " network `advipaddr $ID $N`/32"
|
|
|
+ done
|
|
|
+}
|
|
|
+
|
|
|
+#######################################################################
|
|
|
+
|
|
|
+for ID in $(seq 1 $NUM); do
|
|
|
+ BGP_INST=${BGP_INSTANCES[${ID} % ${#BGP_INSTANCES[@]}]}
|
|
|
+ BGPBIN=${BGP_BINS[$BGP_INST]}
|
|
|
+ CONF="${CONFBASE}"/${BGP_INST}_bgpd${ID}.conf
|
|
|
+ ASN=$(($ASBASE + ${ID}))
|
|
|
+ ADDR=`id2addr $ID`
|
|
|
+
|
|
|
+ #if [ ! -e "$CONF" ] ; then
|
|
|
+ if [ ! -e "$CONF" -o "$CONFWRITE" = "Y" ] ; then
|
|
|
+ ${BGP_CONFIGGEN[$BGP_INST]} $ID $ASN $ADDR > "$CONF"
|
|
|
+ chown $USER:$GROUP "$CONF"
|
|
|
fi
|
|
|
# You may want to automatically add configure a local address
|
|
|
# on a loop interface.
|
|
|
#
|
|
|
# Solaris: ifconfig vni${H} plumb ${ADDR}/${ADDRPLEN} up
|
|
|
- # Linux: ip address add ${ADDR}/${ADDRPLEN} dev lo 2> /dev/null
|
|
|
- ${BGPD} -i "${PIDBASE}"/bgpd${H}.pid \
|
|
|
- -l ${ADDR} \
|
|
|
- -f "${CONF}" \
|
|
|
- -P $((${VTYBASE}+${H})) \
|
|
|
- -d
|
|
|
+ # Linux:
|
|
|
+ #ip address add ${ADDR}/${ADDRPLEN} dev lo 2> /dev/null
|
|
|
+
|
|
|
+ ip link add dummy${ID} type dummy 2> /dev/null
|
|
|
+ ip link set dev dummy${ID} up
|
|
|
+ ip address add ${ADDR}/${ADDRPLEN} dev dummy${ID} 2> /dev/null
|
|
|
+
|
|
|
+ ${BGP_LAUNCH[$BGP_INST]} $ID $ASN $ADDR $BGPBIN $CONF &
|
|
|
+
|
|
|
+ sleep 0.1
|
|
|
done
|
|
|
+
|
|
|
+echo "multiple-bgpd.sh: waiting..."
|
|
|
+
|
|
|
+wait
|