Example #1
0
    def setup_physical_bridges(self, bridge_mappings):
        """Setup the physical network bridges.

        Creates physical network bridges and links them to the
        integration bridge using veths.

        :param bridge_mappings: map physical network names to bridge names.
        """
        self.phys_brs = {}
        self.int_ofports = {}
        self.phys_ofports = {}
        ip_wrapper = ip_lib.IPWrapper(self.root_helper)
        for physical_network, bridge in bridge_mappings.iteritems():
            LOG.info(
                _("Mapping physical network %(physical_network)s to " "bridge %(bridge)s"),
                {"physical_network": physical_network, "bridge": bridge},
            )
            # setup physical bridge
            if not ip_lib.device_exists(bridge, self.root_helper):
                LOG.error(
                    _(
                        "Bridge %(bridge)s for physical network "
                        "%(physical_network)s does not exist. Agent "
                        "terminated!"
                    ),
                    {"physical_network": physical_network, "bridge": bridge},
                )
                sys.exit(1)
            br = ovs_lib.OVSBridge(bridge, self.root_helper)
            br.remove_all_flows()
            br.add_flow(priority=1, actions="normal")
            self.phys_brs[physical_network] = br

            # create veth to patch physical bridge with integration bridge
            int_veth_name = constants.VETH_INTEGRATION_PREFIX + bridge
            self.int_br.delete_port(int_veth_name)
            phys_veth_name = constants.VETH_PHYSICAL_PREFIX + bridge
            br.delete_port(phys_veth_name)
            if ip_lib.device_exists(int_veth_name, self.root_helper):
                ip_lib.IPDevice(int_veth_name, self.root_helper).link.delete()
                # Give udev a chance to process its rules here, to avoid
                # race conditions between commands launched by udev rules
                # and the subsequent call to ip_wrapper.add_veth
                utils.execute(["/sbin/udevadm", "settle", "--timeout=10"])
            int_veth, phys_veth = ip_wrapper.add_veth(int_veth_name, phys_veth_name)
            self.int_ofports[physical_network] = self.int_br.add_port(int_veth)
            self.phys_ofports[physical_network] = br.add_port(phys_veth)

            # block all untranslated traffic over veth between bridges
            self.int_br.add_flow(priority=2, in_port=self.int_ofports[physical_network], actions="drop")
            br.add_flow(priority=2, in_port=self.phys_ofports[physical_network], actions="drop")

            # enable veth to pass traffic
            int_veth.link.set_up()
            phys_veth.link.set_up()

            if self.veth_mtu:
                # set up mtu size for veth interfaces
                int_veth.link.set_mtu(self.veth_mtu)
                phys_veth.link.set_mtu(self.veth_mtu)
Example #2
0
    def _assert_dvr_floating_ips(self, router):
        # in the fip namespace:
        # Check that the fg-<port-id> (floatingip_agent_gateway)
        # is created with the ip address of the external gateway port
        floating_ips = router.router[l3_constants.FLOATINGIP_KEY]
        self.assertTrue(floating_ips)

        external_port = self.agent._get_ex_gw_port(router)
        fip_ns = self.agent.get_fip_ns(floating_ips[0]['floating_network_id'])
        fip_ns_name = fip_ns.get_name()
        fg_port_created_succesfully = ip_lib.device_exists_with_ip_mac(
            fip_ns.get_ext_device_name(external_port['id']),
            external_port['ip_cidr'],
            external_port['mac_address'],
            fip_ns_name, self.root_helper)
        self.assertTrue(fg_port_created_succesfully)
        # Check fpr-router device has been created
        device_name = fip_ns.get_int_device_name(router.router_id)
        fpr_router_device_created_succesfully = ip_lib.device_exists(
            device_name, self.root_helper, fip_ns_name)
        self.assertTrue(fpr_router_device_created_succesfully)

        # In the router namespace
        # Check rfp-<router-id> is created correctly
        for fip in floating_ips:
            device_name = fip_ns.get_rtr_ext_device_name(router.router_id)
            self.assertTrue(ip_lib.device_exists(
                device_name, self.root_helper, router.ns_name))
Example #3
0
    def internal_network_removed(self, ri, port):
        port_id = port['id']
        interface_name = self.get_internal_device_name(port_id)
        if ri.router['distributed'] and ri.ex_gw_port:
            # DVR handling code for SNAT
            self._snat_redirect_remove(ri, port, interface_name)
            if (self.conf.agent_mode == l3_constants.L3_AGENT_MODE_DVR_SNAT
                and ri.ex_gw_port['binding:host_id'] == self.host):
                snat_port = self._map_internal_interfaces(ri, port,
                                                          ri.snat_ports)
                if snat_port:
                    snat_interface = (
                        self.get_snat_int_device_name(snat_port['id'])
                    )
                    ns_name = self.get_snat_ns_name(ri.router['id'])
                    prefix = dvr.SNAT_INT_DEV_PREFIX
                    if ip_lib.device_exists(snat_interface,
                                            namespace=ns_name):
                        self.driver.unplug(snat_interface, namespace=ns_name,
                                           prefix=prefix)

        if ip_lib.device_exists(interface_name, namespace=ri.ns_name):
            if ri.is_ha:
                ri._clear_vips(interface_name)
            self.driver.unplug(interface_name, namespace=ri.ns_name,
                               prefix=INTERNAL_DEV_PREFIX)
Example #4
0
    def _assert_dvr_floating_ips(self, router):
        # in the fip namespace:
        # Check that the fg-<port-id> (floatingip_agent_gateway)
        # is created with the ip address of the external gateway port
        floating_ips = router.router[l3_constants.FLOATINGIP_KEY]
        self.assertTrue(floating_ips)
        # We need to fetch the floatingip agent gateway port info
        # from the router_info
        floating_agent_gw_port = (
            router.router[l3_constants.FLOATINGIP_AGENT_INTF_KEY])
        self.assertTrue(floating_agent_gw_port)

        external_gw_port = floating_agent_gw_port[0]
        fip_ns = self.agent.get_fip_ns(floating_ips[0]['floating_network_id'])
        fip_ns_name = fip_ns.get_name()
        fg_port_created_successfully = ip_lib.device_exists_with_ips_and_mac(
            fip_ns.get_ext_device_name(external_gw_port['id']),
            [self._port_first_ip_cidr(external_gw_port)],
            external_gw_port['mac_address'],
            namespace=fip_ns_name)
        self.assertTrue(fg_port_created_successfully)
        # Check fpr-router device has been created
        device_name = fip_ns.get_int_device_name(router.router_id)
        fpr_router_device_created_successfully = ip_lib.device_exists(
            device_name, namespace=fip_ns_name)
        self.assertTrue(fpr_router_device_created_successfully)

        # In the router namespace
        # Check rfp-<router-id> is created correctly
        for fip in floating_ips:
            device_name = fip_ns.get_rtr_ext_device_name(router.router_id)
            self.assertTrue(ip_lib.device_exists(
                device_name, namespace=router.ns_name))
Example #5
0
 def _get_dvr_snat_namespace_device_status(self, router, internal_dev_name=None):
     """Function returns the internal and external device status."""
     snat_ns = dvr_snat_ns.SnatNamespace.get_snat_ns_name(router.router_id)
     external_port = router.get_ex_gw_port()
     external_device_name = router.get_external_device_name(external_port["id"])
     qg_device_created_successfully = ip_lib.device_exists(external_device_name, namespace=snat_ns)
     sg_device_created_successfully = ip_lib.device_exists(internal_dev_name, namespace=snat_ns)
     return qg_device_created_successfully, sg_device_created_successfully
