1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
3
# Copyright (C) 2011 Midokura KK
4
# Copyright (C) 2011 Nicira, Inc
5
# Copyright 2011 OpenStack LLC.
8
# Licensed under the Apache License, Version 2.0 (the "License"); you may
9
# not use this file except in compliance with the License. You may obtain
10
# a copy of the License at
12
# http://www.apache.org/licenses/LICENSE-2.0
14
# Unless required by applicable law or agreed to in writing, software
15
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17
# License for the specific language governing permissions and limitations
20
"""VIF drivers for libvirt."""
22
from nova import flags
23
from nova import log as logging
24
from nova.network import linux_net
25
from nova.virt.libvirt import netutils
26
from nova import utils
27
from nova.virt.vif import VIFDriver
29
LOG = logging.getLogger('nova.virt.libvirt.vif')
33
flags.DEFINE_string('libvirt_ovs_bridge', 'br-int',
34
'Name of Integration Bridge used by Open vSwitch')
37
class LibvirtBridgeDriver(VIFDriver):
38
"""VIF driver for Linux bridge."""
40
def _get_configurations(self, network, mapping):
41
"""Get a dictionary of VIF configurations for bridge type."""
42
# Assume that the gateway also acts as the dhcp server.
43
gateway6 = mapping.get('gateway6')
44
mac_id = mapping['mac'].replace(':', '')
46
if FLAGS.allow_project_net_traffic:
47
template = "<parameter name=\"%s\"value=\"%s\" />\n"
48
net, mask = netutils.get_net_and_mask(network['cidr'])
49
values = [("PROJNET", net), ("PROJMASK", mask)]
51
net_v6, prefixlen_v6 = netutils.get_net_and_prefixlen(
53
values.extend([("PROJNETV6", net_v6),
54
("PROJMASKV6", prefixlen_v6)])
56
extra_params = "".join([template % value for value in values])
62
'bridge_name': network['bridge'],
63
'mac_address': mapping['mac'],
64
'ip_address': mapping['ips'][0]['ip'],
65
'dhcp_server': mapping['dhcp_server'],
66
'extra_params': extra_params,
70
result['gateway6'] = gateway6 + "/128"
74
def plug(self, instance, network, mapping):
75
"""Ensure that the bridge exists, and add VIF to it."""
76
if (not network.get('multi_host') and
77
mapping.get('should_create_bridge')):
78
if mapping.get('should_create_vlan'):
79
LOG.debug(_('Ensuring vlan %(vlan)s and bridge %(bridge)s'),
80
{'vlan': network['vlan'],
81
'bridge': network['bridge']})
82
linux_net.ensure_vlan_bridge(network['vlan'],
84
network['bridge_interface'])
86
LOG.debug(_("Ensuring bridge %s"), network['bridge'])
87
linux_net.ensure_bridge(network['bridge'],
88
network['bridge_interface'])
90
return self._get_configurations(network, mapping)
92
def unplug(self, instance, network, mapping):
93
"""No manual unplugging required."""
97
class LibvirtOpenVswitchDriver(VIFDriver):
98
"""VIF driver for Open vSwitch."""
100
def plug(self, instance, network, mapping):
101
vif_id = str(instance['id']) + "-" + str(network['id'])
102
dev = "tap-%s" % vif_id
103
iface_id = "nova-" + vif_id
104
if not linux_net._device_exists(dev):
105
utils.execute('sudo', 'ip', 'tuntap', 'add', dev, 'mode', 'tap')
106
utils.execute('sudo', 'ip', 'link', 'set', dev, 'up')
107
utils.execute('sudo', 'ovs-vsctl', '--', '--may-exist', 'add-port',
108
FLAGS.libvirt_ovs_bridge, dev,
109
'--', 'set', 'Interface', dev,
110
"external-ids:iface-id=%s" % iface_id,
111
'--', 'set', 'Interface', dev,
112
"external-ids:iface-status=active",
113
'--', 'set', 'Interface', dev,
114
"external-ids:attached-mac=%s" % mapping['mac'])
119
'mac_address': mapping['mac']}
122
def unplug(self, instance, network, mapping):
123
"""Unplug the VIF from the network by deleting the port from
125
vif_id = str(instance['id']) + "-" + str(network['id'])
126
dev = "tap-%s" % vif_id
128
utils.execute('sudo', 'ovs-vsctl', 'del-port',
129
network['bridge'], dev)
130
utils.execute('sudo', 'ip', 'link', 'delete', dev)
132
LOG.warning(_("Failed while unplugging vif of instance '%s'"),