def alias_to_addr(self, alias): addr = netif.InterfaceAddress() ip = ipaddress.ip_interface('{}/{}'.format(alias['address'], alias['netmask'])) addr.af = getattr(netif.AddressFamily, 'INET6' if ':' in alias['address'] else 'INET') addr.address = ip.ip addr.netmask = ip.netmask addr.broadcast = ip.network.broadcast_address if 'vhid' in alias: addr.vhid = alias['vhid'] return addr
def convert_aliases(entity): for i in entity.get('aliases', []): addr = netif.InterfaceAddress() iface = ipaddress.ip_interface('{0}/{1}'.format(i['address'], i['netmask'])) addr.af = getattr(netif.AddressFamily, i.get('type', 'INET')) addr.address = ipaddress.ip_address(i['address']) addr.netmask = iface.netmask addr.broadcast = iface.network.broadcast_address if i.get('broadcast'): addr.broadcast = ipaddress.ip_address(i['broadcast']) if i.get('dest-address'): addr.dest_address = ipaddress.ip_address(i['dest-address']) yield addr
def up(self): # Destroy old bridge (if exists) try: netif.destroy_interface(self.ifname) except OSError as err: if err.errno != errno.ENXIO: raise RuntimeError('Cannot destroy {0}: {1}'.format(self.ifname, str(err))) # Setup bridge self.bridge_if = netif.get_interface(netif.create_interface('bridge')) self.bridge_if.rename(self.ifname) self.bridge_if.description = 'containerd management network' self.bridge_if.add_address(netif.InterfaceAddress( netif.AddressFamily.INET, self.subnet )) self.bridge_if.up() self.dhcp_server.server_name = 'FreeNAS' self.dhcp_server.on_request = self.dhcp_request self.dhcp_server.start(self.ifname, self.subnet.ip) self.dhcp_server_thread = gevent.spawn(self.dhcp_worker)
def run(self): vpn_state = self.dispatcher.call_sync('service.query', [('name', '=', 'openvpn')], {'single': True}) node = ConfigNode('service.openvpn', self.configstore).__getstate__() if vpn_state['state'] != 'RUNNING': raise TaskException(errno.EPERM, 'For bridging VPN capabilities openvpn needs to be running.') if node['mode'] == 'psk': raise TaskException(errno.EPERM, 'Bridging VPN capabilities only in pki mode.') # This feels like a not so good solution - feel free to change tap_interfaces = netif.get_ifgroup('tap') for vpn_interface_name in tap_interfaces: tap_pids = system('/usr/bin/fuser', '/dev/' + vpn_interface_name)[0].split() if vpn_state['pid'] in tap_pids: break try: vpn_interface = netif.get_interface(vpn_interface_name) except KeyError: raise TaskException( errno.EINVAL, '{0} interface does not exist - Verify OpenVPN status'.format(vpn_interface_name) ) else: vpn_interface.up() default_interface = self.dispatcher.call_sync('networkd.configuration.get_default_interface') if not default_interface: raise TaskException(errno.EINVAL, 'No default interface configured. Verify network setup.') # Heavily inspired by containterd available_bridges = list(b for b in netif.list_interfaces().keys() if isinstance(netif.get_interface(b), netif.BridgeInterface)) for b in available_bridges: bridge_interface = netif.get_interface(b, bridge=True) if default_interface in bridge_interface.members: try: bridge_interface.add_member(vpn_interface_name) except FileExistsError: pass break else: bridge_interface = netif.get_interface(netif.create_interface('bridge')) bridge_interface.rename('brg{0}'.format(len(available_bridges))) bridge_interface.description = 'OpenVPN bridge interface' bridge_interface.up() bridge_interface.add_member(default_interface) bridge_interface.add_member(vpn_interface_name) if node['server_bridge_extended']: subnet = ipaddress.ip_interface('{0}/{1}'.format(node['server_bridge_ip'], node['server_bridge_netmask'])) bridge_interface.add_address(netif.InterfaceAddress( netif.AddressFamily.INET, subnet ))
def bind(old_lease, lease): self.logger.info('{0} DHCP lease on {1} from {2}, valid for {3} seconds'.format( 'Renewed' if old_lease else 'Acquired', interface, client.server_address, lease.lifetime, interface )) if old_lease is None or lease.client_ip != old_lease.client_ip: self.logger.info('Assigning IP address {0} to interface {1}'.format(lease.client_ip, interface)) alias = lease.client_interface iface = netif.get_interface(interface) if old_lease: try: addr = first_or_default(lambda a: a.address == old_lease.client_ip, iface.addresses) if addr: iface.remove_address(addr) except OSError as err: self.logger.error('Cannot remove alias {0}: {1}'.format(old_lease.client_ip, err.strerror)) try: iface.add_address(netif.InterfaceAddress(netif.AddressFamily.INET, alias)) except OSError as err: self.logger.error('Cannot add alias to {0}: {1}'.format(interface, err.strerror)) if lease.router and self.configstore.get('network.dhcp.assign_gateway'): try: rtable = netif.RoutingTable() newroute = default_route(lease.router) if rtable.default_route_ipv4 != newroute: if rtable.default_route_ipv4: self.logger.info('DHCP default route changed from {0} to {1}'.format( rtable.default_route_ipv4, newroute )) rtable.delete(rtable.default_route_ipv4) rtable.add(default_route(lease.router)) else: self.logger.info('Adding default route via {0}'.format(lease.router)) rtable.add(default_route(lease.router)) except OSError as err: self.logger.error('Cannot configure default route: {0}'.format(err.strerror)) if lease.dns_addresses and self.configstore.get('network.dhcp.assign_dns'): inp = [] addrs = [] proc = subprocess.Popen( ['/sbin/resolvconf', '-a', interface], stdout=subprocess.PIPE, stdin=subprocess.PIPE ) for i in lease.dns_addresses: # Filter out bogus DNS server addresses if str(i) in ('127.0.0.1', '0.0.0.0', '255.255.255.255'): continue inp.append('nameserver {0}'.format(i)) addrs.append(i) if lease.domain_name: inp.append('search {0}'.format(lease.domain_name)) proc.communicate('\n'.join(inp).encode('ascii')) proc.wait() self.client.emit_event('network.dns.configured', { 'addresses': addrs, }) self.logger.info('Updated DNS configuration') else: subprocess.call(['/sbin/resolvconf', '-d', interface]) self.client.emit_event('network.dns.configured', { 'addresses': [], }) self.logger.info('Deleted DNS configuration')
def run(self): rtsock = netif.RoutingSocket() rtsock.open() self.build_cache() while True: message = rtsock.read_message() if type(message) is netif.InterfaceAnnounceMessage: args = {'name': message.interface} if message.type == netif.InterfaceAnnounceType.ARRIVAL: self.context.interface_attached(message.interface) self.client.emit_event('network.interface.attached', args) if message.type == netif.InterfaceAnnounceType.DEPARTURE: self.context.interface_detached(message.interface) self.client.emit_event('network.interface.detached', args) self.build_cache() if type(message) is netif.InterfaceInfoMessage: ifname = message.interface if self.mtu_cache[ifname] != message.mtu: self.client.emit_event('network.interface.mtu_changed', { 'interface': ifname, 'old_mtu': self.mtu_cache[ifname], 'new_mtu': message.mtu }) if self.link_state_cache[ifname] != message.link_state: if message.link_state == netif.InterfaceLinkState.LINK_STATE_DOWN: self.context.logger.warn('Link down on interface {0}'.format(ifname)) self.client.emit_event('network.interface.link_down', { 'interface': ifname, }) if message.link_state == netif.InterfaceLinkState.LINK_STATE_UP: self.context.logger.warn('Link up on interface {0}'.format(ifname)) self.client.emit_event('network.interface.link_up', { 'interface': ifname, }) if self.flags_cache[ifname] != message.flags: if (netif.InterfaceFlags.UP in self.flags_cache) and (netif.InterfaceFlags.UP not in message.flags): self.client.emit_event('network.interface.down', { 'interface': ifname, }) if (netif.InterfaceFlags.UP not in self.flags_cache) and (netif.InterfaceFlags.UP in message.flags): self.client.emit_event('network.interface.up', { 'interface': ifname, }) self.client.emit_event('network.interface.flags_changed', { 'interface': ifname, 'old_flags': [f.name for f in self.flags_cache[ifname]], 'new_flags': [f.name for f in message.flags] }) self.client.emit_event('network.interface.changed', { 'operation': 'update', 'ids': [ifname] }) self.build_cache() if type(message) is netif.InterfaceAddrMessage: entity = self.context.datastore.get_by_id('network.interfaces', message.interface) if entity is None: continue # Skip messagess with empty address if not message.address: continue # Skip 0.0.0.0 aliases if message.address == ipaddress.IPv4Address('0.0.0.0'): continue addr = netif.InterfaceAddress() addr.af = netif.AddressFamily.INET addr.address = message.address addr.netmask = message.netmask addr.broadcast = message.dest_address if message.type == netif.RoutingMessageType.NEWADDR: self.context.logger.warn('New alias added to interface {0} externally: {1}/{2}'.format( message.interface, message.address, message.netmask )) if message.type == netif.RoutingMessageType.DELADDR: self.context.logger.warn('Alias removed from interface {0} externally: {1}/{2}'.format( message.interface, message.address, message.netmask )) self.client.emit_event('network.interface.changed', { 'operation': 'update', 'ids': [entity['id']] }) if type(message) is netif.RoutingMessage: if message.errno != 0: continue if message.type == netif.RoutingMessageType.ADD: self.context.logger.info('Route to {0} added'.format(describe_route(message.route))) self.client.emit_event('network.route.added', message.__getstate__()) with self.context.cv: if str(message.route.network) == '0.0.0.0': self.context.default_interface = message.route.interface self.context.cv.notify_all() if message.type == netif.RoutingMessageType.DELETE: self.context.logger.info('Route to {0} deleted'.format(describe_route(message.route))) self.client.emit_event('network.route.deleted', message.__getstate__()) rtsock.close()