Esempio n. 1
0
 def test_add_veth(self):
     ip_lib.IPWrapper('sudo').add_veth('tap0', 'tap1')
     self.execute.assert_called_once_with('', 'link',
                                          ('add', 'tap0', 'type', 'veth',
                                           'peer', 'name', 'tap1'),
                                          'sudo', None)
Esempio n. 2
0
    def plug_new(self,
                 network_id,
                 port_id,
                 device_name,
                 mac_address,
                 bridge=None,
                 namespace=None,
                 prefix=None,
                 mtu=None,
                 link_up=True):
        """Plug in the interface."""
        if not bridge:
            bridge = self.conf.OVS.integration_bridge

        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)
            root_dev.disable_ipv6()
        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)
        for i in range(9):
            # workaround for the OVS shy port syndrome. ports sometimes
            # hide for a bit right after they are first created.
            # see bug/1618987
            try:
                ns_dev.link.set_address(mac_address)
                break
            except RuntimeError as e:
                LOG.warning("Got error trying to set mac, retrying: %s",
                            str(e))
                time.sleep(1)
        else:
            # didn't break, we give it one last shot without catching
            ns_dev.link.set_address(mac_address)

        # Add an interface created by ovs to the namespace.
        if not self.conf.ovs_use_veth and namespace:
            try:
                namespace_obj = ip.ensure_namespace(namespace)
                namespace_obj.add_device_to_namespace(ns_dev)
            except (pyroute2_exc.NetlinkError, OSError):
                # To prevent the namespace failure from blasting OVS, the OVS
                # port creation should be reverted. Possible exceptions:
                # - NetlinkError in case of duplicated interface
                # - OSError in case of corrupted namespace
                LOG.warning(
                    "Failed to plug interface %s into bridge %s, "
                    "cleaning up", device_name, bridge)
                with excutils.save_and_reraise_exception():
                    ovs = ovs_lib.OVSBridge(bridge)
                    ovs.delete_port(tap_name)

        # NOTE(ihrachys): the order here is significant: we must set MTU after
        # the device is moved into a namespace, otherwise OVS bridge does not
        # allow to set MTU that is higher than the least of all device MTUs on
        # the bridge
        if mtu:
            self.set_mtu(device_name, mtu, namespace=namespace, prefix=prefix)
        else:
            LOG.warning("No MTU configured for port %s", port_id)

        if link_up:
            ns_dev.link.set_up()
        if self.conf.ovs_use_veth:
            # ovs-dpdk does not do checksum calculations for veth interface
            # (bug 1832021)
            if self.conf.OVS.datapath_type == ovs_const.OVS_DATAPATH_NETDEV:
                ethtool.offload(ns_dev.name,
                                rx=False,
                                tx=False,
                                namespace=namespace)
            root_dev.link.set_up()
Esempio n. 3
0
 def assert_accept_ra_disabled(self, namespace):
     actual = ip_lib.IPWrapper(namespace=namespace).netns.execute(
         ['sysctl', '-b', 'net.ipv6.conf.default.accept_ra'])
     self.assertEqual('0', actual)
