first commit

This commit is contained in:
root 2018-07-26 08:57:41 +00:00
commit bb377472b0
25 changed files with 619 additions and 0 deletions

5
debian/changelog vendored Normal file
View File

@ -0,0 +1,5 @@
wit-hypervisor (1.0) unstable; urgency=low
* Initial release.
-- Toby Paler <toby@wit.com> Wed, 25 Jul 2018 22:54:00 +0100

1
debian/compat vendored Normal file
View File

@ -0,0 +1 @@
7

14
debian/control vendored Normal file
View File

@ -0,0 +1,14 @@
Source: wit-hypervisor
Section: config
Priority: extra
Maintainer: toby <toby@wit.com>
Build-Depends: debhelper (>= 7.0.0~), config-package-dev (>= 4.15), lynx
Standards-Version: 3.9.2
Package: wit-hypervisor
Architecture: all
Depends: ${misc:Depends}, sed, tcpdump, mtr-tiny, iproute2, ifupdown, ipmitool, iptables, lldpd, strongswan, telnet, netcat, fping, curl, wget, ifstat, rsyslog, ncurses-term, net-tools, bridge-utils, vlan
Provides: ${diverted-files}
Conflicts: ${diverted-files}
Description: Installs basic network packages and
configures the box as hypervisor or datanode.

3
debian/copyright vendored Normal file
View File

@ -0,0 +1,3 @@
wit-hypervisor package.
Author: Toby <toby@wit.com>

55
debian/postinst.ex vendored Normal file
View File

@ -0,0 +1,55 @@
#!/bin/sh
# postinst script for #PACKAGE#
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <postinst> `configure' <most-recently-configured-version>
# * <old-postinst> `abort-upgrade' <new version>
# * <conflictor's-postinst> `abort-remove' `in-favour' <package>
# <new-version>
# * <postinst> `abort-remove'
# * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
# <failed-install-package> <version> `removing'
# <conflicting-package> <version>
# for details, see https://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
configure)
systemctl stop systemd-networkd.socket
systemctl stop systemd-networkd.service
systemctl stop systemd-networkd-wait-online
systemctl disable systemd-networkd.service
systemctl disable systemd-networkd.socket
systemctl disable systemd-networkd-wait-online
systemctl enable firewall
systemctl restart systemd-timesyncd
systemctl restart strongswan
update-grub
sysctl -p /etc/sysctl.d/10-frr.conf
;;
abort-upgrade|abort-remove|abort-deconfigure)
;;
*)
echo "postinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

65
debian/preinst.ex vendored Normal file
View File

@ -0,0 +1,65 @@
#!/bin/sh
# preinst script for #PACKAGE#
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <new-preinst> `install'
# * <new-preinst> `install' <old-version>
# * <new-preinst> `upgrade' <old-version>
# * <old-preinst> `abort-upgrade' <new-version>
# for details, see https://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
install|upgrade)
[ -z "$NODE_ID" ] && export NODE_ID=$(ip -4 -br addr | grep 10.0. | awk '{ print $3 }' | awk 'BEGIN{FS="[./]"} { print $4 }')
MGMT_ID=$(ip -4 -br addr | grep 10.0. | awk '{ print $3 }' | awk 'BEGIN{FS="[./]"} { print $3 }')
[ "$MGMT_ID" -ge 0 -a "$MGMT_ID" -lt 16 ] && export DOMAINNAME=.usw1.wit.com
[ "$MGMT_ID" -ge 16 -a "$MGMT_ID" -lt 32 ] && export DOMAINNAME=.usw2.wit.com
[ ${HOSTNAME:0:1} = h ] && export HOSTTYPE=hypervisor
[ ${HOSTNAME:0:1} = d ] && export HOSTTYPE=datanode
[ $HOSTTYPE = hypervisor -a $DOMAINNAME = .usw1.wit.com ] && export TIER_ID=2
[ $HOSTTYPE = datanode -a $DOMAINNAME = .usw1.wit.com ] && export TIER_ID=4
[ $HOSTTYPE = hypervisor -a $DOMAINNAME = .usw2.wit.com ] && export TIER_ID=18
[ $HOSTTYPE = datanode -a $DOMAINNAME = .usw2.wit.com ] && export TIER_ID=20
if [ -z "$TIER_ID" ]; then
echo "Unable to autodetect TIER_ID, looks like we deal with a special node, please set in environment"
exit 2
fi
if [ -z "$DOMAINNAME" ]; then
echo "Unable to autodetect DOMAINNAME, looks like we deal with a special case, please set in environment and/or update the code"
exit 2
fi
;;
abort-upgrade)
;;
*)
echo "preinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

