Пример #1
0
 def test_install_arp_responder(self):
     vlan = 3333
     ip = '192.0.2.1'
     mac = '08:60:6e:7f:74:e7'
     self.br.install_arp_responder(vlan=vlan, ip=ip, mac=mac)
     expected = [
         call.add_flow(
             proto='arp',
             nw_dst=ip,
             actions='move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],'
             'mod_dl_src:%(mac)s,load:0x2->NXM_OF_ARP_OP[],'
             'move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],'
             'move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],'
             'load:%(mac)#x->NXM_NX_ARP_SHA[],'
             'load:%(ip)#x->NXM_OF_ARP_SPA[],in_port' % {
                 'mac': netaddr.EUI(mac, dialect=netaddr.mac_unix),
                 'ip': netaddr.IPAddress(ip),
             },
             priority=1,
             table=21,
             dl_vlan=vlan),
     ]
     self.assertEqual(expected, self.mock.mock_calls)
Пример #2
0
    def _test_update_router_gw(self,
                               current_enable_snat,
                               gw_info=None,
                               expected_enable_snat=True):
        if not current_enable_snat:
            previous_gw_info = {
                'network_id': self.ext_net_id,
                'enable_snat': current_enable_snat
            }
            self.target_object._update_router_gw_info(self.context,
                                                      self.router.id,
                                                      previous_gw_info)

        self.target_object._update_router_gw_info(self.context, self.router.id,
                                                  gw_info)
        router = self.target_object._get_router(self.context, self.router.id)
        try:
            self.assertEqual(FAKE_GW_PORT_ID, router.gw_port.id)
            self.assertEqual(netaddr.EUI(FAKE_GW_PORT_MAC),
                             router.gw_port.mac_address)
        except AttributeError:
            self.assertIsNone(router.gw_port)
        self.assertEqual(expected_enable_snat, router.enable_snat)
Пример #3
0
def validate_mac_address(data, valid_values=None):
    """Validate data is a MAC address.

    :param data: The data to validate.
    :param valid_values: Not used!
    :returns: None if the data is a valid MAC address, otherwise a human
        readable message as to why validation failed.
    """
    try:
        valid_mac = netaddr.valid_mac(validate_no_whitespace(data))
    except Exception:
        valid_mac = False

    if valid_mac:
        valid_mac = (not netaddr.EUI(data) in map(
            netaddr.EUI, constants.INVALID_MAC_ADDRESSES))
    # TODO(arosen): The code in this file should be refactored
    # so it catches the correct exceptions. validate_no_whitespace
    # raises AttributeError if data is None.
    if not valid_mac:
        msg = _("'%s' is not a valid MAC address") % data
        LOG.debug(msg)
        return msg
Пример #4
0
def router_append_pd_enabled_subnet(router, count=1):
    interfaces = router[l3_constants.INTERFACE_KEY]
    current = sum(
        netaddr.IPNetwork(subnet['cidr']).version == 6 for p in interfaces
        for subnet in p['subnets'])

    mac_address = netaddr.EUI('ca:fe:de:ad:be:ef')
    mac_address.dialect = netaddr.mac_unix
    pd_intfs = []
    for i in range(current, current + count):
        subnet_id = _uuid()
        intf = {
            'id':
            _uuid(),
            'network_id':
            _uuid(),
            'admin_state_up':
            True,
            'fixed_ips': [{
                'ip_address': '::1',
                'prefixlen': 64,
                'subnet_id': subnet_id
            }],
            'mac_address':
            str(mac_address),
            'subnets': [{
                'id': subnet_id,
                'cidr': l3_constants.PROVISIONAL_IPV6_PD_PREFIX,
                'gateway_ip': '::1',
                'ipv6_ra_mode': l3_constants.IPV6_SLAAC,
                'subnetpool_id': l3_constants.IPV6_PD_POOL_ID
            }]
        }
        interfaces.append(intf)
        pd_intfs.append(intf)
        mac_address.value += 1
    return pd_intfs
Пример #5
0
def hwaddr(value, query='', alias='hwaddr'):
    ''' Check if string is a HW/MAC address and filter it '''

    query_func_extra_args = {
        '': ('value',),
    }

    query_func_map = {
        '': _empty_hwaddr_query,
        'bare': _bare_query,
        'bool': _bool_hwaddr_query,
        'int': _int_hwaddr_query,
        'cisco': _cisco_query,
        'eui48': _win_query,
        'linux': _linux_query,
        'pgsql': _postgresql_query,
        'postgresql': _postgresql_query,
        'psql': _postgresql_query,
        'unix': _unix_query,
        'win': _win_query,
    }

    try:
        v = netaddr.EUI(value)
    except Exception:
        if query and query != 'bool':
            raise errors.AnsibleFilterError(alias + ': not a hardware address: %s' % value)

    extras = []
    for arg in query_func_extra_args.get(query, tuple()):
        extras.append(locals()[arg])
    try:
        return query_func_map[query](v, *extras)
    except KeyError:
        raise errors.AnsibleFilterError(alias + ': unknown filter type: %s' % query)

    return False
Пример #6
0
    def _connect_router_network(self,
                                router_id,
                                network_id,
                                subnet_id=None,
                                gw_network=False):
        port = obj_reg.new_instance(
            'Port',
            self.context,
            network_id=network_id,
            mac_address=netaddr.EUI(GW_MAC, dialect=netaddr.mac_unix_expanded),
            device_id='test_device_id',
            device_owner=constants.DEVICE_OWNER_ROUTER_INTF,
            status="DUMMY_STATUS",
            admin_state_up=True)
        if gw_network:
            port.device_owner = constants.DEVICE_OWNER_ROUTER_GW

        port.create()

        if subnet_id:
            allocation = obj_reg.new_instance(
                'IPAllocation',
                self.context,
                port_id=port.id,
                subnet_id=subnet_id,
                network_id=network_id,
                ip_address=netaddr.IPNetwork(GW_IP))
            allocation.create()

            port.fixed_ips = [allocation]
            port.update()

        router_if = obj_reg.new_instance('RouterPort',
                                         self.context,
                                         router_id=router_id,
                                         port_id=port.id)
        router_if.create()