Esempio n. 4
0
    def provision_datapath(self, datapath):
        """Provision the datapath so that it can serve metadata.

        This function will create the namespace and VETH pair if needed
        and assign the IP addresses to the interface corresponding to the
        metadata port of the network. It will also remove existing IP
        addresses that are no longer needed.

        :return: The metadata namespace name of this datapath
        """
        LOG.debug("Provisioning datapath %s", datapath)
        port = self.sb_idl.get_metadata_port_network(datapath)
        # If there's no metadata port or it doesn't have a MAC or IP
        # addresses, then tear the namespace down if needed. This might happen
        # when there are no subnets yet created so metadata port doesn't have
        # an IP address.
        if not (port and port.mac and port.external_ids.get(
                ovn_const.OVN_CIDRS_EXT_ID_KEY, None)):
            LOG.debug(
                "There is no metadata port for datapath %s or it has no "
                "MAC or IP addresses configured, tearing the namespace "
                "down if needed", datapath)
            self.teardown_datapath(datapath)
            return

        # First entry of the mac field must be the MAC address.
        match = MAC_PATTERN.match(port.mac[0].split(' ')[0])
        # If it is not, we can't provision the namespace. Tear it down if
        # needed and log the error.
        if not match:
            LOG.error(
                "Metadata port for datapath %s doesn't have a MAC "
                "address, tearing the namespace down if needed", datapath)
            self.teardown_datapath(datapath)
            return

        mac = match.group()
        ip_addresses = set(
            port.external_ids[ovn_const.OVN_CIDRS_EXT_ID_KEY].split(' '))
        ip_addresses.add(ovn_const.METADATA_DEFAULT_CIDR)
        metadata_port = MetadataPortInfo(mac, ip_addresses)

        # Create the VETH pair if it's not created. Also the add_veth function
        # will create the namespace for us.
        namespace = self._get_namespace_name(datapath)
        veth_name = self._get_veth_name(datapath)

        ip1 = ip_lib.IPDevice(veth_name[0])
        if ip_lib.device_exists(veth_name[1], namespace):
            ip2 = ip_lib.IPDevice(veth_name[1], namespace)
        else:
            LOG.debug("Creating VETH %s in %s namespace", veth_name[1],
                      namespace)
            # Might happen that the end in the root namespace exists even
            # though the other end doesn't. Make sure we delete it first if
            # that's the case.
            if ip1.exists():
                ip1.link.delete()
            ip1, ip2 = ip_lib.IPWrapper().add_veth(veth_name[0], veth_name[1],
                                                   namespace)

        # Make sure both ends of the VETH are up
        ip1.link.set_up()
        ip2.link.set_up()

        # Configure the MAC address.
        ip2.link.set_address(metadata_port.mac)
        dev_info = ip2.addr.list()

        # Configure the IP addresses on the VETH pair and remove those
        # that we no longer need.
        current_cidrs = {dev['cidr'] for dev in dev_info}
        for ipaddr in current_cidrs - metadata_port.ip_addresses:
            ip2.addr.delete(ipaddr)
        for ipaddr in metadata_port.ip_addresses - current_cidrs:
            # NOTE(dalvarez): metadata only works on IPv4. We're doing this
            # extra check here because it could be that the metadata port has
            # an IPv6 address if there's an IPv6 subnet with SLAAC in its
            # network. Neutron IPAM will autoallocate an IPv6 address for every
            # port in the network.
            if utils.get_ip_version(ipaddr) == 4:
                ip2.addr.add(ipaddr)

        # Check that this port is not attached to any other OVS bridge. This
        # can happen when the OVN bridge changes (for example, during a
        # migration from ML2/OVS).
        ovs_bridges = set(self.ovs_idl.list_br().execute())
        try:
            ovs_bridges.remove(self.ovn_bridge)
        except KeyError:
            LOG.warning(
                "Configured OVN bridge %s cannot be found in "
                "the system. Resyncing the agent.", self.ovn_bridge)
            raise ConfigException()

        if ovs_bridges:
            with self.ovs_idl.transaction() as txn:
                for br in ovs_bridges:
                    txn.add(
                        self.ovs_idl.del_port(veth_name[0],
                                              bridge=br,
                                              if_exists=True))

        # Configure the OVS port and add external_ids:iface-id so that it
        # can be tracked by OVN.
        self.ovs_idl.add_port(self.ovn_bridge, veth_name[0]).execute()
        self.ovs_idl.db_set('Interface', veth_name[0],
                            ('external_ids', {
                                'iface-id': port.logical_port
                            })).execute()

        # Spawn metadata proxy if it's not already running.
        metadata_driver.MetadataDriver.spawn_monitored_metadata_proxy(
            self._process_monitor,
            namespace,
            ovn_const.METADATA_PORT,
            self.conf,
            bind_address=ovn_const.METADATA_DEFAULT_IP,
            network_id=datapath)

        self.update_chassis_metadata_networks(datapath)
        return namespace
Esempio n. 5
0
 def _setUp(self):
     ip = ip_lib.IPWrapper()
     self.name = self.prefix + uuidutils.generate_uuid()
     self.ip_wrapper = ip.ensure_namespace(self.name)
     self.addCleanup(self.destroy)
