3 # Public domain, not copyrighted..
7 # number of bgpd instances, not more than 255 at this point. At least 3 are
8 # needed to connect in a ring.
11 # The NUM peers can be connected in a ring topology.
13 # This sets the proportion of other peers that each peer should be
14 # configured to connect to E.g., 20 means each BGP instance will peer with
15 # 20% of the other peers before and after it in the ring. So 10% of the
16 # peers prior to this instance in the ring, and 10% of the following peers.
17 # 100 should lead to a full-mesh, for an odd total number of peers.
19 # A value of 1 will result in each instance having at least 2 peers in the ring.
21 # A value of 0 will disable creating a ring, in which case the only peers
22 # configured will be those in the EXPEERS list.
25 # number of routes each BGP instance should advertise
27 # First octet to use for the IPv4 advertisements. The advertisements
28 # will be /32s under this /8. E.g. ADVPREF=10 will mean
29 # 10.x.y.z/32's are advertised.
32 # Base VTY port to allocate Quagga telnet vtys from. VTYBASE+ID will be
35 # Base ASN to allocate ASNs to instances.
38 #PREFIX=3ffe:123:456::
41 PIDBASE=/var/run/quagga
45 # MRAI to specify, where an implementation supports it.
50 # The binary locations for BGP instances.
52 [quagga]=/usr/sbin/bgpd
54 [birdgit]=/home/paul/code/bird/bird
55 [quaggagit]=/home/paul/code/quagga/bgpd/bgpd
56 [exabgp]=/home/paul/code/exabgp/sbin/exabgp
59 # Configuration generation functions for the BGP instances.
60 declare -A BGP_CONFIGGEN=(
61 [quagga]=quagga_config
62 [quaggagit]=quagga_config
65 [exabgp]=exabgp_config
68 # Launch functions for the BGP instances.
69 declare -A BGP_LAUNCH=(
70 [quagga]=quagga_launch
71 [quaggagit]=quagga_launch
74 [quaggagit]=quagga_launch
75 [exabgp]=exabgp_launch
78 # the instances to run, in the order they should appear in the ring
79 # (repeated over until there are $NUM instances). The value must exist as a
80 # key into the above two arrays.
81 declare -a BGP_INSTANCES=(
88 # Peers to configure, that are external to this script. One list of IPs, with
89 # corresponding list of their ASes.
92 #EXPEERS=(192.168.147.{1..10})
93 #EXPEERASES=($(seq $((ASBASE+11)) $(($ASBASE+20))))
98 ############################################################################
99 # Can override any of the above from a supplied file with declarations
101 if [ $# -gt 0 ] ; then
102 echo "multiple-bgpd.sh: sourcing config from $1"
103 [ -f "$1" ] && . "$1"
105 # keep config, if exists
106 [ $# -gt 1 ] && [ "$2" = "k" ] && CONFWRITE=N
109 ############################################################################
110 # Internal variables.
112 # Number of peers for each instance to peer with
113 PEERNUM=$(( ($NUM-1) * $PEERPROP / 100 ))
114 [ "$PEERNUM" -gt $(($NUM-1)) ] && PEERNUM=$(($NUM-1))
116 # the 'range', i.e. how many of the previous and next peers in the ring to
118 PEERRANGE=$(( $PEERNUM/2 ))
119 [ "$PEERPROP" -gt 0 -a "$NUM" -ge 3 -a "$PEERRANGE" -le 0 ] && PEERRANGE=1
121 # and a convenience expansion
123 if [ "$PEERRANGE" -gt 0 ]; then
124 PEEREXP=($(seq -${PEERRANGE} ${PEERRANGE}))
126 unset PEEREXP[PEERRANGE]
131 ############################################################################
134 # translate instance ID to its address.
140 # return the ID of a peer, in terms of an offset on the given instance's ID.
142 # E.g., given an ID of 1 and an offset of -1, if there are 10 instances overall,
143 # this will return 10.
147 echo $(( (($ID + $OFF - 1 + $NUM) % $NUM) + 1 ))
150 # return IPv4 address to advertise, for given instance ID and number.
154 echo "$ADVPREF.$(( ($N >> 16) %256 )).$(( ($N >> 8) % 256 )).$(( $N % 256 ))"
157 ############################################################################
160 # do not daemonise, so that all launched instances can be killed by killing
170 ${BIN} -i "${PIDBASE}"/bgpd${ID}.pid \
174 -P $((${VTYBASE}+${ID}))
184 env exabgp.api.file="${PIDBASE}"/exabgp${ID}.ctl \
185 exabgp.daemon.pid="${PIDBASE}"/bgpd${ID}.pid \
186 exabgp.daemon.daemonize=false \
187 exabgp.tcp.bind=${ADDR} \
188 exabgp.log.enable=false \
189 exabgp.daemon.user=quagga \
199 ${BIN} -P "${PIDBASE}"/bird${ID}.pid \
201 -s "${PIDBASE}"/bird${ID}.ctl \
205 #######################################################################
207 # functions to write the configuration for instances
229 for N in $(seq 1 $ADV) ; do
231 echo " route `advipaddr $ID $N`/32 {"
232 echo " next-hop $ADDR;"
237 for P in ${PEEREXP[@]}; do
238 [ "$P" -eq 0 ] && continue;
240 #local PID=$(( (($ID + $P - 1 + $NUM) % $NUM) + 1 ))
241 local PID=`peeridoff $ID $P`
242 #local PADDR="${PREFIX}${PID}"
243 local PADDR=`id2addr $PID`
244 local PAS=$((${ASBASE} + $PID))
246 echo " neighbor $PADDR {"
247 #echo " local-address $ADDR;"
248 #echo " local-as $ASN;"
249 #echo " graceful-restart;"
250 #echo " router-id $ADDR;"
251 echo " peer-as $PAS;"
255 for P in ${!EXPEERS[@]}; do
256 echo " neighbor ${EXPEERS[$P]} {"
257 echo " peer-as ${EXPEERASES[$P]};"
274 # Edit config to suit.
280 bgp router-id ${ADDR}
282 !bgp bestpath as-path multipath-relax
285 for N in $(seq 1 $ADV) ; do
286 echo " network `advipaddr $ID $N`/32"
290 neighbor default peer-group
291 neighbor default update-source ${ADDR}
292 neighbor default capability orf prefix-list both
293 !neighbor default soft-reconfiguration inbound
294 neighbor default advertisement-interval $MRAI
295 neighbor default timers connect $CONNECTRETRY
296 neighbor default route-map test out
299 for P in ${PEEREXP[@]}; do
300 [ "$P" -eq 0 ] && continue;
302 local PID=`peeridoff $ID $P`
303 local PADDR=`id2addr $PID`
304 local PAS=$((${ASBASE} + $PID))
305 echo " neighbor ${PADDR} remote-as ${PAS}"
306 echo " neighbor ${PADDR} peer-group default"
309 for P in ${!EXPEERS[@]}; do
310 echo " neighbor ${EXPEERS[$P]} remote-as ${EXPEERASES[$P]}"
311 echo " neighbor ${EXPEERS[$P]} peer-group default"
317 network 3ffe:${ID}::/48
318 network 3ffe:${ID}:1::/48 pathlimit 1
319 network 3ffe:${ID}:2::/48 pathlimit 3
320 network 3ffe:${ID}:3::/48 pathlimit 3
321 neighbor default activate
322 neighbor default capability orf prefix-list both
323 neighbor default default-originate
324 neighbor default route-map test out
327 for P in ${PEEREXP[@]}; do
328 [ "$P" -eq 0 ] && continue;
330 local PID=`peeridoff $ID $P`
331 local PADDR=`id2addr $PID`
332 local PAS=$((${ASBASE} + $PID))
333 echo " neighbor ${PADDR} peer-group default"
339 ! bgpd still has problems with extcommunity rt/soo
340 route-map test permit 10
341 set extcommunity rt ${ASN}:1
342 set extcommunity soo ${ASN}:2
343 set community ${ASN}:1
358 #log "/var/log/bird.log" all;
359 #debug protocols all;
363 listen bgp address ${ADDR};
365 protocol kernel { device routes; import all; }
366 protocol device { import all; }
368 function avoid_martians()
372 224.0.0.0/4+, 240.0.0.0/4+
375 # Avoid RFC1918 and similar networks
376 if net ~ martians then return false;
382 if ! (avoid_martians()) then reject;
388 bgp_community.add ((${ASN}, 1));
392 template bgp peer_conf {
394 source address ${ADDR};
395 import filter import_filter;
396 export filter set_comm;
403 for P in ${PEEREXP[@]}; do
404 [ "$P" -eq 0 ] && continue;
406 local PID=`peeridoff $ID $P`
407 local PADDR=`id2addr $PID`
408 local PAS=$((${ASBASE} + $PID))
409 echo "protocol bgp from peer_conf {"
410 echo " neighbor ${PADDR} as ${PAS};"
414 for P in ${!EXPEERS[@]}; do
415 echo "protocol bgp from peer_conf {"
416 echo " neighbor ${EXPEERS[$P]} as ${EXPEERASES[$P]};"
421 for N in $(seq 1 $ADV) ; do
422 echo " network `advipaddr $ID $N`/32"
426 #######################################################################
428 for ID in $(seq 1 $NUM); do
429 BGP_INST=${BGP_INSTANCES[${ID} % ${#BGP_INSTANCES[@]}]}
430 BGPBIN=${BGP_BINS[$BGP_INST]}
431 CONF="${CONFBASE}"/${BGP_INST}_bgpd${ID}.conf
432 ASN=$(($ASBASE + ${ID}))
435 #if [ ! -e "$CONF" ] ; then
436 if [ ! -e "$CONF" -o "$CONFWRITE" = "Y" ] ; then
437 ${BGP_CONFIGGEN[$BGP_INST]} $ID $ASN $ADDR > "$CONF"
438 chown $USER:$GROUP "$CONF"
440 # You may want to automatically add configure a local address
441 # on a loop interface.
443 # Solaris: ifconfig vni${H} plumb ${ADDR}/${ADDRPLEN} up
445 #ip address add ${ADDR}/${ADDRPLEN} dev lo 2> /dev/null
447 ip link add dummy${ID} type dummy 2> /dev/null
448 ip link set dev dummy${ID} up
449 ip address add ${ADDR}/${ADDRPLEN} dev dummy${ID} 2> /dev/null
451 ${BGP_LAUNCH[$BGP_INST]} $ID $ASN $ADDR $BGPBIN $CONF &
456 echo "multiple-bgpd.sh: waiting..."