4
debian/rules vendored Executable file
View File

@ -0,0 +1,4 @@
#!/usr/bin/make -f
%:
dh $@ --with=config-package

1
debian/source/format vendored Normal file
View File

@ -0,0 +1 @@
3.0 (native)

1
debian/wit-hypervisor.hide vendored Normal file
View File

@ -0,0 +1 @@
/etc/systemd/network/*

14
debian/wit-hypervisor.install vendored Normal file
View File

@ -0,0 +1,14 @@
files/vrf.conf etc/iproute2/rt_tables.d
files/vrf-dhcp-enter etc/dhcp/dhclient-enter-hooks.d
files/vrf-dhcp-exit etc/dhcp/dhclient-exit-hooks.d
files/rc.local etc
files/10-frr.conf etc/sysctl.d
files/wit-gc usr/local/bin
files/resolv.conf etc
files/bashrc-witaddon root
files/qemu-ifdown etc/libvirt/hooks
files/qemu-ifup-public etc/libvirt/hooks
files/qemu-ifup etc/libvirt/hooks
files/firewall etc/init.d
files/frr.conf etc/frr
files/interfaces etc/network

9
debian/wit-hypervisor.transform vendored Normal file
View File

@ -0,0 +1,9 @@
/etc/network/interfaces sed -e "s/TIERID/$TIER_ID/g"
/etc/frr/frr.conf sed -e "s/VTEPINDEX/$NODE_ID/" -e "s/TIERID/$TIER_ID/" -e "s/TIERASN/$(printf "%03d" $TIER_ID)/" -e "s/VTEPASN/$(printf "%03d" $NODE_ID)/"
/etc/hosts sed -e "/.*debcore1/d" -e "/.*$MYHOSTNAME/d" -e "$ s/$/\n10.1.$TIER_ID.$NODE_ID\t$MYHOSTNAME/"
/etc/frr/daemons sed -e 's/bgpd=no/bgpd=yes/' -e 's/zebra=no/zebra=yes/'
/etc/ssh/sshd_config sed -e '/PasswordAuthentication/d' -e '$ s/$/\nPasswordAuthentication no/'
/etc/systemd/timesyncd.conf sed -e 's/#NTP=.*/NTP=ipv6.ntp.ubuntu.com/g'
/etc/default/grub sed -e '/GRUB_CMDLINE_LINUX_DEFAULT=/d' -e '/GRUB_CMDLINE_LINUX=/d' -e '/GRUB_SERIAL_COMMAND=/d' -e '/GRUB_TERMINAL=/d' -e '$ s/$/\nGRUB_CMDLINE_LINUX_DEFAULT=""\nGRUB_CMDLINE_LINUX="console=tty0 console=ttyS1,115200n8"\nGRUB_TERMINAL=serial\nGRUB_SERIAL_COMMAND="serial --speed=115200 --unit=1 --word=8 --parity=no --stop=1"/'
/root/.bashrc sed -e '/.*bashrc-witaddon.*/d' -e '$ /$/\nsource ~/bashrc-witaddon/'

54
files/10-frr.conf Normal file
View File