Esempio n. 6
0
    def spawn_process(self):
        """Spawns a Dnsmasq process for the network."""
        env = {
            self.NEUTRON_NETWORK_ID_KEY: self.network.id,
        }

        cmd = [
            'dnsmasq',
            '--no-hosts',
            '--no-resolv',
            '--strict-order',
            '--bind-interfaces',
            '--interface=%s' % self.interface_name,
            '--except-interface=lo',
            '--pid-file=%s' %
            self.get_conf_file_name('pid', ensure_conf_dir=True),
            '--dhcp-hostsfile=%s' % self._output_hosts_file(),
            '--addn-hosts=%s' % self._output_addn_hosts_file(),
            '--dhcp-optsfile=%s' % self._output_opts_file(),
            '--leasefile-ro',
        ]

        possible_leases = 0
        for i, subnet in enumerate(self.network.subnets):
            # if a subnet is specified to have dhcp disabled
            if not subnet.enable_dhcp:
                continue
            if subnet.ip_version == 4:
                mode = 'static'
            else:
                # TODO(mark): how do we indicate other options
                # ra-only, slaac, ra-nameservers, and ra-stateless.
                mode = 'static'
            if self.version >= self.MINIMUM_VERSION:
                set_tag = 'set:'
            else:
                set_tag = ''

            cidr = netaddr.IPNetwork(subnet.cidr)

            if self.conf.dhcp_lease_duration == -1:
                lease = 'infinite'
            else:
                lease = '%ss' % self.conf.dhcp_lease_duration

            cmd.append(
                '--dhcp-range=%s%s,%s,%s,%s' %
                (set_tag, self._TAG_PREFIX % i, cidr.network, mode, lease))

            possible_leases += cidr.size

        # Cap the limit because creating lots of subnets can inflate
        # this possible lease cap.
        cmd.append('--dhcp-lease-max=%d' %
                   min(possible_leases, self.conf.dnsmasq_lease_max))

        cmd.append('--conf-file=%s' % self.conf.dnsmasq_config_file)
        if self.conf.dnsmasq_dns_servers:
            cmd.extend('--server=%s' % server
                       for server in self.conf.dnsmasq_dns_servers)

        if self.conf.dhcp_domain:
            cmd.append('--domain=%s' % self.conf.dhcp_domain)

        ip_wrapper = ip_lib.IPWrapper(self.root_helper, self.network.namespace)
        ip_wrapper.netns.execute(cmd, addl_env=env)
Esempio n. 7
0
 def _release_lease(self, mac_address, ip):
     """Release a DHCP lease."""
     cmd = ['dhcp_release', self.interface_name, ip, mac_address]
     ip_wrapper = ip_lib.IPWrapper(self.root_helper, self.network.namespace)
     ip_wrapper.netns.execute(cmd)
Esempio n. 8
0
def ebtables(comm):
    execute = ip_lib.IPWrapper(NAMESPACE).netns.execute
    return execute(['ebtables', '--concurrent'] + comm, run_as_root=True)
Esempio n. 9
0
 def _update_routing_table(self, operation, route):
     cmd = ['ip', 'route', operation, 'to', route['destination'],
            'via', route['nexthop']]
     ip_wrapper = ip_lib.IPWrapper(self.root_helper,
                                   namespace=self.ns_name)
     ip_wrapper.netns.execute(cmd, check_exit_code=False)
Esempio n. 10
0
 def test_add_device_to_namespace_is_none(self):
     dev = mock.Mock()
     ip_lib.IPWrapper('sudo').add_device_to_namespace(dev)
     self.assertEqual(dev.mock_calls, [])
Esempio n. 11
0
    def plug_new(self,
                 network_id,
                 port_id,
                 device_name,
                 mac_address,
                 bridge=None,
                 namespace=None,
                 prefix=None,
                 mtu=None):
        """Plug in the interface."""
        if not bridge:
            bridge = self.conf.ovs_integration_bridge

        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)
            root_dev.disable_ipv6()
        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)
        for i in range(9):
            # workaround for the OVS shy port syndrome. ports sometimes
            # hide for a bit right after they are first created.
            # see bug/1618987
            try:
                ns_dev.link.set_address(mac_address)
                break
            except RuntimeError as e:
                LOG.warning(_LW("Got error trying to set mac, retrying: %s"),
                            str(e))
                time.sleep(1)
        else:
            # didn't break, we give it one last shot without catching
            ns_dev.link.set_address(mac_address)

        # 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)

        # NOTE(ihrachys): the order here is significant: we must set MTU after
        # the device is moved into a namespace, otherwise OVS bridge does not
        # allow to set MTU that is higher than the least of all device MTUs on
        # the bridge
        if mtu:
            ns_dev.link.set_mtu(mtu)
            if self.conf.ovs_use_veth:
                root_dev.link.set_mtu(mtu)
        else:
            LOG.warning(_LW("No MTU configured for port %s"), port_id)

        ns_dev.link.set_up()
        if self.conf.ovs_use_veth:
            root_dev.link.set_up()