Example #6
0
    def setup_physical_bridges(self, bridge_mappings):
        '''Setup the physical network bridges.

        Creates physical network bridges and links them to the
        integration bridge using veths.

        :param bridge_mappings: map physical network names to bridge names.
        '''
        self.phys_brs = {}
        self.int_ofports = {}
        self.phys_ofports = {}
        ip_wrapper = ip_lib.IPWrapper(self.root_helper)
        for physical_network, bridge in bridge_mappings.iteritems():
            LOG.info(_("Mapping physical network %(physical_network)s to "
                       "bridge %(bridge)s"),
                     {'physical_network': physical_network,
                      'bridge': bridge})
            # setup physical bridge
            if not ip_lib.device_exists(bridge, self.root_helper):
                LOG.error(_("Bridge %(bridge)s for physical network "
                            "%(physical_network)s does not exist. Agent "
                            "terminated!"),
                          {'physical_network': physical_network,
                           'bridge': bridge})
                sys.exit(1)
            br = ovs_lib.OVSBridge(bridge, self.root_helper)
            br.remove_all_flows()
            br.add_flow(priority=1, actions="normal")
            self.phys_brs[physical_network] = br

            # create veth to patch physical bridge with integration bridge
            int_veth_name = constants.VETH_INTEGRATION_PREFIX + bridge
            self.int_br.delete_port(int_veth_name)
            phys_veth_name = constants.VETH_PHYSICAL_PREFIX + bridge
            br.delete_port(phys_veth_name)
            if ip_lib.device_exists(int_veth_name, self.root_helper):
                ip_lib.IPDevice(int_veth_name, self.root_helper).link.delete()
            int_veth, phys_veth = ip_wrapper.add_veth(int_veth_name,
                                                      phys_veth_name)
            self.int_ofports[physical_network] = self.int_br.add_port(int_veth)
            self.phys_ofports[physical_network] = br.add_port(phys_veth)

            # block all untranslated traffic over veth between bridges
            self.int_br.add_flow(priority=2,
                                 in_port=self.int_ofports[physical_network],
                                 actions="drop")
            br.add_flow(priority=2,
                        in_port=self.phys_ofports[physical_network],
                        actions="drop")

            # enable veth to pass traffic
            int_veth.link.set_up()
            phys_veth.link.set_up()

            if self.veth_mtu:
                # set up mtu size for veth interfaces
                int_veth.link.set_mtu(self.veth_mtu)
                phys_veth.link.set_mtu(self.veth_mtu)
Example #7
0
    def test_device_exists(self):
        attr = self.generate_device_details()

        self.assertFalse(ip_lib.device_exists(attr.name, namespace=attr.namespace))

        device = self.manage_device(attr)

        self.assertTrue(ip_lib.device_exists(device.name, namespace=attr.namespace))

        device.link.delete()

        self.assertFalse(ip_lib.device_exists(attr.name, namespace=attr.namespace))
Example #8
0
    def _get_router_info_list_for_tenant(self, router_ids, tenant_id):
        """Returns the list of router info objects on which to apply the fw."""
        root_ip = ip_lib.IPWrapper(self.root_helper)
        local_ns_list = root_ip.get_namespaces(
            self.root_helper) if self.conf.use_namespaces else []

        router_info_list = []
        # Pick up namespaces for Tenant Routers
        for rid in router_ids:
            # for routers without an interface - get_routers returns
            # the router - but this is not yet populated in router_info
            if rid not in self.router_info:
                continue
            self.router_info[rid].fip_exist = False
            rtr_2_fip_name = self.get_rtr_int_device_name(rid)
            if ip_lib.device_exists(rtr_2_fip_name, self.root_helper,
                                    namespace=self.router_info[rid].ns_name):
                self.router_info[rid].fip_exist = True
            if self.router_info[rid].use_namespaces:
                router_ns = self.router_info[rid].ns_name
                if router_ns in local_ns_list:
                    router_info_list.append(self.router_info[rid])
            else:
                router_info_list.append(self.router_info[rid])
        return router_info_list
 def validate_bridge_mappings(self):
     for physnet, bridge in self.bridge_mappings.items():
         if not ip_lib.device_exists(bridge):
             LOG.error(_LE("Bridge %(brq)s for physical network %(net)s"
                           " does not exist. Agent terminated!"),
                       {'brq': bridge, 'net': physnet})
             sys.exit(1)
Example #10
0
    def create_rtr_2_fip_link(self, ri):
        """Create interface between router and Floating IP namespace."""
        rtr_2_fip_name = self.get_rtr_ext_device_name(ri.router_id)
        fip_2_rtr_name = self.get_int_device_name(ri.router_id)
        fip_ns_name = self.get_name()

        # add link local IP to interface
        if ri.rtr_fip_subnet is None:
            ri.rtr_fip_subnet = self.local_subnets.allocate(ri.router_id)
        rtr_2_fip, fip_2_rtr = ri.rtr_fip_subnet.get_pair()
        ip_wrapper = ip_lib.IPWrapper(namespace=ri.ns_name)
        device_exists = ip_lib.device_exists(rtr_2_fip_name,
                                             namespace=ri.ns_name)
        if not device_exists:
            int_dev = ip_wrapper.add_veth(rtr_2_fip_name,
                                          fip_2_rtr_name,
                                          fip_ns_name)
            self._internal_ns_interface_added(str(rtr_2_fip),
                                              rtr_2_fip_name,
                                              ri.ns_name)
            self._internal_ns_interface_added(str(fip_2_rtr),
                                              fip_2_rtr_name,
                                              fip_ns_name)
            if self.agent_conf.network_device_mtu:
                int_dev[0].link.set_mtu(self.agent_conf.network_device_mtu)
                int_dev[1].link.set_mtu(self.agent_conf.network_device_mtu)
            int_dev[0].link.set_up()
            int_dev[1].link.set_up()

        # add default route for the link local interface
        device = ip_lib.IPDevice(rtr_2_fip_name, namespace=ri.ns_name)
        device.route.add_gateway(str(fip_2_rtr.ip), table=FIP_RT_TBL)
        #setup the NAT rules and chains
        ri._handle_fip_nat_rules(rtr_2_fip_name, 'add_rules')
Example #11
0
    def external_gateway_added(self, ri, ex_gw_port,
                               interface_name, internal_cidrs):

        if not ip_lib.device_exists(interface_name,
                                    root_helper=self.root_helper,
                                    namespace=ri.ns_name()):
            self.driver.plug(ex_gw_port['network_id'],
                             ex_gw_port['id'], interface_name,
                             ex_gw_port['mac_address'],
                             bridge=self.conf.external_network_bridge,
                             namespace=ri.ns_name(),
                             prefix=EXTERNAL_DEV_PREFIX)
        self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']],
                            namespace=ri.ns_name())
        ip_address = ex_gw_port['ip_cidr'].split('/')[0]
        self._send_gratuitous_arp_packet(ri, interface_name, ip_address)

        gw_ip = ex_gw_port['subnet']['gateway_ip']
        if ex_gw_port['subnet']['gateway_ip']:
            cmd = ['route', 'add', 'default', 'gw', gw_ip]
            if self.conf.use_namespaces:
                ip_wrapper = ip_lib.IPWrapper(self.root_helper,
                                              namespace=ri.ns_name())
                ip_wrapper.netns.execute(cmd, check_exit_code=False)
            else:
                utils.execute(cmd, check_exit_code=False,
                              root_helper=self.root_helper)
Example #12
0
 def internal_network_removed(self, ri, port_id, internal_cidr):
     interface_name = self.get_internal_device_name(port_id)
     if ip_lib.device_exists(interface_name,
                             root_helper=self.root_helper,
                             namespace=ri.ns_name()):
         self.driver.unplug(interface_name, namespace=ri.ns_name(),
                            prefix=INTERNAL_DEV_PREFIX)
Example #13
0
    def plug(self, network_id, port_id, device_name, mac_address,
             bridge=None, namespace=None, prefix=None):
        """This method is called by the Dhcp agent or by the L3 agent
        when a new network is created
        """
        if not ip_lib.device_exists(device_name,
                                    self.root_helper,
                                    namespace=namespace):
            ip = ip_lib.IPWrapper(self.root_helper)
            tap_name = device_name.replace(prefix or n_const.TAP_DEVICE_PREFIX,
                                           n_const.TAP_DEVICE_PREFIX)

            # Create ns_dev in a namespace if one is configured.
            root_dev, ns_dev = ip.add_veth(tap_name, device_name,
                                           namespace2=namespace)

            ns_dev.link.set_address(mac_address)

            # Add an interface created by ovs to the namespace.
            namespace_obj = ip.ensure_namespace(namespace)
            namespace_obj.add_device_to_namespace(ns_dev)

            ns_dev.link.set_up()
            root_dev.link.set_up()

            cmd = ['mm-ctl', '--bind-port', port_id, device_name]
            utils.execute(cmd, self.root_helper)

        else:
            LOG.info(_LI("Device %s already exists"), device_name)