@ -0,0 +1,54 @@
# Enables IPv4/IPv6 Routing
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding=1
# Routing
net.ipv6.route.max_size=131072
net.ipv4.conf.all.ignore_routes_with_linkdown=1
net.ipv6.conf.all.ignore_routes_with_linkdown=1
# Best Settings for Peering w/ BGP Unnumbered
# and OSPF Neighbors
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.lo.rp_filter = 0
net.ipv4.conf.all.forwarding = 1
net.ipv4.conf.default.forwarding = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.default.arp_notify = 1
net.ipv4.conf.default.arp_ignore=1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.all.arp_notify = 1
net.ipv4.conf.all.arp_ignore=1
net.ipv4.icmp_errors_use_inbound_ifaddr=1
# Miscellaneous Settings
# Keep ipv6 permanent addresses on an admin down
net.ipv6.conf.all.keep_addr_on_down=1
# igmp
net.ipv4.igmp_max_memberships=1000
net.ipv4.neigh.default.mcast_solicit = 10
# MLD
net.ipv6.mld_max_msf=512
# Garbage Collection Settings for ARP and Neighbors
net.ipv4.neigh.default.gc_thresh2=7168
net.ipv4.neigh.default.gc_thresh3=8192
net.ipv4.neigh.default.base_reachable_time_ms=14400000
net.ipv6.neigh.default.gc_thresh2=3584
net.ipv6.neigh.default.gc_thresh3=4096
net.ipv6.neigh.default.base_reachable_time_ms=14400000
# Use neigh information on selection of nexthop for multipath hops
net.ipv4.fib_multipath_use_neigh=1
# Allows Apps to Work with VRF
net.ipv4.tcp_l3mdev_accept=1
# disable forwarding for mgmt interface
net.ipv6.conf.mgmt1.forwarding = 0

8
files/bashrc-witaddon Executable file
View File

@ -0,0 +1,8 @@
PROMPT_COMMAND='export VRF=$(ip vrf identify $$)'
PS1=$PS1'[${VRF:=default}] '
function chvrf() {
ip vrf exec $1 /bin/bash
}
alias ll='ls -lha'

100
files/firewall Executable file
View File

@ -0,0 +1,100 @@
#!/bin/bash
### BEGIN INIT INFO
# Provides: scriptname
# Required-Start: $network
# Required-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: iptables
# Description: Enable firewall rules
### END INIT INFO
exec 1> >(logger -s -t $(basename $0)) 2>&1
case $1 in
start)
echo -n "firewall start..."
### IPv4
iptables -P INPUT ACCEPT
iptables -F INPUT
#unencrypted traffic
iptables -A INPUT -s 10.1.0.0/16 -p esp -j ACCEPT
iptables -A INPUT -s 10.1.0.0/16 -p udp --dport 500 --sport 500 -j ACCEPT
iptables -A INPUT -s 10.1.0.0/16 -p udp --dport 4500 --sport 4500 -j ACCEPT
iptables -A INPUT -p icmp -j ACCEPT
#traffic we wanna see from the VPN
iptables -A INPUT -m policy --pol ipsec --dir in -s 10.1.0.0/16 -p udp --dport 4789 -m policy --pol ipsec --dir in -j ACCEPT # vxlan traffic
iptables -A INPUT -m policy --pol ipsec --dir in -m multiport -s 10.1.0.0/16 -p tcp --dports 49152:49215 -j ACCEPT # libvirt live migration
#iptables -A INPUT -m policy --pol ipsec --dir in -m multiport -s 10.1.0.0/16 -p tcp --dports 6800:7300 -j ACCEPT # ceph traffic
##### DROP the rest
iptables -P INPUT DROP
#### IPv6
ip6tables -P INPUT ACCEPT
ip6tables -F INPUT
ip6tables -A INPUT -p ipv6-icmp -j ACCEPT
ip6tables -A INPUT -s fe80::/10 -p tcp --sport 179 -j ACCEPT
ip6tables -A INPUT -s fe80::/10 -p tcp --dport 179 -j ACCEPT
ip6tables -A INPUT -s 2001:4860:4860::8888 -p udp --sport 53 -j ACCEPT
ip6tables -A INPUT -s 2001:4860:4860::8844 -p udp --sport 53 -j ACCEPT
ip6tables -A INPUT -s 2001:67c:1560:8003::c7 -p udp --sport 123 -j ACCEPT
ip6tables -A INPUT -s 2001:67c:1560:8003::c8 -p udp --sport 123 -j ACCEPT
### DROP the rest
ip6tables -P INPUT DROP
#special tables
iptables -t mangle -F
iptables -t nat -F
iptables -t raw -F
ip6tables -t mangle -F
ip6tables -t nat -F
ip6tables -t raw -F
ip6tables -t raw -A PREROUTING -j NOTRACK
ip6tables -t raw -A OUTPUT -j NOTRACK
##### temp rules till we get VRF in place in the factory, just flip the 3 rules below
if ip link show dev mgmt >/dev/null 2>&1; then
iptables -t raw -A PREROUTING ! -i mgmt1 -j NOTRACK
iptables -t raw -A OUTPUT ! -o mgmt -j NOTRACK
iptables -A INPUT -i mgmt -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -i mgmt -s 10.0.0.0/8 -p tcp --dport 22 -j ACCEPT
else
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -s 10.0.0.0/8 -p tcp --dport 22 -j ACCEPT
fi
##### end temp rules
;;
stop)
echo -n "firewall stop..."
#### Firewall rules
iptables -P INPUT ACCEPT
iptables -F
iptables -t raw -F
iptables -t nat -F
iptables -t mangle -F
ip6tables -P INPUT ACCEPT
ip6tables -F
ip6tables -t raw -F
ip6tables -t nat -F
ip6tables -t mangle -F
echo " done"
;;
restart)
#$0 stop
$0 start
;;
*)
echo "use $0 [start|stop|restart]"
;;
esac

