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 check_sync(self): alerts = [] for iface in netif.list_interfaces().values(): if not isinstance(iface, netif.LaggInterface): continue active = [] inactive = [] for name, flags in iface.ports: if netif.LaggPortFlags.ACTIVE not in flags: inactive.append(name) else: active.append(name) # ports that are not ACTIVE and LACP if inactive and iface.protocol == netif.AggregationProtocol.LACP: # Only alert if this has happened more than twice, see #24160 self.count[iface.name] += 1 if self.count[iface.name] > 2: alerts.append(Alert( LAGGInactivePortsAlertClass, {"name": iface.name, "ports": ", ".join(inactive)}, )) # For FAILOVER protocol we should have one ACTIVE port elif len(active) != 1 and iface.protocol == netif.AggregationProtocol.FAILOVER: # Only alert if this has happened more than twice, see #24160 self.count[iface.name] += 1 if self.count[iface.name] > 2: alerts.append(Alert( LAGGNoActivePortsAlertClass, {"name": iface.name}, )) else: self.count[iface.name] = 0 return alerts
def my_ips(): for iface in netif.list_interfaces().values(): for addr in iface.addresses: if addr.af == netif.AddressFamily.LINK: continue yield str(addr.address)
async def bridge_setup(self, tapname, tap, attach_iface): if attach_iface is None: # XXX: backward compatibility prior to 11.1-RELEASE. try: attach_iface = netif.RoutingTable( ).default_route_ipv4.interface except: return if_bridge = [] bridge_enabled = False for brgname, iface in list(netif.list_interfaces().items()): if brgname.startswith('bridge'): if_bridge.append(iface) if if_bridge: for bridge in if_bridge: if attach_iface in bridge.members: bridge_enabled = True self.set_tap_mtu(bridge, tap) bridge.add_member(tapname) break if bridge_enabled is False: bridge = netif.get_interface(netif.create_interface('bridge')) self.set_tap_mtu(bridge, tap) bridge.add_member(tapname) bridge.add_member(attach_iface) bridge.up()
def query(self, filters, options): data = [] for name, iface in netif.list_interfaces().items(): if name in ('lo0', 'pfsync0', 'pflog0'): continue data.append(self.iface_extend(iface.__getstate__())) return filter_list(data, filters, options)
async def bridge_setup(self, tapname, tap, attach_iface): if attach_iface is None: # XXX: backward compatibility prior to 11.1-RELEASE. try: attach_iface = netif.RoutingTable().default_route_ipv4.interface except: return if_bridge = [] bridge_enabled = False for brgname, iface in list(netif.list_interfaces().items()): if brgname.startswith('bridge'): if_bridge.append(iface) if if_bridge: for bridge in if_bridge: if attach_iface in bridge.members: bridge_enabled = True self.set_tap_mtu(bridge, tap) bridge.add_member(tapname) break if bridge_enabled is False: bridge = netif.get_interface(netif.create_interface('bridge')) self.set_tap_mtu(bridge, tap) bridge.add_member(tapname) bridge.add_member(attach_iface) bridge.up()
def filter_routes(routes): """ Filter out routes for loopback addresses and local subnets :param routes: routes list :return: filtered routes list """ aliases = [i.addresses for i in list(netif.list_interfaces().values())] aliases = reduce(lambda x, y: x+y, aliases) aliases = [a for a in aliases if a.af == netif.AddressFamily.INET] aliases = [ipaddress.ip_interface('{0}/{1}'.format(a.address, a.netmask)) for a in aliases] for i in routes: if type(i.gateway) is str: continue if i.af != netif.AddressFamily.INET: continue found = True for a in aliases: if i.network in a.network: found = False break if found: yield i
def scan_interfaces(self): self.logger.info('Scanning available network interfaces...') existing = [] # Add newly plugged NICs to DB for i in list(netif.list_interfaces().values()): existing.append(i.name) # We want only physical NICs if i.cloned: continue if i.name in ('mgmt0', 'nat0'): continue if not self.datastore.exists('network.interfaces', ('id', '=', i.name)): self.logger.info('Found new interface {0} ({1})'.format(i.name, i.type.name)) self.datastore.insert('network.interfaces', { 'enabled': False, 'id': i.name, 'type': i.type.name, 'dhcp': False, 'noipv6': False, 'rtadv': False, 'mtu': None, 'media': None, 'aliases': [] }) # Remove unplugged NICs from DB for i in self.datastore.query('network.interfaces', ('id', 'nin', existing), ('cloned', '=', False)): self.datastore.delete('network.interfaces', i['id'])
def run(self): alerts = [] for iface in netif.list_interfaces().values(): if not isinstance(iface, netif.LaggInterface): continue active = [] inactive = [] for name, flags in iface.ports: if netif.LaggPortFlags.ACTIVE not in flags: inactive.append(name) else: active.append(name) # ports that are not ACTIVE and LACP if inactive and iface.protocol == netif.AggregationProtocol.LACP: # Only alert if this has happened more than twice, see #24160 self.__count[iface.name] += 1 if self.__count[iface.name] > 2: alerts.append(Alert( Alert.CRIT, _('These ports are not ACTIVE on LAGG interface %(name)s: %(ports)s. Please check cabling and switch.') % {'name': iface.name, 'ports': ', '.join(inactive)}, )) # For FAILOVER protocol we should have one ACTIVE port elif len(active) != 1 and iface.protocol == netif.AggregationProtocol.FAILOVER: # Only alert if this has happened more than twice, see #24160 self.__count[iface.name] += 1 if self.__count[iface.name] > 2: alerts.append(Alert( Alert.CRIT, _('There are no ACTIVE ports on LAGG interface %(name)s. Please check cabling and switch.') % {'name': iface.name}, )) else: self.__count[iface.name] = 0 return alerts
def run(self): cp_time_last = None cp_times_last = None last_interface_stats = None while not self._cancel.is_set(): data = {} # Virtual memory use data['virtual_memory'] = psutil.virtual_memory()._asdict() data['cpu'] = {} # Get CPU usage % # cp_times has values for all cores cp_times = sysctl.filter('kern.cp_times')[0].value # cp_time is the sum of all cores cp_time = sysctl.filter('kern.cp_time')[0].value if cp_times_last: # Get the difference of times between the last check and the current one # cp_time has a list with user, nice, system, interrupt and idle cp_diff = list(map(lambda x: x[0] - x[1], zip(cp_times, cp_times_last))) cp_nums = int(len(cp_times) / 5) for i in range(cp_nums): data['cpu'][i] = self.get_cpu_usages(cp_diff[i * 5:i * 5 + 5]) cp_diff = list(map(lambda x: x[0] - x[1], zip(cp_time, cp_time_last))) data['cpu']['average'] = self.get_cpu_usages(cp_diff) cp_time_last = cp_time cp_times_last = cp_times # CPU temperature data['cpu']['temperature'] = {} for i in itertools.count(): v = sysctl.filter(f'dev.cpu.{i}.temperature') if not v: break data['cpu']['temperature'][i] = v[0].value # Interface related statistics data['interfaces'] = {} retrieve_stat_keys = ['received_bytes', 'sent_bytes'] for iface in netif.list_interfaces().values(): for addr in filter(lambda addr: addr.af.name.lower() == 'link', iface.addresses): addr_data = addr.__getstate__(stats=True) data['interfaces'][iface.name] = {} for k in retrieve_stat_keys: data['interfaces'][iface.name].update({ k: addr_data['stats'][k], f'{k}_last': addr_data['stats'][k] - ( 0 if not last_interface_stats else last_interface_stats.get(iface.name, {}).get(k, 0) ) }) last_interface_stats = data['interfaces'].copy() self.send_event('ADDED', fields=data) time.sleep(2)
def _get_class_network(self): result = [] for i in netif.list_interfaces().keys(): if i.startswith('lo'): continue desc = get_sysctl(re.sub('(\w+)([0-9]+)', 'dev.\\1.\\2.%desc', i)) result.append({'name': i, 'description': desc}) return result
def get_interface(ipaddress): get_all_ifaces = netif.list_interfaces() ifaces = [] for iface in get_all_ifaces.keys(): all_ip = [a.__getstate__()['address'] for a in netif.get_interface(iface).addresses if a.af == netif.AddressFamily.INET] is_ip_exist = list(set(ipaddress).intersection(all_ip)) if is_ip_exist: ifaces.append(iface) return ifaces
def query_interfaces(self): def extend(name, iface): iface = iface.__getstate__() dhcp = self.context.dhcp_clients.get(name) if dhcp: iface['dhcp'] = dhcp.__getstate__() return iface return {name: extend(name, i) for name, i in netif.list_interfaces().items()}
def _get_class_network(self): result = [] for i in list(netif.list_interfaces().keys()): if i.startswith('lo'): continue desc = get_sysctl(re.sub('(\w+)([0-9]+)', 'dev.\\1.\\2.%desc', i)) result.append({ 'name': i, 'description': desc }) return result
def _get_class_network(self): result = [] for i in list(netif.list_interfaces().keys()): if i.startswith(tuple(netif.CLONED_PREFIXES)): continue try: desc = get_sysctl( re.sub('(\\w+)([0-9]+)', 'dev.\\1.\\2.%desc', i)) result.append({'name': i, 'description': desc}) except FileNotFoundError: continue return result
def build_cache(self): # Build a cache of certain interface states so we'll later know what has changed for i in list(netif.list_interfaces().values()): try: self.mtu_cache[i.name] = i.mtu self.flags_cache[i.name] = i.flags self.link_state_cache[i.name] = i.link_state except OSError as err: # Apparently interface doesn't exist anymore if err.errno == errno.ENXIO: self.mtu_cache.pop(i.name, None) self.flags_cache.pop(i.name, None) self.link_state_cache.pop(i.name, None) else: self.context.logger.warn('Building interface cache for {0} failed: {1}'.format(i.name, str(err)))
def query_interfaces(self): def extend(name, iface): iface = iface.__getstate__() dhcp = self.context.dhcp_clients.get(name) if dhcp: iface['dhcp'] = dhcp.__getstate__() # Bridge interfaces don't report link state, so pretend they always have a link. if iface['name'].startswith('bridge'): iface['link_state'] = 'LINK_STATE_UP' return iface return {name: extend(name, i) for name, i in netif.list_interfaces().items()}
def _get_class_network(self): result = [] for i in list(netif.list_interfaces().keys()): if i.startswith(tuple(netif.CLONED_PREFIXES)): continue try: desc = get_sysctl(re.sub('(\w+)([0-9]+)', 'dev.\\1.\\2.%desc', i)) result.append({ 'name': i, 'description': desc }) except FileNotFoundError: continue return result
def get_next_name(self, type): type_map = { 'VLAN': 'vlan', 'LAGG': 'lagg', 'BRIDGE': 'bridge' } if type not in list(type_map.keys()): raise RpcException(errno.EINVAL, 'Invalid type: {0}'.format(type)) ifaces = netif.list_interfaces() for i in range(2 if type == 'BRIDGE' else 0, 999): name = '{0}{1}'.format(type_map[type], i) if name not in list(ifaces.keys()) and not self.datastore.exists('network.interfaces', ('id', '=', name)): return name raise RpcException(errno.EBUSY, 'No free interfaces left')
def get_next_name(self, type): type_map = { 'VLAN': 'vlan', 'LAGG': 'lagg', 'BRIDGE': ('bridge', 'brg') } if type not in list(type_map.keys()): raise RpcException(errno.EINVAL, 'Invalid type: {0}'.format(type)) ifaces = netif.list_interfaces() for i in range(2 if type == 'BRIDGE' else 0, 999): name = '{0}{1}'.format(type_map[type], i) if name not in list(ifaces.keys()) and not self.datastore.exists('network.interfaces', ('id', '=', name)): return name raise RpcException(errno.EBUSY, 'No free interfaces left')
def ipv4_in_use(self): """ Get all IPv4 from all valid interfaces, excluding lo0, bridge* and tap*. Returns: list: A list with all IPv4 in use, or an empty list. """ list_of_ipv4 = [] ignore_nics = ('lo', 'bridge', 'tap', 'epair') for if_name, iface in list(netif.list_interfaces().items()): if not if_name.startswith(ignore_nics): for nic_address in iface.addresses: if nic_address.af == netif.AddressFamily.INET: ipv4_address = nic_address.address.exploded list_of_ipv4.append(str(ipv4_address)) return list_of_ipv4
def run(self, bridge_enable=False): node = ConfigNode('service.openvpn', self.configstore).__getstate__() interface_list = list(netif.list_interfaces().keys()) default_interface = self.dispatcher.call_sync('networkd.configuration.get_default_interface') vpn_interface = netif.get_interface(self.configstore.get('service.openvpn.dev')) vpn_interface.up() if 'VPNbridge' not in interface_list: bridge_interface = netif.get_interface(netif.create_interface('bridge')) bridge_interface.rename('VPNbridge') bridge_interface.description = 'OpenVPN bridge interface' else: bridge_interface = netif.get_interface('VPNbridge') if node['server_bridge_extended']: subnet = ipaddress.ip_interface('{0}/{1}'.format(node['server_bridge_ip'], bridge_values['server_bridge_netmask'])) bridge_interface.add_address(netif.InterfaceAddress( netif.AddressFamily.INET, subnet )) try: bridge_interface.add_member(default_interface) except FileExistsError as e: logger.info('Default interface already bridged: {0}'.format(e)) except OSError as e: raise TaskException(errno.EBUSY, 'Default interface busy - check other bridge interfaces. {0}'.format(e)) try: bridge_interface.add_member(self.configstore.get('service.openvpn.dev')) except FileExistsError as e: logger.info('OpenVPN interface already bridged: {0}'.format(e)) except OSError as e: raise TaskException(errno.EBUSY, 'VPN interface busy - check other bridge interfaces. {0}'.format(e)) else: bridge_interface.up()
def check_sync(self): count = defaultdict(int) alerts = [] for iface in netif.list_interfaces().values(): if not isinstance(iface, netif.LaggInterface): continue active = [] inactive = [] for name, flags in iface.ports: if netif.LaggPortFlags.ACTIVE not in flags: inactive.append(name) else: active.append(name) # ports that are not ACTIVE and LACP if inactive and iface.protocol == netif.AggregationProtocol.LACP: # Only alert if this has happened more than twice, see #24160 count[iface.name] += 1 if count[iface.name] > 2: alerts.append( Alert( "These ports are not ACTIVE on LAGG interface %(name)s: %(ports)s. " "Please check cabling and switch.", { "name": iface.name, "ports": ", ".join(inactive) }, )) # For FAILOVER protocol we should have one ACTIVE port elif len( active ) != 1 and iface.protocol == netif.AggregationProtocol.FAILOVER: # Only alert if this has happened more than twice, see #24160 count[iface.name] += 1 if count[iface.name] > 2: alerts.append( Alert( "There are no ACTIVE ports on LAGG interface %(name)s. Please check cabling and switch.", {"name": iface.name}, )) else: count[iface.name] = 0 return alerts
def check_sync(self): if not netif: return [] alerts = [] for iface in netif.list_interfaces().values(): if not isinstance(iface, netif.LaggInterface): continue active = [] inactive = [] for name, flags in iface.ports: if netif.LaggPortFlags.ACTIVE not in flags: inactive.append(name) else: active.append(name) # ports that are not ACTIVE and LACP if inactive and iface.protocol == netif.AggregationProtocol.LACP: # Only alert if this has happened more than twice, see #24160 self.count[iface.name] += 1 if self.count[iface.name] > 2: alerts.append( Alert( LAGGInactivePortsAlertClass, { "name": iface.name, "ports": ", ".join(inactive) }, )) # For FAILOVER protocol we should have one ACTIVE port elif len( active ) != 1 and iface.protocol == netif.AggregationProtocol.FAILOVER: # Only alert if this has happened more than twice, see #24160 self.count[iface.name] += 1 if self.count[iface.name] > 2: alerts.append( Alert( LAGGNoActivePortsAlertClass, {"name": iface.name}, )) else: self.count[iface.name] = 0 return alerts
def ip_in_use(self, choices=None): """ Get all IPv4 / Ipv6 from all valid interfaces, excluding lo0, bridge* and tap*. Choices is a dictionary with defaults to {'ipv4': True, 'ipv6': True} Returns a list of dicts - eg - [ { "type": "INET6", "address": "fe80::5054:ff:fe16:4aac", "netmask": 64 }, { "type": "INET", "address": "192.168.122.148", "netmask": 24, "broadcast": "192.168.122.255" }, ] """ if choices is None: choices = { 'ipv4': True, 'ipv6': True } ipv4 = choices['ipv4'] if choices.get('ipv4') else False ipv6 = choices['ipv6'] if choices.get('ipv6') else False list_of_ip = [] ignore_nics = ('lo', 'bridge', 'tap', 'epair', 'pflog') for if_name, iface in list(netif.list_interfaces().items()): if not if_name.startswith(ignore_nics): aliases_list = iface.__getstate__()['aliases'] for alias_dict in aliases_list: if ipv4 and alias_dict['type'] == 'INET': list_of_ip.append(alias_dict) if ipv6 and alias_dict['type'] == 'INET6': list_of_ip.append(alias_dict) return list_of_ip
def ipv4gw_reachable(self, ipv4_gateway): """ Get the IPv4 gateway and verify if it is reachable by any interface. Returns: bool: True if the gateway is reachable or otherwise False. """ ignore_nics = ('lo', 'bridge', 'tap', 'epair') for if_name, iface in list(netif.list_interfaces().items()): if not if_name.startswith(ignore_nics): for nic_address in iface.addresses: if nic_address.af == netif.AddressFamily.INET: ipv4_nic = ipaddress.IPv4Interface(nic_address) nic_network = ipaddr.IPv4Network(ipv4_nic) nic_prefixlen = nic_network.prefixlen nic_result = str(nic_network.network) + '/' + str(nic_prefixlen) if ipaddress.ip_address(ipv4_gateway) in ipaddress.ip_network(nic_result): return True return False
def run(self): alerts = [] for iface in netif.list_interfaces().values(): if not isinstance(iface, netif.LaggInterface): continue active = [] inactive = [] for name, flags in iface.ports: if netif.LaggPortFlags.ACTIVE not in flags: inactive.append(name) else: active.append(name) # ports that are not ACTIVE and LACP if inactive and iface.protocol == netif.AggregationProtocol.LACP: # Only alert if this has happened more than twice, see #24160 self.__count[iface.name] += 1 if self.__count[iface.name] > 2: alerts.append( Alert( Alert.CRIT, _('These ports are not ACTIVE on LAGG interface %(name)s: %(ports)s. Please check cabling and switch.' ) % { 'name': iface.name, 'ports': ', '.join(inactive) }, )) # For FAILOVER protocol we should have one ACTIVE port elif len( active ) != 1 and iface.protocol == netif.AggregationProtocol.FAILOVER: # Only alert if this has happened more than twice, see #24160 self.__count[iface.name] += 1 if self.__count[iface.name] > 2: alerts.append( Alert( Alert.CRIT, _('There are no ACTIVE ports on LAGG interface %(name)s. Please check cabling and switch.' ) % {'name': iface.name}, )) else: self.__count[iface.name] = 0 return alerts
def ip_in_use(self, choices=None): """ Get all IPv4 / Ipv6 from all valid interfaces, excluding lo0, bridge* and tap*. Choices is a dictionary with defaults to {'ipv4': True, 'ipv6': True} Returns a list of dicts - eg - [ { "type": "INET6", "address": "fe80::5054:ff:fe16:4aac", "netmask": 64 }, { "type": "INET", "address": "192.168.122.148", "netmask": 24, "broadcast": "192.168.122.255" }, ] """ if not choices: choices = { 'ipv4': True, 'ipv6': True } ipv4 = choices['ipv4'] if choices.get('ipv4') else False ipv6 = choices['ipv6'] if choices.get('ipv6') else False list_of_ip = [] ignore_nics = ('lo', 'bridge', 'tap', 'epair', 'pflog') for if_name, iface in list(netif.list_interfaces().items()): if not if_name.startswith(ignore_nics): aliases_list = iface.__getstate__()['aliases'] for alias_dict in aliases_list: if ipv4 and alias_dict['type'] == 'INET': list_of_ip.append(alias_dict) if ipv6 and alias_dict['type'] == 'INET6': list_of_ip.append(alias_dict) return list_of_ip
def scan_interfaces(self): self.logger.info('Scanning available network interfaces...') existing = [] # Add newly plugged NICs to DB for i in list(netif.list_interfaces().values()): existing.append(i.name) # We want only physical NICs if i.cloned: continue if i.name in ('mgmt0', 'nat0'): continue if i.name.startswith(('tap', 'brg')): continue if not self.datastore.exists('network.interfaces', ('id', '=', i.name)): self.logger.info('Found new interface {0} ({1})'.format(i.name, i.type.name)) self.datastore.insert('network.interfaces', { 'enabled': False, 'id': i.name, 'name': None, 'cloned': False, 'type': i.type.name, 'dhcp': False, 'noipv6': False, 'rtadv': False, 'mtu': i.mtu, 'media': None, 'mediaopts': [], 'aliases': [], 'capabilities': { 'add': [], 'del': [] } }) # Remove unplugged NICs from DB for i in self.datastore.query('network.interfaces', ('id', 'nin', existing), ('cloned', '=', False)): self.datastore.delete('network.interfaces', i['id'])
async def bridge_setup(self, tapname, tap, attach_iface): if_bridge = [] bridge_enabled = False if attach_iface is None: # XXX: backward compatibility prior to 11.1-RELEASE. try: attach_iface = netif.RoutingTable().default_route_ipv4.interface attach_iface_info = netif.get_interface(attach_iface) except: return else: attach_iface_info = netif.get_interface(attach_iface) # If for some reason the main iface is down, we need to up it. attach_iface_status = netif.InterfaceFlags.UP in attach_iface_info.flags if attach_iface_status is False: attach_iface_info.up() for brgname, iface in list(netif.list_interfaces().items()): if brgname.startswith('bridge'): if_bridge.append(iface) if if_bridge: for bridge in if_bridge: if attach_iface in bridge.members: bridge_enabled = True self.set_iface_mtu(attach_iface_info, tap) bridge.add_member(tapname) if netif.InterfaceFlags.UP not in bridge.flags: bridge.up() break if bridge_enabled is False: bridge = netif.get_interface(netif.create_interface('bridge')) self.set_iface_mtu(attach_iface_info, tap) bridge.add_member(tapname) bridge.add_member(attach_iface) bridge.up()
def scan_interfaces(self): self.logger.info('Scanning available network interfaces...') existing = [] # Add newly plugged NICs to DB for i in list(netif.list_interfaces().values()): # We want only physical NICs if i.cloned: continue existing.append(i.name) if not self.datastore.exists('network.interfaces', ('id', '=', i.name)): self.logger.info('Found new interface {0} ({1})'.format(i.name, i.type.name)) self.datastore.insert('network.interfaces', { 'enabled': False, 'id': i.name, 'type': i.type.name }) # Remove unplugged NICs from DB for i in self.datastore.query('network.interfaces', ('id', 'nin', existing)): self.datastore.delete('network.interfaces', i['id'])
async def bridge_setup(self, tapname, tap, attach_iface): if_bridge = [] bridge_enabled = False if attach_iface is None: # XXX: backward compatibility prior to 11.1-RELEASE. try: attach_iface = netif.RoutingTable( ).default_route_ipv4.interface attach_iface_info = netif.get_interface(attach_iface) except: return else: attach_iface_info = netif.get_interface(attach_iface) # If for some reason the main iface is down, we need to up it. attach_iface_status = netif.InterfaceFlags.UP in attach_iface_info.flags if attach_iface_status is False: attach_iface_info.up() for brgname, iface in list(netif.list_interfaces().items()): if brgname.startswith('bridge'): if_bridge.append(iface) if if_bridge: for bridge in if_bridge: if attach_iface in bridge.members: bridge_enabled = True self.set_iface_mtu(attach_iface_info, tap) bridge.add_member(tapname) break if bridge_enabled is False: bridge = netif.get_interface(netif.create_interface('bridge')) self.set_iface_mtu(attach_iface_info, tap) bridge.add_member(tapname) bridge.add_member(attach_iface) bridge.up()
def check_sync(self): count = defaultdict(int) alerts = [] for iface in netif.list_interfaces().values(): if not isinstance(iface, netif.LaggInterface): continue active = [] inactive = [] for name, flags in iface.ports: if netif.LaggPortFlags.ACTIVE not in flags: inactive.append(name) else: active.append(name) # ports that are not ACTIVE and LACP if inactive and iface.protocol == netif.AggregationProtocol.LACP: # Only alert if this has happened more than twice, see #24160 count[iface.name] += 1 if count[iface.name] > 2: alerts.append(Alert( "These ports are not ACTIVE on LAGG interface %(name)s: %(ports)s. " "Please check cabling and switch.", {"name": iface.name, "ports": ", ".join(inactive)}, )) # For FAILOVER protocol we should have one ACTIVE port elif len(active) != 1 and iface.protocol == netif.AggregationProtocol.FAILOVER: # Only alert if this has happened more than twice, see #24160 count[iface.name] += 1 if count[iface.name] > 2: alerts.append(Alert( "There are no ACTIVE ports on LAGG interface %(name)s. Please check cabling and switch.", {"name": iface.name}, )) else: count[iface.name] = 0 return alerts
def run(self): vpn_state = self.dispatcher.call_sync('service.query', [('name', '=', 'openvpn')], {'single': True}) node = ConfigNode('service.openvpn', self.configstore).__getstate__() if vpn_state['state'] != 'RUNNING': raise TaskException(errno.EPERM, 'For bridging VPN capabilities openvpn needs to be running.') if node['mode'] == 'psk': raise TaskException(errno.EPERM, 'Bridging VPN capabilities only in pki mode.') # This feels like a not so good solution - feel free to change tap_interfaces = netif.get_ifgroup('tap') for vpn_interface_name in tap_interfaces: tap_pids = system('/usr/bin/fuser', '/dev/' + vpn_interface_name)[0].split() if vpn_state['pid'] in tap_pids: break try: vpn_interface = netif.get_interface(vpn_interface_name) except KeyError: raise TaskException( errno.EINVAL, '{0} interface does not exist - Verify OpenVPN status'.format(vpn_interface_name) ) else: vpn_interface.up() default_interface = self.dispatcher.call_sync('networkd.configuration.get_default_interface') if not default_interface: raise TaskException(errno.EINVAL, 'No default interface configured. Verify network setup.') # Heavily inspired by containterd available_bridges = list(b for b in netif.list_interfaces().keys() if isinstance(netif.get_interface(b), netif.BridgeInterface)) for b in available_bridges: bridge_interface = netif.get_interface(b, bridge=True) if default_interface in bridge_interface.members: try: bridge_interface.add_member(vpn_interface_name) except FileExistsError: pass break else: bridge_interface = netif.get_interface(netif.create_interface('bridge')) bridge_interface.rename('brg{0}'.format(len(available_bridges))) bridge_interface.description = 'OpenVPN bridge interface' bridge_interface.up() bridge_interface.add_member(default_interface) bridge_interface.add_member(vpn_interface_name) if node['server_bridge_extended']: subnet = ipaddress.ip_interface('{0}/{1}'.format(node['server_bridge_ip'], node['server_bridge_netmask'])) bridge_interface.add_address(netif.InterfaceAddress( netif.AddressFamily.INET, subnet ))
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 run(self): cp_time_last = None cp_times_last = None last_interface_stats = {} while not self._cancel.is_set(): data = {} # Virtual memory use data['virtual_memory'] = psutil.virtual_memory()._asdict() # ZFS ARC Size (raw value is in Bytes) data['zfs'] = {} if osc.IS_FREEBSD: data['zfs']['arc_size'] = sysctl.filter( 'kstat.zfs.misc.arcstats.size')[0].value elif osc.IS_LINUX: with open('/proc/spl/kstat/zfs/arcstats') as f: rv = f.read() for line in rv.split('\n'): if line.startswith('size'): data['zfs']['arc_size'] = int( line.strip().split()[-1]) data['cpu'] = {} # Get CPU usage % if osc.IS_FREEBSD: num_times = 5 # cp_times has values for all cores cp_times = sysctl.filter('kern.cp_times')[0].value # cp_time is the sum of all cores cp_time = sysctl.filter('kern.cp_time')[0].value elif osc.IS_LINUX: num_times = 10 with open('/proc/stat') as f: stat = f.read() cp_times = [] cp_time = [] for line in stat.split('\n'): if line.startswith('cpu'): line_ints = [int(i) for i in line[5:].strip().split()] # cpu has a sum of all cpus if line[3] == ' ': cp_time = line_ints # cpuX is for each core else: cp_times += line_ints else: break else: cp_time = cp_times = None if cp_time and cp_times and cp_times_last: # Get the difference of times between the last check and the current one # cp_time has a list with user, nice, system, interrupt and idle cp_diff = list( map(lambda x: x[0] - x[1], zip(cp_times, cp_times_last))) cp_nums = int(len(cp_times) / num_times) for i in range(cp_nums): data['cpu'][i] = self.get_cpu_usages( cp_diff[i * num_times:i * num_times + num_times]) cp_diff = list( map(lambda x: x[0] - x[1], zip(cp_time, cp_time_last))) data['cpu']['average'] = self.get_cpu_usages(cp_diff) cp_time_last = cp_time cp_times_last = cp_times # CPU temperature data['cpu']['temperature'] = {} if osc.IS_FREEBSD: for i in itertools.count(): v = sysctl.filter(f'dev.cpu.{i}.temperature') if not v: break data['cpu']['temperature'][i] = v[0].value elif osc.IS_LINUX: cp = subprocess.run(['sensors', '-j'], capture_output=True, text=True) try: sensors = json.loads(cp.stdout) except json.decoder.JSONDecodeError: pass except Exception: self.middleware.logger.error( 'Failed to read sensors output', exc_info=True) else: for chip, value in sensors.items(): for name, temps in value.items(): if not name.startswith('Core '): continue core = name[5:].strip() if not core.isdigit(): continue core = int(core) for temp, value in temps.items(): if 'input' in temp: data['cpu']['temperature'][ core] = 2732 + int(value * 10) break if osc.IS_FREEBSD: # Interface related statistics data['interfaces'] = {} retrieve_stat_keys = ['received_bytes', 'sent_bytes'] for iface in netif.list_interfaces().values(): for addr in filter( lambda addr: addr.af.name.lower() == 'link', iface.addresses): addr_data = addr.__getstate__(stats=True) stats_time = time.time() data['interfaces'][iface.name] = {} for k in retrieve_stat_keys: traffic_stats = addr_data['stats'][k] if last_interface_stats.get(iface.name): traffic_stats = traffic_stats - last_interface_stats[ iface.name][k] traffic_stats = int( traffic_stats / (time.time() - last_interface_stats[ iface.name]['stats_time'])) details_dict = { k: addr_data['stats'][k], f'{k}_rate': traffic_stats, } data['interfaces'][iface.name].update(details_dict) last_interface_stats[iface.name] = { **data['interfaces'][iface.name], 'stats_time': stats_time } self.send_event('ADDED', fields=data) time.sleep(2)
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 run(self): cp_time_last = None cp_times_last = None last_interface_stats = {} last_interface_speeds = { 'time': time.monotonic(), 'speeds': self.get_interface_speeds(), } if osc.IS_LINUX: disk_stats = DiskStats() while not self._cancel.is_set(): data = {} # Virtual memory use data['virtual_memory'] = psutil.virtual_memory()._asdict() # ZFS ARC Size (raw value is in Bytes) hits = 0 misses = 0 data['zfs'] = {} if osc.IS_FREEBSD: hits = sysctl.filter('kstat.zfs.misc.arcstats.hits')[0].value misses = sysctl.filter( 'kstat.zfs.misc.arcstats.misses')[0].value data['zfs']['arc_max_size'] = sysctl.filter( 'kstat.zfs.misc.arcstats.c_max')[0].value data['zfs']['arc_size'] = sysctl.filter( 'kstat.zfs.misc.arcstats.size')[0].value elif osc.IS_LINUX: with open('/proc/spl/kstat/zfs/arcstats') as f: for line in f.readlines()[2:]: if line.strip(): name, type, value = line.strip().split() if name == 'hits': hits = int(value) if name == 'misses': misses = int(value) if name == 'c_max': data['zfs']['arc_max_size'] = int(value) if name == 'size': data['zfs']['arc_size'] = int(value) total = hits + misses if total > 0: data['zfs']['cache_hit_ratio'] = hits / total else: data['zfs']['cache_hit_ratio'] = 0 data['cpu'] = {} # Get CPU usage % if osc.IS_FREEBSD: num_times = 5 # cp_times has values for all cores cp_times = sysctl.filter('kern.cp_times')[0].value # cp_time is the sum of all cores cp_time = sysctl.filter('kern.cp_time')[0].value elif osc.IS_LINUX: num_times = 10 with open('/proc/stat') as f: stat = f.read() cp_times = [] cp_time = [] for line in stat.split('\n'): if line.startswith('cpu'): line_ints = [int(i) for i in line[5:].strip().split()] # cpu has a sum of all cpus if line[3] == ' ': cp_time = line_ints # cpuX is for each core else: cp_times += line_ints else: break else: cp_time = cp_times = None if cp_time and cp_times and cp_times_last: # Get the difference of times between the last check and the current one # cp_time has a list with user, nice, system, interrupt and idle cp_diff = list( map(lambda x: x[0] - x[1], zip(cp_times, cp_times_last))) cp_nums = int(len(cp_times) / num_times) for i in range(cp_nums): data['cpu'][i] = self.get_cpu_usages( cp_diff[i * num_times:i * num_times + num_times]) cp_diff = list( map(lambda x: x[0] - x[1], zip(cp_time, cp_time_last))) data['cpu']['average'] = self.get_cpu_usages(cp_diff) cp_time_last = cp_time cp_times_last = cp_times # CPU temperature data['cpu']['temperature'] = {} if osc.IS_FREEBSD: for i in itertools.count(): v = sysctl.filter(f'dev.cpu.{i}.temperature') if not v: break data['cpu']['temperature'][i] = v[0].value elif osc.IS_LINUX: cp = subprocess.run(['sensors', '-j'], capture_output=True, text=True) try: sensors = json.loads(cp.stdout) except json.decoder.JSONDecodeError: pass except Exception: self.middleware.logger.error( 'Failed to read sensors output', exc_info=True) else: for chip, value in sensors.items(): for name, temps in value.items(): if not name.startswith('Core '): continue core = name[5:].strip() if not core.isdigit(): continue core = int(core) for temp, value in temps.items(): if 'input' in temp: data['cpu']['temperature'][ core] = 2732 + int(value * 10) break # Interface related statistics if last_interface_speeds['time'] < time.monotonic( ) - self.INTERFACE_SPEEDS_CACHE_INTERLVAL: last_interface_speeds.update({ 'time': time.monotonic(), 'speeds': self.get_interface_speeds(), }) data['interfaces'] = defaultdict(dict) retrieve_stat = { 'rx_bytes': 'received_bytes', 'tx_bytes': 'sent_bytes' } if osc.IS_FREEBSD: for iface in netif.list_interfaces().values(): data['interfaces'][iface.name][ 'speed'] = last_interface_speeds['speeds'].get( iface.name) for addr in filter( lambda addr: addr.af.name.lower() == 'link', iface.addresses): addr_data = addr.__getstate__(stats=True) stats_time = time.time() for k in retrieve_stat.values(): traffic_stats = 0 if last_interface_stats.get(iface.name): traffic_stats = addr_data['stats'][ k] - last_interface_stats[iface.name][k] traffic_stats = int( traffic_stats / (time.time() - last_interface_stats[ iface.name]['stats_time'])) details_dict = { k: addr_data['stats'][k], f'{k}_rate': traffic_stats, } data['interfaces'][iface.name].update(details_dict) last_interface_stats[iface.name] = { **data['interfaces'][iface.name], 'stats_time': stats_time } else: stats_time = time.time() for i in glob.glob('/sys/class/net/*/statistics'): iface_name = i.replace('/sys/class/net/', '').split('/')[0] data['interfaces'][iface_name][ 'speed'] = last_interface_speeds['speeds'].get( iface_name) for stat, name in retrieve_stat.items(): with open(f'{i}/{stat}', 'r') as f: value = int(f.read()) data['interfaces'][iface_name][name] = value traffic_stats = None if (last_interface_stats.get(iface_name) and name in last_interface_stats[iface_name]): traffic_stats = value - last_interface_stats[ iface_name][name] traffic_stats = int( traffic_stats / (stats_time - last_interface_stats[iface_name]['stats_time'] )) data['interfaces'][iface_name][ f'{retrieve_stat[stat]}_rate'] = traffic_stats last_interface_stats[iface_name] = { **data['interfaces'][iface_name], 'stats_time': stats_time, } if osc.IS_LINUX: data['disks'] = disk_stats.get() self.send_event('ADDED', fields=data) time.sleep(2)
def query_interfaces(self): return netif.list_interfaces()
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): config = await self.middleware.call('datastore.query', 'network.globalconfiguration', [], {'get': True}) # Generate dhclient.conf so we can ignore routes (def gw) option # in case there is one explictly set in network config await self.middleware.call('etc.generate', 'network') ipv4_gateway = config['gc_ipv4gateway'] or None if not ipv4_gateway: interfaces = await self.middleware.call('datastore.query', 'network.interfaces') if interfaces: interfaces = [ interface['int_interface'] for interface in interfaces if interface['int_dhcp'] ] else: interfaces = [ interface for interface in netif.list_interfaces().keys() if not (re.match("^(bridge|epair|ipfw|lo)[0-9]+", interface) or ":" in interface) ] for interface in interfaces: dhclient_running, dhclient_pid = dhclient_status(interface) if dhclient_running: leases = dhclient_leases(interface) reg_routers = re.search(r'option routers (.+);', leases or '') if reg_routers: # Make sure to get first route only ipv4_gateway = reg_routers.group(1).split(' ')[0] break routing_table = netif.RoutingTable() if ipv4_gateway: ipv4_gateway = netif.Route('0.0.0.0', '0.0.0.0', ipaddress.ip_address(str(ipv4_gateway))) ipv4_gateway.flags.add(netif.RouteFlags.STATIC) ipv4_gateway.flags.add(netif.RouteFlags.GATEWAY) # If there is a gateway but there is none configured, add it # Otherwise change it if not routing_table.default_route_ipv4: self.logger.info('Adding IPv4 default route to {}'.format( ipv4_gateway.gateway)) routing_table.add(ipv4_gateway) elif ipv4_gateway != routing_table.default_route_ipv4: self.logger.info( 'Changing IPv4 default route from {} to {}'.format( routing_table.default_route_ipv4.gateway, ipv4_gateway.gateway)) routing_table.change(ipv4_gateway) elif routing_table.default_route_ipv4: # If there is no gateway in database but one is configured # remove it self.logger.info('Removing IPv4 default route') routing_table.delete(routing_table.default_route_ipv4) ipv6_gateway = config['gc_ipv6gateway'] or None if ipv6_gateway: if ipv6_gateway.count("%") == 1: ipv6_gateway, ipv6_gateway_interface = ipv6_gateway.split("%") else: ipv6_gateway_interface = None ipv6_gateway = netif.Route('::', '::', ipaddress.ip_address(str(ipv6_gateway)), ipv6_gateway_interface) ipv6_gateway.flags.add(netif.RouteFlags.STATIC) ipv6_gateway.flags.add(netif.RouteFlags.GATEWAY) # If there is a gateway but there is none configured, add it # Otherwise change it if not routing_table.default_route_ipv6: self.logger.info('Adding IPv6 default route to {}'.format( ipv6_gateway.gateway)) routing_table.add(ipv6_gateway) elif ipv6_gateway != routing_table.default_route_ipv6: self.logger.info( 'Changing IPv6 default route from {} to {}'.format( routing_table.default_route_ipv6.gateway, ipv6_gateway.gateway)) routing_table.change(ipv6_gateway) elif routing_table.default_route_ipv6: # If there is no gateway in database but one is configured # remove it self.logger.info('Removing IPv6 default route') routing_table.delete(routing_table.default_route_ipv6)
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): config = await self.middleware.call('datastore.query', 'network.globalconfiguration', [], {'get': True}) # Generate dhclient.conf so we can ignore routes (def gw) option # in case there is one explictly set in network config await self.middleware.call('etc.generate', 'network') ipv4_gateway = config['gc_ipv4gateway'] or None if not ipv4_gateway: interfaces = await self.middleware.call('datastore.query', 'network.interfaces') if interfaces: interfaces = [interface['int_interface'] for interface in interfaces if interface['int_dhcp']] else: interfaces = [ interface for interface in netif.list_interfaces().keys() if not ( re.match("^(bridge|epair|ipfw|lo)[0-9]+", interface) or ":" in interface ) ] for interface in interfaces: dhclient_running, dhclient_pid = dhclient_status(interface) if dhclient_running: leases = dhclient_leases(interface) reg_routers = re.search(r'option routers (.+);', leases or '') if reg_routers: # Make sure to get first route only ipv4_gateway = reg_routers.group(1).split(' ')[0] break routing_table = netif.RoutingTable() if ipv4_gateway: ipv4_gateway = netif.Route('0.0.0.0', '0.0.0.0', ipaddress.ip_address(str(ipv4_gateway))) ipv4_gateway.flags.add(netif.RouteFlags.STATIC) ipv4_gateway.flags.add(netif.RouteFlags.GATEWAY) # If there is a gateway but there is none configured, add it # Otherwise change it if not routing_table.default_route_ipv4: self.logger.info('Adding IPv4 default route to {}'.format(ipv4_gateway.gateway)) routing_table.add(ipv4_gateway) elif ipv4_gateway != routing_table.default_route_ipv4: self.logger.info('Changing IPv4 default route from {} to {}'.format(routing_table.default_route_ipv4.gateway, ipv4_gateway.gateway)) routing_table.change(ipv4_gateway) elif routing_table.default_route_ipv4: # If there is no gateway in database but one is configured # remove it self.logger.info('Removing IPv4 default route') routing_table.delete(routing_table.default_route_ipv4) ipv6_gateway = config['gc_ipv6gateway'] or None if ipv6_gateway: if ipv6_gateway.count("%") == 1: ipv6_gateway, ipv6_gateway_interface = ipv6_gateway.split("%") else: ipv6_gateway_interface = None ipv6_gateway = netif.Route('::', '::', ipaddress.ip_address(str(ipv6_gateway)), ipv6_gateway_interface) ipv6_gateway.flags.add(netif.RouteFlags.STATIC) ipv6_gateway.flags.add(netif.RouteFlags.GATEWAY) # If there is a gateway but there is none configured, add it # Otherwise change it if not routing_table.default_route_ipv6: self.logger.info('Adding IPv6 default route to {}'.format(ipv6_gateway.gateway)) routing_table.add(ipv6_gateway) elif ipv6_gateway != routing_table.default_route_ipv6: self.logger.info('Changing IPv6 default route from {} to {}'.format(routing_table.default_route_ipv6.gateway, ipv6_gateway.gateway)) routing_table.change(ipv6_gateway) elif routing_table.default_route_ipv6: # If there is no gateway in database but one is configured # remove it self.logger.info('Removing IPv6 default route') routing_table.delete(routing_table.default_route_ipv6)
def configure_interface(self, name, restart_rtsold=True): entity = self.datastore.get_one('network.interfaces', ('id', '=', name)) if not entity: raise RpcException(errno.ENXIO, "Configuration for interface {0} not found".format(name)) try: iface = netif.get_interface(name) except KeyError: if entity.get('cloned'): netif.create_interface(entity['id']) iface = netif.get_interface(name) else: yield errno.ENOENT, "Interface {0} not found".format(name) return if not entity.get('enabled'): self.logger.info('Interface {0} is disabled'.format(name)) return # check whether interface is a lagg member for j in netif.list_interfaces().values(): try: if isinstance(j, netif.LaggInterface) and name in [p[0] for p in j.ports]: lagg_member = True break except OSError: continue else: lagg_member = False try: if netif.InterfaceFlags.UP not in iface.flags: self.logger.info('Bringing interface {0} up'.format(name)) iface.up() # If it's VLAN, configure parent and tag if entity.get('type') == 'VLAN': vlan = entity.get('vlan') if vlan: parent = vlan.get('parent') tag = vlan.get('tag') if parent != iface.parent or tag != iface.tag: try: tag = int(tag) iface.unconfigure() iface.configure(parent, tag) except OSError as e: yield e.errno, 'Failed to configure VLAN interface {0}: {1}'.format(name, str(e)) # Configure protocol and member ports for a LAGG if entity.get('type') == 'LAGG': lagg = entity.get('lagg') if lagg: new_protocol = getattr(netif.AggregationProtocol, lagg.get('protocol', 'FAILOVER')) old_ports = set(p[0] for p in iface.ports) new_ports = set(lagg['ports']) if iface.protocol != new_protocol: iface.protocol = new_protocol for port in old_ports - new_ports: iface.delete_port(port) for port in new_ports - old_ports: iface.add_port(port) # Configure member interfaces for a bridge if entity.get('type') == 'BRIDGE': bridge = entity.get('bridge') if bridge: old_members = set(iface.members) new_members = set(bridge['members']) for port in old_members - new_members: iface.delete_member(port) for port in new_members - old_members: iface.add_member(port) if entity.get('dhcp'): if name in self.context.dhcp_clients: self.logger.info('Interface {0} already configured using DHCP'.format(name)) else: # Remove all existing aliases for i in iface.addresses: iface.remove_address(i) self.logger.info('Trying to acquire DHCP lease on interface {0}...'.format(name)) if not self.context.configure_dhcp(name): yield errno.ENETUNREACH, 'Failed to configure interface {0} using DHCP'.format(name) else: if name in self.context.dhcp_clients: self.logger.info('Stopping DHCP client on interface {0}'.format(name)) self.context.deconfigure_dhcp(name) addresses = set(convert_aliases(entity)) existing_addresses = set([a for a in iface.addresses if a.af != netif.AddressFamily.LINK]) # Remove orphaned addresses for i in existing_addresses - addresses: if i.af == netif.AddressFamily.INET6 and str(i.address).startswith('fe80::'): # skip link-local IPv6 addresses continue self.logger.info('Removing address from interface {0}: {1}'.format(name, i)) iface.remove_address(i) # Add new or changed addresses for i in addresses - existing_addresses: self.logger.info('Adding new address to interface {0}: {1}'.format(name, i)) iface.add_address(i) # nd6 stuff if entity.get('rtadv', False): iface.nd6_flags = iface.nd6_flags | {netif.NeighborDiscoveryFlags.ACCEPT_RTADV} if restart_rtsold: self.client.call_sync('service.restart', 'rtsold') else: iface.nd6_flags = iface.nd6_flags - {netif.NeighborDiscoveryFlags.ACCEPT_RTADV} if entity.get('noipv6', False): iface.nd6_flags = iface.nd6_flags | {netif.NeighborDiscoveryFlags.IFDISABLED} iface.nd6_flags = iface.nd6_flags - {netif.NeighborDiscoveryFlags.AUTO_LINKLOCAL} else: iface.nd6_flags = iface.nd6_flags - {netif.NeighborDiscoveryFlags.IFDISABLED} iface.nd6_flags = iface.nd6_flags | {netif.NeighborDiscoveryFlags.AUTO_LINKLOCAL} if entity.get('mtu') and not isinstance(iface, netif.LaggInterface) and not lagg_member: try: iface.mtu = entity['mtu'] except OSError as err: yield err.errno, 'Cannot set MTU of {0}: {1}'.format(name, str(err)) if entity.get('media'): iface.media_subtype = entity['media'] # vlan interfaces don't support capabilities if entity.get('capabilities') and not isinstance(iface, (netif.VlanInterface, netif.BridgeInterface)): caps = iface.capabilities for c in entity['capabilities'].get('add'): caps.add(getattr(netif.InterfaceCapability, c)) for c in entity['capabilities'].get('del'): caps.remove(getattr(netif.InterfaceCapability, c)) iface.capabilities = caps except OSError as err: yield err.errno, err.strerror self.client.emit_event('network.interface.configured', { 'interface': name, })
def configure_interface(self, name, restart_rtsold=True): entity = self.datastore.get_one('network.interfaces', ('id', '=', name)) if not entity: raise RpcException(errno.ENXIO, "Configuration for interface {0} not found".format(name)) try: iface = netif.get_interface(name) except KeyError: if entity.get('cloned'): netif.create_interface(entity['id']) iface = netif.get_interface(name) else: yield errno.ENOENT, "Interface {0} not found".format(name) return if not entity.get('enabled'): self.logger.info('Interface {0} is disabled'.format(name)) return # check whether interface is a lagg member for j in netif.list_interfaces().values(): try: if isinstance(j, netif.LaggInterface) and name in [p[0] for p in j.ports]: lagg_member = True break except OSError: continue else: lagg_member = False try: if netif.InterfaceFlags.UP not in iface.flags: self.logger.info('Bringing interface {0} up'.format(name)) iface.up() # If it's VLAN, configure parent and tag if entity.get('type') == 'VLAN': vlan = entity.get('vlan') if vlan: parent = vlan.get('parent') tag = vlan.get('tag') if parent != iface.parent or tag != iface.tag: try: tag = int(tag) iface.unconfigure() iface.configure(parent, tag) except OSError as e: yield e.errno, 'Failed to configure VLAN interface {0}: {1}'.format(name, str(e)) # Configure protocol and member ports for a LAGG if entity.get('type') == 'LAGG': lagg = entity.get('lagg') if lagg: new_protocol = getattr(netif.AggregationProtocol, lagg.get('protocol', 'FAILOVER')) old_ports = set(p[0] for p in iface.ports) new_ports = set(lagg['ports']) if iface.protocol != new_protocol: iface.protocol = new_protocol for port in old_ports - new_ports: iface.delete_port(port) for port in lagg['ports']: if port not in old_ports: iface.add_port(port) # Configure member interfaces for a bridge if entity.get('type') == 'BRIDGE': bridge = entity.get('bridge') if bridge: old_members = set(iface.members) new_members = set(bridge['members']) for port in old_members - new_members: iface.delete_member(port) for port in new_members - old_members: iface.add_member(port) if entity.get('dhcp'): if name in self.context.dhcp_clients: self.logger.info('Interface {0} already configured using DHCP'.format(name)) else: # Remove all existing aliases for i in iface.addresses: iface.remove_address(i) self.logger.info('Trying to acquire DHCP lease on interface {0}...'.format(name)) if not self.context.configure_dhcp(name, True, INITIAL_DHCP_TIMEOUT): yield errno.ENETUNREACH, 'Failed to configure interface {0} using DHCP'.format(name) else: if name in self.context.dhcp_clients: self.logger.info('Stopping DHCP client on interface {0}'.format(name)) self.context.deconfigure_dhcp(name) addresses = set(convert_aliases(entity)) existing_addresses = set([a for a in iface.addresses if a.af != netif.AddressFamily.LINK]) # Remove orphaned addresses for i in existing_addresses - addresses: if i.af == netif.AddressFamily.INET6 and str(i.address).startswith('fe80::'): # skip link-local IPv6 addresses continue self.logger.info('Removing address from interface {0}: {1}'.format(name, i)) iface.remove_address(i) # Add new or changed addresses for i in addresses - existing_addresses: self.logger.info('Adding new address to interface {0}: {1}'.format(name, i)) iface.add_address(i) # nd6 stuff if entity.get('rtadv', False): iface.nd6_flags = iface.nd6_flags | {netif.NeighborDiscoveryFlags.ACCEPT_RTADV} if restart_rtsold: self.client.call_sync('service.restart', 'rtsold', timeout=300) else: iface.nd6_flags = iface.nd6_flags - {netif.NeighborDiscoveryFlags.ACCEPT_RTADV} if entity.get('noipv6', False): iface.nd6_flags = iface.nd6_flags | {netif.NeighborDiscoveryFlags.IFDISABLED} iface.nd6_flags = iface.nd6_flags - {netif.NeighborDiscoveryFlags.AUTO_LINKLOCAL} else: iface.nd6_flags = iface.nd6_flags - {netif.NeighborDiscoveryFlags.IFDISABLED} iface.nd6_flags = iface.nd6_flags | {netif.NeighborDiscoveryFlags.AUTO_LINKLOCAL} if entity.get('mtu') and not isinstance(iface, netif.LaggInterface) and not lagg_member: try: iface.mtu = entity['mtu'] except OSError as err: yield err.errno, 'Cannot set MTU of {0}: {1}'.format(name, str(err)) if entity.get('media'): iface.media_subtype = entity['media'] # vlan interfaces don't support capabilities if entity.get('capabilities') and not isinstance(iface, (netif.VlanInterface, netif.BridgeInterface)): caps = iface.capabilities for c in entity['capabilities'].get('add'): caps.add(getattr(netif.InterfaceCapability, c)) for c in entity['capabilities'].get('del'): caps.remove(getattr(netif.InterfaceCapability, c)) iface.capabilities = caps except OSError as err: yield err.errno, err.strerror self.client.emit_event('network.interface.configured', { 'interface': name, })
def build_cache(self): # Build a cache of certain interface states so we'll later know what has changed for i in list(netif.list_interfaces().values()): self.mtu_cache[i.name] = i.mtu self.flags_cache[i.name] = i.flags self.link_state_cache[i.name] = i.link_state
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()