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)
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)
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
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
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
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()
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)
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
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)
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
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
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)
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)
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)
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]])
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)
def get_random_EUI(): return netaddr.EUI(net.get_random_mac(['fe', '16', '3e', '00', '00', '00']))
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)
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)
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
def get_ipv6_lladdr(mac_addr): return '%s/64' % netaddr.EUI(mac_addr).ipv6_link_local()
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
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
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
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
# # @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')
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
def parse_value(self, value): if value is not None: return netaddr.EUI(value, dialect=netaddr.mac_unix_expanded)
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
def process_result_value(self, value, dialect): return netaddr.EUI(value)