def configure_network(self): if self.config.get('network.autoconfigure'): # Try DHCP on each interface until we find lease. Mark failed ones as disabled. self.logger.warn('Network in autoconfiguration mode') for i in list(netif.list_interfaces().values()): entity = self.datastore.get_by_id('network.interfaces', i.name) if i.type == netif.InterfaceType.LOOP: continue if i.name in ('mgmt0', 'nat0'): continue if i.name.startswith(('brg', 'tap')): continue msg = 'Trying to acquire DHCP lease on interface {0}...'.format(i.name) self.logger.info(msg) push_status(msg) i.up() if self.context.configure_dhcp(i.name, True, INITIAL_DHCP_TIMEOUT): entity.update({ 'enabled': True, 'dhcp': True }) self.datastore.update('network.interfaces', entity['id'], entity) self.config.set('network.autoconfigure', False) self.logger.info('Successfully configured interface {0}'.format(i.name)) return else: i.down() self.config.set('network.autoconfigure', False) yield errno.ENOENT, 'Failed to configure any network interface' return for i in self.datastore.query('network.interfaces', sort='cloned'): msg = 'Configuring interface {0}...'.format(i['id']) self.logger.info(msg) push_status(msg) try: yield from self.configure_interface(i['id'], False) except BaseException as e: self.logger.warning('Cannot configure {0}: {1}'.format(i['id'], str(e)), exc_info=True) # Are there any orphaned interfaces? for name, iface in list(netif.list_interfaces().items()): if not name.startswith(('vlan', 'lagg', 'bridge')): continue if not self.datastore.exists('network.interfaces', ('id', '=', name)): netif.destroy_interface(name) yield from self.configure_routes() yield from self.configure_dns() self.client.call_sync('service.restart', 'rtsold', timeout=300) self.client.emit_event('network.changed', { 'operation': 'update' })
def configure_network(self): if self.config.get('network.autoconfigure'): # Try DHCP on each interface until we find lease. Mark failed ones as disabled. self.logger.warn('Network in autoconfiguration mode') for i in list(netif.list_interfaces().values()): entity = self.datastore.get_by_id('network.interfaces', i.name) if i.type == netif.InterfaceType.LOOP: continue if i.name in ('mgmt0', 'nat0'): continue if i.name.startswith(('brg', 'tap')): continue self.logger.info('Trying to acquire DHCP lease on interface {0}...'.format(i.name)) i.up() if self.context.configure_dhcp(i.name, True, INITIAL_DHCP_TIMEOUT): entity.update({ 'enabled': True, 'dhcp': True }) self.datastore.update('network.interfaces', entity['id'], entity) self.config.set('network.autoconfigure', False) self.logger.info('Successfully configured interface {0}'.format(i.name)) return else: i.down() self.config.set('network.autoconfigure', False) yield errno.ENOENT, 'Failed to configure any network interface' return for i in self.datastore.query('network.interfaces', sort='cloned'): self.logger.info('Configuring interface {0}...'.format(i['id'])) try: yield from self.configure_interface(i['id'], False) except BaseException as e: self.logger.warning('Cannot configure {0}: {1}'.format(i['id'], str(e)), exc_info=True) # Are there any orphaned interfaces? for name, iface in list(netif.list_interfaces().items()): if not name.startswith(('vlan', 'lagg', 'bridge')): continue if not self.datastore.exists('network.interfaces', ('id', '=', name)): netif.destroy_interface(name) yield from self.configure_routes() yield from self.configure_dns() self.client.call_sync('service.restart', 'rtsold', timeout=300) self.client.emit_event('network.changed', { 'operation': 'update' })
def up(self): # Destroy old bridge (if exists) try: netif.destroy_interface(self.ifname) except OSError as err: if err.errno != errno.ENXIO: raise RuntimeError('Cannot destroy {0}: {1}'.format(self.ifname, str(err))) # Setup bridge self.bridge_if = netif.get_interface(netif.create_interface('bridge')) self.bridge_if.rename(self.ifname) self.bridge_if.description = 'containerd management network' self.bridge_if.add_address(netif.InterfaceAddress( netif.AddressFamily.INET, self.subnet )) self.bridge_if.up() self.dhcp_server.server_name = 'FreeNAS' self.dhcp_server.on_request = self.dhcp_request self.dhcp_server.start(self.ifname, self.subnet.ip) self.dhcp_server_thread = gevent.spawn(self.dhcp_worker)
def sync(self): """ Sync interfaces configured in database to the OS. """ interfaces = [i['int_interface'] for i in self.middleware.call('datastore.query', 'network.interfaces')] cloned_interfaces = [] # First of all we need to create the virtual interfaces # LAGG comes first and then VLAN laggs = self.middleware.call('datastore.query', 'network.lagginterface') for lagg in laggs: name = lagg['lagg_interface']['int_name'] cloned_interfaces.append(name) self.logger.info('Setting up {}'.format(name)) try: iface = netif.get_interface(name) except KeyError: netif.create_interface(name) iface = netif.get_interface(name) if lagg['lagg_protocol'] == 'fec': protocol = netif.AggregationProtocol.ETHERCHANNEL else: protocol = getattr(netif.AggregationProtocol, lagg['lagg_protocol'].upper()) if iface.protocol != protocol: self.logger.info('{}: changing protocol to {}'.format(name, protocol)) iface.protocol = protocol members_configured = set(p[0] for p in iface.ports) members_database = set() for member in self.middleware.call('datastore.query', 'network.lagginterfacemembers', [('lagg_interfacegroup_id', '=', lagg['id'])]): members_database.add(member['lagg_physnic']) # Remeve member configured but not in database for member in (members_configured - members_database): iface.delete_port(member) # Add member in database but not configured for member in (members_database - members_configured): iface.add_port(member) for port in iface.ports: try: port_iface = netif.get_interface(port[0]) except KeyError: self.logger.warn('Could not find {} from {}'.format(port[0], name)) continue port_iface.up() vlans = self.middleware.call('datastore.query', 'network.vlan') for vlan in vlans: cloned_interfaces.append(vlan['vlan_vint']) self.logger.info('Setting up {}'.format(vlan['vlan_vint'])) try: iface = netif.get_interface(vlan['vlan_vint']) except KeyError: netif.create_interface(vlan['vlan_vint']) iface = netif.get_interface(vlan['vlan_vint']) if iface.parent != vlan['vlan_pint'] or iface.tag != vlan['vlan_tag']: iface.unconfigure() iface.configure(vlan['vlan_pint'], vlan['vlan_tag']) try: parent_iface = netif.get_interface(iface.parent) except KeyError: self.logger.warn('Could not find {} from {}'.format(iface.parent, vlan['vlan_vint'])) continue parent_iface.up() self.logger.info('Interfaces in database: {}'.format(', '.join(interfaces) or 'NONE')) for interface in interfaces: try: self.sync_interface(interface) except: self.logger.error('Failed to configure {}'.format(interface), exc_info=True) internal_interfaces = ['lo', 'pflog', 'pfsync', 'tun', 'tap'] if not self.middleware.call('system.is_freenas'): internal_interfaces.extend(self.middleware.call('notifier.failover_internal_interfaces') or []) internal_interfaces = tuple(internal_interfaces) # Destroy interfaces which are not in database for name, iface in list(netif.list_interfaces().items()): # Skip internal interfaces if name.startswith(internal_interfaces): continue # Skip interfaces in database if name in interfaces: continue # Interface not in database lose addresses for address in iface.addresses: iface.remove_address(address) # Kill dhclient if its running for this interface dhclient_running, dhclient_pid = dhclient_status(name) if dhclient_running: os.kill(dhclient_pid, signal.SIGTERM) # If we have vlan or lagg not in the database at all # It gets destroy, otherwise just bring it down if name not in cloned_interfaces and name.startswith(('lagg', 'vlan')): netif.destroy_interface(name) else: iface.down()
def cleanup_tap(self, iface): iface.down() netif.destroy_interface(iface.name)
def run(self): args = [ 'bhyve', '-A', '-P', '-H', '-c', str(self.vm['vcpus']), '-m', str(self.vm['memory']), '-s', '0:0,hostbridge', '-s', '31,lpc', '-l', 'com1,/dev/nmdm{}A'.format(self.vm['id']), ] if self.vm['bootloader'] in ('UEFI', 'UEFI_CSM'): args += [ '-l', 'bootrom,/usr/local/share/uefi-firmware/BHYVE_UEFI{}.fd'.format('_CSM' if self.vm['bootloader'] == 'UEFI_CSM' else ''), ] nid = Nid(3) for device in self.vm['devices']: if device['dtype'] == 'DISK': if device['attributes'].get('mode') == 'AHCI': args += ['-s', '{},ahci-hd,{}'.format(nid(), device['attributes']['path'])] else: args += ['-s', '{},virtio-blk,{}'.format(nid(), device['attributes']['path'])] elif device['dtype'] == 'CDROM': args += ['-s', '{},ahci-cd,{}'.format(nid(), device['attributes']['path'])] elif device['dtype'] == 'NIC': tapname = netif.create_interface('tap') tap = netif.get_interface(tapname) tap.up() self.taps.append(tapname) # If Bridge if True: bridge = None for name, iface in netif.list_interfaces().items(): if name.startswith('bridge'): bridge = iface break if not bridge: bridge = netif.get_interface(netif.create_interface('bridge')) bridge.add_member(tapname) defiface = Popen("route -nv show default|grep -w interface|awk '{ print $2 }'", stdout=subprocess.PIPE, shell=True).communicate()[0].strip() if defiface and defiface not in bridge.members: bridge.add_member(defiface) bridge.up() if device['attributes'].get('type') == 'VIRTIO': nictype = 'virtio-net' else: nictype = 'e1000' args += ['-s', '{},{},{}'.format(nid(), nictype, tapname)] elif device['dtype'] == 'VNC': if device['attributes'].get('wait'): wait = 'wait' else: wait = '' args += [ '-s', '29,fbuf,tcp=0.0.0.0:{},w=1024,h=768,{}'.format(5900 + self.vm['id'], wait), '-s', '30,xhci,tablet', ] args.append(self.vm['name']) self.logger.debug('Starting bhyve: {}'.format(' '.join(args))) self.proc = Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) for line in self.proc.stdout: self.logger.debug('{}: {}'.format(self.vm['name'], line)) self.proc.wait() self.logger.info('Destroying {}'.format(self.vm['name'])) Popen(['bhyvectl', '--destroy', '--vm={}'.format(self.vm['name'])], stdout=subprocess.PIPE, stderr=subprocess.PIPE).wait() while self.taps: netif.destroy_interface(self.taps.pop()) self.manager._vm.pop(self.vm['id'], None)
def destroy_tap(self): while self.taps: netif.destroy_interface(self.taps.pop())
def sync(self): """ Sync interfaces configured in database to the OS. """ interfaces = [ i['int_interface'] for i in self.middleware.call( 'datastore.query', 'network.interfaces') ] cloned_interfaces = [] parent_interfaces = [] # First of all we need to create the virtual interfaces # LAGG comes first and then VLAN laggs = self.middleware.call('datastore.query', 'network.lagginterface') for lagg in laggs: name = lagg['lagg_interface']['int_interface'] cloned_interfaces.append(name) self.logger.info('Setting up {}'.format(name)) try: iface = netif.get_interface(name) except KeyError: netif.create_interface(name) iface = netif.get_interface(name) if lagg['lagg_protocol'] == 'fec': protocol = netif.AggregationProtocol.ETHERCHANNEL else: protocol = getattr(netif.AggregationProtocol, lagg['lagg_protocol'].upper()) if iface.protocol != protocol: self.logger.info('{}: changing protocol to {}'.format( name, protocol)) iface.protocol = protocol members_configured = set(p[0] for p in iface.ports) members_database = set() for member in self.middleware.call( 'datastore.query', 'network.lagginterfacemembers', [('lagg_interfacegroup_id', '=', lagg['id'])]): members_database.add(member['lagg_physnic']) # Remeve member configured but not in database for member in (members_configured - members_database): iface.delete_port(member) # Add member in database but not configured for member in (members_database - members_configured): iface.add_port(member) for port in iface.ports: try: port_iface = netif.get_interface(port[0]) except KeyError: self.logger.warn('Could not find {} from {}'.format( port[0], name)) continue parent_interfaces.append(port[0]) port_iface.up() vlans = self.middleware.call('datastore.query', 'network.vlan') for vlan in vlans: cloned_interfaces.append(vlan['vlan_vint']) self.logger.info('Setting up {}'.format(vlan['vlan_vint'])) try: iface = netif.get_interface(vlan['vlan_vint']) except KeyError: netif.create_interface(vlan['vlan_vint']) iface = netif.get_interface(vlan['vlan_vint']) if iface.parent != vlan['vlan_pint'] or iface.tag != vlan[ 'vlan_tag']: iface.unconfigure() iface.configure(vlan['vlan_pint'], vlan['vlan_tag']) try: parent_iface = netif.get_interface(iface.parent) except KeyError: self.logger.warn('Could not find {} from {}'.format( iface.parent, vlan['vlan_vint'])) continue parent_interfaces.append(iface.parent) parent_iface.up() self.logger.info('Interfaces in database: {}'.format( ', '.join(interfaces) or 'NONE')) for interface in interfaces: try: self.sync_interface(interface) except: self.logger.error('Failed to configure {}'.format(interface), exc_info=True) internal_interfaces = [ 'lo', 'pflog', 'pfsync', 'tun', 'tap', 'bridge', 'epair' ] if not self.middleware.call('system.is_freenas'): internal_interfaces.extend( self.middleware.call('notifier.failover_internal_interfaces') or []) internal_interfaces = tuple(internal_interfaces) # Destroy interfaces which are not in database for name, iface in list(netif.list_interfaces().items()): # Skip internal interfaces if name.startswith(internal_interfaces): continue # Skip interfaces in database if name in interfaces: continue # Interface not in database lose addresses for address in iface.addresses: iface.remove_address(address) # Kill dhclient if its running for this interface dhclient_running, dhclient_pid = dhclient_status(name) if dhclient_running: os.kill(dhclient_pid, signal.SIGTERM) # If we have vlan or lagg not in the database at all # It gets destroy, otherwise just bring it down if name not in cloned_interfaces and name.startswith( ('lagg', 'vlan')): netif.destroy_interface(name) elif name not in parent_interfaces: iface.down()
async def sync(self): """ Sync interfaces configured in database to the OS. """ interfaces = [ i['int_interface'] for i in (await self.middleware.call( 'datastore.query', 'network.interfaces')) ] cloned_interfaces = [] parent_interfaces = [] # First of all we need to create the virtual interfaces # LAGG comes first and then VLAN laggs = await self.middleware.call('datastore.query', 'network.lagginterface') for lagg in laggs: name = lagg['lagg_interface']['int_interface'] cloned_interfaces.append(name) self.logger.info('Setting up {}'.format(name)) try: iface = netif.get_interface(name) except KeyError: netif.create_interface(name) iface = netif.get_interface(name) protocol = getattr(netif.AggregationProtocol, lagg['lagg_protocol'].upper()) if iface.protocol != protocol: self.logger.info('{}: changing protocol to {}'.format( name, protocol)) iface.protocol = protocol members_database = set() members_configured = set(p[0] for p in iface.ports) members_changes = [] # In case there are MTU changes we need to use the lowest MTU between # all members and use that. lower_mtu = None for member in (await self.middleware.call( 'datastore.query', 'network.lagginterfacemembers', [('lagg_interfacegroup_id', '=', lagg['id'])])): members_database.add(member['lagg_physnic']) try: member_iface = netif.get_interface(member['lagg_physnic']) except KeyError: self.logger.warn('Could not find {} from {}'.format( member['lagg_physnic'], name)) continue # In case there is no MTU in interface options and it is currently # different than the default of 1500, revert it. # If there is MTU and its different set it (using member options). reg_mtu = RE_MTU.search(member['lagg_deviceoptions']) if (reg_mtu and (int(reg_mtu.group(1)) != member_iface.mtu or int(reg_mtu.group(1)) != iface.mtu)) or ( not reg_mtu and (member_iface.mtu != 1500 or iface.mtu != 1500)): if not reg_mtu: if not lower_mtu or lower_mtu > 1500: lower_mtu = 1500 else: reg_mtu = int(reg_mtu.group(1)) if not lower_mtu or lower_mtu > reg_mtu: lower_mtu = reg_mtu members_changes.append((member_iface, member['lagg_physnic'], member['lagg_deviceoptions'])) for member_iface, member_name, member_options in members_changes: # We need to remove interface from LAGG before changing MTU if lower_mtu and member_iface.mtu != lower_mtu and member_name in members_configured: iface.delete_port(member_name) members_configured.remove(member_name) proc = await Popen(['/sbin/ifconfig', member_name] + shlex.split(member_options), stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) err = (await proc.communicate())[1].decode() if err: self.logger.info(f'{member_name}: error applying: {err}') if lower_mtu and member_iface.mtu != lower_mtu: member_iface.mtu = lower_mtu # Remove member configured but not in database for member in (members_configured - members_database): iface.delete_port(member) # Add member in database but not configured for member in (members_database - members_configured): iface.add_port(member) for port in iface.ports: try: port_iface = netif.get_interface(port[0]) except KeyError: self.logger.warn('Could not find {} from {}'.format( port[0], name)) continue parent_interfaces.append(port[0]) port_iface.up() vlans = await self.middleware.call('datastore.query', 'network.vlan') for vlan in vlans: cloned_interfaces.append(vlan['vlan_vint']) self.logger.info('Setting up {}'.format(vlan['vlan_vint'])) try: iface = netif.get_interface(vlan['vlan_vint']) except KeyError: netif.create_interface(vlan['vlan_vint']) iface = netif.get_interface(vlan['vlan_vint']) if iface.parent != vlan['vlan_pint'] or iface.tag != vlan[ 'vlan_tag'] or iface.pcp != vlan['vlan_pcp']: iface.unconfigure() iface.configure(vlan['vlan_pint'], vlan['vlan_tag'], vlan['vlan_pcp']) try: parent_iface = netif.get_interface(iface.parent) except KeyError: self.logger.warn('Could not find {} from {}'.format( iface.parent, vlan['vlan_vint'])) continue parent_interfaces.append(iface.parent) parent_iface.up() self.logger.info('Interfaces in database: {}'.format( ', '.join(interfaces) or 'NONE')) for interface in interfaces: try: await self.sync_interface(interface) except Exception: self.logger.error('Failed to configure {}'.format(interface), exc_info=True) internal_interfaces = [ 'lo', 'pflog', 'pfsync', 'tun', 'tap', 'bridge', 'epair' ] if not await self.middleware.call('system.is_freenas'): internal_interfaces.extend( await self.middleware.call('notifier.failover_internal_interfaces') or []) internal_interfaces = tuple(internal_interfaces) # Destroy interfaces which are not in database for name, iface in list(netif.list_interfaces().items()): # Skip internal interfaces if name.startswith(internal_interfaces): continue # Skip interfaces in database if name in interfaces: continue # Interface not in database lose addresses for address in iface.addresses: iface.remove_address(address) # Kill dhclient if its running for this interface dhclient_running, dhclient_pid = dhclient_status(name) if dhclient_running: os.kill(dhclient_pid, signal.SIGTERM) # If we have vlan or lagg not in the database at all # It gets destroy, otherwise just bring it down if name not in cloned_interfaces and name.startswith( ('lagg', 'vlan')): netif.destroy_interface(name) elif name not in parent_interfaces: iface.down()
async def sync(self): """ Sync interfaces configured in database to the OS. """ interfaces = [i['int_interface'] for i in (await self.middleware.call('datastore.query', 'network.interfaces'))] cloned_interfaces = [] parent_interfaces = [] # First of all we need to create the virtual interfaces # LAGG comes first and then VLAN laggs = await self.middleware.call('datastore.query', 'network.lagginterface') for lagg in laggs: name = lagg['lagg_interface']['int_interface'] cloned_interfaces.append(name) self.logger.info('Setting up {}'.format(name)) try: iface = netif.get_interface(name) except KeyError: netif.create_interface(name) iface = netif.get_interface(name) protocol = getattr(netif.AggregationProtocol, lagg['lagg_protocol'].upper()) if iface.protocol != protocol: self.logger.info('{}: changing protocol to {}'.format(name, protocol)) iface.protocol = protocol members_database = set() members_configured = set(p[0] for p in iface.ports) members_changes = [] # In case there are MTU changes we need to use the lowest MTU between # all members and use that. lower_mtu = None for member in (await self.middleware.call('datastore.query', 'network.lagginterfacemembers', [('lagg_interfacegroup_id', '=', lagg['id'])])): members_database.add(member['lagg_physnic']) try: member_iface = netif.get_interface(member['lagg_physnic']) except KeyError: self.logger.warn('Could not find {} from {}'.format(member['lagg_physnic'], name)) continue # In case there is no MTU in interface options and it is currently # different than the default of 1500, revert it. # If there is MTU and its different set it (using member options). reg_mtu = RE_MTU.search(member['lagg_deviceoptions']) if ( reg_mtu and ( int(reg_mtu.group(1)) != member_iface.mtu or int(reg_mtu.group(1)) != iface.mtu ) ) or (not reg_mtu and (member_iface.mtu != 1500 or iface.mtu != 1500)): if not reg_mtu: if not lower_mtu or lower_mtu > 1500: lower_mtu = 1500 else: reg_mtu = int(reg_mtu.group(1)) if not lower_mtu or lower_mtu > reg_mtu: lower_mtu = reg_mtu members_changes.append((member_iface, member['lagg_physnic'], member['lagg_deviceoptions'])) for member_iface, member_name, member_options in members_changes: # We need to remove interface from LAGG before changing MTU if lower_mtu and member_iface.mtu != lower_mtu and member_name in members_configured: iface.delete_port(member_name) members_configured.remove(member_name) proc = await Popen(['/sbin/ifconfig', member_name] + shlex.split(member_options), stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) err = (await proc.communicate())[1].decode() if err: self.logger.info(f'{member_name}: error applying: {err}') if lower_mtu and member_iface.mtu != lower_mtu: member_iface.mtu = lower_mtu # Remove member configured but not in database for member in (members_configured - members_database): iface.delete_port(member) # Add member in database but not configured for member in (members_database - members_configured): iface.add_port(member) for port in iface.ports: try: port_iface = netif.get_interface(port[0]) except KeyError: self.logger.warn('Could not find {} from {}'.format(port[0], name)) continue parent_interfaces.append(port[0]) port_iface.up() vlans = await self.middleware.call('datastore.query', 'network.vlan') for vlan in vlans: cloned_interfaces.append(vlan['vlan_vint']) self.logger.info('Setting up {}'.format(vlan['vlan_vint'])) try: iface = netif.get_interface(vlan['vlan_vint']) except KeyError: netif.create_interface(vlan['vlan_vint']) iface = netif.get_interface(vlan['vlan_vint']) if iface.parent != vlan['vlan_pint'] or iface.tag != vlan['vlan_tag'] or iface.pcp != vlan['vlan_pcp']: iface.unconfigure() iface.configure(vlan['vlan_pint'], vlan['vlan_tag'], vlan['vlan_pcp']) try: parent_iface = netif.get_interface(iface.parent) except KeyError: self.logger.warn('Could not find {} from {}'.format(iface.parent, vlan['vlan_vint'])) continue parent_interfaces.append(iface.parent) parent_iface.up() self.logger.info('Interfaces in database: {}'.format(', '.join(interfaces) or 'NONE')) for interface in interfaces: try: await self.sync_interface(interface) except Exception: self.logger.error('Failed to configure {}'.format(interface), exc_info=True) internal_interfaces = ['lo', 'pflog', 'pfsync', 'tun', 'tap', 'bridge', 'epair'] if not await self.middleware.call('system.is_freenas'): internal_interfaces.extend(await self.middleware.call('notifier.failover_internal_interfaces') or []) internal_interfaces = tuple(internal_interfaces) # Destroy interfaces which are not in database for name, iface in list(netif.list_interfaces().items()): # Skip internal interfaces if name.startswith(internal_interfaces): continue # Skip interfaces in database if name in interfaces: continue # Interface not in database lose addresses for address in iface.addresses: iface.remove_address(address) # Kill dhclient if its running for this interface dhclient_running, dhclient_pid = dhclient_status(name) if dhclient_running: os.kill(dhclient_pid, signal.SIGTERM) # If we have vlan or lagg not in the database at all # It gets destroy, otherwise just bring it down if name not in cloned_interfaces and name.startswith(('lagg', 'vlan')): netif.destroy_interface(name) elif name not in parent_interfaces: iface.down()
def down(self): self.bridge_if.down() netif.destroy_interface(self.ifname)