Example #14
0
    def plug(self, network_id, port_id, device_name, mac_address,
             bridge=None, namespace=None, prefix=None):
        """Plugin the interface."""
        if not ip_lib.device_exists(device_name,
                                    self.root_helper,
                                    namespace=namespace):
            ip = ip_lib.IPWrapper(self.root_helper)

            # Enable agent to define the prefix
            tap_name = device_name.replace(prefix or self.DEV_NAME_PREFIX,
                                        n_const.TAP_DEVICE_PREFIX)
            # Create ns_veth in a namespace if one is configured.
            root_veth, ns_veth = ip.add_veth(tap_name, device_name,
                                             namespace2=namespace)
            ns_veth.link.set_address(mac_address)

            if self.conf.network_device_mtu:
                root_veth.link.set_mtu(self.conf.network_device_mtu)
                ns_veth.link.set_mtu(self.conf.network_device_mtu)

            root_veth.link.set_up()
            ns_veth.link.set_up()

        else:
            LOG.info(_LI("Device %s already exists"), device_name)
    def delete_vlan_bridge(self, bridge_name):
        if ip_lib.device_exists(bridge_name):
            interfaces_on_bridge = self.get_interfaces_on_bridge(bridge_name)
            for interface in interfaces_on_bridge:
                self.remove_interface(bridge_name, interface)

                if interface.startswith(VXLAN_INTERFACE_PREFIX):
                    self.delete_vxlan(interface)
                    continue

                for physical_interface in self.interface_mappings.values():
                    if (interface.startswith(physical_interface)):
                        ips, gateway = self.get_interface_details(bridge_name)
                        if ips:
                            # This is a flat network or a VLAN interface that
                            # was setup outside of neutron => return IP's from
                            # bridge to interface
                            self.update_interface_ip_details(interface,
                                                             bridge_name,
                                                             ips, gateway)
                        elif physical_interface != interface:
                            self.delete_vlan(interface)

            LOG.debug("Deleting bridge %s", bridge_name)
            if utils.execute(['ip', 'link', 'set', bridge_name, 'down'],
                             run_as_root=True):
                return
            if utils.execute(['brctl', 'delbr', bridge_name],
                             run_as_root=True):
                return
            LOG.debug("Done deleting bridge %s", bridge_name)

        else:
            LOG.error(_LE("Cannot delete bridge %s, does not exist"),
                      bridge_name)
    def vxlan_ucast_supported(self):
        if not cfg.CONF.VXLAN.l2_population:
            return False
        if not ip_lib.iproute_arg_supported(
                ['bridge', 'fdb'], 'append'):
            LOG.warning(_LW('Option "%(option)s" must be supported by command '
                            '"%(command)s" to enable %(mode)s mode'),
                        {'option': 'append',
                         'command': 'bridge fdb',
                         'mode': 'VXLAN UCAST'})
            return False

        test_iface = None
        for seg_id in moves.range(1, p_const.MAX_VXLAN_VNI + 1):
            if not ip_lib.device_exists(
                    self.get_vxlan_device_name(seg_id)):
                test_iface = self.ensure_vxlan(seg_id)
                break
        else:
            LOG.error(_LE('No valid Segmentation ID to perform UCAST test.'))
            return False

        try:
            utils.execute(
                cmd=['bridge', 'fdb', 'append', constants.FLOODING_ENTRY[0],
                     'dev', test_iface, 'dst', '1.1.1.1'],
                run_as_root=True, log_fail_as_error=False)
            return True
        except RuntimeError:
            return False
        finally:
            self.delete_vxlan(test_iface)
Example #17
0
 def internal_network_removed(self, port):
     interface_name = self.get_internal_device_name(port['id'])
     LOG.debug("removing internal network: port(%s) interface(%s)",
               port['id'], interface_name)
     if ip_lib.device_exists(interface_name, namespace=self.ns_name):
         self.driver.unplug(interface_name, namespace=self.ns_name,
                            prefix=INTERNAL_DEV_PREFIX)
Example #18
0
    def _dvr_internal_network_removed(self, port):
        if not self.ex_gw_port:
            return

        sn_port = self._map_internal_interfaces(port, self.snat_ports)
        if not sn_port:
            return

        # DVR handling code for SNAT
        interface_name = self.get_internal_device_name(port['id'])
        self._snat_redirect_remove(sn_port, port, interface_name)

        mode = self.agent_conf.agent_mode
        is_this_snat_host = (mode == l3_constants.L3_AGENT_MODE_DVR_SNAT
            and self.ex_gw_port['binding:host_id'] == self.host)
        if not is_this_snat_host:
            return

        snat_interface = (
            self.get_snat_int_device_name(sn_port['id']))
        ns_name = self.snat_namespace.name
        prefix = dvr_snat_ns.SNAT_INT_DEV_PREFIX
        if ip_lib.device_exists(snat_interface, namespace=ns_name):
            self.driver.unplug(snat_interface, namespace=ns_name,
                               prefix=prefix)
Example #19
0
 def ensure_vxlan(self, segmentation_id):
     """Create a vxlan unless it already exists."""
     interface = self.get_vxlan_device_name(segmentation_id)
     if not ip_lib.device_exists(interface):
         LOG.debug("Creating vxlan interface %(interface)s for "
                   "VNI %(segmentation_id)s",
                   {'interface': interface,
                    'segmentation_id': segmentation_id})
         args = {'dev': self.local_int}
         if self.vxlan_mode == lconst.VXLAN_MCAST:
             args['group'] = self.get_vxlan_group(segmentation_id)
         if cfg.CONF.VXLAN.ttl:
             args['ttl'] = cfg.CONF.VXLAN.ttl
         if cfg.CONF.VXLAN.tos:
             args['tos'] = cfg.CONF.VXLAN.tos
         if cfg.CONF.VXLAN.l2_population:
             args['proxy'] = True
         try:
             int_vxlan = self.ip.add_vxlan(interface, segmentation_id,
                                           **args)
         except RuntimeError:
             with excutils.save_and_reraise_exception() as ctxt:
                 # perform this check after an attempt rather than before
                 # to avoid excessive lookups and a possible race condition.
                 if ip_lib.vxlan_in_use(segmentation_id):
                     ctxt.reraise = False
                     LOG.error(_LE("Unable to create VXLAN interface for "
                                   "VNI %s because it is in use by another "
                                   "interface."), segmentation_id)
                     return None
         int_vxlan.link.set_up()
         LOG.debug("Done creating vxlan interface %s", interface)
     return interface
 def get_interfaces_on_bridge(self, bridge_name):
     if ip_lib.device_exists(bridge_name):
         bridge_interface_path = BRIDGE_INTERFACES_FS.replace(
             BRIDGE_NAME_PLACEHOLDER, bridge_name)
         return os.listdir(bridge_interface_path)
     else:
         return []
Example #21
0
    def plug(self, network_id, port_id, device_name, mac_address,
             bridge=None, namespace=None, prefix=None):
        """Plug in the interface."""
        if not ip_lib.device_exists(device_name,
                                    self.root_helper,
                                    namespace=namespace):

            ip = ip_lib.IPWrapper(self.root_helper)
            tap_name = self._get_tap_name(device_name, prefix)

            root_dev, ns_dev = ip.add_veth(tap_name, device_name)

            self._ivs_add_port(tap_name, port_id, mac_address)

            ns_dev = ip.device(device_name)
            ns_dev.link.set_address(mac_address)

            if self.conf.network_device_mtu:
                ns_dev.link.set_mtu(self.conf.network_device_mtu)
                root_dev.link.set_mtu(self.conf.network_device_mtu)

            if namespace:
                namespace_obj = ip.ensure_namespace(namespace)
                namespace_obj.add_device_to_namespace(ns_dev)

            ns_dev.link.set_up()
            root_dev.link.set_up()
        else:
            LOG.info(_LI("Device %s already exists"), device_name)
Example #22
0
 def validate_interface_mappings(self):
     for physnet, interface in self.interface_mappings.items():
         if not ip_lib.device_exists(interface):
             LOG.error(_LE("Interface %(intf)s for physical network %(net)s"
                           " does not exist. Agent terminated!"),
                       {'intf': interface, 'net': physnet})
             sys.exit(1)
 def delete_vxlan(self, interface):
     if ip_lib.device_exists(interface):
         LOG.debug("Deleting vxlan interface %s for vlan", interface)
         int_vxlan = self.ip.device(interface)
         int_vxlan.link.set_down()
         int_vxlan.link.delete()
         LOG.debug("Done deleting vxlan interface %s", interface)
    def vxlan_ucast_supported(self):
        if not cfg.CONF.VXLAN.l2_population:
            return False
        if not ip_lib.iproute_arg_supported(
                ['bridge', 'fdb'], 'append'):
            LOG.warning('Option "%(option)s" must be supported by command '
                        '"%(command)s" to enable %(mode)s mode',
                        {'option': 'append',
                         'command': 'bridge fdb',
                         'mode': 'VXLAN UCAST'})
            return False

        test_iface = None
        for seg_id in moves.range(1, constants.MAX_VXLAN_VNI + 1):
            if (ip_lib.device_exists(self.get_vxlan_device_name(seg_id)) or
                    ip_lib.vxlan_in_use(seg_id)):
                continue
            test_iface = self.ensure_vxlan(seg_id)
            break
        else:
            LOG.error('No valid Segmentation ID to perform UCAST test.')
            return False

        try:
            bridge_lib.FdbInterface.append(constants.FLOODING_ENTRY[0],
                                           test_iface, '1.1.1.1',
                                           log_fail_as_error=False)
            return True
        except RuntimeError:
            return False
        finally:
            self.delete_interface(test_iface)