Esempio n. 12
0
 def test_add_device_to_namespace(self):
     dev = mock.Mock()
     ip_lib.IPWrapper('sudo', 'ns').add_device_to_namespace(dev)
     dev.assert_has_calls([mock.call.link.set_netns('ns')])
Esempio n. 13
0
 def test_ensure_namespace_existing(self):
     with mock.patch.object(ip_lib, 'IpNetnsCommand') as ip_ns_cmd:
         ip_ns_cmd.exists.return_value = True
         ns = ip_lib.IPWrapper('sudo').ensure_namespace('ns')
         self.assertFalse(self.execute.called)
         self.assertEqual(ns.namespace, 'ns')
Esempio n. 14
0
 def test_get_device(self):
     dev = ip_lib.IPWrapper('sudo', 'ns').device('eth0')
     self.assertEqual(dev.root_helper, 'sudo')
     self.assertEqual(dev.namespace, 'ns')
     self.assertEqual(dev.name, 'eth0')
Esempio n. 15
0
 def execute(self, *args, **kwargs):
     ns_ip_wrapper = ip_lib.IPWrapper(self.namespace)
     return ns_ip_wrapper.netns.execute(*args, **kwargs)
Esempio n. 16
0
 def test_ipwrapper_get_device_by_ip(self):
     attr = self.generate_device_details()
     self.manage_device(attr)
     ip_wrapper = ip_lib.IPWrapper(namespace=attr.namespace)
     self.assertEqual(attr.name, ip_wrapper.get_device_by_ip(TEST_IP).name)
     self.assertIsNone(ip_wrapper.get_device_by_ip(WRONG_IP))
 def _local_namespaces(self):
     root_ip = ip_lib.IPWrapper()
     local_ns_list = root_ip.get_namespaces()
     return local_ns_list
Esempio n. 18
0
    def _router_lifecycle(self,
                          enable_ha,
                          ip_version=4,
                          dual_stack=False,
                          v6_ext_gw_with_sub=True):
        router_info = self.generate_router_info(
            enable_ha,
            ip_version,
            dual_stack=dual_stack,
            v6_ext_gw_with_sub=(v6_ext_gw_with_sub))
        router = self.manage_router(self.agent, router_info)

        # Add multiple-IPv6-prefix internal router port
        slaac = n_const.IPV6_SLAAC
        slaac_mode = {'ra_mode': slaac, 'address_mode': slaac}
        subnet_modes = [slaac_mode] * 2
        self._add_internal_interface_by_subnet(router.router,
                                               count=2,
                                               ip_version=6,
                                               ipv6_subnet_modes=subnet_modes)
        router.process(self.agent)

        if enable_ha:
            port = router.get_ex_gw_port()
            interface_name = router.get_external_device_name(port['id'])
            self._assert_no_ip_addresses_on_interface(router.ns_name,
                                                      interface_name)
            common_utils.wait_until_true(lambda: router.ha_state == 'master')

            # Keepalived notifies of a state transition when it starts,
            # not when it ends. Thus, we have to wait until keepalived finishes
            # configuring everything. We verify this by waiting until the last
            # device has an IP address.
            device = router.router[l3_constants.INTERFACE_KEY][-1]
            device_exists = functools.partial(
                self.device_exists_with_ips_and_mac, device,
                router.get_internal_device_name, router.ns_name)
            common_utils.wait_until_true(device_exists)

        self.assertTrue(self._namespace_exists(router.ns_name))
        common_utils.wait_until_true(
            lambda: self._metadata_proxy_exists(self.agent.conf, router))
        self._assert_internal_devices(router)
        self._assert_external_device(router)
        if not (enable_ha and (ip_version == 6 or dual_stack)):
            # Note(SridharG): enable the assert_gateway for IPv6 once
            # keepalived on Ubuntu14.04 (i.e., check-neutron-dsvm-functional
            # platform) is updated to 1.2.10 (or above).
            # For more details: https://review.openstack.org/#/c/151284/
            self._assert_gateway(router, v6_ext_gw_with_sub)
            self.assertTrue(self.floating_ips_configured(router))
            self._assert_snat_chains(router)
            self._assert_floating_ip_chains(router)
            self._assert_iptables_rules_converged(router)
            self._assert_extra_routes(router)
            ip_versions = [4, 6] if (ip_version == 6 or dual_stack) else [4]
            self._assert_onlink_subnet_routes(router, ip_versions)
        self._assert_metadata_chains(router)

        # Verify router gateway interface is configured to receive Router Advts
        # when IPv6 is enabled and no IPv6 gateway is configured.
        if router.use_ipv6 and not v6_ext_gw_with_sub:
            if not self.agent.conf.ipv6_gateway:
                external_port = router.get_ex_gw_port()
                external_device_name = router.get_external_device_name(
                    external_port['id'])
                ip_wrapper = ip_lib.IPWrapper(namespace=router.ns_name)
                ra_state = ip_wrapper.netns.execute([
                    'sysctl', '-b',
                    'net.ipv6.conf.%s.accept_ra' % external_device_name
                ])
                self.assertEqual('2', ra_state)

        if enable_ha:
            self._assert_ha_device(router)
            self.assertTrue(router.keepalived_manager.get_process().active)

        self._delete_router(self.agent, router.router_id)

        self._assert_interfaces_deleted_from_ovs()
        self._assert_router_does_not_exist(router)
        if enable_ha:
            self.assertFalse(router.keepalived_manager.get_process().active)