78
files/frr.conf Normal file
View File

@ -0,0 +1,78 @@
frr defaults datacenter
username cumulus nopassword
!
service integrated-vtysh-config
!
log syslog informational
!
interface feth1
ipv6 nd ra-interval 10
no ipv6 nd suppress-ra
!
interface feth2
ipv6 nd ra-interval 10
no ipv6 nd suppress-ra
!
router bgp 4200TIERASNVTEPASN
bgp router-id 10.1.TIERID.VTEPINDEX
no bgp default ipv4-unicast
coalesce-time 1000
bgp bestpath as-path multipath-relax
bgp bestpath compare-routerid
neighbor fabric peer-group
neighbor fabric remote-as external
neighbor fabric capability extended-nexthop
neighbor feth1 interface peer-group fabric
neighbor feth2 interface peer-group fabric
!
address-family ipv4 unicast
redistribute kernel route-map EIP
redistribute connected route-map LOOPBACK
neighbor fabric activate
neighbor fabric addpath-tx-all-paths
neighbor fabric soft-reconfiguration inbound
exit-address-family
!
address-family ipv6 unicast
redistribute kernel route-map EIPv6
redistribute connected route-map LOOPBACKv6
neighbor fabric activate
neighbor fabric addpath-tx-all-paths
neighbor fabric soft-reconfiguration inbound
exit-address-family
!
address-family l2vpn evpn
neighbor fabric activate
advertise-all-vni
exit-address-family
!
ip prefix-list LOOPBACK seq 5 permit 10.1.0.0/16 ge 32
ip prefix-list WITV4 seq 5 permit 168.245.146.0/24 ge 25
ip prefix-list WITV4 seq 10 permit 170.199.210.0/24 ge 25
ip prefix-list WITV4 seq 15 permit 170.199.211.0/24 ge 25
ip prefix-list WITV4 seq 20 permit 170.199.212.0/24 ge 25
ip prefix-list WITV4 seq 25 permit 170.199.213.0/24 ge 25
ip prefix-list WITV4 seq 30 permit 170.199.214.0/24 ge 25
ip prefix-list WITV4 seq 35 permit 170.199.215.0/24 ge 25
ip prefix-list WITV4 seq 40 permit 170.199.216.0/24 ge 25
ip prefix-list WITV4 seq 45 permit 170.199.217.0/24 ge 25
!
ipv6 prefix-list LOOPBACK seq 5 permit 2604:bbc0::/96 ge 128
ipv6 prefix-list WITV6-CUSTOMERS seq 5 permit 2604:bbc0:1::/48 ge 64
!
route-map EIPv6 permit 5
match ipv6 address prefix-list WITV6-CUSTOMERS
!
route-map EIP permit 5
match ip address prefix-list WITV4
!
route-map LOOPBACK permit 5
description "permit loopback ips"
match ip address prefix-list LOOPBACK
!
route-map LOOPBACKv6 permit 5
description "permit ipv6 loopback ips"
match ipv6 address prefix-list LOOPBACK
!
line vty
!

