summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2011-02-08 19:09:42 +0000
committerTarmac <>2011-02-08 19:09:42 +0000
commit7c78d71eba66b64f2a2cac0309dcd01f2acf8b4d (patch)
tree670cb65da6324b3bf3a66fb03a7d2356afff4875
parent035136525ef7944d3da4dcf8a4b0d28840bdfae3 (diff)
parent6f30cff7374e91c2920759e13971c0149d96d821 (diff)
downloadnova-7c78d71eba66b64f2a2cac0309dcd01f2acf8b4d.tar.gz
nova-7c78d71eba66b64f2a2cac0309dcd01f2acf8b4d.tar.xz
nova-7c78d71eba66b64f2a2cac0309dcd01f2acf8b4d.zip
Automates the setup for FlatDHCP regardless of whether the interface has an ip address.
FlatDHCP only has worked until now if the underlying interface that you bridge into has no ip address. This branch will do the necessary setup to allow it to work by: * Creating a bridge with the private address for dhcp * Moving any existing ips from the interface onto the bridge * Adding the interface to the bridge * Recreating the default route if it was deleted by moving the interface It will additionally add a route to compute hosts for bridges that it adds to the compute hosts. This seems to be necessary in some cases where the default route uses a different interface.
-rw-r--r--nova/network/linux_net.py68
1 files changed, 57 insertions, 11 deletions
diff --git a/nova/network/linux_net.py b/nova/network/linux_net.py
index b740d0423..df54606db 100644
--- a/nova/network/linux_net.py
+++ b/nova/network/linux_net.py
@@ -20,6 +20,7 @@ Implements vlans, bridges, and iptables rules using linux utilities.
import os
from nova import db
+from nova import exception
from nova import flags
from nova import log as logging
from nova import utils
@@ -185,27 +186,72 @@ def ensure_vlan(vlan_num):
def ensure_bridge(bridge, interface, net_attrs=None):
- """Create a bridge unless it already exists"""
+ """Create a bridge unless it already exists.
+
+ :param interface: the interface to create the bridge on.
+ :param net_attrs: dictionary with attributes used to create the bridge.
+
+ If net_attrs is set, it will add the net_attrs['gateway'] to the bridge
+ using net_attrs['broadcast'] and net_attrs['cidr']. It will also add
+ the ip_v6 address specified in net_attrs['cidr_v6'] if use_ipv6 is set.
+
+ The code will attempt to move any ips that already exist on the interface
+ onto the bridge and reset the default gateway if necessary.
+ """
if not _device_exists(bridge):
LOG.debug(_("Starting Bridge interface for %s"), interface)
_execute("sudo brctl addbr %s" % bridge)
_execute("sudo brctl setfd %s 0" % bridge)
# _execute("sudo brctl setageing %s 10" % bridge)
_execute("sudo brctl stp %s off" % bridge)
- if interface:
- _execute("sudo brctl addif %s %s" % (bridge, interface))
+ _execute("sudo ip link set %s up" % bridge)
if net_attrs:
- _execute("sudo ip addr add %s/%s dev %s broadcast %s" % \
- (net_attrs['gateway'],
- net_attrs['netmask'],
- bridge,
- net_attrs['broadcast']))
+ # NOTE(vish): The ip for dnsmasq has to be the first address on the
+ # bridge for it to respond to reqests properly
+ suffix = net_attrs['cidr'].rpartition('/')[2]
+ out, err = _execute("sudo ip addr add %s/%s brd %s dev %s" %
+ (net_attrs['gateway'],
+ suffix,
+ net_attrs['broadcast'],
+ bridge),
+ check_exit_code=False)
+ if err and err != "RTNETLINK answers: File exists\n":
+ raise exception.Error("Failed to add ip: %s" % err)
if(FLAGS.use_ipv6):
_execute("sudo ip -f inet6 addr change %s dev %s" %
(net_attrs['cidr_v6'], bridge))
- _execute("sudo ip link set %s up" % bridge)
- else:
- _execute("sudo ip link set %s up" % bridge)
+ # NOTE(vish): If the public interface is the same as the
+ # bridge, then the bridge has to be in promiscuous
+ # to forward packets properly.
+ if(FLAGS.public_interface == bridge):
+ _execute("sudo ip link set dev %s promisc on" % bridge)
+ if interface:
+ # NOTE(vish): This will break if there is already an ip on the
+ # interface, so we move any ips to the bridge
+ gateway = None
+ out, err = _execute("sudo route -n")
+ for line in out.split("\n"):
+ fields = line.split()
+ if fields and fields[0] == "0.0.0.0" and fields[-1] == interface:
+ gateway = fields[1]
+ out, err = _execute("sudo ip addr show dev %s scope global" %
+ interface)
+ for line in out.split("\n"):
+ fields = line.split()
+ if fields and fields[0] == "inet":
+ params = ' '.join(fields[1:-1])
+ _execute("sudo ip addr del %s dev %s" % (params, fields[-1]))
+ _execute("sudo ip addr add %s dev %s" % (params, bridge))
+ if gateway:
+ _execute("sudo route add 0.0.0.0 gw %s" % gateway)
+ out, err = _execute("sudo brctl addif %s %s" %
+ (bridge, interface),
+ check_exit_code=False)
+
+ if (err and err != "device %s is already a member of a bridge; can't "
+ "enslave it to bridge %s.\n" % (interface, bridge)):
+ raise exception.Error("Failed to add interface: %s" % err)
+
if FLAGS.use_nova_chains:
(out, err) = _execute("sudo iptables -N nova_forward",
check_exit_code=False)