Esempio n. 19
0
    def spawn_process(self):
        """Spawns a Dnsmasq process for the network."""
        env = {
            self.NEUTRON_NETWORK_ID_KEY: self.network.id,
        }

        cmd = [
            'dnsmasq',
            '--no-hosts',
            '--no-resolv',
            '--strict-order',
            '--bind-interfaces',
            '--interface=%s' % self.interface_name,
            '--except-interface=lo',
            '--pid-file=%s' %
            self.get_conf_file_name('pid', ensure_conf_dir=True),
            '--dhcp-hostsfile=%s' % self._output_hosts_file(),
            '--addn-hosts=%s' % self._output_addn_hosts_file(),
            '--dhcp-optsfile=%s' % self._output_opts_file(),
            '--leasefile-ro',
        ]

        possible_leases = 0
        for i, subnet in enumerate(self.network.subnets):
            mode = None
            # if a subnet is specified to have dhcp disabled
            if not subnet.enable_dhcp:
                continue
            if subnet.ip_version == 4:
                mode = 'static'
            else:
                # Note(scollins) If the IPv6 attributes are not set, set it as
                # static to preserve previous behavior
                addr_mode = getattr(subnet, 'ipv6_address_mode', None)
                ra_mode = getattr(subnet, 'ipv6_ra_mode', None)
                if (addr_mode in [
                        constants.DHCPV6_STATEFUL, constants.DHCPV6_STATELESS
                ] or not addr_mode and not ra_mode):
                    mode = 'static'

            cidr = netaddr.IPNetwork(subnet.cidr)

            if self.conf.dhcp_lease_duration == -1:
                lease = 'infinite'
            else:
                lease = '%ss' % self.conf.dhcp_lease_duration

            # mode is optional and is not set - skip it
            if mode:
                if subnet.ip_version == 4:
                    cmd.append('--dhcp-range=%s%s,%s,%s,%s' %
                               ('set:', self._TAG_PREFIX % i, cidr.network,
                                mode, lease))
                else:
                    cmd.append('--dhcp-range=%s%s,%s,%s,%d,%s' %
                               ('set:', self._TAG_PREFIX % i, cidr.network,
                                mode, cidr.prefixlen, lease))
                possible_leases += cidr.size

        # Cap the limit because creating lots of subnets can inflate
        # this possible lease cap.
        cmd.append('--dhcp-lease-max=%d' %
                   min(possible_leases, self.conf.dnsmasq_lease_max))

        cmd.append('--conf-file=%s' % self.conf.dnsmasq_config_file)
        if self.conf.dnsmasq_dns_servers:
            cmd.extend('--server=%s' % server
                       for server in self.conf.dnsmasq_dns_servers)

        if self.conf.dhcp_domain:
            cmd.append('--domain=%s' % self.conf.dhcp_domain)

        ip_wrapper = ip_lib.IPWrapper(self.root_helper, self.network.namespace)
        ip_wrapper.netns.execute(cmd, addl_env=env)