Пример #7
0
def hwaddr(value, query="", alias="hwaddr"):
    """ Check if string is a HW/MAC address and filter it """

    query_func_extra_args = {"": ("value", )}

    query_func_map = {
        "": _empty_hwaddr_query,
        "bare": _bare_query,
        "bool": _bool_hwaddr_query,
        "int": _int_hwaddr_query,
        "cisco": _cisco_query,
        "eui48": _win_query,
        "linux": _linux_query,
        "pgsql": _postgresql_query,
        "postgresql": _postgresql_query,
        "psql": _postgresql_query,
        "unix": _unix_query,
        "win": _win_query,
    }

    try:
        v = netaddr.EUI(value)
    except Exception:
        v = None
        if query and query != "bool":
            raise errors.AnsibleFilterError(alias +
                                            ": not a hardware address: %s" %
                                            value)

    extras = []
    for arg in query_func_extra_args.get(query, tuple()):
        extras.append(locals()[arg])
    try:
        return query_func_map[query](v, *extras)
    except KeyError:
        raise errors.AnsibleFilterError(alias +
                                        ": unknown filter type: %s" % query)
Пример #8
0
    def _find_nexthop_mac_addr(self, packet):
        mac_addr = None
        src_ip_addr = netaddr.IPAddress(packet['net']['srcIp'])
        dst_ip_addr = netaddr.IPAddress(packet['net']['dstIp'])
        # use lower 64 bits and invert U/L bit
        derived_dst_mac = str(
            netaddr.EUI((int(dst_ip_addr) & 0xFFFFFFFFFFFFFFFF)
                        ^ 0x0200000000000000))

        if (dst_ip_addr.words[0] & 0xFF00) == 0xFF00:
            # this is an IPv6 multicast address
            mac_addr = d.BROADCAST_ADDRESS

        elif self.mote.dagRoot:
            if derived_dst_mac in self.on_link_neighbor_list:
                # on-link
                mac_addr = derived_dst_mac
            else:
                # off-link
                mac_addr = None
        else:
            if self.mote.rpl.dodagId is None:
                # upward during secure join process
                mac_addr = str(self.mote.tsch.join_proxy)
            elif ((((src_ip_addr.words[0] & 0xFE80) == 0xFE80))
                  or (('downward' in packet['net']) and
                      (packet['net']['downward'] is True))):
                if derived_dst_mac in self.on_link_neighbor_list:
                    # on-link
                    mac_addr = derived_dst_mac
                else:
                    mac_addr = None
            else:
                # use the default router (preferred parent)
                mac_addr = self.mote.rpl.getPreferredParent()

        return mac_addr
Пример #9
0
 def create_host(self):
     hostname = self.args.hostname
     obj = self._new_object("host", hostname)
     if self.args.descr:
         obj.append("descr", self.args.descr)
     obj.extend((("l2-address", address)
                 for address in self.args.l2_address), append_group=True)
     obj.extend((("address", address) for address in self.args.address),
                append_group=True)
     for prefix in self.args.eui64:
         for l2_address in self.args.l2_address:
             obj.append("address", str(netaddr.EUI(l2_address).ipv6(
                 netaddr.IPNetwork(prefix)[0])))
     obj.extend((("admin-c", admin_c) for admin_c in self.args.admin_c),
                append_group=True)
     obj.extend((("tech-c", tech_c) for tech_c in self.args.tech_c),
                append_group=True)
     if self.args.status:
         obj.append("status", self.args.status)
     if self.args.edit:
         obj = self._edit_object(obj)
     self._save_object(obj)
     if self.add_inverse:
         self._add_inverse_addresses(obj)
Пример #10
0
 def get_dvr_mac_address_with_retry(self):
     # Get the local DVR MAC Address from the Neutron Server.
     # This is the first place where we contact the server on startup
     # so retry in case it's not ready to respond
     for retry_count in reversed(range(5)):
         try:
             details = self.plugin_rpc.get_dvr_mac_address_by_host(
                 self.context, self.host)
         except oslo_messaging.MessagingTimeout as e:
             with excutils.save_and_reraise_exception() as ctx:
                 if retry_count > 0:
                     ctx.reraise = False
                     LOG.warning(
                         'L2 agent could not get DVR MAC '
                         'address from server. Retrying. '
                         'Detailed message: %s', e)
         else:
             LOG.debug(
                 "L2 Agent DVR: Received response for "
                 "get_dvr_mac_address_by_host() from "
                 "plugin: %r", details)
             self.dvr_mac_address = (netaddr.EUI(
                 details['mac_address'], dialect=netaddr.mac_unix_expanded))
             return
Пример #11
0
def to_mac_range(val):
    cidr_parts = val.split("/")
    prefix = cidr_parts[0]
    prefix = prefix.replace(':', '')
    prefix = prefix.replace('-', '')
    prefix_length = len(prefix)
    if prefix_length < 6 or prefix_length > 12:
        r = "6>len({0}) || len({0})>12 len == {1}]".format(val, prefix_length)
        raise ValueError(r)
    diff = 12 - len(prefix)
    if len(cidr_parts) > 1:
        mask = int(cidr_parts[1])
    else:
        mask = 48 - diff * 4
    mask_size = 1 << (48 - mask)
    prefix = "%s%s" % (prefix, "0" * diff)
    try:
        cidr = "%s/%s" % (str(netaddr.EUI(prefix)).replace("-", ":"), mask)
    except Exception as e:
        r = "{0} raised netaddr.AddrFormatError: ".format(prefix)
        r += "{0}... ignoring.".format(e.message)
        print(r)
    prefix_int = int(prefix, base=16)
    return cidr, prefix_int, prefix_int + mask_size