Example #25
0
 def _check_rtr_2_fip_connect(self):
     """Checks if the rtr to fip connect exists, if not sets to false."""
     fip_ns_name = self.fip_ns.get_name()
     if ip_lib.network_namespace_exists(fip_ns_name):
         fip_2_rtr_name = self.fip_ns.get_int_device_name(self.router_id)
         if not ip_lib.device_exists(fip_2_rtr_name, namespace=fip_ns_name):
             self.rtr_fip_connect = False
Example #26
0
    def test_plug_with_namespace_sets_mtu_higher_than_bridge(self):
        device_mtu = 1450

        # Create a new OVS bridge
        ovs_bridge = self.useFixture(net_helpers.OVSBridgeFixture()).bridge
        self.assertFalse(ovs_bridge.get_port_name_list())

        # Add a new linuxbridge port with reduced MTU to OVS bridge
        lb_bridge = self.useFixture(
            net_helpers.LinuxBridgeFixture()).bridge
        lb_bridge_port = self.useFixture(
            net_helpers.LinuxBridgePortFixture(lb_bridge))
        lb_bridge_port.port.link.set_mtu(device_mtu - 1)
        ovs_bridge.add_port(lb_bridge_port.port.name)

        # Now plug a device with intended MTU that is higher than for the port
        # above and validate that its MTU is not reduced to the least MTU on
        # the bridge
        device_name = utils.get_rand_name()
        mac_address = utils.get_random_mac('fa:16:3e:00:00:00'.split(':'))
        namespace = self.useFixture(net_helpers.NamespaceFixture()).name
        self.interface.plug(network_id=uuidutils.generate_uuid(),
                            port_id=uuidutils.generate_uuid(),
                            device_name=device_name,
                            mac_address=mac_address,
                            bridge=ovs_bridge.br_name,
                            namespace=namespace,
                            mtu=device_mtu)

        self.assertIn(device_name, ovs_bridge.get_port_name_list())
        self.assertTrue(ip_lib.device_exists(device_name, namespace))
        self.assertEqual(
            device_mtu,
            ip_lib.IPDevice(device_name, namespace=namespace).link.mtu
        )
    def ensure_vxlan(self, segmentation_id, mtu=None):
        """Create a vxlan unless it already exists."""
        interface = self.get_vxlan_device_name(segmentation_id)
        if not ip_lib.device_exists(interface):
            LOG.debug("Creating vxlan interface %(interface)s for "
                      "VNI %(segmentation_id)s",
                      {'interface': interface,
                       'segmentation_id': segmentation_id})
            args = {'dev': self.local_int,
                    'srcport': (cfg.CONF.VXLAN.udp_srcport_min,
                                cfg.CONF.VXLAN.udp_srcport_max),
                    'dstport': cfg.CONF.VXLAN.udp_dstport,
                    'ttl': cfg.CONF.VXLAN.ttl}
            if cfg.CONF.VXLAN.tos:
                args['tos'] = cfg.CONF.VXLAN.tos
                if cfg.CONF.AGENT.dscp or cfg.CONF.AGENT.dscp_inherit:
                    LOG.warning('The deprecated tos option in group VXLAN '
                                'is set and takes precedence over dscp and '
                                'dscp_inherit in group AGENT.')
            elif cfg.CONF.AGENT.dscp_inherit:
                args['tos'] = 'inherit'
            elif cfg.CONF.AGENT.dscp:
                args['tos'] = int(cfg.CONF.AGENT.dscp) << 2

            if self.vxlan_mode == lconst.VXLAN_MCAST:
                args['group'] = self.get_vxlan_group(segmentation_id)
            if cfg.CONF.VXLAN.l2_population:
                args['proxy'] = cfg.CONF.VXLAN.arp_responder

            try:
                int_vxlan = self.ip.add_vxlan(interface, segmentation_id,
                                              **args)
            except RuntimeError:
                with excutils.save_and_reraise_exception() as ctxt:
                    # perform this check after an attempt rather than before
                    # to avoid excessive lookups and a possible race condition.
                    if ip_lib.vxlan_in_use(segmentation_id):
                        ctxt.reraise = False
                        LOG.error("Unable to create VXLAN interface for "
                                  "VNI %s because it is in use by another "
                                  "interface.", segmentation_id)
                        return None
            if mtu:
                try:
                    int_vxlan.link.set_mtu(mtu)
                except ip_lib.InvalidArgument:
                    phys_dev_mtu = ip_lib.get_device_mtu(self.local_int)
                    LOG.error("Provided MTU value %(mtu)s for VNI "
                              "%(segmentation_id)s is too high according "
                              "to physical device %(dev)s MTU=%(phys_mtu)s.",
                              {'mtu': mtu,
                               'segmentation_id': segmentation_id,
                               'dev': self.local_int,
                               'phys_mtu': phys_dev_mtu})
                    int_vxlan.link.delete()
                    return None
            int_vxlan.disable_ipv6()
            int_vxlan.link.set_up()
            LOG.debug("Done creating vxlan interface %s", interface)
        return interface
    def delete_vlan_bridge(self, bridge_name):
        if ip_lib.device_exists(bridge_name):
            interfaces_on_bridge = self.get_interfaces_on_bridge(bridge_name)
            for interface in interfaces_on_bridge:
                #self.remove_interface(bridge_name, interface)

                if interface.startswith(VXLAN_INTERFACE_PREFIX):
                    self.delete_vxlan(interface)
                    continue

                for physical_interface in self.interface_mappings.itervalues():
                    if (interface.startswith(physical_interface)):
                        ips, gateway = self.get_interface_details(bridge_name)
                        if ips:
                            # This is a flat network or a VLAN interface that
                            # was setup outside of neutron => return IP's from
                            # bridge to interface
                            self.update_interface_ip_details(interface,
                                                             bridge_name,
                                                             ips, gateway)
                        elif physical_interface != interface:
                            self.delete_vlan(interface)

            LOG.debug("Deleting bridge %s", bridge_name)
            bridge = self.ip.device(bridge_name)
            bridge.link.delete()
            LOG.debug("Done deleting bridge %s", bridge_name)

        else:
            LOG.debug("Cannot delete bridge %s; it does not exist",
                      bridge_name)
Example #29
0
    def create_probe(self, network_id, device_owner='network'):
        network = self._get_network(network_id)
        bridge = None
        if network.external:
            bridge = self.conf.external_network_bridge

        port = self._create_port(network, device_owner)
        interface_name = self.driver.get_device_name(port)
        namespace = None
        if self.conf.use_namespaces:
            namespace = self._get_namespace(port)

        if ip_lib.device_exists(interface_name, self.root_helper, namespace):
            LOG.debug(_('Reusing existing device: %s.'), interface_name)
        else:
            self.driver.plug(network.id,
                             port.id,
                             interface_name,
                             port.mac_address,
                             bridge=bridge,
                             namespace=namespace)
        ip_cidrs = []
        for fixed_ip in port.fixed_ips:
            subnet = fixed_ip.subnet
            net = netaddr.IPNetwork(subnet.cidr)
            ip_cidr = '%s/%s' % (fixed_ip.ip_address, net.prefixlen)
            ip_cidrs.append(ip_cidr)
        self.driver.init_l3(interface_name, ip_cidrs, namespace=namespace)
        return port