28
files/interfaces Normal file
View File

@ -0,0 +1,28 @@
auto lo
iface lo inet loopback
auto lo:0
iface lo:0 inet static
address 10.1.TIERID.VTEPINDEX/32
iface lo:0 inet6 static
address 2604:bbc0::TIERID:VTEPINDEX/128
auto mgmt1
iface mgmt1 inet6 auto
iface mgmt1 inet dhcp
pre-up /bin/ip link add mgmt type vrf table mgmt
pre-up /bin/ip link set up dev mgmt
pre-up /bin/ip link set master mgmt dev mgmt1
post-down /bin/ip link del dev mgmt
auto feth1
iface feth1 inet manual
mtu 9000
auto feth2
iface feth2 inet manual
mtu 9000

33
files/qemu-ifdown Executable file
View File

@ -0,0 +1,33 @@
#!/bin/bash
set -e
IFACE=$1
### IPv4 is IFACE public and has a route? if so, nuke it
for route in $(vtysh -c "show ip route kernel" | grep "$IFACE" | awk '{ print $2 }')
do
echo "removing route for $IFACE: $route"
ip route del $route
done
#### IPv6 is IFACE public and has a route? if so, nuke it
#for route in $(vtysh -c "show ipv6 route kernel" | grep "$IFACE" | awk '{ print $2 }')
# do
# echo "removing route for $IFACE: $route"
# ip route del $route
#done
### is IFACE private and has a local bridge?
BRIDGE=$(readlink -f /sys/devices/virtual/net/$IFACE/brport/bridge || true)
if [ ! -z $BRIDGE ]; then
BRIDGE=${BRIDGE##*/}
echo "removing $IFACE from $BRIDGE"
brctl delif $BRIDGE $IFACE
if ! ls /sys/devices/virtual/net/$BRIDGE/brif/ | grep -qv vxlan; then #if so is the *local* bridge now empty? if so, nuke the whole bridge including tunnel endpoint
echo "removing unused bridge: $BRIDGE"
ip link del dev $(ls /sys/devices/virtual/net/$BRIDGE/brif/ | grep vxlan)
ip link set down $BRIDGE
brctl delbr $BRIDGE
fi
fi

34
files/qemu-ifup Executable file
View File

@ -0,0 +1,34 @@
#!/bin/bash
set -e
IFACE=$1
# vm<vm_id>.<num>
CLUSTER=$(curl -s -H 'X-Wit-Auth: true' http://10.0.0.1:4000/get-by-iface/${IFACE} | sed 's/"//g' | awk '{print $1}')
if ! [[ $CLUSTER =~ ^[0-9]+$ ]]; then
echo "CLUSTER seems not to be valid"
exit 10
fi
LOOPBACKIP=$(hostname -i)
BRIDGE=br${CLUSTER}
VXLAN=vxlan${CLUSTER}
VNI=${CLUSTER}
ip link set up ${IFACE}
if ! ip link show dev ${VXLAN} &>/dev/null; then
ip link add ${VXLAN} type vxlan id ${VNI} dstport 4789 local ${LOOPBACKIP} nolearning
ip link set up ${VXLAN}
fi
if ! ip link show dev ${BRIDGE} &>/dev/null; then
brctl addbr ${BRIDGE}
brctl stp ${BRIDGE} off
brctl addif ${BRIDGE} ${VXLAN}
ip link set up dev ${BRIDGE}
bridge vlan del dev ${BRIDGE} vid 1 self
echo 1 >/sys/class/net/${BRIDGE}/bridge/vlan_filtering
fi
brctl addif ${BRIDGE} ${IFACE}

69
files/qemu-ifup-public Executable file
View File

@ -0,0 +1,69 @@
#!/bin/bash
set -e
IFACE=$1
maxprefixv6=64
maxprefixv4=29
publicmac=52:54:00:00:00:11
IP=$(curl -s -H 'X-Wit-Auth: true' http://10.0.0.1:4000/get-by-iface/${IFACE} | sed 's/"//g' | awk '{print $2}')
if [ -z $IP ]; then
echo "got nothing back from the API"
exit 10
fi
eui64() {
local macaddr="$1"
printf "%02x%s" $(( 16#${macaddr:0:2} ^ 2#00000010 )) "${macaddr:2}" \
| sed -E -e 's/([0-9a-zA-Z]{2})*/0x\0|/g' \
| tr -d ':\n' \
| xargs -d '|' \
printf "fe80::%02x%02x:%02xff:fe%02x:%02x%02x"
}
ip link set up ${IFACE}
arp -i ${IFACE} -Ds 169.254.0.1 ${IFACE} netmask 255.255.255.255 pub
IFS=',' read -ra IPS <<< "$IP"
for IP in "${IPS[@]}"; do
if [[ $IP =~ ^170.199.21[0-9]\.[0-9]{1,3}/([0-9]{2})$ ]]; then ### we got a IPv4 prefix < maxprefixv4
if [ ${BASH_REMATCH[1]} -lt $maxprefixv4 ]; then
echo "we don't support such a big customer net?"
continue
fi
if [ ${BASH_REMATCH[1]} -gt 32 ]; then
echo "prefix is invalid"
continue
fi
echo "we got IPv4 with prefix ${BASH_REMATCH[0]}"
ip route add ${IP} dev ${IFACE}
elif [[ $IP =~ ^2604:bbc0:[0-9,a-f,:]{1,444}/([0-9]{2,3})$ ]]; then ### we got a PIv6 prefix < masprefixv6
if [ ${BASH_REMATCH[1]} -lt $maxprefixv6 ]; then
echo "we don't support such a big customer net?"
continue
fi
if [ ${BASH_REMATCH[1]} -gt 128 ]; then
echo "prefix is invalid"
continue
fi
echo "we got IPv6 with prefix ${BASH_REMATCH[0]}"
ip route add ${IP} dev ${IFACE} via $(eui64 $publicmac)
else ### don't know what we have but something we can't work with
echo "Unable to detect with what prefix I'm working with"
fi
done

3
files/rc.local Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
echo lldp stop | /usr/bin/tee /sys/kernel/debug/i40e/*/command

2
files/resolv.conf Normal file
View File

@ -0,0 +1,2 @@
nameserver 2001:4860:4860::8888
nameserver 2001:4860:4860::8844

7
files/vrf-dhcp-enter Normal file
View File

@ -0,0 +1,7 @@
vrfid=$(ip -o -d link show dev ${interface} 2>/dev/null | egrep ' vrf_slave table [0-9]*' | sed -e 's/.*vrf_slave table \([0-9]*\) .*/\1/')
if [ "$reason" = "BOUND" ] && [ "$vrfid" != "" ]; then
/sbin/ip route flush table $vrfid
vrfgateway=$new_routers
new_routers=""
fi

3
files/vrf-dhcp-exit Normal file
View File

@ -0,0 +1,3 @@
if [ "$reason" = "BOUND" ] && [ "$vrfid" != "" ]; then
/sbin/ip route add default via $vrfgateway table $vrfid
fi

1
files/vrf.conf Normal file
View File

@ -0,0 +1 @@
1001 mgmt

27
files/wit-gc Executable file
View File

@ -0,0 +1,27 @@
#!/bin/bash
EMPTYBR=$(for br in /sys/devices/virtual/net/br*; do if [ ! -d $br ]; then continue; fi; ls $br/brif/ | grep -qv vxlan || echo ${br##*/br}; done)
for id in $EMPTYBR
do
echo "removing unused customer bridge/vxlan id: $id"
ip link del dev vxlan$id
ip link set down br$id
brctl delbr br$id
done
for route in $(vtysh -c "show ip route kernel" | grep 'unknown inactive' | awk '{ print $3 }')
do
echo "removing zombie route: $route"
ip route add blackhole $route
ip route del $route
done
#for route in $(vtysh -c "show ipv6 route kernel" | grep 'unknown inactive' | awk '{ print $3 }')
# do
# echo "removing zombie route: $route"
# ip route add blackhole $route
# ip route del $route
#done