Пример #12
0
    def _enable_gw_redirect(self, vlan, gateway_ip):
        # Add ARP responder entry for default gateway in br-tun

        # We may compete with the ARP responder entry for the real MAC
        # if the router is on a network node and we are a compute node,
        # so we must add our rule with a higher priority. Using a different
        # priority also means that arp_responder will not remove our ARP
        # responding flows and we won't remove theirs.

        # NOTE(tmorin): consider adding priority to install_arp_responder
        # and then use it here

        # (mostly copy-pasted ovs_ofctl....install_arp_responder)
        actions = a_const.ARP_RESPONDER_ACTIONS % {
            'mac': netaddr.EUI(DEFAULT_GATEWAY_MAC, dialect=netaddr.mac_unix),
            'ip': netaddr.IPAddress(gateway_ip),
        }
        self.tun_br.add_flow(table=a_const.ARP_RESPONDER,
                             priority=2,  # see above
                             dl_vlan=vlan,
                             proto='arp',
                             arp_op=0x01,
                             arp_tpa='%s' % gateway_ip,
                             actions=actions)
Пример #13
0
    def create_address(self, ipaddr, addrobjname=None, temp=True,
                       ifcheck=True, addrcheck=True):
        if ifcheck and not self.ifname_exists(self._ifname):
            # create ip interface
            cmd = ['/usr/sbin/ipadm', 'create-ip', self._ifname]
            if temp:
                cmd.insert(2, '-t')
            self.execute_with_pfexec(cmd)
        elif addrcheck and self.ipaddr_exists(ipaddr, self._ifname):
            return

        # If an address is IPv6, then to create a static IPv6 address
        # we need to create link-local address first
        if netaddr.IPNetwork(ipaddr).version == 6:
            # check if link-local address already exists
            cmd = ['/usr/sbin/dladm', 'show-linkprop', '-co', 'value',
                   '-p', 'mac-address', self._ifname]
            stdout = self.execute(cmd)
            mac_addr = stdout.splitlines()[0].strip()
            ll_addr = netaddr.EUI(mac_addr).ipv6_link_local()

            if addrcheck and not self.ipaddr_exists(str(ll_addr),
                                                    self._ifname):
                # create a link-local address
                cmd = ['/usr/sbin/ipadm', 'create-addr', '-T', 'static', '-a',
                       str(ll_addr), self._ifname]
                if temp:
                    cmd.insert(2, '-t')
                self.execute_with_pfexec(cmd)

        cmd = ['/usr/sbin/ipadm', 'create-addr', '-T', 'static', '-a',
               ipaddr, self._ifname]
        if temp:
            cmd.insert(2, '-t')

        self.execute_with_pfexec(cmd)
Пример #14
0
def get_ipv6_addr_by_EUI64(cidr, mac):
    """Generate a IPv6 addr by EUI-64 with CIDR and MAC

    :param str cidr: a IPv6 CIDR
    :param str mac: a MAC address
    :return: an IPv6 Address
    :rtype: netaddr.IPAddress
    """
    # Check if the prefix is IPv4 address
    is_ipv4 = netaddr.valid_ipv4(cidr)
    if is_ipv4:
        msg = "Unable to generate IP address by EUI64 for IPv4 prefix"
        raise TypeError(msg)
    try:
        eui64 = int(netaddr.EUI(mac).eui64())
        prefix = netaddr.IPNetwork(cidr)
        return netaddr.IPAddress(prefix.first + eui64 ^ (1 << 57))
    except (ValueError, netaddr.AddrFormatError):
        raise TypeError('Bad prefix or mac format for generating IPv6 '
                        'address by EUI-64: %(prefix)s, %(mac)s:'
                        % {'prefix': cidr, 'mac': mac})
    except TypeError:
        raise TypeError('Bad prefix type for generate IPv6 address by '
                        'EUI-64: %s' % cidr)
Пример #15
0
def to_mac(ipv6_address):
    address = netaddr.IPAddress(ipv6_address)
    mask1 = netaddr.IPAddress('::ff:ffff')
    mac = netaddr.EUI(int(address & mask1)).words
    return ':'.join(['02', '16', '3e'] + ['%02x' % i for i in mac[3:6]])
Пример #16
0
def canonicalise_mac(mac):
    # Use the Unix dialect, which uses ':' for its separator instead of
    # '-'.  This fits best with what iptables is expecting.
    eui = netaddr.EUI(mac, dialect=eui48.mac_unix)
    return str(eui)
Пример #17
0
def get_random_EUI():
    return netaddr.EUI(net.get_random_mac(['fe', '16', '3e', '00', '00',
                                           '00']))
Пример #18
0
    def create_port(self, context, network_id, port_id, **kwargs):
        """Create a port.

        :param context: neutron api request context.
        :param network_id: neutron network id.
        :param port_id: neutron port id.
        :param kwargs:
            required keys - device_id: neutron port device_id (instance_id)
                            instance_node_id: nova hypervisor host id
                            mac_address: neutron port mac address
                            base_net_driver: the base network driver
            optional keys - addresses: list of allocated IPAddress models
                            security_groups: list of associated security groups
        :raises IronicException: If the client is unable to create the
            downstream port for any reason, the exception will be logged
            and IronicException raised.
        """
        LOG.info("create_port %s %s %s" %
                 (context.tenant_id, network_id, port_id))

        # sanity check
        if not kwargs.get('base_net_driver'):
            raise IronicException(msg='base_net_driver required.')
        base_net_driver = kwargs['base_net_driver']

        if not kwargs.get('device_id'):
            raise IronicException(msg='device_id required.')
        device_id = kwargs['device_id']

        if not kwargs.get('instance_node_id'):
            raise IronicException(msg='instance_node_id required.')
        instance_node_id = kwargs['instance_node_id']

        if not kwargs.get('mac_address'):
            raise IronicException(msg='mac_address is required.')
        mac_address = str(netaddr.EUI(kwargs["mac_address"]["address"]))
        mac_address = mac_address.replace('-', ':')

        # TODO(morgabra): Change this when we enable security groups.
        if kwargs.get('security_groups'):
            msg = 'ironic driver does not support security group operations.'
            raise IronicException(msg=msg)

        # unroll the given address models into a fixed_ips list we can
        # pass downstream
        fixed_ips = []
        addresses = kwargs.get('addresses')
        if not isinstance(addresses, list):
            addresses = [addresses]
        for address in addresses:
            fixed_ips.append(self._make_fixed_ip_dict(context, address))

        body = {
            "id": port_id,
            "network_id": network_id,
            "device_id": device_id,
            "device_owner": kwargs.get('device_owner', ''),
            "tenant_id": context.tenant_id or "quark",
            "roles": context.roles,
            "mac_address": mac_address,
            "fixed_ips": fixed_ips,
            "switch:hardware_id": instance_node_id,
            "dynamic_network": not STRATEGY.is_provider_network(network_id)
        }

        net_info = self._get_base_network_info(context, network_id,
                                               base_net_driver)
        body.update(net_info)

        try:
            LOG.info("creating downstream port: %s" % (body))
            port = self._create_port(context, body)
            LOG.info("created downstream port: %s" % (port))
            return {
                "uuid": port['port']['id'],
                "vlan_id": port['port']['vlan_id']
            }
        except Exception as e:
            msg = "failed to create downstream port. Exception: %s" % (e)
            raise IronicException(msg=msg)
