mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-03 04:12:31 +01:00
The routing table with two nics may be messed up, due to we sent same router(gateway) information from different DHCP server, in order to specify default gateway. E.g. Network A: 192.168.1.0/24, gw 192.168.1.1 Network B: 192.168.2.0/24, gw 192.168.2.1 User VM: Nic 1 connect to network A, get ip 192.168.1.10; nic 2 connect to network B, get ip 192.168.2.10. Set network A as the default network of user VM. Currently we would send this information to user VM through DHCP offer: In network A: dhcp-option:router 192.168.1.1 In network B: dhcp-option:router 192.168.1.1 So both NIC in the guest VM would receive 192.168.1.1 as router(gateway). But, in CentOS 5.6, dhclient-scripts try to tell if the gateway is reachable for current subnet. So when we try to enable nic 2(eth1) of user VM, dhclient would receive: IP: 192.168.2.10 Mask: 255.255.255.0 Router: 192.168.1.1 Then it would found that the specified gateway(router) is not within its own subnet(192.168.2.0/24). But since we send out this ip(192.168.1.1) as the gateway for it, dhclient thought that it should got someway to access the network through this IP. So it would execute: ip route add 192.168.1.1 dev eth1 ip route replace default via 192.168.1.1 dev eth1 But it can never reach 192.168.1.1(which is in the eth0's subnet and the gateway of eth0) by go through eth1 interface. So it is messed up. We've tested Windows 2008 R2, CentOS 5.3, CentOS 5.6 and Ubuntu 10.04. Windows and Ubuntu are fine with above policy. To solve this, we send different dhcp:router option according to the guest OS type now. We may need expand this list later, but for now we only know that CentOS and RHEL would behavior in this way. status 14042: resolved fixed
138 lines
3.4 KiB
Bash
Executable File
138 lines
3.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Copyright (C) 2011 Citrix Systems, Inc. All rights reserved
|
|
#
|
|
# This software is licensed under the GNU General Public License v3 or later.
|
|
#
|
|
# It is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or any later version.
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
|
|
|
|
|
|
|
|
# edithosts.sh -- edit the dhcphosts file on the routing domain
|
|
# $mac : the mac address
|
|
# $ip : the associated ip address
|
|
# $host : the hostname
|
|
# $4 : default router
|
|
# $5 : nameserver on default nic
|
|
# $6 : comma separated static routes
|
|
|
|
mac=$1
|
|
ip=$2
|
|
host=$3
|
|
dflt=$4
|
|
dns=$5
|
|
routes=$6
|
|
|
|
DHCP_HOSTS=/etc/dhcphosts.txt
|
|
DHCP_OPTS=/etc/dhcpopts.txt
|
|
DHCP_LEASES=/var/lib/misc/dnsmasq.leases
|
|
HOSTS=/etc/hosts
|
|
|
|
source /root/func.sh
|
|
|
|
lock="biglock"
|
|
locked=$(getLockFile $lock)
|
|
if [ "$locked" != "1" ]
|
|
then
|
|
exit 1
|
|
fi
|
|
|
|
grep "redundant_router=1" /var/cache/cloud/cmdline > /dev/null
|
|
no_redundant=$?
|
|
|
|
wait_for_dnsmasq () {
|
|
local _pid=$(pidof dnsmasq)
|
|
for i in 0 1 2 3 4 5 6 7 8 9 10
|
|
do
|
|
sleep 1
|
|
_pid=$(pidof dnsmasq)
|
|
[ "$_pid" != "" ] && break;
|
|
done
|
|
[ "$_pid" != "" ] && return 0;
|
|
logger -t cloud "edithosts: timed out waiting for dnsmasq to start"
|
|
return 1
|
|
}
|
|
|
|
logger -t cloud "edithosts: update $1 $2 $3 to hosts"
|
|
|
|
[ ! -f $DHCP_HOSTS ] && touch $DHCP_HOSTS
|
|
[ ! -f $DHCP_OPTS ] && touch $DHCP_OPTS
|
|
[ ! -f $DHCP_LEASES ] && touch $DHCP_LEASES
|
|
|
|
#delete any previous entries from the dhcp hosts file
|
|
sed -i /$mac/d $DHCP_HOSTS
|
|
sed -i /$ip,/d $DHCP_HOSTS
|
|
sed -i /$host,/d $DHCP_HOSTS
|
|
|
|
|
|
#put in the new entry
|
|
echo "$mac,$ip,$host,infinite" >>$DHCP_HOSTS
|
|
|
|
#delete leases to supplied mac and ip addresses
|
|
sed -i /$mac/d $DHCP_LEASES
|
|
sed -i /"$ip "/d $DHCP_LEASES
|
|
sed -i /"$host "/d $DHCP_LEASES
|
|
|
|
#put in the new entry
|
|
echo "0 $mac $ip $host *" >> $DHCP_LEASES
|
|
|
|
#edit hosts file as well
|
|
sed -i /"$ip "/d $HOSTS
|
|
sed -i /"$host "/d $HOSTS
|
|
echo "$ip $host" >> $HOSTS
|
|
|
|
if [ "$dflt" != "" ]
|
|
then
|
|
#make sure dnsmasq looks into options file
|
|
sed -i /dhcp-optsfile/d /etc/dnsmasq.conf
|
|
echo "dhcp-optsfile=$DHCP_OPTS" >> /etc/dnsmasq.conf
|
|
|
|
tag=$(echo $ip | tr '.' '_')
|
|
sed -i /$tag/d $DHCP_OPTS
|
|
if [ "$dflt" != "0.0.0.0" ]
|
|
then
|
|
logger -t cloud "$0: setting default router for $ip to $dflt"
|
|
echo "$tag,3,$dflt" >> $DHCP_OPTS
|
|
else
|
|
logger -t cloud "$0: unset default router for $ip"
|
|
echo "$tag,3," >> $DHCP_OPTS
|
|
fi
|
|
if [ "$dns" != "" ]
|
|
then
|
|
logger -t cloud "$0: setting dns server for $ip to $dns"
|
|
echo "$tag,6,$dns" >> $DHCP_OPTS
|
|
fi
|
|
[ "$routes" != "" ] && echo "$tag,121,$routes" >> $DHCP_OPTS
|
|
#delete entry we just put in because we need a tag
|
|
sed -i /$mac/d $DHCP_HOSTS
|
|
#put it back with a tag
|
|
echo "$mac,set:$tag,$ip,$host,infinite" >>$DHCP_HOSTS
|
|
fi
|
|
|
|
# make dnsmasq re-read files
|
|
pid=$(pidof dnsmasq)
|
|
if [ "$pid" != "" ]
|
|
then
|
|
service dnsmasq restart
|
|
else
|
|
if [ $no_redundant -eq 1 ]
|
|
then
|
|
wait_for_dnsmasq
|
|
else
|
|
logger -t cloud "edithosts: skip wait dnsmasq due to redundant virtual router"
|
|
fi
|
|
fi
|
|
|
|
ret=$?
|
|
unlock_exit $ret $lock $locked
|