Example #30
0
    def _process_router_if_compatible(self, router):
        if (self.conf.external_network_bridge and
            not ip_lib.device_exists(self.conf.external_network_bridge)):
            LOG.error(_LE("The external network bridge '%s' does not exist"),
                      self.conf.external_network_bridge)
            return

        # Either ex_net_id or handle_internal_only_routers must be set
        ex_net_id = (router['external_gateway_info'] or {}).get('network_id')
        if not ex_net_id and not self.conf.handle_internal_only_routers:
            raise n_exc.RouterNotCompatibleWithAgent(router_id=router['id'])

        # If target_ex_net_id and ex_net_id are set they must be equal
        target_ex_net_id = self._fetch_external_net_id()
        if (target_ex_net_id and ex_net_id and ex_net_id != target_ex_net_id):
            # Double check that our single external_net_id has not changed
            # by forcing a check by RPC.
            if ex_net_id != self._fetch_external_net_id(force=True):
                raise n_exc.RouterNotCompatibleWithAgent(
                    router_id=router['id'])

        if router['id'] not in self.router_info:
            self._process_added_router(router)
        else:
            self._process_updated_router(router)
Example #31
0
 def ensure_vlan(self, physical_interface, vlan_id):
     """Create a vlan unless it already exists."""
     interface = self.get_subinterface_name(physical_interface, vlan_id)
     if not ip_lib.device_exists(interface):
         LOG.debug("Creating subinterface %(interface)s for "
                   "VLAN %(vlan_id)s on interface "
                   "%(physical_interface)s",
                   {'interface': interface, 'vlan_id': vlan_id,
                    'physical_interface': physical_interface})
         if utils.execute(['ip', 'link', 'add', 'link',
                           physical_interface,
                           'name', interface, 'type', 'vlan', 'id',
                           vlan_id], run_as_root=True):
             return
         if utils.execute(['ip', 'link', 'set',
                           interface, 'up'], run_as_root=True):
             return
         LOG.debug("Done creating subinterface %s", interface)
     return interface
Example #32
0
    def _dvr_internal_network_removed(self, port):
        super(DvrEdgeRouter, self)._dvr_internal_network_removed(port)

        if not self.ex_gw_port:
            return

        sn_port = self.get_snat_port_for_internal_port(port, self.snat_ports)
        if not sn_port:
            return

        if not self._is_this_snat_host():
            return

        snat_interface = self._get_snat_int_device_name(sn_port['id'])
        ns_name = self.snat_namespace.name
        prefix = lib_constants.SNAT_INT_DEV_PREFIX
        if ip_lib.device_exists(snat_interface, namespace=ns_name):
            self.driver.unplug(snat_interface, namespace=ns_name,
                               prefix=prefix)
Example #33
0
    def init_host(self):
        LOG.info(_LI("APIC host agent: agent starting on %s"), self.host)
        self.state = {
            'binary': BINARY_APIC_HOST_AGENT,
            'host': self.host,
            'topic': self.topic,
            'configurations': {},
            'start_flag': True,
            'agent_type': TYPE_APIC_HOST_AGENT,
        }

        self.uplink_ports = []
        for inf in self.conf.apic_host_uplink_ports:
            if ip_lib.device_exists(inf):
                self.uplink_ports.append(inf)
            else:
                # ignore unknown interfaces
                LOG.error(_LE("No such interface (ignored): %s"), inf)
        self.lldpcmd = ['lldpctl', '-f', 'keyvalue'] + self.uplink_ports
    def add_tap_interface(self, network_id, network_type, physical_network,
                          segmentation_id, tap_device_name):
        """Add tap interface.

        If a VIF has been plugged into a network, this function will
        add the corresponding tap device to the relevant bridge.
        """
        if not ip_lib.device_exists(tap_device_name,
                                    root_helper=self.root_helper):
            LOG.debug(
                _("Tap device: %s does not exist on "
                  "this host, skipped"), tap_device_name)
            return False

        bridge_name = self.get_bridge_name(network_id)
        if network_type == p_const.TYPE_LOCAL:
            self.ensure_local_bridge(network_id)
        elif not self.ensure_physical_in_bridge(
                network_id, network_type, physical_network, segmentation_id):
            return False

        # Check if device needs to be added to bridge
        tap_device_in_bridge = self.get_bridge_for_tap_device(tap_device_name)
        if not tap_device_in_bridge:
            data = {
                'tap_device_name': tap_device_name,
                'bridge_name': bridge_name
            }
            msg = _("Adding device %(tap_device_name)s to bridge "
                    "%(bridge_name)s") % data
            LOG.debug(msg)
            if utils.execute(['brctl', 'addif', bridge_name, tap_device_name],
                             root_helper=self.root_helper):
                return False
        else:
            data = {
                'tap_device_name': tap_device_name,
                'bridge_name': bridge_name
            }
            msg = _("%(tap_device_name)s already exists on bridge "
                    "%(bridge_name)s") % data
            LOG.debug(msg)
        return True
Example #35
0
    def setup(self, network, reuse_existing=False):
        """Create and initialize a device for network's DHCP on this host."""
        port = self.setup_dhcp_port(network)
        interface_name = self.get_interface_name(network, port)

        if self.conf.use_namespaces:
            namespace = NS_PREFIX + network.id
        else:
            namespace = None

        if ip_lib.device_exists(interface_name, self.root_helper, namespace):
            if not reuse_existing:
                raise exceptions.PreexistingDeviceFailure(
                    dev_name=interface_name)

            LOG.debug(_('Reusing existing device: %s.'), interface_name)
        else:
            self.driver.plug(network.id,
                             port.id,
                             interface_name,
                             port.mac_address,
                             namespace=namespace)
        ip_cidrs = []
        for fixed_ip in port.fixed_ips:
            subnet = fixed_ip.subnet
            net = netaddr.IPNetwork(subnet.cidr)
            ip_cidr = '%s/%s' % (fixed_ip.ip_address, net.prefixlen)
            ip_cidrs.append(ip_cidr)

        if (self.conf.enable_isolated_metadata and self.conf.use_namespaces):
            ip_cidrs.append(METADATA_DEFAULT_IP)

        self.driver.init_l3(interface_name, ip_cidrs, namespace=namespace)

        # ensure that the dhcp interface is first in the list
        if namespace is None:
            device = ip_lib.IPDevice(interface_name, self.root_helper)
            device.route.pullup_route(interface_name)

        if self.conf.use_namespaces:
            self._set_default_route(network)

        return interface_name
Example #36
0
    def scan_fip_ports(self, ri):
        # don't scan if not dvr or count is not None
        if not ri.router.get('distributed') or ri.dist_fip_count is not None:
            return

        # scan system for any existing fip ports
        ri.dist_fip_count = 0
        rtr_2_fip_interface = self.get_rtr_int_device_name(ri.router_id)
        if ip_lib.device_exists(rtr_2_fip_interface,
                                root_helper=self.root_helper,
                                namespace=ri.ns_name):
            device = ip_lib.IPDevice(rtr_2_fip_interface,
                                     self.root_helper,
                                     namespace=ri.ns_name)
            existing_cidrs = [addr['cidr'] for addr in device.addr.list()]
            fip_cidrs = [
                c for c in existing_cidrs if common_utils.is_cidr_host(c)
            ]
            ri.dist_fip_count = len(fip_cidrs)
Example #37
0
    def plug(self, network_id, port_id, device_name, mac_address,
             bridge=None, namespace=None, prefix=None):
        """Plug in the interface."""
        if not bridge:
            bridge = self.conf.ovs_integration_bridge

        if not ip_lib.device_exists(device_name, namespace=namespace):

            self.check_bridge_exists(bridge)

            ip = ip_lib.IPWrapper()
            tap_name = self._get_tap_name(device_name, prefix)

            if self.conf.ovs_use_veth:
                # Create ns_dev in a namespace if one is configured.
                root_dev, ns_dev = ip.add_veth(tap_name,
                                               device_name,
                                               namespace2=namespace)
            else:
                ns_dev = ip.device(device_name)

            internal = not self.conf.ovs_use_veth
            self._ovs_add_port(bridge, tap_name, port_id, mac_address,
                               internal=internal)

            ns_dev.link.set_address(mac_address)

            if self.conf.network_device_mtu:
                ns_dev.link.set_mtu(self.conf.network_device_mtu)
                if self.conf.ovs_use_veth:
                    root_dev.link.set_mtu(self.conf.network_device_mtu)

            # Add an interface created by ovs to the namespace.
            if not self.conf.ovs_use_veth and namespace:
                namespace_obj = ip.ensure_namespace(namespace)
                namespace_obj.add_device_to_namespace(ns_dev)

            ns_dev.link.set_up()
            if self.conf.ovs_use_veth:
                root_dev.link.set_up()
        else:
            LOG.info(_LI("Device %s already exists"), device_name)