Пример #19
0
class DHCPAgentOVSTestFramework(base.BaseSudoTestCase):

    _DHCP_PORT_MAC_ADDRESS = netaddr.EUI("24:77:03:7d:00:4c")
    _DHCP_PORT_MAC_ADDRESS.dialect = netaddr.mac_unix
    _TENANT_PORT_MAC_ADDRESS = netaddr.EUI("24:77:03:7d:00:3a")
    _TENANT_PORT_MAC_ADDRESS.dialect = netaddr.mac_unix

    _IP_ADDRS = {
        4: {
            'addr': '192.168.10.11',
            'cidr': '192.168.10.0/24',
            'gateway': '192.168.10.1'
        },
        6: {
            'addr': '2001:db8:0:1::c0a8:a0b',
            'cidr': '2001:db8:0:1::c0a8:a00/120',
            'gateway': '2001:db8:0:1::c0a8:a01'
        },
    }

    def setUp(self):
        super(DHCPAgentOVSTestFramework, self).setUp()
        config.setup_logging()
        self.conf_fixture = self.useFixture(fixture_config.Config())
        self.conf = self.conf_fixture.conf
        dhcp_agent.register_options(self.conf)

        # NOTE(cbrandily): TempDir fixture creates a folder with 0o700
        # permissions but agent dir must be readable by dnsmasq user (nobody)
        agent_config_dir = self.useFixture(fixtures.TempDir()).path
        self.useFixture(
            helpers.RecursivePermDirFixture(agent_config_dir, 0o555))

        self.conf.set_override("dhcp_confs", agent_config_dir)
        self.conf.set_override(
            'interface_driver',
            'neutron.agent.linux.interface.OVSInterfaceDriver')
        self.conf.set_override('report_interval', 0, 'AGENT')
        br_int = self.useFixture(net_helpers.OVSBridgeFixture()).bridge
        self.conf.set_override('integration_bridge', br_int.br_name, 'OVS')

        self.mock_plugin_api = mock.patch(
            'neutron.agent.dhcp.agent.DhcpPluginApi').start().return_value
        mock.patch('neutron.agent.rpc.PluginReportStateAPI').start()
        self.agent = agent.DhcpAgentWithStateReport('localhost')

        self.ovs_driver = interface.OVSInterfaceDriver(self.conf)

        self.conf.set_override('check_child_processes_interval', 1, 'AGENT')

    def network_dict_for_dhcp(self,
                              dhcp_enabled=True,
                              ip_version=lib_const.IP_VERSION_4,
                              prefix_override=None):
        net_id = uuidutils.generate_uuid()
        subnet_dict = self.create_subnet_dict(net_id, dhcp_enabled, ip_version,
                                              prefix_override)
        port_dict = self.create_port_dict(net_id,
                                          subnet_dict.id,
                                          mac_address=str(
                                              self._DHCP_PORT_MAC_ADDRESS),
                                          ip_version=ip_version)
        port_dict.device_id = common_utils.get_dhcp_agent_device_id(
            net_id, self.conf.host)
        net_dict = self.create_network_dict(net_id, [subnet_dict], [port_dict])
        return net_dict

    def create_subnet_dict(self,
                           net_id,
                           dhcp_enabled=True,
                           ip_version=lib_const.IP_VERSION_4,
                           prefix_override=None):
        cidr = self._IP_ADDRS[ip_version]['cidr']
        if prefix_override is not None:
            cidr = '/'.join((cidr.split('/')[0], str(prefix_override)))
        sn_dict = dhcp.DictModel(
            id=uuidutils.generate_uuid(),
            network_id=net_id,
            ip_version=ip_version,
            cidr=cidr,
            gateway_ip=self._IP_ADDRS[ip_version]['gateway'],
            enable_dhcp=dhcp_enabled,
            dns_nameservers=[],
            host_routes=[],
            ipv6_ra_mode=None,
            ipv6_address_mode=None)
        if ip_version == lib_const.IP_VERSION_6:
            sn_dict['ipv6_address_mode'] = lib_const.DHCPV6_STATEFUL
        return sn_dict

    def create_port_dict(self,
                         network_id,
                         subnet_id,
                         mac_address,
                         ip_version=lib_const.IP_VERSION_4,
                         ip_address=None):
        ip_address = (self._IP_ADDRS[ip_version]['addr']
                      if not ip_address else ip_address)
        port_dict = dhcp.DictModel(id=uuidutils.generate_uuid(),
                                   name="foo",
                                   mac_address=mac_address,
                                   network_id=network_id,
                                   admin_state_up=True,
                                   device_id=uuidutils.generate_uuid(),
                                   device_owner="foo",
                                   fixed_ips=[{
                                       "subnet_id": subnet_id,
                                       "ip_address": ip_address
                                   }])
        return port_dict

    def create_network_dict(self,
                            net_id,
                            subnets=None,
                            ports=None,
                            non_local_subnets=None):
        subnets = [] if not subnets else subnets
        ports = [] if not ports else ports
        non_local_subnets = [] if not non_local_subnets else non_local_subnets
        net_dict = dhcp.NetModel(id=net_id,
                                 subnets=subnets,
                                 non_local_subnets=non_local_subnets,
                                 ports=ports,
                                 admin_state_up=True,
                                 tenant_id=uuidutils.generate_uuid())
        return net_dict

    def get_interface_name(self, network, port):
        device_manager = dhcp.DeviceManager(conf=self.conf, plugin=mock.Mock())
        return device_manager.get_interface_name(network, port)

    def configure_dhcp_for_network(self, network, dhcp_enabled=True):
        self.agent.configure_dhcp_for_network(network)
        self.addCleanup(self._cleanup_network, network, dhcp_enabled)

    def _cleanup_network(self, network, dhcp_enabled):
        self.mock_plugin_api.release_dhcp_port.return_value = None
        if dhcp_enabled:
            self.agent.call_driver('disable', network)

    def assert_dhcp_resources(self, network, dhcp_enabled):
        ovs = ovs_lib.BaseOVS()
        port = network.ports[0]
        iface_name = self.get_interface_name(network, port)
        self.assertEqual(dhcp_enabled, ovs.port_exists(iface_name))
        self.assert_dhcp_namespace(network.namespace, dhcp_enabled)
        self.assert_accept_ra_disabled(network.namespace)
        self.assert_dhcp_device(network.namespace, iface_name, dhcp_enabled)

    def assert_dhcp_namespace(self, namespace, dhcp_enabled):
        self.assertEqual(dhcp_enabled,
                         ip_lib.network_namespace_exists(namespace))

    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)

    def assert_dhcp_device(self, namespace, dhcp_iface_name, dhcp_enabled):
        dev = ip_lib.IPDevice(dhcp_iface_name, namespace)
        self.assertEqual(dhcp_enabled,
                         ip_lib.device_exists(dhcp_iface_name, namespace))
        if dhcp_enabled:
            self.assertEqual(self._DHCP_PORT_MAC_ADDRESS, dev.link.address)

    def _plug_port_for_dhcp_request(self, network, port):
        namespace = network.namespace
        vif_name = self.get_interface_name(network.id, port)

        self.ovs_driver.plug(network.id,
                             port.id,
                             vif_name,
                             port.mac_address,
                             self.conf.OVS.integration_bridge,
                             namespace=namespace)

    def _ip_list_for_vif(self, vif_name, namespace):
        ip_device = ip_lib.IPDevice(vif_name, namespace)
        return ip_device.addr.list(ip_version=lib_const.IP_VERSION_4)

    def _get_network_port_for_allocation_test(self):
        network = self.network_dict_for_dhcp()
        ip_addr = netaddr.IPNetwork(network.subnets[0].cidr)[1]
        port = self.create_port_dict(network.id,
                                     network.subnets[0].id,
                                     mac_address=str(
                                         self._TENANT_PORT_MAC_ADDRESS),
                                     ip_address=str(ip_addr))
        return network, port

    def assert_good_allocation_for_port(self, network, port):
        vif_name = self.get_interface_name(network.id, port)
        self._run_dhclient(vif_name, network)

        predicate = lambda: len(
            self._ip_list_for_vif(vif_name, network.namespace))
        common_utils.wait_until_true(predicate, 10)

        ip_list = self._ip_list_for_vif(vif_name, network.namespace)
        cidr = ip_list[0].get('cidr')
        ip_addr = str(netaddr.IPNetwork(cidr).ip)
        self.assertEqual(port.fixed_ips[0].ip_address, ip_addr)

    def assert_bad_allocation_for_port(self, network, port):
        vif_name = self.get_interface_name(network.id, port)
        self._run_dhclient(vif_name, network)
        # we need wait some time (10 seconds is enough) and check
        # that dhclient not configured ip-address for interface
        eventlet.sleep(10)

        ip_list = self._ip_list_for_vif(vif_name, network.namespace)
        self.assertEqual([], ip_list)

    def _run_dhclient(self, vif_name, network):
        # NOTE: Before run dhclient we should create resolv.conf file
        # in namespace,  where we will run dhclient for testing address
        # allocation for port, otherwise, dhclient will override
        # system /etc/resolv.conf
        # By default, folder for dhcp-agent's namespace doesn't exist
        # that's why we use AdminDirFixture for create directory
        # with admin permissions in /etc/netns/ and touch resolv.conf in it.
        etc_dir = '/etc/netns/%s' % network.namespace
        self.useFixture(helpers.AdminDirFixture(etc_dir))
        cmd = ['touch', os.path.join(etc_dir, 'resolv.conf')]
        utils.execute(cmd, run_as_root=True)
        dhclient_cmd = ['dhclient', '--no-pid', '-d', '-1', vif_name]
        proc = net_helpers.RootHelperProcess(cmd=dhclient_cmd,
                                             namespace=network.namespace)
        self.addCleanup(proc.wait)
        self.addCleanup(proc.kill)

    def _get_metadata_proxy_process(self, network):
        return external_process.ProcessManager(
            self.conf,
            network.id,
            network.namespace,
            service=metadata_driver.HAPROXY_SERVICE)
