Example #1
0
    def unplug(self, datalink_name, bridge=None, namespace=None, prefix=None):
        """Unplug the interface."""

        # remove any IP addresses on top of this datalink, otherwise we will
        # get 'device busy' error while deleting the datalink
        self.fini_l3(datalink_name)

        dl = net_lib.Datalink(datalink_name)
        dl.delete_vnic()

        if bridge is None:
            bridge = self.conf.ovs_integration_bridge

        # check if bridge exists
        ovs = ovs_lib.OVSBridge(bridge)
        if not ovs.bridge_exists(bridge):
            raise exceptions.BridgeDoesNotExist(bridge=bridge)

        try:
            ovs.delete_port(datalink_name)
            LOG.debug("Unplugged interface '%s'", datalink_name)
        except RuntimeError as err:
            LOG.exception(
                _("Failed unplugging interface '%s': %s") %
                (datalink_name, err))
Example #2
0
 def check_bridge_exists(self, bridge):
     if not ip_lib.device_exists(bridge):
         raise exceptions.BridgeDoesNotExist(bridge=bridge)
Example #3
0
    def plug(self,
             tenant_id,
             network_id,
             port_id,
             datalink_name,
             mac_address,
             network=None,
             bridge=None,
             namespace=None,
             prefix=None,
             protection=False,
             mtu=None,
             vif_type=None):
        """Plug in the interface."""

        if net_lib.Datalink.datalink_exists(datalink_name):
            LOG.info(_("Device %s already exists"), datalink_name)
            return

        if bridge is None:
            bridge = self.conf.ovs_integration_bridge

        # check if bridge exists
        ovs = ovs_lib.OVSBridge(bridge)
        if not ovs.bridge_exists(bridge):
            raise exceptions.BridgeDoesNotExist(bridge=bridge)

        if network is None:
            network = self.neutron_client.show_network(network_id)['network']
            mtu = network.get('mtu')

        network_type = network.get('provider:network_type')
        vid = None
        lower_link = None
        if network_type == p_const.TYPE_VXLAN:
            lower_link = 'ovs.vxlan1'
        elif network_type in [p_const.TYPE_VLAN, p_const.TYPE_FLAT]:
            phys_network = network.get('provider:physical_network')
            # For integration bridge the ovs agent will take care of
            # adding the vlan id
            if bridge != self.conf.ovs_integration_bridge:
                vid = network.get('provider:segmentation_id')
            # need to determine the bridge mapping
            try:
                results = get_ovsdb_info('Open_vSwitch', ['other_config'])
            except Exception as err:
                LOG.exception(_("Failed to retrieve other_config from %s: %s"),
                              bridge, err)
                raise
            other_config = results[0]['other_config']
            if not other_config:
                msg = (_("'other_config' column in 'Open_vSwitch' OVSDB table "
                         "is not configured. Please configure it so that "
                         "lower-link can be determined for the VNICs"))
                raise exceptions.Invalid(message=msg)
            bridge_mappings = other_config.get('bridge_mappings')
            if not bridge_mappings:
                msg = (_("'bridge_mappings' info is not set in 'other_config' "
                         "column of 'Open_vSwitch' OVSDB table. Please "
                         "configure it so that lower-link can be determined "
                         "for the VNICs"))
                raise exceptions.Invalid(message=msg)
            for bridge_mapping in bridge_mappings.split(','):
                if phys_network not in bridge_mapping:
                    continue
                lower_link = bridge_mapping.split(':')[1]
                break
        else:
            # TYPE_GRE and TYPE_LOCAL
            msg = (_("Unsupported network type: %s") % network_type)
            LOG.error(msg)
            raise exceptions.Invalid(message=msg)

        # if lower_link is not set or empty, we need to fail
        if not lower_link:
            msg = (_("Failed to determine the lower_link for VNIC "
                     "%s on physical_network %s") %
                   (datalink_name, phys_network))
            LOG.error(msg)
            raise exceptions.Invalid(message=msg)

        if vif_type == 'binding_failed':
            msg = (_('Port binding has failed for %s. Ensure that '
                     'OVS agent is running and/or bridge_mappings are '
                     'correctly configured. Port will not have network '
                     'connectivity') % datalink_name)
            LOG.error(msg)

        dl = net_lib.Datalink(datalink_name)
        dl.create_vnic(lower_link, mac_address, vid, temp=True)
        if mtu:
            try:
                dl.set_prop('mtu', mtu)
            except Exception:
                msg = (_("Failed to set mtu value of '%s' on '%s' over lower "
                         "link '%s'. If you are using VLANs, then ensure that "
                         "either the mapping of physical networks to MTU "
                         "values (ml2_conf.ini`physical_network_mtus option) "
                         "or neutron.conf`global_physnet_mtu value is set "
                         "correctly. If you are using VXLANs, make sure that "
                         "ml2_conf.ini`path_mtu value is set correctly.") %
                       (mtu, datalink_name, lower_link))
                LOG.error(msg)

        attrs = [('external_ids', {
            'iface-id': port_id,
            'iface-status': 'active',
            'attached-mac': mac_address
        })]
        ovs.replace_port(datalink_name, *attrs)