Example #38
0
 def ensure_vxlan(self, segmentation_id):
     """Create a vxlan unless it already exists."""
     interface = self.get_vxlan_device_name(segmentation_id)
     if not ip_lib.device_exists(interface):
         LOG.debug(_("Creating vxlan interface %(interface)s for "
                     "VNI %(segmentation_id)s"),
                   {'interface': interface,
                    'segmentation_id': segmentation_id})
         args = {'dev': self.local_int}
         if self.vxlan_mode == lconst.VXLAN_MCAST:
             args['group'] = cfg.CONF.VXLAN.vxlan_group
         if cfg.CONF.VXLAN.ttl:
             args['ttl'] = cfg.CONF.VXLAN.ttl
         if cfg.CONF.VXLAN.tos:
             args['tos'] = cfg.CONF.VXLAN.tos
         if cfg.CONF.VXLAN.l2_population:
             args['proxy'] = True
         int_vxlan = self.ip.add_vxlan(interface, segmentation_id, **args)
         int_vxlan.link.set_up()
         LOG.debug(_("Done creating vxlan interface %s"), interface)
     return interface
Example #39
0
    def _test_mtu_set_after_action(self, device_name, br_name, namespace,
                                   action=None):
        mac_address = net.get_random_mac('fa:16:3e:00:00:00'.split(':'))

        plug = functools.partial(
            self.interface.plug,
            network_id=uuidutils.generate_uuid(),
            port_id=uuidutils.generate_uuid(),
            device_name=device_name,
            mac_address=mac_address,
            bridge=self.bridge_name,
            namespace=namespace)
        plug(mtu=1500)
        self.assertTrue(ip_lib.device_exists(device_name, namespace))

        action = action or plug
        for mtu in (1450, 1500, 9000, 9000, 1450):
            action(mtu=mtu)
            self.assertEqual(
                mtu,
                ip_lib.IPDevice(device_name, namespace=namespace).link.mtu)
Example #40
0
    def _dvr_internal_network_removed(self, port):
        super(DvrEdgeRouter, self)._dvr_internal_network_removed(port)

        if not self.ex_gw_port:
            return

        sn_port = self.get_snat_port_for_internal_port(port)
        if not sn_port:
            return

        is_this_snat_host = ('binding:host_id' in self.ex_gw_port) and (
            self.ex_gw_port['binding:host_id'] == self.host)
        if not is_this_snat_host:
            return

        snat_interface = self._get_snat_int_device_name(sn_port['id'])
        ns_name = self.snat_namespace.name
        prefix = dvr_snat_ns.SNAT_INT_DEV_PREFIX
        if ip_lib.device_exists(snat_interface, namespace=ns_name):
            self.driver.unplug(snat_interface, namespace=ns_name,
                               prefix=prefix)
    def _test_linuxbridge_cleanup(self, bridge_exists, callback):
        br_fixture = self.useFixture(
            tools.SafeCleanupFixture(
                net_helpers.LinuxBridgeFixture(
                    prefix=lb_agent.BRIDGE_NAME_PREFIX))).fixture

        config = callback(br_fixture)

        temp_dir = self.useFixture(fixtures.TempDir()).path
        conf = self.useFixture(
            config_fixtures.ConfigFileFixture(base_filename='neutron.conf',
                                              config=config,
                                              temp_dir=temp_dir))

        cmd = 'neutron-linuxbridge-cleanup', '--config-file', conf.filename
        ip_wrapper = ip_lib.IPWrapper(br_fixture.namespace)
        ip_wrapper.netns.execute(cmd)

        self.assertEqual(
            bridge_exists,
            ip_lib.device_exists(br_fixture.bridge.name, br_fixture.namespace))
Example #42
0
    def setup_physical_interfaces(self, interface_mappings):
        '''Sets up the physical network interfaces.

        Link physical interfaces to the integration bridge.
        :param interface_mappings: map physical net names to interface names.
        '''

        for physical_network, interface in interface_mappings.iteritems():
            LOG.info(_("Mapping physical network %(physical_network)s to "
                       "interface %(interface)s"),
                     {'physical_network': physical_network,
                      'interface': interface})
            # Connect the physical interface to the bridge
            if not ip_lib.device_exists(interface, self.root_helper):
                LOG.error(_("Interface %(interface)s for physical network "
                            "%(physical_network)s does not exist. Agent "
                            "terminated!"),
                          {'physical_network': physical_network,
                           'interface': interface})
                raise SystemExit(1)
            self.int_br.add_port(interface)
Example #43
0
    def _external_gateway_added(self, ri, ex_gw_port, interface_name, ns_name,
                                preserve_ips):
        if not ip_lib.device_exists(interface_name, namespace=ns_name):
            self.driver.plug(ex_gw_port['network_id'],
                             ex_gw_port['id'],
                             interface_name,
                             ex_gw_port['mac_address'],
                             bridge=self.conf.external_network_bridge,
                             namespace=ns_name,
                             prefix=EXTERNAL_DEV_PREFIX)

        if not ri.is_ha:
            self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']],
                                namespace=ns_name,
                                gateway=ex_gw_port['subnet'].get('gateway_ip'),
                                extra_subnets=ex_gw_port.get(
                                    'extra_subnets', []),
                                preserve_ips=preserve_ips)
            ip_address = ex_gw_port['ip_cidr'].split('/')[0]
            ip_lib.send_gratuitous_arp(ns_name, interface_name, ip_address,
                                       self.conf.send_arp_for_ha)
Example #44
0
 def plug(self,
          network_id,
          port_id,
          device_name,
          mac_address,
          bridge=None,
          namespace=None,
          prefix=None,
          mtu=None):
     if not ip_lib.device_exists(device_name, namespace=namespace):
         self.plug_new(network_id, port_id, device_name, mac_address,
                       bridge, namespace, prefix, mtu)
     else:
         LOG.info("Device %s already exists", device_name)
         if mtu:
             self.set_mtu(device_name,
                          mtu,
                          namespace=namespace,
                          prefix=prefix)
         else:
             LOG.warning("No MTU configured for port %s", port_id)
Example #45
0
    def external_gateway_added(self, ri, ex_gw_port, interface_name,
                               internal_cidrs):

        if not ip_lib.device_exists(interface_name,
                                    root_helper=self.root_helper,
                                    namespace=ri.ns_name()):
            self.driver.plug(ex_gw_port['network_id'],
                             ex_gw_port['id'],
                             interface_name,
                             ex_gw_port['mac_address'],
                             bridge=self.conf.external_network_bridge,
                             namespace=ri.ns_name(),
                             prefix=EXTERNAL_DEV_PREFIX)

        # Compute a list of addresses this router is supposed to have.
        # This avoids unnecessarily removing those addresses and
        # causing a momentarily network outage.
        floating_ips = ri.router.get(l3_constants.FLOATINGIP_KEY, [])
        preserve_ips = [
            ip['floating_ip_address'] + FLOATING_IP_CIDR_SUFFIX
            for ip in floating_ips
        ]

        self.driver.init_l3(interface_name, [ex_gw_port['ip_cidr']],
                            namespace=ri.ns_name(),
                            preserve_ips=preserve_ips)
        ip_address = ex_gw_port['ip_cidr'].split('/')[0]
        self._send_gratuitous_arp_packet(ri, interface_name, ip_address)

        gw_ip = ex_gw_port['subnet']['gateway_ip']
        if ex_gw_port['subnet']['gateway_ip']:
            cmd = ['route', 'add', 'default', 'gw', gw_ip]
            if self.conf.use_namespaces:
                ip_wrapper = ip_lib.IPWrapper(self.root_helper,
                                              namespace=ri.ns_name())
                ip_wrapper.netns.execute(cmd, check_exit_code=False)
            else:
                utils.execute(cmd,
                              check_exit_code=False,
                              root_helper=self.root_helper)
    def _test_linuxbridge_cleanup(self, bridge_exists, callback):
        br_fixture = self.useFixture(
            tools.SafeCleanupFixture(
                net_helpers.LinuxBridgeFixture(
                    prefix=lb_agent.BRIDGE_NAME_PREFIX))).fixture

        config = callback(br_fixture)
        # NOTE(slaweq): use of oslo.privsep inside neutron-linuxbridge-cleanup
        # script requires rootwrap helper to be configured in this script's
        # config
        privsep_helper = os.path.join(os.getenv('VIRTUAL_ENV'), 'bin',
                                      'privsep-helper')
        config.update({
            'AGENT': {
                'root_helper': tests_base.get_rootwrap_cmd(),
                'root_helper_daemon': tests_base.get_rootwrap_daemon_cmd()
            },
            'privsep': {
                'helper_command': ' '.join(['sudo', '-E', privsep_helper]),
            },
            'privsep_link': {
                'helper_command': ' '.join(['sudo', '-E', privsep_helper]),
            },
        })

        config.update({'VXLAN': {'enable_vxlan': 'False'}})

        temp_dir = self.useFixture(fixtures.TempDir()).path
        conf = self.useFixture(
            config_fixtures.ConfigFileFixture(base_filename='neutron.conf',
                                              config=config,
                                              temp_dir=temp_dir))

        cmd = 'neutron-linuxbridge-cleanup', '--config-file', conf.filename
        ip_wrapper = ip_lib.IPWrapper(br_fixture.namespace)
        ip_wrapper.netns.execute(cmd, privsep_exec=True)

        self.assertEqual(
            bridge_exists,
            ip_lib.device_exists(br_fixture.bridge.name, br_fixture.namespace))