Пример #20
0
def test_macs():
    instance = HostBase()
    assert instance._is_unicast(int(netaddr.EUI('0e:00:00:00:00:01'))) == True
    assert instance._is_unicast(int(netaddr.EUI('ff:ff:ff:ff:ff:ff'))) == False
Пример #21
0
def get_ipv6_lladdr(mac_addr):
    return '%s/64' % netaddr.EUI(mac_addr).ipv6_link_local()
Пример #22
0
def check_mac(argument: str, mac: Any) -> netaddr.EUI:
    try:
        return netaddr.EUI(mac)
    except (netaddr.AddrFormatError, TypeError) as e:
        raise ArgumentError(argument, "Invalid MAC address: "
                            "{}".format(mac)) from e
Пример #23
0
def router_append_subnet(router,
                         count=1,
                         ip_version=4,
                         ipv6_subnet_modes=None,
                         interface_id=None,
                         dns_nameservers=None,
                         network_mtu=0):
    if ip_version == 6:
        subnet_mode_none = {'ra_mode': None, 'address_mode': None}
        if not ipv6_subnet_modes:
            ipv6_subnet_modes = [subnet_mode_none] * count
        elif len(ipv6_subnet_modes) != count:
            ipv6_subnet_modes.extend([
                subnet_mode_none
                for i in moves.range(len(ipv6_subnet_modes), count)
            ])

    if ip_version == 4:
        ip_pool = '35.4.%i.4'
        cidr_pool = '35.4.%i.0/24'
        prefixlen = 24
        gw_pool = '35.4.%i.1'
    elif ip_version == 6:
        ip_pool = 'fd01:%x::6'
        cidr_pool = 'fd01:%x::/64'
        prefixlen = 64
        gw_pool = 'fd01:%x::1'
    else:
        raise ValueError("Invalid ip_version: %s" % ip_version)

    interfaces = copy.deepcopy(router.get(l3_constants.INTERFACE_KEY, []))
    if interface_id:
        try:
            interface = next(i for i in interfaces if i['id'] == interface_id)
        except StopIteration:
            raise ValueError("interface_id not found")

        fixed_ips, subnets = interface['fixed_ips'], interface['subnets']
    else:
        interface = None
        fixed_ips, subnets = [], []

    num_existing_subnets = len(subnets)
    for i in moves.range(count):
        subnet_id = _uuid()
        fixed_ips.append({
            'ip_address': ip_pool % (i + num_existing_subnets),
            'subnet_id': subnet_id,
            'prefixlen': prefixlen
        })
        subnets.append({
            'id':
            subnet_id,
            'cidr':
            cidr_pool % (i + num_existing_subnets),
            'gateway_ip':
            gw_pool % (i + num_existing_subnets),
            'dns_nameservers':
            dns_nameservers,
            'ipv6_ra_mode':
            ipv6_subnet_modes[i]['ra_mode'],
            'ipv6_address_mode':
            ipv6_subnet_modes[i]['address_mode']
        })

    if interface:
        # Update old interface
        index = interfaces.index(interface)
        interfaces[index].update({'fixed_ips': fixed_ips, 'subnets': subnets})
    else:
        # New interface appended to interfaces list
        mac_address = netaddr.EUI('ca:fe:de:ad:be:ef')
        mac_address.dialect = netaddr.mac_unix
        interfaces.append({
            'id': _uuid(),
            'mtu': network_mtu,
            'network_id': _uuid(),
            'admin_state_up': True,
            'mac_address': str(mac_address),
            'fixed_ips': fixed_ips,
            'subnets': subnets
        })

    router[l3_constants.INTERFACE_KEY] = interfaces