Esempio n. 20
0
 def _execute(self, cmd, check_exit_code=True, extra_ok_codes=None):
     """Execute command on namespace."""
     ip_wrapper = ip_lib.IPWrapper(namespace=self.namespace)
     return ip_wrapper.netns.execute(cmd, check_exit_code=check_exit_code,
                                     extra_ok_codes=extra_ok_codes)
Esempio n. 21
0
def iproute2_vxlan_supported():
    ip = ip_lib.IPWrapper()
    name = common_utils.get_rand_device_name(prefix='vxlantest-')
    port = ip.add_vxlan(name, 3000)
    ip.del_veth(name)
    return name == port.name
Esempio n. 22
0
 def configure_ipv6_ra(namespace, dev_name):
     """Configure acceptance of IPv6 route advertisements on an intf."""
     # Learn the default router's IP address via RAs
     ip_lib.IPWrapper(namespace=namespace).netns.execute(
         ['sysctl', '-w',
          'net.ipv6.conf.%s.accept_ra=2' % dev_name])
Esempio n. 23
0
def assert_ping(src_namespace, dst_ip, timeout=1, count=3):
    ipversion = netaddr.IPAddress(dst_ip).version
    ping_command = 'ping' if ipversion == 4 else 'ping6'
    ns_ip_wrapper = ip_lib.IPWrapper(src_namespace)
    ns_ip_wrapper.netns.execute(
        [ping_command, '-c', count, '-W', timeout, dst_ip])
Esempio n. 24
0
 def _get_existing_devices(self):
     ip_wrapper = ip_lib.IPWrapper(namespace=self.ns_name)
     ip_devs = ip_wrapper.get_devices(exclude_loopback=True)
     return [ip_dev.name for ip_dev in ip_devs]
Esempio n. 25
0
 def _setUp(self):
     ip_wrapper = ip_lib.IPWrapper()
     self.ports = ip_wrapper.add_veth(self.veth0_name, self.veth1_name)
     self.addCleanup(self.destroy)
Esempio n. 26
0
 def _namespace_exists(self, namespace):
     ip = ip_lib.IPWrapper(namespace=namespace)
     return ip.netns.exists(namespace)
Esempio n. 27
0
 def assert_dhcp_namespace(self, namespace, dhcp_enabled):
     ip = ip_lib.IPWrapper()
     self.assertEqual(dhcp_enabled, ip.netns.exists(namespace))