Example #47
0
    def set_qos_for_port(self, port_name, port_id, rate_limit):
        #set qlen for interface if qlen equal zero
        if ip_lib.device_exists(port_name):
            device = ip_lib.IPDevice(port_name, self.root_helper)
            device.link.set_qlen(50000)
        else:
            LOG.error(_("Can not find device (%s)."), port_name)

        args = [
            'set', 'port', port_name, 'qos=@newqos', '--', '--id=@newqos',
            'create', 'qos', 'type=linux-htb',
            'other-config:max-rate=%s' % rate_limit,
            'external_ids:port-id=%s' % port_id, 'queues=0=@q0', '--',
            '--id=@q0', 'create', 'queue',
            'other-config:min-rate=%s' % rate_limit,
            'other-config:max-rate=%s' % rate_limit
        ]
        result = self.run_vsctl(args)
        if not result:
            LOG.error(_("Unable to set qos for %s(%s)."), (port_name, port_id))

        return result.split()
    def _add_tap_interface(self, network_id, network_type, physical_network,
                          segmentation_id, tap_device_name, device_owner, mtu):
        """Add tap interface.

        If a VIF has been plugged into a network, this function will
        add the corresponding tap device to the relevant bridge.
        """
        if not ip_lib.device_exists(tap_device_name):
            LOG.debug("Tap device: %s does not exist on "
                      "this host, skipped", tap_device_name)
            return False

        bridge_name = self.get_existing_bridge_name(physical_network)
        if not bridge_name:
            bridge_name = self.get_bridge_name(network_id)

        if network_type == p_const.TYPE_LOCAL:
            self.ensure_local_bridge(network_id, bridge_name)
        elif not self.ensure_physical_in_bridge(network_id,
                                                network_type,
                                                physical_network,
                                                segmentation_id):
            return False
        if mtu:  # <-None with device_details from older neutron servers.
            # we ensure the MTU here because libvirt does not set the
            # MTU of a bridge it creates and the tap device it creates will
            # inherit from the bridge its plugged into, which will be 1500
            # at the time. See bug/1684326 for details.
            self._set_tap_mtu(tap_device_name, mtu)
        # Check if device needs to be added to bridge
        if not bridge_lib.BridgeDevice.get_interface_bridge(
            tap_device_name):
            data = {'tap_device_name': tap_device_name,
                    'bridge_name': bridge_name}
            LOG.debug("Adding device %(tap_device_name)s to bridge "
                      "%(bridge_name)s", data)
            if bridge_lib.BridgeDevice(bridge_name).addif(tap_device_name):
                return False
        return True
Example #49
0
 def remove_interface(self, bridge_name, interface_name):
     if ip_lib.device_exists(bridge_name):
         if not self.is_device_on_bridge(interface_name):
             return True
         LOG.debug(_("Removing device %(interface_name)s from bridge "
                     "%(bridge_name)s"),
                   {'interface_name': interface_name,
                    'bridge_name': bridge_name})
         if utils.execute(['brctl', 'delif', bridge_name, interface_name],
                          root_helper=self.root_helper):
             return False
         LOG.debug(_("Done removing device %(interface_name)s from bridge "
                     "%(bridge_name)s"),
                   {'interface_name': interface_name,
                    'bridge_name': bridge_name})
         return True
     else:
         LOG.debug(_("Cannot remove device %(interface_name)s bridge "
                     "%(bridge_name)s does not exist"),
                   {'interface_name': interface_name,
                    'bridge_name': bridge_name})
         return False
Example #50
0
 def plug(self,
          network_id,
          port_id,
          device_name,
          mac_address,
          bridge=None,
          namespace=None,
          prefix=None,
          mtu=None):
     if not ip_lib.device_exists(device_name, namespace=namespace):
         try:
             self.plug_new(network_id, port_id, device_name, mac_address,
                           bridge, namespace, prefix, mtu)
         except TypeError:
             versionutils.report_deprecated_feature(
                 LOG,
                 _LW('Interface driver does not support MTU parameter. '
                     'This may not work in future releases.'))
             self.plug_new(network_id, port_id, device_name, mac_address,
                           bridge, namespace, prefix)
     else:
         LOG.info(_LI("Device %s already exists"), device_name)
 def ensure_vxlan(self, segmentation_id):
     """Create a vxlan unless it already exists."""
     interface = self.get_vxlan_device_name(segmentation_id)
     if not ip_lib.device_exists(interface):
         LOG.debug(
             "Creating vxlan interface %(interface)s for "
             "VNI %(segmentation_id)s", {
                 'interface': interface,
                 'segmentation_id': segmentation_id
             })
         args = {'dev': self.local_int}
         if self.vxlan_mode == lconst.VXLAN_MCAST:
             args['group'] = self.get_vxlan_group(segmentation_id)
         if cfg.CONF.VXLAN.ttl:
             args['ttl'] = cfg.CONF.VXLAN.ttl
         if cfg.CONF.VXLAN.tos:
             args['tos'] = cfg.CONF.VXLAN.tos
         if cfg.CONF.network_device_mtu:
             args['mtu'] = cfg.CONF.network_device_mtu
         if cfg.CONF.VXLAN.l2_population:
             args['proxy'] = cfg.CONF.VXLAN.arp_responder
         try:
             int_vxlan = self.ip.add_vxlan(interface, segmentation_id,
                                           **args)
         except RuntimeError:
             with excutils.save_and_reraise_exception() as ctxt:
                 # perform this check after an attempt rather than before
                 # to avoid excessive lookups and a possible race condition.
                 if ip_lib.vxlan_in_use(segmentation_id):
                     ctxt.reraise = False
                     LOG.error(
                         _LE("Unable to create VXLAN interface for "
                             "VNI %s because it is in use by another "
                             "interface."), segmentation_id)
                     return None
         int_vxlan.disable_ipv6()
         int_vxlan.link.set_up()
         LOG.debug("Done creating vxlan interface %s", interface)
     return interface
Example #52
0
    def create_probe(self, network_id, device_owner='network'):
        network = self._get_network(network_id)

        port = self._create_port(network, device_owner)
        interface_name = self.driver.get_device_name(port)
        namespace = self._get_namespace(port)

        if ip_lib.device_exists(interface_name, namespace=namespace):
            LOG.debug('Reusing existing device: %s.', interface_name)
        else:
            self.driver.plug(network.id,
                             port.id,
                             interface_name,
                             port.mac_address,
                             namespace=namespace)
        ip_cidrs = []
        for fixed_ip in port.fixed_ips:
            subnet = fixed_ip.subnet
            net = netaddr.IPNetwork(subnet.cidr)
            ip_cidr = '%s/%s' % (fixed_ip.ip_address, net.prefixlen)
            ip_cidrs.append(ip_cidr)
        self.driver.init_l3(interface_name, ip_cidrs, namespace=namespace)
        return port
Example #53
0
    def plug(self, network_id, port_id, device_name, mac_address,
             bridge=None, namespace=None, prefix=None):
        """Plugin the interface."""
        if not ip_lib.device_exists(device_name, namespace=namespace):
            ip = ip_lib.IPWrapper()

            # Enable agent to define the prefix
            tap_name = device_name.replace(prefix or self.DEV_NAME_PREFIX,
                                        n_const.TAP_DEVICE_PREFIX)
            # Create ns_veth in a namespace if one is configured.
            root_veth, ns_veth = ip.add_veth(tap_name, device_name,
                                             namespace2=namespace)
            ns_veth.link.set_address(mac_address)

            if self.conf.network_device_mtu:
                root_veth.link.set_mtu(self.conf.network_device_mtu)
                ns_veth.link.set_mtu(self.conf.network_device_mtu)

            root_veth.link.set_up()
            ns_veth.link.set_up()

        else:
            LOG.info(_LI("Device %s already exists"), device_name)
