Merge branch 'master' of ssh://git.onelab.eu/git/build
[build.git] / lbuild-bridge.sh
1 #!/bin/bash
2
3 # taking this bridge-initialization code out of lbuild-initvm.sh 
4 # so we can use it on our libvirt/lxc local infra 
5 # there's something very similar in 
6 # tests/system/template-qemu/qemu-bridge-init
7 # that the current code was actually based on, but 
8 # nobody was ever bold enough to reconcile these two 
9
10 # hard-wired 
11 DEFAULT_PUBLIC_BRIDGE=br0
12
13 ##############################
14 # use /proc/net/dev instead of a hard-wired list
15 function gather_interfaces () {
16     python <<EOF
17 for line in file("/proc/net/dev"):
18     if ':' not in line: continue
19     ifname=line.replace(" ","").split(":")[0]
20     if ifname.find("lo")==0: continue
21     if ifname.find("br")==0: continue
22     if ifname.find("virbr")==0: continue
23     if ifname.find("veth")==0: continue
24     if ifname.find("tap")==0: continue
25     if ifname.find("vif")==0: continue
26     print ifname
27 EOF
28 }
29
30 function discover_interface () {
31     for ifname in $(gather_interfaces); do
32         ip link show $ifname | grep -qi 'state UP' && { echo $ifname; return; }
33     done
34     # still not found ? that's bad
35     echo unknown
36 }
37
38 ##############################
39 function check_yum_installed () {
40     package=$1; shift
41     rpm -q $package >& /dev/null || yum -y install $package
42 }
43
44 # not used apparently
45 function check_yumgroup_installed () {
46     group="$1"; shift
47     yum grouplist "$group" | grep -q Installed || { yum -y groupinstall "$group" ; }
48 }
49
50 #################### bridge initialization
51 function create_bridge_if_needed() {
52
53     # do not turn on verbosity
54     # set -x
55
56     public_bridge=$1; shift
57
58     # already created ? - we're done
59     ip addr show $public_bridge >& /dev/null && {
60         echo "Bridge already set up - skipping create_bridge_if_needed"
61         return 0
62     }
63
64     # find out the physical interface to bridge onto
65     if_lan=$(discover_interface)
66
67     ip addr show $if_lan &>/dev/null || {
68         echo "Cannot use interface $if_lan - exiting"
69         exit 1
70     }
71
72     #################### bride initialization
73     check_yum_installed bridge-utils
74
75     echo "========== $COMMAND: entering create_bridge - beg"
76     hostname
77     uname -a
78     ip addr show
79     ip route
80     echo "========== $COMMAND: entering create_bridge - end"
81
82     # disable netfilter calls for bridge interface (they cause panick on 2.6.35 anyway)
83     #
84     # another option would be to accept the all forward packages for
85     # bridged interface like: -A FORWARD -m physdev --physdev-is-bridged -j ACCEPT
86     sysctl net.bridge.bridge-nf-call-iptables=0
87     sysctl net.bridge.bridge-nf-call-ip6tables=0
88     sysctl net.bridge.bridge-nf-call-arptables=0
89
90     
91     #Getting host IP/masklen
92     address=$(ip addr show $if_lan | grep -v inet6 | grep inet | head --lines=1 | awk '{print $2;}')
93     [ -z "$address" ] && { echo "ERROR: Could not determine IP address for $if_lan" ; exit 1 ; }
94
95     broadcast=$(ip addr show $if_lan | grep -v inet6 | grep inet | head --lines=1 | awk '{print $4;}')
96     [ -z "$broadcast" ] && echo "WARNING: Could not determine broadcast address for $if_lan"
97
98     gateway=$(ip route show | grep default | awk '{print $3;}')
99     [ -z "$gateway" ] && echo "WARNING: Could not determine gateway IP"
100
101
102     # creating the bridge
103     echo "Creating public bridge interface $public_bridge"
104     brctl addbr $public_bridge
105     brctl addif $public_bridge $if_lan
106     echo "Activating promiscuous mode if_lan=$if_lan"
107     ip link set $if_lan up promisc on
108     sleep 2
109     # rely on dhcp to re assign IP.. 
110     echo "Starting dhclient on $public_bridge"
111     dhclient $public_bridge
112     sleep 1
113
114     #Reconfigure the routing table
115     echo "Configuring gateway=$gateway"
116     ip route add default via $gateway dev $public_bridge
117     ip route del default via $gateway dev $if_lan
118     # at this point we have an extra route like e.g.
119     ## ip route show
120     #default via 138.96.112.250 dev br0
121     #138.96.112.0/21 dev em1  proto kernel  scope link  src 138.96.112.57
122     #138.96.112.0/21 dev br0  proto kernel  scope link  src 138.96.112.57
123     #192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1
124     route_dest=$(ip route show | grep -v default | grep "dev $public_bridge" | awk '{print $1;}')
125     ip route del $route_dest dev $if_lan
126
127     echo "========== $COMMAND: exiting create_bridge - beg"
128     ip addr show
129     ip route show
130     echo "========== $COMMAND: exiting create_bridge - end"
131
132     # for safety
133     sleep 3
134     return 0
135
136 }
137
138 function main () {
139     if [[ -n "$@" ]] ; then 
140         public_bridge="$1"; shift
141     else
142         public_bridge="$DEFAULT_PUBLIC_BRIDGE"
143     fi
144     create_bridge_if_needed $public_bridge
145 }
146
147 main "$@"