Esempio n. 28
0
    def setUp(self):
        super(TunnelTest, self).setUp()
        cfg.CONF.set_override('rpc_backend',
                              'neutron.openstack.common.rpc.impl_fake')
        cfg.CONF.set_override('report_interval', 0, 'AGENT')
        self.mox = mox.Mox()
        self.addCleanup(self.mox.UnsetStubs)

        self.INT_BRIDGE = 'integration_bridge'
        self.TUN_BRIDGE = 'tunnel_bridge'
        self.MAP_TUN_BRIDGE = 'tunnel_bridge_mapping'
        self.NET_MAPPING = {'net1': self.MAP_TUN_BRIDGE}
        self.INT_OFPORT = 11111
        self.TUN_OFPORT = 22222
        self.MAP_TUN_OFPORT = 33333
        self.VETH_MTU = None
        self.inta = self.mox.CreateMock(ip_lib.IPDevice)
        self.intb = self.mox.CreateMock(ip_lib.IPDevice)
        self.inta.link = self.mox.CreateMock(ip_lib.IpLinkCommand)
        self.intb.link = self.mox.CreateMock(ip_lib.IpLinkCommand)

        self.mox.StubOutClassWithMocks(ovs_lib, 'OVSBridge')
        self.mock_int_bridge = ovs_lib.OVSBridge(self.INT_BRIDGE, 'sudo')
        self.mock_int_bridge.get_local_port_mac().AndReturn('000000000001')
        self.mock_int_bridge.delete_port('patch-tun')
        self.mock_int_bridge.remove_all_flows()
        self.mock_int_bridge.add_flow(priority=1, actions='normal')

        self.mock_map_tun_bridge = ovs_lib.OVSBridge(self.MAP_TUN_BRIDGE,
                                                     'sudo')
        self.mock_map_tun_bridge.br_name = self.MAP_TUN_BRIDGE
        self.mock_map_tun_bridge.remove_all_flows()
        self.mock_map_tun_bridge.add_flow(priority=1, actions='normal')
        self.mock_int_bridge.delete_port('int-tunnel_bridge_mapping')
        self.mock_map_tun_bridge.delete_port('phy-tunnel_bridge_mapping')
        self.mock_int_bridge.add_port(self.inta)
        self.mock_map_tun_bridge.add_port(self.intb)
        self.inta.link.set_up()
        self.intb.link.set_up()

        self.mock_int_bridge.add_flow(priority=2, in_port=None, actions='drop')
        self.mock_map_tun_bridge.add_flow(priority=2,
                                          in_port=None,
                                          actions='drop')

        self.mock_tun_bridge = ovs_lib.OVSBridge(self.TUN_BRIDGE, 'sudo')
        self.mock_tun_bridge.reset_bridge()
        self.mock_int_bridge.add_patch_port(
            'patch-tun', 'patch-int').AndReturn(self.TUN_OFPORT)
        self.mock_tun_bridge.add_patch_port(
            'patch-int', 'patch-tun').AndReturn(self.INT_OFPORT)

        self.mock_tun_bridge.remove_all_flows()
        self.mock_tun_bridge.add_flow(priority=1,
                                      in_port=self.INT_OFPORT,
                                      actions="resubmit(,%s)" %
                                      constants.PATCH_LV_TO_TUN)
        self.mock_tun_bridge.add_flow(priority=0, actions='drop')
        self.mock_tun_bridge.add_flow(table=constants.PATCH_LV_TO_TUN,
                                      dl_dst=UCAST_MAC,
                                      actions="resubmit(,%s)" %
                                      constants.UCAST_TO_TUN)
        self.mock_tun_bridge.add_flow(table=constants.PATCH_LV_TO_TUN,
                                      dl_dst=BCAST_MAC,
                                      actions="resubmit(,%s)" %
                                      constants.FLOOD_TO_TUN)
        for tunnel_type in constants.TUNNEL_NETWORK_TYPES:
            self.mock_tun_bridge.add_flow(
                table=constants.TUN_TABLE[tunnel_type],
                priority=0,
                actions="drop")
        learned_flow = ("table=%s,"
                        "priority=1,"
                        "hard_timeout=300,"
                        "NXM_OF_VLAN_TCI[0..11],"
                        "NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],"
                        "load:0->NXM_OF_VLAN_TCI[],"
                        "load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],"
                        "output:NXM_OF_IN_PORT[]" % constants.UCAST_TO_TUN)
        self.mock_tun_bridge.add_flow(table=constants.LEARN_FROM_TUN,
                                      priority=1,
                                      actions="learn(%s),output:%s" %
                                      (learned_flow, self.INT_OFPORT))
        self.mock_tun_bridge.add_flow(table=constants.UCAST_TO_TUN,
                                      priority=0,
                                      actions="resubmit(,%s)" %
                                      constants.FLOOD_TO_TUN)
        self.mock_tun_bridge.add_flow(table=constants.FLOOD_TO_TUN,
                                      priority=0,
                                      actions="drop")

        self.mox.StubOutWithMock(ip_lib, 'device_exists')
        ip_lib.device_exists('tunnel_bridge_mapping', 'sudo').AndReturn(True)
        ip_lib.device_exists('int-tunnel_bridge_mapping',
                             'sudo').AndReturn(True)

        self.mox.StubOutWithMock(ip_lib.IpLinkCommand, 'delete')
        ip_lib.IPDevice('int-tunnel_bridge_mapping').link.delete()

        self.mox.StubOutClassWithMocks(ip_lib, 'IPWrapper')
        ip_lib.IPWrapper('sudo').add_veth(
            'int-tunnel_bridge_mapping',
            'phy-tunnel_bridge_mapping').AndReturn([self.inta, self.intb])

        self.mox.StubOutWithMock(ovs_lib, 'get_bridges')
        ovs_lib.get_bridges('sudo').AndReturn(
            [self.INT_BRIDGE, self.TUN_BRIDGE, self.MAP_TUN_BRIDGE])
Esempio n. 29
0
 def _execute_tc_cmd(self, cmd, **kwargs):
     cmd = ['tc'] + cmd
     ip_wrapper = ip_lib.IPWrapper(self.namespace)
     return ip_wrapper.netns.execute(cmd, run_as_root=True, **kwargs)
Esempio n. 30
0
 def test_add_tuntap(self):
     ip_lib.IPWrapper('sudo').add_tuntap('tap0')
     self.execute.assert_called_once_with('', 'tuntap',
                                          ('add', 'tap0', 'mode', 'tap'),
                                          'sudo', None)