Commit c302172d authored by Jan Moskyto Matejka's avatar Jan Moskyto Matejka

Merge birdlab's framework

this closes #1
parents 6db504f2 272cb404
......@@ -8,3 +8,16 @@ netns-bin/netns_run
netlab/bird6/bird*
netlab/bird4/bird*
birdlab/img/*
birdlab/iso/*
birdlab/run/*
birdlab/nfs/bird*
birdlab/nfs/net/vl-*
birdlab/nfs/net/rc-*
birdlab/nfs/net/gr-*
birdlab/nfs/net/hostname-*
birdlab/nfs/net/misc-*
birdlab/nfs/tmp
birdlab/bin/socat
birdlab/savelog
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
NAME=$1
ID=$2
if [ -z "$NAME" ] || [ -z "$ID" ]; then
echo "Usage: $0 NAME ID"
exit 2
fi
socat UNIX-CONNECT:$ROOT/run/$NAME.sock - >/dev/null <<EOF
netdev_add type=tap,id=$ID,ifname=$ID,script=no
device_add e1000,netdev=$ID
EOF
#!/bin/bash
. $(dirname $0)/virt-lib
[ -f $ROOT/run/dhcpd.pid ] && kill $(cat $ROOT/run/dhcpd.pid)
iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
iptables -D FORWARD -i eth0 -o $VIRTCTRL -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -D FORWARD -i eth0 -o $VIRTCTRL -j ACCEPT
iptables -D FORWARD -i $VIRTCTRL -o eth0 -j ACCEPT
iptables -D FORWARD -o eth0 -j REJECT
ovs-vsctl del-br $VIRTBR
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
NETLIST=$ROOT/run/networks
NET=$1
if [ -z "$NET" ] || [ -z "$2" ]; then
echo "Usage: $0 NET hosts"
exit 2
fi
shift
if grep -q $NET $NETLIST; then
echo "Network $NET exists"
exit 2
fi
MAXID=$(sort -k1,1nr $NETLIST | head -n1|cut -f1 -d' ')
MAXID=$((MAXID+1))
echo "$MAXID $NET" >> $NETLIST
i=0
idprefix=auto-$MAXID
for H in "$@"; do
$ROOT/bin/addnic $H $idprefix-$i
ip link set $idprefix-$i up
ovs-vsctl add-port $VIRTBR $idprefix-$i tag=$MAXID
i=$((i+1))
done
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
NAME=$1
ID=$2
if [ -z "$NAME" ] || [ -z "$ID" ]; then
echo "Usage: $0 NAME ID"
exit 2
fi
socat UNIX-CONNECT:$ROOT/run/$NAME.sock - >/dev/null <<EOF
netdev_del $ID
device_del e1000,netdev=$ID
EOF
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
NAME=$1
if [ -z "$NAME" ]; then
echo "Usage: $0 NAME"
exit 2
fi
$SOCAT READLINE,history=$ROOT/run/$NAME.mon-history UNIX-CONNECT:$ROOT/run/$NAME.sock
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
set -e
EVENT=$1
shift
idtoip() {
echo 10.255.$(($1 / 254)).$(($1 % 254))
}
idtolink() {
echo 10.254.$(($1 / 254)).$(($1 % 254))
}
if ! brctl show | grep -q br-mpls; then brctl addbr br-mpls; ip link set br-mpls up; fi
case $EVENT in
add-rr|add-p|add-pe)
T=${EVENT##add-}
id=$1
ip=$(idtoip $id)
vctl start -t mpls-auto $T-$id
gethost mpls-auto-$T-$id
vctl serial-mikrotik-fix.pl mpls-auto-$T-$id
vctl ssh mpls-auto-$T-$id -t <<EOF
/interface bridge add name=lo
/ip address add address=$ip/32 interface=lo
/routing ospf instance set distribute-default=never redistribute-connected=as-type-1 router-id=$ip 0
/routing ospf network add network=$ip/32 area=backbone
EOF
if [ "$EVENT" != "add-rr" ]; then
echo "/mpls ldp set enabled=yes lsr-id=$ip transport-address=$ip" | vctl ssh mpls-auto-$T-$id -t
fi
;;
add-c)
id=$1
vpn=$2
pe=$3
ip=$(idtoip $id)
peip=$(idtoip $pe)
linkip=$(idtolink $id)
linkpeip=$(idtolink $pe)
vctl start -t mpls-auto c-$id
gethost mpls-auto-c-$id
cip=$HOSTIP4
gethost mpls-auto-pe-$pe
cpeip=$HOSTIP4
vctl serial-mikrotik-fix.pl mpls-auto-c-$id
vctl ssh mpls-auto-c-$id -t <<EOF
/interface bridge add name=lo
/ip address add address=$ip/32 interface=lo
/interface gre add remote-address=$cpeip name=pe-$pe
/ip address add address=$linkip/32 network=$linkpeip interface=pe-$pe
/routing ospf instance set distribute-default=never redistribute-connected=as-type-1 router-id=$ip 0
/routing ospf network add network=$ip/32 area=backbone
/routing ospf network add network=$linkpeip/32 area=backbone
EOF
vctl ssh mpls-auto-pe-$pe -t <<EOF
/interface gre add remote-address=$cip name=c-$id
/ip address add address=$linkpeip/32 network=$linkip interface=c-$id
/ip route vrf add routing-mark=$vpn interfaces=c-$id route-distinguisher=$vpn import-route-targets=$vpn export-route-targets=$vpn
/routing bgp instance vrf add instance=default routing-mark=$vpn redistribute-connected=yes redistribute-ospf=yes
/routing ospf instance add name=c-$id routing-table=$vpn redistribute-bgp=as-type-1
/routing ospf area add instance=c-$id name=c-$id
/routing ospf network add network=$linkip/32 area=c-$id
EOF
;;
add-link)
from=$1
to=$2
fip=$(idtolink ${from##*-})
tip=$(idtolink ${to##*-})
gethost mpls-auto-$from
cfip=$HOSTIP4
gethost mpls-auto-$to
ctip=$HOSTIP4
vctl ssh mpls-auto-$from -t <<EOF
/interface gre add remote-address=$ctip name=$to
/ip address add address=$fip/32 network=$tip interface=$to
/routing ospf network add network=$tip/32 area=backbone
EOF
vctl ssh mpls-auto-$to -t <<EOF
/interface gre add remote-address=$cfip name=$from
/ip address add address=$tip/32 network=$fip interface=$from
/routing ospf network add network=$fip/32 area=backbone
EOF
case "$from$to" in
*rr*) :
;;
*)
echo "/mpls ldp interface add interface=$to" | vctl ssh mpls-auto-$from -t
echo "/mpls ldp interface add interface=$from" | vctl ssh mpls-auto-$to -t
;;
esac
;;
bgp-rr)
pe=$1
rr=$2
peip=$(idtoip $pe)
rrip=$(idtoip $rr)
echo "/routing bgp peer add remote-address=$rrip remote-as=65530 address-families=vpnv4 update-source=lo" | vctl ssh mpls-auto-pe-$pe -t
echo "/routing bgp peer add remote-address=$peip remote-as=65530 address-families=vpnv4 update-source=lo route-reflect=yes" | vctl ssh mpls-auto-rr-$rr -t
;;
bgp-link)
from=$1
to=$2
fip=$(idtoip ${from})
tip=$(idtoip ${to})
echo "/routing bgp peer add remote-address=$tip remote-as=65530 address-families=vpnv4 update-source=lo" | vctl ssh mpls-auto-rr-$from -t
echo "/routing bgp peer add remote-address=$fip remote-as=65530 address-families=vpnv4 update-source=lo" | vctl ssh mpls-auto-rr-$to -t
;;
*)
echo "Commands: add-rr ID, add-p ID, add-pe ID, add-c ID VPN PE, add-link FROM TO, bgp-rr PE RR"
exit 2
;;
esac
#!/usr/bin/env python
import pypureomapi
import sys
keyname = "dhcp_key"
#secret = "6Qsf2UG4cvSli+Fup3bHI/4lCGO4i3SO6hl6WWBr042vUHktQ/1KiQwI 3MQrNrGs7c7EMDr/fho2Fzr3y1EP/Q=="
secret = "3MQrNrGs7c7EMDr/fho2Fzr3y1EP/Q=="
server = "127.0.0.1"
port = 7911
try:
oma = pypureomapi.Omapi(server, port, keyname, secret, debug=False)
except pypureomapi.OmapiError, err:
print "OMAPI error: %s" % (err,)
sys.exit(1)
if sys.argv[1] == "add":
oma.add_host(sys.argv[4], sys.argv[3], sys.argv[2])
elif sys.argv[1] == "del":
oma.del_host(sys.argv[2])
else:
print("Usage: omapi (add MAC IP|del MAC)")
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
HOST=$1
if ! gethost $HOST; then
echo "Unknown host: $HOST"
exit 2
fi
case ${HOSTTYPE^^} in
FREEBSD) ;&
OPENBSD) ;&
NETBSD)
FSTAB="192.168.192.1:/var/lib/virt/nfs /mnt/nfs nfs rw 0 0"
;;
LINUX)
FSTAB="192.168.192.1:/var/lib/virt/nfs /mnt/nfs nfs defaults,intr,_netdev 0 0"
;;
*)
echo "Unknown type of host: $TYPE"
exit 2
;;
esac
AUTH=`mktemp`
cat >$AUTH <<EOF
mkdir -p /root/.ssh
cat >/root/.ssh/authorized_keys <<EOC
EOF
cat /home/birdlab/.ssh/authorized_keys >> $AUTH
cat /root/.ssh/virt-rsa.pub >>$AUTH
echo EOC >>$AUTH
ssh root@$HOSTIP4 bash <$AUTH
SCRIPT=`mktemp`
cat >$SCRIPT <<EOF
if [ ! -x /bin/bash ]; then
ln -s \$(command -v bash) /bin/bash
fi
rm -f /etc/udev/rules.d/70-persistent-net.rules
if egrep -q '/mnt/nfs[[:space:]]+nfs[[:space:]]+' /etc/fstab; then
( egrep -v '/mnt/nfs[[:space:]]+nfs[[:space:]]+' /etc/fstab ; echo "$FSTAB") > /etc/fstab.new
cp /etc/fstab.new /etc/fstab
mkdir -p /mnt/nfs
mount -o remount /mnt/nfs
else
echo "$FSTAB" >> /etc/fstab
mkdir -p /mnt/nfs
mount /mnt/nfs
fi
cat >/etc/rc.local <<EOC
#!/bin/bash
until [ -x /mnt/nfs/rc.local ]; do
sleep 1
done
/mnt/nfs/rc.local > /tmp/rc-local-log 2>/tmp/rc-local-err
EOC
chmod +x /etc/rc.local
EOF
ssh root@$HOSTIP4 bash <$SCRIPT
rm $SCRIPT
rm $AUTH
#!/bin/bash
. $(dirname $0)/virt-lib
vsctl add-br $VIRTBR
ip link set $VIRTBR up
ip addr add 192.168.10.1/28 dev $VIRTBR
ip link add $VIRTCTRL type veth peer name $VIRTUPLINK
ip link set $VIRTCTRL up
ip link set $VIRTUPLINK up
ip addr add 192.168.192.1/18 dev $VIRTCTRL
vsctl add-port $VIRTBR $VIRTUPLINK tag=1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o $VIRTCTRL -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i eth0 -o $VIRTCTRL -j ACCEPT
iptables -A FORWARD -i $VIRTCTRL -o eth0 -j ACCEPT
iptables -A FORWARD -o eth0 -j REJECT
dhcpd -cf $ROOT/etc/dhcpd.conf -pf $ROOT/run/dhcpd.pid $VIRTCTRL
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
[ -f $ROOT/run/dhcpd.pid ] && kill $(cat $ROOT/run/dhcpd.pid)
dhcpd -cf $ROOT/etc/dhcpd.conf -pf $ROOT/run/dhcpd.pid $VIRTCTRL
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
NAME=$1
if [ -z "$NAME" ]; then
echo -e "Usage: $0 name [custom options for qemu]\n or $0 -m list of names"
exit 2
fi
vctl stop "$@"
vctl start "$@"
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
NAME=$1
if [ -z "$NAME" ]; then
echo "Usage: $0 NAME"
exit 2
fi
minicom -D unix\#$ROOT/run/$1.serial
#!/usr/bin/perl -CL
use common::sense;
use Data::Dumper;
use IO::Socket::UNIX;
my $client = IO::Socket::UNIX->new( Type => SOCK_STREAM(), Peer => "/var/lib/virt/run/$ARGV[0].serial");
my $data;
$/ = "";
my $state = "login";
say "init client";
syswrite $client, "\r";
while (1) {
say "";
sleep 1;
sysread $client, $data, 65536;
$data =~ s/[^ -~]/?/g;
print Dumper \$data;
if ($data =~ /MikroTik Login: $/) {
say "sending login";
syswrite $client, "root\r";
$state = "login";
next;
}
if ($data =~ /assword: $/) {
say "sending password";
syswrite $client, "root\r";
next;
}
if ($data =~ /tinue!/) {
say "continue boilerplate";
syswrite $client, "\r";
# $state = "export";
$state = "macreset";
next;
}
if ($data =~ /\[root\@MikroTik\] > $/ && $state eq "export") {
say "export";
syswrite $client, "export\r";
$state = "macreset";
next;
}
if ($data =~ /\[root\@MikroTik\] > $/ && $state eq "macreset") {
say "interface ethernet reset-mac-address numbers=0";
syswrite $client, "interface ethernet reset-mac-address numbers=0\r";
$state = "dhcp";
next;
}
if ($data =~ /\[root\@MikroTik\] > $/ && $state eq "dhcp") {
say "ip dhcp-client renew numbers=0";
syswrite $client, "ip dhcp-client renew numbers=0\r";
$state = "quit";
next;
}
if ($data =~ /\[root\@MikroTik\] > $/ && $state eq "quit") {
say "quit";
syswrite $client, "quit\r";
sleep 1;
sysread $client, $data, 65536;
$data =~ s/[^ -~]/?/g;
print Dumper \$data;
exit 0;
}
if ($data =~ /\[root\@MikroTik\] > $/) {
say "Logged in, noop now";
syswrite $client, "\r";
$state = "macreset";
next;
}
say "NOP, strange input";
}
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
NAME=$1
if [ -z "$NAME" ]; then
echo "Usage: $0 NAME"
exit 2
fi
shift
gethost $NAME
if [ "${#@}" == "0" ]; then
TERM=rxvt-256color ssh -i /root/.ssh/virt-rsa -t root@$HOSTIP4 bash
else
TERM=rxvt-256color ssh -i /root/.ssh/virt-rsa root@$HOSTIP4 "$@"
fi
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
NAME=$1
shift
usage() {
echo -e "Usage: $0 name [custom options for qemu]\n or $0 -m list of names\n or $0 -t name suffix [custom options for qemu]"
exit 2
}
check_stale() {
local NAME=$1
if [ -e $ROOT/run/$NAME.pid ]; then
echo -n "Host $NAME pidfile found"
if [ -d /proc/$(<$ROOT/run/$NAME.pid) ]; then
echo " running with PID $(<$ROOT/run/$NAME.pid)"
exit 1
else
echo " stale ... removing"
rm $ROOT/run/$NAME.pid
fi
fi
}
[ -z "$NAME" ] && usage
if [ "$NAME" = "-m" ]; then
set -e
for N in "$@"; do
echo Starting "$N"
$0 "$N"
done
exit 0
fi
if [ "$NAME" = "-t" ]; then
NAME=$1
SUFFIX=$2
([ -z "$SUFFIX" ] || [ -z "$NAME" ]) && usage
ID=0
if [ -e $ROOT/run/tmp-$NAME-$SUFFIX ]; then
echo "Host $NAME tmpfile found."
check_stale $NAME-$SUFFIX
rm $(readlink -f $ROOT/run/tmp-$NAME-$SUFFIX) $ROOT/run/tmp-$NAME-$SUFFIX
fi
while [ -e $ROOT/run/tmp-$ID ]; do
ID=$((ID+1))
done
HEXID=$(printf "%02x" $ID)
echo "$SUFFIX" > $ROOT/run/tmp-$ID
ln -s tmp-$ID $ROOT/run/tmp-$NAME-$SUFFIX
shift 2
else
check_stale $NAME
fi
NAME=$NAME${SUFFIX:+-$SUFFIX}
gethost $NAME
if [ "$?" != 0 ]; then
echo "Host $NAME not configured"
exit 2
fi
if [ "$1" = "--install" ]; then
INSTALL="-cdrom $2 -boot d"
shift 2
fi
declare -a HOSTNICVLAN
if [ -n "$HOSTNIC" ]; then
declare -a HOSTNIC=( $HOSTNIC )
for N in ${HOSTNIC[@]}; do
IFS=';' read NETNAME MAC TAG IP4 IP4PEER <<<"$N"
TAPID=$(mactotap $MAC)
HOSTNICDEV="$HOSTNICDEV -netdev tap,id=$TAPID,ifname=$TAPID,script=no -device e1000,netdev=$TAPID,mac=$MAC"
TAPFILE=$ROOT/nfs/net/$TAPID
echo "NAME $NETNAME" > $TAPFILE
echo "IP4 $IP4" >> $TAPFILE
if [ -n "$IP4PEER" ]; then echo "IP4PEER $IP4PEER" >> $TAPFILE; fi
HOSTNICVLAN+=( $TAPID,$TAG )
done
fi
GREFILE=$ROOT/nfs/net/gr-${HOSTMAC//:}
truncate -s0 $GREFILE
if [ -n "$HOSTVARS" ]; then
declare -a HOSTVARS=( $HOSTVARS )
for V in ${HOSTVARS[@]}; do
echo "export $V" >> $GREFILE
done
declare -a HOSTVARNAMES
for V in ${HOSTVARS[@]}; do
HOSTVARNAMES+=( ${V%%=*} )
done
echo "declare -a VARNAMES=(${HOSTVARNAMES[@]})" >> $GREFILE
fi
if [ -n "$HOSTDUMMY" ]; then
declare -a HOSTDUMMY=( $HOSTDUMMY )
for D in ${HOSTDUMMY[@]}; do
IFS=';' read DNAME IP4 IP6 <<<"$D"
echo dummy $DNAME $IP4 $IP6 >> $GREFILE
done
fi
if [ -n "$HOSTGRE" ]; then
declare -a HOSTGRE=( $HOSTGRE )
for G in ${HOSTGRE[@]}; do
IFS=';' read GRENAME PEER IP4 IP4PEER <<<"$G"
echo gre $GRENAME $HOSTIP4 ${CONF[$PEER;IP4]} $IP4 $IP4PEER >> $GREFILE
done
fi
if [ -n "$HOSTSOCK" ]; then
declare -a HOSTSOCK=( $HOSTSOCK )
for S in ${HOSTSOCK[@]}; do
IFS=';' read SOCKNAME APPEND MAC IP4 <<<"$S"
TAPID=$(mactotap $MAC)
HOSTNICDEV="$HOSTNICDEV -netdev socket,$APPEND,id=$SOCKNAME -device e1000,netdev=$SOCKNAME,mac=$MAC"
TAPFILE=$ROOT/nfs/net/$TAPID
echo "NAME $NETNAME" > $TAPFILE
echo "IP4 $IP4" >> $TAPFILE
if [ -n "$IP4PEER" ]; then echo "IP4PEER $IP4PEER" >> $TAPFILE; fi
done
fi
echo -e "hostname $HOSTNAME\nexport HOSTNAME=$HOSTNAME" > $ROOT/nfs/net/hostname-${HOSTMAC//:}
$ROOT/bin/omapi add $NAME $HOSTMAC $HOSTIP4
qemu-system-$HOSTARCH -enable-kvm -m $HOSTMEMORY -hda $ROOT/img/$HOSTIMAGE $HOSTCOW -display none ${HOSTVNCID:+-vnc 10.0.0.11:$HOSTVNCID} -netdev tap,id=ctl,ifname=$HOSTTAP,script=no -device e1000,netdev=ctl,mac=$HOSTMAC $HOSTNICDEV -pidfile $ROOT/run/$NAME.pid -monitor unix:$ROOT/run/$NAME.sock,server,nowait -serial unix:$ROOT/run/$NAME.serial,server,nowait -daemonize $INSTALL "$@"
#-runas $VIRTUSER
ip link set $HOSTTAP up
vsctl add-port $VIRTBR $HOSTTAP tag=1
echo vsctl add-port $VIRTBR $HOSTTAP tag=1
for T in ${HOSTNICVLAN[@]}; do
IFS=, read TAPID TAG <<<"$T"
ip link set $TAPID up
if ip link show br-$TAG 2>/dev/null >/dev/null; then :; else
brctl addbr br-$TAG
ip link set br-$TAG up
fi
echo "brctl addif br-$TAG $TAPID"
brctl addif br-$TAG $TAPID
# vsctl add-port $VIRTBR $TAPID tag=$TAG
done
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
if [ "$1" == "-n" ]; then
shift
DO_PING=false
else
DO_PING=true
fi
if [ "$1" == "-v" ]; then
for C in $(echo ${!CONF[@]} | tr ' ' '\n' | sort); do
echo $C: ${CONF[$C]}
done
exit 0
fi
declare -A seen
seen[dhcpd]=1
for H in $(hostlist); do
if [ -S $ROOT/run/$H.sock ]; then
if [ -e $ROOT/run/tmp-$H ]; then
ID=$(basename $(readlink -f $ROOT/run/tmp-$H))
ID=${ID##tmp-}
HOSTIP4=192.168.255.$(($ID % 254))
else
HOSTIP4=${CONF[$H;IP4]}
fi
if $DO_PING; then
if ping -nc1 $HOSTIP4 >/dev/null; then
PING="(ping ok)"
else
PING="(ping FAIL)"
fi
else
PING=""
fi
echo "$H running, IPv4 $HOSTIP4 $PING, monitor $ROOT/run/$H.sock"
elif [ -f $ROOT/run/$H.pid ]; then
if ps -p $(<$ROOT/run/$H.pid) >/dev/null; then
echo "$H probably running at PID $(<$ROOT/run/$H.pid), no socket, IPv4 ${CONF[$H;IP4]}"
else
echo "$H stopped, $ROOT/run/$H.pid stale pidfile found, removing"
rm $ROOT/run/$H.pid
fi
else
echo "$H stopped"
fi
done
#!/bin/bash
. $(dirname $(readlink -f $0))/virt-lib
NAME=$1
shift
if [ -z "$NAME" ]; then
echo -e "Usage: $0 name\n or $0 -m list of names"
exit 2
fi
if [ "$NAME" = "-m" ]; then
set -e
declare -a PIDS
for N in "$@"; do
echo Stopping "$N"
$0 -q "$N" &
PIDS+=($!)
done
echo ${PIDS[@]}
while true; do
declare -a NEWPIDS
NEWPIDS=()
for P in ${PIDS[@]}; do
if [ -d /proc/$P ]; then
NEWPIDS+=($P)
fi
done
PIDS=( ${NEWPIDS[@]} )
if [ "${#PIDS[@]}" -eq 0 ]; then break; fi
echo -e "Still ${#PIDS[@]} machine(s) running ... \r"
sleep 1
done
echo "Everything OK. "