~rackspace-titan/nova/extensions-osapi1.1-serx

« back to all changes in this revision

Viewing changes to nova/virt/libvirt/vif.py

  • Committer: Naveed Massjouni
  • Date: 2011-07-29 05:58:12 UTC
  • mfrom: (1299.1.44 nova)
  • Revision ID: naveedm9@gmail.com-20110729055812-xabjblxndjkf3of1
MergeĀ fromĀ trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# vim: tabstop=4 shiftwidth=4 softtabstop=4
 
2
 
 
3
# Copyright (C) 2011 Midokura KK
 
4
# Copyright (C) 2011 Nicira, Inc
 
5
# Copyright 2011 OpenStack LLC.
 
6
# All Rights Reserved.
 
7
#
 
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
 
11
#
 
12
#         http://www.apache.org/licenses/LICENSE-2.0
 
13
#
 
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
 
18
#    under the License.
 
19
 
 
20
"""VIF drivers for libvirt."""
 
21
 
 
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
 
28
 
 
29
LOG = logging.getLogger('nova.virt.libvirt.vif')
 
30
 
 
31
FLAGS = flags.FLAGS
 
32
 
 
33
flags.DEFINE_string('libvirt_ovs_bridge', 'br-int',
 
34
                    'Name of Integration Bridge used by Open vSwitch')
 
35
 
 
36
 
 
37
class LibvirtBridgeDriver(VIFDriver):
 
38
    """VIF driver for Linux bridge."""
 
39
 
 
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(':', '')
 
45
 
 
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)]
 
50
            if FLAGS.use_ipv6:
 
51
                net_v6, prefixlen_v6 = netutils.get_net_and_prefixlen(
 
52
                                           network['cidr_v6'])
 
53
                values.extend([("PROJNETV6", net_v6),
 
54
                               ("PROJMASKV6", prefixlen_v6)])
 
55
 
 
56
            extra_params = "".join([template % value for value in values])
 
57
        else:
 
58
            extra_params = "\n"
 
59
 
 
60
        result = {
 
61
            'id': mac_id,
 
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,
 
67
        }
 
68
 
 
69
        if gateway6:
 
70
            result['gateway6'] = gateway6 + "/128"
 
71
 
 
72
        return result
 
73
 
 
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'],
 
83
                                             network['bridge'],
 
84
                                             network['bridge_interface'])
 
85
            else:
 
86
                LOG.debug(_("Ensuring bridge %s"), network['bridge'])
 
87
                linux_net.ensure_bridge(network['bridge'],
 
88
                                        network['bridge_interface'])
 
89
 
 
90
        return self._get_configurations(network, mapping)
 
91
 
 
92
    def unplug(self, instance, network, mapping):
 
93
        """No manual unplugging required."""
 
94
        pass
 
95
 
 
96
 
 
97
class LibvirtOpenVswitchDriver(VIFDriver):
 
98
    """VIF driver for Open vSwitch."""
 
99
 
 
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'])
 
115
 
 
116
        result = {
 
117
            'script': '',
 
118
            'name': dev,
 
119
            'mac_address': mapping['mac']}
 
120
        return result
 
121
 
 
122
    def unplug(self, instance, network, mapping):
 
123
        """Unplug the VIF from the network by deleting the port from
 
124
        the bridge."""
 
125
        vif_id = str(instance['id']) + "-" + str(network['id'])
 
126
        dev = "tap-%s" % vif_id
 
127
        try:
 
128
            utils.execute('sudo', 'ovs-vsctl', 'del-port',
 
129
                          network['bridge'], dev)
 
130
            utils.execute('sudo', 'ip', 'link', 'delete', dev)
 
131
        except:
 
132
            LOG.warning(_("Failed while unplugging vif of instance '%s'"),
 
133
                        instance['name'])
 
134
            raise