Пример #24
0
def router_append_interface(router, count=1,
                            ip_version=lib_constants.IP_VERSION_4,
                            ra_mode=None, addr_mode=None, dual_stack=False,
                            same_port=False):
    interfaces = router[lib_constants.INTERFACE_KEY]
    current = sum(
        [netaddr.IPNetwork(subnet['cidr']).version == ip_version
         for p in interfaces for subnet in p['subnets']])

    # If dual_stack=True, create IPv4 and IPv6 subnets on each port
    # If same_port=True, create ip_version number of subnets on a single port
    # Else create just an ip_version subnet on each port
    if dual_stack:
        ip_versions = [lib_constants.IP_VERSION_4, lib_constants.IP_VERSION_6]
    elif same_port:
        ip_versions = [ip_version] * count
        count = 1
    else:
        ip_versions = [ip_version]

    mac_address = netaddr.EUI('ca:fe:de:ad:be:ef')
    mac_address.dialect = netaddr.mac_unix
    for i in range(current, current + count):
        fixed_ips = []
        subnets = []
        for loop_version in ip_versions:
            if (loop_version == lib_constants.IP_VERSION_4 and
                    (ip_version == lib_constants.IP_VERSION_4 or dual_stack)):
                ip_pool = '35.4.%i.4'
                cidr_pool = '35.4.%i.0/24'
                prefixlen = 24
                gw_pool = '35.4.%i.1'
            elif (loop_version == lib_constants.IP_VERSION_6 and
                    (ip_version == lib_constants.IP_VERSION_6 or dual_stack)):
                ip_pool = 'fd01:%x:1::6'
                cidr_pool = 'fd01:%x:1::/64'
                prefixlen = 64
                gw_pool = 'fd01:%x:1::1'
            else:
                continue
            subnet_id = _uuid()
            fixed_ips.append({'ip_address': ip_pool % i,
                              'subnet_id': subnet_id,
                              'prefixlen': prefixlen})
            subnets.append({'id': subnet_id,
                            'cidr': cidr_pool % i,
                            'gateway_ip': gw_pool % i,
                            'ipv6_ra_mode': ra_mode,
                            'ipv6_address_mode': addr_mode})
        if not fixed_ips:
            raise ValueError("Invalid ip_version: %s" % ip_version)

        interfaces.append(
            {'id': _uuid(),
             'mtu': 1500,
             'network_id': _uuid(),
             'admin_state_up': True,
             'fixed_ips': fixed_ips,
             'mac_address': str(mac_address),
             'subnets': subnets})
        mac_address.value += 1
