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