Example #54
0
    def _internal_network_added(self,
                                ns_name,
                                network_id,
                                port_id,
                                internal_cidr,
                                mac_address,
                                interface_name,
                                prefix,
                                is_ha=False):
        if not ip_lib.device_exists(interface_name, namespace=ns_name):
            self.driver.plug(network_id,
                             port_id,
                             interface_name,
                             mac_address,
                             namespace=ns_name,
                             prefix=prefix)

        if not is_ha:
            self.driver.init_l3(interface_name, [internal_cidr],
                                namespace=ns_name)
            ip_address = internal_cidr.split('/')[0]
            ip_lib.send_gratuitous_arp(ns_name, interface_name, ip_address,
                                       self.conf.send_arp_for_ha)
Example #55
0
    def add_tap_interface(self, network_id, network_type, physical_network,
                          segmentation_id, tap_device_name):
        """Add tap interface.

        If a VIF has been plugged into a network, this function will
        add the corresponding tap device to the relevant bridge.
        """
        if not ip_lib.device_exists(tap_device_name):
            LOG.debug("Tap device: %s does not exist on "
                      "this host, skipped", tap_device_name)
            return False

        bridge_name = self.get_bridge_name(network_id)
        if network_type == p_const.TYPE_LOCAL:
            self.ensure_local_bridge(network_id)
        else:
            phy_dev_name = self.ensure_physical_in_bridge(
                network_id, network_type, physical_network, segmentation_id)
            if not phy_dev_name:
                return False
            # (mirlos) we are setting MTU to the configured value below
            #self.ensure_tap_mtu(tap_device_name, phy_dev_name)

        # fix-neutron-agent-for-mtu-config hack
        # also set the bridge in one go
        LOG.debug("Set MTU and master of %s", tap_device_name)
        try:
            utils.execute([
                'ip', 'link', 'set', tap_device_name, 'mtu',
                cfg.CONF.network_device_mtu, 'master', bridge_name, 'up'
            ],
                          run_as_root=True)
        except RuntimeError:
            LOG.error('Failed to process interface %s for bridge %s',
                      tap_device_name, bridge_name)
            return False
        return True
Example #56
0
def environment_setup():
    bridge = cfg.CONF.df.integration_bridge
    interface = cfg.CONF.df_metadata.metadata_interface
    port = cfg.CONF.df_metadata.port
    if ip_lib.device_exists(interface):
        LOG.info("Device %s already exists", interface)
        # Destroy the environment when the device exists.
        # We can re-initialize the environment correctly.
        environment_destroy()

    cmd = [
        "ovs-vsctl", "add-port", bridge, interface, "--", "set", "Interface",
        interface, "type=internal"
    ]
    utils.execute(cmd, run_as_root=True)

    ip = cfg.CONF.df_metadata.ip
    cmd = ["ip", "addr", "add", "dev", interface, "{}/0".format(ip)]
    utils.execute(cmd, run_as_root=True)

    cmd = ["ip", "link", "set", "dev", interface, "up"]
    utils.execute(cmd, run_as_root=True)

    cmd = [
        "ip", "route", "add", "0.0.0.0/0", "dev", interface, "table",
        METADATA_ROUTE_TABLE_ID
    ]
    utils.execute(cmd, run_as_root=True)

    cmd = ["ip", "rule", "add", "from", ip, "table", METADATA_ROUTE_TABLE_ID]
    utils.execute(cmd, run_as_root=True)

    cmd = [
        "iptables", '-I', 'INPUT', '-i', interface, '-p', 'tcp', '--dport',
        str(port), '-j', 'ACCEPT'
    ]
    utils.execute(cmd, run_as_root=True)
Example #57
0
    def teardown_datapath(self, net_name):
        """Unprovision this datapath to stop serving metadata.

        This function will shutdown metadata proxy if it's running and delete
        the VETH pair, the OVS port and the namespace.
        """
        namespace = self._get_namespace_name(net_name)
        ip = ip_lib.IPWrapper(namespace)
        # If the namespace doesn't exist, return
        if not ip.netns.exists(namespace):
            return

        LOG.info("Cleaning up %s namespace which is not needed anymore",
                 namespace)

        metadata_driver.MetadataDriver.destroy_monitored_metadata_proxy(
            self._process_monitor, net_name, self.conf, namespace)

        veth_name = self._get_veth_name(net_name)
        self.ovs_idl.del_port(veth_name[0]).execute()
        if ip_lib.device_exists(veth_name[0]):
            ip_lib.IPWrapper().del_veth(veth_name[0])

        ip.garbage_collect_namespace()
Example #58
0
    def vxlan_ucast_supported(self):
        if not cfg.CONF.VXLAN.l2_population:
            return False
        if not ip_lib.iproute_arg_supported(['bridge', 'fdb'], 'append'):
            LOG.warning(
                _LW('Option "%(option)s" must be supported by command '
                    '"%(command)s" to enable %(mode)s mode'), {
                        'option': 'append',
                        'command': 'bridge fdb',
                        'mode': 'VXLAN UCAST'
                    })
            return False

        test_iface = None
        for seg_id in moves.range(1, p_const.MAX_VXLAN_VNI + 1):
            if (ip_lib.device_exists(self.get_vxlan_device_name(seg_id))
                    or ip_lib.vxlan_in_use(seg_id)):
                continue
            test_iface = self.ensure_vxlan(seg_id)
            break
        else:
            LOG.error(_LE('No valid Segmentation ID to perform UCAST test.'))
            return False

        try:
            utils.execute(cmd=[
                'bridge', 'fdb', 'append', constants.FLOODING_ENTRY[0], 'dev',
                test_iface, 'dst', '1.1.1.1'
            ],
                          run_as_root=True,
                          log_fail_as_error=False)
            return True
        except RuntimeError:
            return False
        finally:
            self.delete_interface(test_iface)
Example #59
0
    def plug(self,
             network_id,
             port_id,
             device_name,
             mac_address,
             bridge=None,
             namespace=None,
             prefix=None):
        """This method is called by the Dhcp agent or by the L3 agent
        when a new network is created
        """
        if not ip_lib.device_exists(
                device_name, self.root_helper, namespace=namespace):
            ip = ip_lib.IPWrapper(self.root_helper)
            tap_name = device_name.replace(prefix or n_const.TAP_DEVICE_PREFIX,
                                           n_const.TAP_DEVICE_PREFIX)

            # Create ns_dev in a namespace if one is configured.
            root_dev, ns_dev = ip.add_veth(tap_name,
                                           device_name,
                                           namespace2=namespace)

            ns_dev.link.set_address(mac_address)

            # Add an interface created by ovs to the namespace.
            namespace_obj = ip.ensure_namespace(namespace)
            namespace_obj.add_device_to_namespace(ns_dev)

            ns_dev.link.set_up()
            root_dev.link.set_up()

            cmd = ['mm-ctl', '--bind-port', port_id, device_name]
            utils.execute(cmd, self.root_helper)

        else:
            LOG.info(_LI("Device %s already exists"), device_name)
Example #60
0
 def ensure_vlan(self, physical_interface, vlan_id):
     """Create a vlan unless it already exists."""
     interface = self.get_subinterface_name(physical_interface, vlan_id)
     if not ip_lib.device_exists(interface):
         LOG.debug("Creating subinterface %(interface)s for "
                   "VLAN %(vlan_id)s on interface "
                   "%(physical_interface)s",
                   {'interface': interface, 'vlan_id': vlan_id,
                    'physical_interface': physical_interface})
         try:
             int_vlan = self.ip.add_vlan(interface, physical_interface,
                                         vlan_id)
         except RuntimeError:
             with excutils.save_and_reraise_exception() as ctxt:
                 if ip_lib.vlan_in_use(vlan_id):
                     ctxt.reraise = False
                     LOG.error(_LE("Unable to create VLAN interface for "
                                   "VLAN ID %s because it is in use by "
                                   "another interface."), vlan_id)
                     return
         int_vlan.disable_ipv6()
         int_vlan.link.set_up()
         LOG.debug("Done creating subinterface %s", interface)
     return interface