Пример #25
0
 def get_device_details(self, context, device, agent_id, host=None):
     port_obj = self.remote_resource_cache.get_resource_by_id(
         resources.PORT, device)
     if not port_obj:
         LOG.debug("Device %s does not exist in cache.", device)
         return {'device': device}
     if not port_obj.binding_levels:
         LOG.warning("Device %s is not bound.", port_obj)
         return {'device': device}
     segment = port_obj.binding_levels[-1].segment
     if not segment:
         LOG.debug("Device %s is not bound to any segment.", port_obj)
         return {'device': device}
     binding = utils.get_port_binding_by_status_and_host(
         port_obj.bindings,
         constants.ACTIVE,
         raise_if_not_found=True,
         port_id=port_obj.id)
     if (port_obj.device_owner.startswith(
             constants.DEVICE_OWNER_COMPUTE_PREFIX)
             and binding[pb_ext.HOST] != host):
         LOG.debug("Device %s has no active binding in this host", port_obj)
         return {'device': device, n_const.NO_ACTIVE_BINDING: True}
     net = self.remote_resource_cache.get_resource_by_id(
         resources.NETWORK, port_obj.network_id)
     net_qos_policy_id = net.qos_policy_id
     # match format of old RPC interface
     mac_addr = str(
         netaddr.EUI(str(port_obj.mac_address),
                     dialect=netaddr.mac_unix_expanded))
     entry = {
         'device':
         device,
         'network_id':
         port_obj.network_id,
         'port_id':
         port_obj.id,
         'mac_address':
         mac_addr,
         'admin_state_up':
         port_obj.admin_state_up,
         'network_type':
         segment.network_type,
         'segmentation_id':
         segment.segmentation_id,
         'physical_network':
         segment.physical_network,
         'fixed_ips': [{
             'subnet_id': o.subnet_id,
             'ip_address': str(o.ip_address)
         } for o in port_obj.fixed_ips],
         'device_owner':
         port_obj.device_owner,
         'allowed_address_pairs': [{
             'mac_address': o.mac_address,
             'ip_address': o.ip_address
         } for o in port_obj.allowed_address_pairs],
         'port_security_enabled':
         getattr(port_obj.security, 'port_security_enabled', True),
         'qos_policy_id':
         port_obj.qos_policy_id,
         'network_qos_policy_id':
         net_qos_policy_id,
         'profile':
         binding.profile,
         'security_groups':
         list(port_obj.security_group_ids)
     }
     LOG.debug("Returning: %s", entry)
     return entry
Пример #26
0
#
# @author: Edouard Thuleau, Cloudwatt.

from builtins import str
import mock
import netaddr
import requests
import unittest
import uuid

from opencontrail_vrouter_netns.vrouter_netns import NetnsManager

NIC1_UUID = str(uuid.uuid4())
NIC1 = {
    'uuid': NIC1_UUID,
    'mac': netaddr.EUI('00:11:22:33:44:55'),
    'ip': netaddr.IPNetwork('172.16.0.12/24')
}

NIC2_UUID = str(uuid.uuid4())
NIC2 = {
    'uuid': NIC2_UUID,
    'mac': netaddr.EUI('66:77:88:99:aa:bb'),
    'ip': netaddr.IPNetwork('80.0.0.123/29')
}


class NetnsManagerTest(unittest.TestCase):
    def setUp(self):
        self.ip_cls_p = mock.patch('opencontrail_vrouter_netns.linux.ip_lib.'
                                   'IPWrapper')
Пример #27
0
    def _prepare_flows(self,
                       operation,
                       switch_name,
                       port1,
                       port2,
                       traffic=None):
        """Prepare flows for add_connection, del_connection and validate methods
           It returns a list of flows based on given parameters.
        """
        flows = []
        if operation == 'add':
            bridge = self._switches[switch_name]
            flow = self._flow_template.copy()
            actions = [
                action.format(bridge.get_ports()[port2][0])
                for action in self._flow_actions
            ]
            flow.update({
                'in_port': bridge.get_ports()[port1][0],
                'actions': actions
            })
            # check if stream specific connection(s) should be crated for multistream feature
            if traffic and traffic['pre_installed_flows'].lower() == 'yes':
                for stream in range(traffic['multistream']):
                    tmp_flow = flow.copy()
                    # update flow based on trafficgen settings
                    if traffic['stream_type'] == 'L2':
                        dst_mac_value = netaddr.EUI(
                            traffic['l2']['dstmac']).value
                        tmp_mac = netaddr.EUI(dst_mac_value + stream)
                        tmp_mac.dialect = netaddr.mac_unix_expanded
                        tmp_flow.update({'dl_dst': tmp_mac})
                    elif traffic['stream_type'] == 'L3':
                        dst_ip_value = netaddr.IPAddress(
                            traffic['l3']['dstip']).value
                        tmp_ip = netaddr.IPAddress(dst_ip_value + stream)
                        tmp_flow.update({
                            'dl_type': '0x0800',
                            'nw_dst': tmp_ip
                        })
                    elif traffic['stream_type'] == 'L4':
                        tmp_flow.update({
                            'dl_type':
                            '0x0800',
                            'nw_proto':
                            socket.getprotobyname(
                                traffic['l3']['proto'].lower()),
                            'tp_dst':
                            (traffic['l4']['dstport'] + stream) % 65536
                        })
                    flows.append(tmp_flow)
            elif traffic and traffic['flow_type'].lower() == 'ip':
                flow.update({
                    'dl_type': '0x0800',
                    'nw_src': traffic['l3']['srcip'],
                    'nw_dst': traffic['l3']['dstip']
                })
                flows.append(flow)
            else:
                flows.append(flow)
        elif operation == 'del' and port1:
            bridge = self._switches[switch_name]
            flows.append({'in_port': bridge.get_ports()[port1][0]})
        else:
            flows.append({})

        return flows
Пример #28
0
 def parse_value(self, value):
     if value is not None:
         return netaddr.EUI(value, dialect=netaddr.mac_unix_expanded)
