예제 #1
0
파일: main.py 프로젝트: lukegb/middleware
    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'
        })
예제 #2
0
파일: main.py 프로젝트: piotrgl/middleware
    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'
        })
예제 #3
0
파일: lagg.py 프로젝트: freenas/freenas
    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
예제 #4
0
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)
예제 #5
0
파일: vm.py 프로젝트: bopopescu/freenas
    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()
예제 #6
0
파일: network.py 프로젝트: razzfazz/freenas
 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)
예제 #7
0
파일: vm.py 프로젝트: binzyw/freenas
    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()
예제 #8
0
파일: main.py 프로젝트: erinix/middleware
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
예제 #9
0
파일: main.py 프로젝트: 650elx/middleware
    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'])
예제 #10
0
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
예제 #11
0
    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
예제 #12
0
파일: main.py 프로젝트: 650elx/middleware
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)
예제 #13
0
 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)
예제 #14
0
    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)
예제 #15
0
    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
예제 #16
0
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
예제 #17
0
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
예제 #18
0
파일: main.py 프로젝트: 650elx/middleware
    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
예제 #20
0
    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
예제 #21
0
파일: main.py 프로젝트: erinix/middleware
 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)))
예제 #22
0
 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)))
예제 #23
0
파일: main.py 프로젝트: erinix/middleware
    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()}
예제 #24
0
    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()}
예제 #25
0
    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
예제 #26
0
파일: main.py 프로젝트: 650elx/middleware
    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')
예제 #27
0
    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')
예제 #28
0
    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
예제 #29
0
    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()
예제 #30
0
파일: network.py 프로젝트: binzyw/freenas
    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
예제 #31
0
    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
예제 #32
0
    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
예제 #33
0
    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
예제 #34
0
파일: network.py 프로젝트: razzfazz/freenas
    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
예제 #35
0
    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
예제 #36
0
파일: network.py 프로젝트: razzfazz/freenas
    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
예제 #37
0
    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
예제 #38
0
    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'])
예제 #39
0
파일: vm.py 프로젝트: razzfazz/freenas
    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()
예제 #40
0
    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'])
예제 #41
0
    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()
예제 #42
0
파일: lagg.py 프로젝트: razzfazz/freenas
    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
예제 #43
0
    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
            ))
예제 #44
0
    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()
예제 #45
0
    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)
예제 #46
0
파일: vm.py 프로젝트: william-gr/freenas
    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)
예제 #47
0
파일: events.py 프로젝트: sbignell/freenas
    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)
예제 #48
0
 def query_interfaces(self):
     return netif.list_interfaces()
예제 #49
0
    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()
예제 #50
0
    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)
예제 #51
0
    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()
예제 #52
0
파일: network.py 프로젝트: razzfazz/freenas
    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)
예제 #53
0
    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,
        })
예제 #54
0
파일: main.py 프로젝트: erinix/middleware
    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,
        })
예제 #55
0
    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
            ))
예제 #56
0
 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
예제 #57
0
파일: network.py 프로젝트: razzfazz/freenas
    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()