Пример #29
0
    def setup(self):
        """ Sets up the switch for PXP
        """
        self._logger.debug('Setup using %s', str(self._vswitch_class))

        try:
            self._vswitch.start()

            self._vswitch.add_switch(self._bridge)

            # create physical ports
            (phy1, _) = self._vswitch.add_phy_port(self._bridge)
            (phy2, _) = self._vswitch.add_phy_port(self._bridge)

            # create VM ports
            # initialize vport array to requested number of VMs
            guest_nics = settings.getValue('GUEST_NICS_NR')
            vm_ports = [[] for _ in range(self._pxp_vm_count)]
            # create as many VM ports as requested by configuration, but configure
            # only even number of NICs or just one
            for vmindex in range(self._pxp_vm_count):
                # just for case, enforce even number of NICs or 1
                nics_nr = int(guest_nics[vmindex] /
                              2) * 2 if guest_nics[vmindex] > 1 else 1
                self._logger.debug('Create %s vports for %s. VM with index %s',
                                   nics_nr, vmindex + 1, vmindex)
                for _ in range(nics_nr):
                    (vport, _) = self._vswitch.add_vport(self._bridge)
                    vm_ports[vmindex].append(vport)

            # configure connections according to the TC definition
            if self._pxp_topology == 'serial':
                # NOTE: all traffic from VMs is sent to other ports directly
                # without applying traffic options to avoid issues with MAC swapping
                # and upper layer mods performed inside guests

                # insert connections for phy ports first
                # from 1st PHY to 1st vport of 1st VM
                self._vswitch.add_connection(self._bridge, phy1,
                                             vm_ports[0][0], self._traffic)
                self._vswitch.add_connection(self._bridge, vm_ports[0][0],
                                             phy1)
                # from last vport of last VM to 2nd phy
                self._vswitch.add_connection(
                    self._bridge, vm_ports[self._pxp_vm_count - 1][-1], phy2)
                self._vswitch.add_connection(
                    self._bridge, phy2, vm_ports[self._pxp_vm_count - 1][-1],
                    self._traffic)

                # add serial connections among VMs and VM NICs pairs if needed
                # in case of multiple NICs pairs per VM, the pairs are chained
                # first, before connection to the next VM is created
                for vmindex in range(self._pxp_vm_count):
                    # connect VMs NICs pairs in case of 4 and more NICs per VM
                    connections = [
                        (vm_ports[vmindex][2 * (x + 1) - 1],
                         vm_ports[vmindex][2 * (x + 1)])
                        for x in range(int(len(vm_ports[vmindex]) / 2) - 1)
                    ]
                    for connection in connections:
                        self._vswitch.add_connection(self._bridge,
                                                     connection[0],
                                                     connection[1])
                        self._vswitch.add_connection(self._bridge,
                                                     connection[1],
                                                     connection[0])
                    # connect last NICs to the next VM if there is any
                    if self._pxp_vm_count > vmindex + 1:
                        self._vswitch.add_connection(self._bridge,
                                                     vm_ports[vmindex][-1],
                                                     vm_ports[vmindex + 1][0])
                        self._vswitch.add_connection(self._bridge,
                                                     vm_ports[vmindex + 1][0],
                                                     vm_ports[vmindex][-1])
            else:
                mac_value = netaddr.EUI(self._traffic['l2']['dstmac']).value
                ip_value = netaddr.IPAddress(
                    self._traffic['l3']['dstip']).value
                port_value = self._traffic['l4']['dstport']
                # initialize stream index; every NIC pair of every VM uses unique stream
                stream = 0
                for vmindex in range(self._pxp_vm_count):
                    # iterate through all VMs NIC pairs...
                    if len(vm_ports[vmindex]) > 1:
                        port_pairs = [
                            (vm_ports[vmindex][2 * x],
                             vm_ports[vmindex][2 * x + 1])
                            for x in range(int(len(vm_ports[vmindex]) / 2))
                        ]
                    else:
                        # ...or connect VM with just one NIC to both phy ports
                        port_pairs = [(vm_ports[vmindex][0],
                                       vm_ports[vmindex][0])]

                    for port_pair in port_pairs:
                        # override traffic options to ensure, that traffic is
                        # dispatched among VMs connected in parallel
                        options = {
                            'multistream': 1,
                            'stream_type': self._traffic['stream_type'],
                            'pre_installed_flows': 'Yes'
                        }
                        # update connection based on trafficgen settings
                        if self._traffic['stream_type'] == 'L2':
                            tmp_mac = netaddr.EUI(mac_value + stream)
                            tmp_mac.dialect = netaddr.mac_unix_expanded
                            options.update({'l2': {'dstmac': tmp_mac}})
                        elif self._traffic['stream_type'] == 'L3':
                            tmp_ip = netaddr.IPAddress(ip_value + stream)
                            options.update({'l3': {'dstip': tmp_ip}})
                        elif self._traffic['stream_type'] == 'L4':
                            options.update({
                                'l3': {
                                    'proto': self._traffic['l3']['proto']
                                }
                            })
                            options.update({
                                'l4': {
                                    'dstport': (port_value + stream) % 65536
                                }
                            })
                        else:
                            raise RuntimeError('Unknown stream_type {}'.format(
                                self._traffic['stream_type']))

                        # insert connection to dispatch traffic from physical ports
                        # to VMs based on stream type; all traffic from VMs is
                        # sent to physical ports to avoid issues with MAC swapping
                        # and upper layer mods performed inside guests
                        self._vswitch.add_connection(self._bridge, phy1,
                                                     port_pair[0], options)
                        self._vswitch.add_connection(self._bridge,
                                                     port_pair[1], phy2)
                        self._vswitch.add_connection(self._bridge, phy2,
                                                     port_pair[1], options)
                        self._vswitch.add_connection(self._bridge,
                                                     port_pair[0], phy1)

                        # every NIC pair needs its own unique traffic stream
                        stream += 1

        except:
            self._vswitch.stop()
            raise
Пример #30
0
 def process_result_value(self, value, dialect):
     return netaddr.EUI(value)