Search in sources :

Example 1 with RouteService

use of org.eclipse.kura.linux.net.route.RouteService in project kura by eclipse.

the class EthernetMonitorServiceImpl method monitor.

private void monitor(String interfaceName) {
    synchronized (s_lock) {
        try {
            List<? extends NetInterfaceAddressConfig> new_niacs = null;
            List<? extends NetInterfaceAddressConfig> cur_niacs = null;
            InterfaceState currentInterfaceState = null;
            boolean interfaceEnabled = false;
            boolean isDhcpClient = false;
            IP4Address staticGateway = null;
            boolean dhcpServerEnabled = false;
            // IPAddress dhcpServerSubnet = null;
            // short dhcpServerPrefix = -1;
            boolean postStatusChangeEvent = false;
            EthernetInterfaceConfigImpl currentInterfaceConfig = this.m_networkConfiguration.get(interfaceName);
            EthernetInterfaceConfigImpl newInterfaceConfig = this.m_newNetworkConfiguration.get(interfaceName);
            // FIXME:MC it should be possible to refactor this under the InterfaceState to avoid dual checks
            if (!LinuxNetworkUtil.isUp(interfaceName)) {
                LinuxNetworkUtil.bringUpDeletingAddress(interfaceName);
            }
            // If a new configuration exists, compare it to the existing configuration
            if (newInterfaceConfig != null) {
                // Get all configurations for the interface
                new_niacs = newInterfaceConfig.getNetInterfaceAddresses();
                if (currentInterfaceConfig != null) {
                    cur_niacs = currentInterfaceConfig.getNetInterfaceAddresses();
                }
                if (isConfigChanged(new_niacs, cur_niacs)) {
                    s_logger.info("Found a new Ethernet network configuration for {}", interfaceName);
                    // Disable the interface to be reconfigured below
                    disableInterface(interfaceName);
                    // Set the current config to the new config
                    this.m_networkConfiguration.put(interfaceName, newInterfaceConfig);
                    currentInterfaceConfig = newInterfaceConfig;
                    // Post a status change event - not to be confusd with the Config Change that I am consuming
                    postStatusChangeEvent = true;
                }
                this.m_newNetworkConfiguration.remove(interfaceName);
            }
            // Monitor for status changes and ensure dhcp server is running when enabled
            interfaceEnabled = isEthernetEnabled(currentInterfaceConfig);
            InterfaceState prevInterfaceState = this.m_interfaceState.get(interfaceName);
            // FIXME:MC Deprecate this constructor and prefer the one with the explicit parameters
            // (String interfaceName, boolean up, boolean link, IPAddress ipAddress)
            // It will save a call to determine the iface type and it will keep InterfaceState
            // as a state object as it should be. Maybe introduce an InterfaceStateBuilder.
            currentInterfaceState = new InterfaceState(NetInterfaceType.ETHERNET, interfaceName);
            if (!currentInterfaceState.equals(prevInterfaceState)) {
                postStatusChangeEvent = true;
            }
            // Find if DHCP server or DHCP client mode is enabled
            if (currentInterfaceConfig != null) {
                NetInterfaceStatus netInterfaceStatus = getStatus(currentInterfaceConfig);
                cur_niacs = currentInterfaceConfig.getNetInterfaceAddresses();
                if (cur_niacs != null && cur_niacs.size() > 0) {
                    for (NetInterfaceAddressConfig niac : cur_niacs) {
                        List<NetConfig> netConfigs = niac.getConfigs();
                        if (netConfigs != null && netConfigs.size() > 0) {
                            for (NetConfig netConfig : netConfigs) {
                                if (netConfig instanceof DhcpServerConfig4) {
                                    // only enable if Enabled for LAN
                                    if (netInterfaceStatus.equals(NetInterfaceStatus.netIPv4StatusEnabledLAN)) {
                                        dhcpServerEnabled = ((DhcpServerConfig4) netConfig).isEnabled();
                                    // dhcpServerSubnet = ((DhcpServerConfig4) netConfig).getSubnet();
                                    // dhcpServerPrefix = ((DhcpServerConfig4) netConfig).getPrefix();
                                    } else {
                                        s_logger.trace("Not enabling DHCP server for {} since it is set to {}", interfaceName, netInterfaceStatus);
                                    }
                                } else if (netConfig instanceof NetConfigIP4) {
                                    isDhcpClient = ((NetConfigIP4) netConfig).isDhcp();
                                    staticGateway = ((NetConfigIP4) netConfig).getGateway();
                                }
                            }
                        }
                    }
                } else {
                    s_logger.debug("No current net interface addresses for {}", interfaceName);
                }
            } else {
                s_logger.debug("Current interface config is null for {}", interfaceName);
            }
            // Enable/disable based on configuration and current status
            boolean interfaceStateChanged = false;
            if (interfaceEnabled) {
                if (currentInterfaceState.isUp()) {
                    if (!currentInterfaceState.isLinkUp()) {
                        s_logger.debug("link is down - disabling {}", interfaceName);
                        disableInterface(interfaceName);
                        interfaceStateChanged = true;
                    }
                } else {
                    // State is currently down
                    if (currentInterfaceState.isLinkUp()) {
                        s_logger.debug("link is up - enabling {}", interfaceName);
                        this.m_netAdminService.enableInterface(interfaceName, isDhcpClient);
                        interfaceStateChanged = true;
                    }
                }
            } else {
                if (currentInterfaceState.isUp()) {
                    s_logger.debug("{} is currently up - disable interface", interfaceName);
                    disableInterface(interfaceName);
                    interfaceStateChanged = true;
                }
            }
            // FIXME: reload the configuration IFF one of above enable/disable happened
            if (interfaceStateChanged) {
                currentInterfaceState = new InterfaceState(NetInterfaceType.ETHERNET, interfaceName);
            }
            // Manage the DHCP server and validate routes
            if (currentInterfaceState != null && currentInterfaceState.isUp() && currentInterfaceState.isLinkUp()) {
                NetInterfaceStatus netInterfaceStatus = getStatus(currentInterfaceConfig);
                if (netInterfaceStatus == NetInterfaceStatus.netIPv4StatusEnabledWAN) {
                    // This should be the default gateway - make sure it is
                    boolean found = false;
                    RouteConfig[] routes = this.m_routeService.getRoutes();
                    if (routes != null && routes.length > 0) {
                        for (RouteConfig route : routes) {
                            if (route.getInterfaceName().equals(interfaceName) && route.getDestination().equals(IPAddress.parseHostAddress("0.0.0.0")) && !route.getGateway().equals(IPAddress.parseHostAddress("0.0.0.0"))) {
                                found = true;
                                break;
                            }
                        }
                    }
                    if (!found) {
                        if (isDhcpClient || staticGateway != null) {
                            // disable the interface and reenable - something didn't happen at initialization as it
                            // was supposed to
                            s_logger.error("WAN interface " + interfaceName + " did not have a route setting it as the default gateway, restarting it");
                            this.m_netAdminService.disableInterface(interfaceName);
                            this.m_netAdminService.enableInterface(interfaceName, isDhcpClient);
                        }
                    }
                } else if (netInterfaceStatus == NetInterfaceStatus.netIPv4StatusEnabledLAN) {
                    if (isDhcpClient) {
                        RouteService rs = RouteServiceImpl.getInstance();
                        RouteConfig rconf = rs.getDefaultRoute(interfaceName);
                        if (rconf != null) {
                            s_logger.debug("{} is configured for LAN/DHCP - removing GATEWAY route ...", rconf.getInterfaceName());
                            rs.removeStaticRoute(rconf.getDestination(), rconf.getGateway(), rconf.getNetmask(), rconf.getInterfaceName());
                        }
                    }
                }
                if (dhcpServerEnabled && !DhcpServerManager.isRunning(interfaceName)) {
                    s_logger.debug("Starting DHCP server for {}", interfaceName);
                    this.m_netAdminService.manageDhcpServer(interfaceName, true);
                }
            } else if (DhcpServerManager.isRunning(interfaceName)) {
                s_logger.debug("Stopping DHCP server for {}", interfaceName);
                this.m_netAdminService.manageDhcpServer(interfaceName, false);
            }
            // post event if there were any changes
            if (postStatusChangeEvent) {
                s_logger.debug("Posting NetworkStatusChangeEvent for {}: {}", interfaceName, currentInterfaceState);
                this.m_eventAdmin.postEvent(new NetworkStatusChangeEvent(interfaceName, currentInterfaceState, null));
                this.m_interfaceState.put(interfaceName, currentInterfaceState);
            }
            // If the interface is disabled in Denali, stop the monitor
            if (!interfaceEnabled) {
                s_logger.debug("{} is disabled - stopping monitor", interfaceName);
                stopMonitor(interfaceName);
            }
        } catch (Exception e) {
            s_logger.warn("Error during Ethernet Monitor", e);
        }
    }
}
Also used : IP4Address(org.eclipse.kura.net.IP4Address) NetInterfaceStatus(org.eclipse.kura.net.NetInterfaceStatus) RouteConfig(org.eclipse.kura.net.route.RouteConfig) DhcpServerConfig4(org.eclipse.kura.net.dhcp.DhcpServerConfig4) KuraException(org.eclipse.kura.KuraException) NetConfigIP4(org.eclipse.kura.net.NetConfigIP4) EthernetInterfaceConfigImpl(org.eclipse.kura.core.net.EthernetInterfaceConfigImpl) NetworkStatusChangeEvent(org.eclipse.kura.net.admin.event.NetworkStatusChangeEvent) NetConfig(org.eclipse.kura.net.NetConfig) RouteService(org.eclipse.kura.linux.net.route.RouteService) NetInterfaceAddressConfig(org.eclipse.kura.net.NetInterfaceAddressConfig)

Example 2 with RouteService

use of org.eclipse.kura.linux.net.route.RouteService in project kura by eclipse.

the class WifiMonitorServiceImpl method isAccessPointReachable.

private boolean isAccessPointReachable(String interfaceName, int tout) throws KuraException {
    boolean ret = true;
    RouteService rs = RouteServiceImpl.getInstance();
    RouteConfig rconf = rs.getDefaultRoute(interfaceName);
    if (rconf != null) {
        IPAddress ipAddress = rconf.getGateway();
        String iface = rconf.getInterfaceName();
        if (ipAddress != null && iface != null && iface.equals(interfaceName)) {
            try {
                InetAddress inetAddress = InetAddress.getByName(ipAddress.getHostAddress());
                try {
                    ret = inetAddress.isReachable(tout);
                    s_logger.info("Access point reachable? " + ret);
                } catch (IOException e) {
                    throw new KuraException(KuraErrorCode.INTERNAL_ERROR, e);
                }
            } catch (UnknownHostException e) {
                throw new KuraException(KuraErrorCode.INTERNAL_ERROR, e);
            }
        }
    }
    return ret;
}
Also used : UnknownHostException(java.net.UnknownHostException) KuraException(org.eclipse.kura.KuraException) RouteConfig(org.eclipse.kura.net.route.RouteConfig) RouteService(org.eclipse.kura.linux.net.route.RouteService) IOException(java.io.IOException) IPAddress(org.eclipse.kura.net.IPAddress) InetAddress(java.net.InetAddress)

Example 3 with RouteService

use of org.eclipse.kura.linux.net.route.RouteService in project kura by eclipse.

the class WifiMonitorServiceImpl method monitor.

private void monitor() {
    synchronized (s_lock) {
        NetworkConfiguration newNetConfiguration = this.m_newNetConfiguration;
        try {
            // Track the interfaces being reconfigured
            List<String> interfacesToReconfigure = new ArrayList<String>();
            // Check to see if the configuration has changed
            // s_logger.debug("m_newNetConfiguration: " + m_newNetConfiguration);
            // s_logger.debug("m_currentNetworkConfiguration: " + m_currentNetworkConfiguration);
            s_logger.debug("monitor() :: wifi has started another run ...");
            // Find and disable interfaces affected by the configuration change
            if (newNetConfiguration != null && !newNetConfiguration.equals(this.m_currentNetworkConfiguration)) {
                s_logger.info("monitor() :: Found a new network configuration, will check if wifi has been reconfigured ...");
                // Note that the call to getReconfiguredWifiInterfaces() may also update
                // m_enabledInterfaces or m_disabledInterfaces
                interfacesToReconfigure.addAll(getReconfiguredWifiInterfaces());
                this.m_currentNetworkConfiguration = newNetConfiguration;
                // interface statuses, a call to WifiState.isUp() should return false.
                for (String interfaceName : interfacesToReconfigure) {
                    s_logger.debug("monitor() :: configuration has changed for {} , disabling...", interfaceName);
                    disableInterface(interfaceName);
                }
            }
            // Check all interfaces configured to be enabled.
            // This includes the interfaces that might have been enabled by the above configuration change.
            // Get fresh interface statuses and post status change events.
            Map<String, InterfaceState> newStatuses = getInterfaceStatuses(this.m_enabledInterfaces);
            checkStatusChange(this.m_interfaceStatuses, newStatuses);
            this.m_interfaceStatuses = newStatuses;
            for (String interfaceName : this.m_enabledInterfaces) {
                // Get current configuration
                WifiInterfaceConfigImpl wifiInterfaceConfig = (WifiInterfaceConfigImpl) this.m_currentNetworkConfiguration.getNetInterfaceConfig(interfaceName);
                WifiConfig wifiConfig = getWifiConfig(wifiInterfaceConfig);
                // Make sure we have enough information
                if (wifiInterfaceConfig == null) {
                    s_logger.warn("monitor() :: missing WifiInterfaceConfigImpl for {}", interfaceName);
                    continue;
                }
                if (wifiConfig == null) {
                    s_logger.warn("monitor() :: missing WifiConfig for {}", interfaceName);
                    continue;
                }
                // If not we treat the interface as if needing to be reconfigured.
                if (this.m_first && !LinuxNetworkUtil.isKernelModuleLoadedForMode(interfaceName, wifiConfig.getMode())) {
                    s_logger.info("monitor() :: {} kernel module not suitable for WiFi mode {}", interfaceName, wifiConfig.getMode());
                    this.m_first = false;
                    interfacesToReconfigure.add(interfaceName);
                    disableInterface(interfaceName);
                    // Update the current wifi state
                    m_interfaceStatuses.remove(interfaceName);
                    m_interfaceStatuses.put(interfaceName, new InterfaceState(NetInterfaceType.WIFI, interfaceName));
                }
                // Get current state
                InterfaceState wifiState = this.m_interfaceStatuses.get(interfaceName);
                if (wifiState == null) {
                    s_logger.warn("monitor() :: missing InterfaceState for {}", interfaceName);
                    continue;
                }
                // s_logger.debug("Evaluating: " + interfaceName + " and is currently up? " + wifiState.isUp());
                // s_logger.debug("Evaluating: " + interfaceName + " and is currently link up? " +
                // wifiState.isLinkUp());
                // This flag is changed if the interface is disabled intentionally by the code below
                boolean up = wifiState.isUp();
                if (up) {
                    // FIXME should we just disable it like in the Infrastructure case above?
                    if (WifiMode.INFRA.equals(wifiConfig.getMode())) {
                        // get signal strength only if somebody needs it
                        if (this.m_listeners != null && this.m_listeners.size() > 0) {
                            int rssi = 0;
                            try {
                                s_logger.debug("monitor() :: Getting Signal Level for {} -> {}", interfaceName, wifiConfig.getSSID());
                                rssi = getSignalLevel(interfaceName, wifiConfig.getSSID());
                                s_logger.debug("monitor() :: Wifi RSSI is {}", rssi);
                            } catch (KuraException e) {
                                s_logger.error("monitor() :: Failed to get Signal Level for {} -> {}", interfaceName, wifiConfig.getSSID());
                                s_logger.error("monitor() :: Failed to get Signal Level - {}", e);
                                rssi = 0;
                            }
                            for (WifiClientMonitorListener listener : this.m_listeners) {
                                listener.setWifiSignalLevel(rssi);
                            }
                        }
                        if (!wifiState.isLinkUp()) {
                            s_logger.debug("monitor() :: link is down - disabling {}", interfaceName);
                            disableInterface(interfaceName);
                            up = false;
                        }
                        s_logger.debug("monitor() :: pingAccessPoint()? {}", wifiConfig.pingAccessPoint());
                        if (wifiConfig.pingAccessPoint()) {
                            NetConfigIP4 netConfigIP4 = getIP4config(wifiInterfaceConfig);
                            if (netConfigIP4 != null && netConfigIP4.isDhcp()) {
                                boolean isApReachable = false;
                                for (int i = 0; i < 3; i++) {
                                    isApReachable = isAccessPointReachable(interfaceName, 1000);
                                    if (isApReachable) {
                                        break;
                                    }
                                    try {
                                        Thread.sleep(1000);
                                    } catch (InterruptedException e) {
                                    }
                                }
                                if (!isApReachable) {
                                    this.m_netAdminService.renewDhcpLease(interfaceName);
                                }
                            }
                        }
                        NetConfigIP4 netConfigIP4 = getIP4config(wifiInterfaceConfig);
                        if (netConfigIP4.getStatus().equals(NetInterfaceStatus.netIPv4StatusEnabledLAN)) {
                            if (netConfigIP4.isDhcp()) {
                                RouteService rs = RouteServiceImpl.getInstance();
                                RouteConfig rconf = rs.getDefaultRoute(interfaceName);
                                if (rconf != null) {
                                    s_logger.debug("monitor() :: {} is configured for LAN/DHCP - removing GATEWAY route ...", rconf.getInterfaceName());
                                    rs.removeStaticRoute(rconf.getDestination(), rconf.getGateway(), rconf.getNetmask(), rconf.getInterfaceName());
                                }
                            }
                        }
                    } else if (WifiMode.MASTER.equals(wifiConfig.getMode())) {
                        if (!wifiState.isLinkUp()) {
                            // disabling interface is probably needed to handle potential driver issues.
                            s_logger.warn("monitor() :: !! Link is down for the {} in AP mode, while IP address is assigned. Will disable and reenable interface ...", interfaceName);
                            disableInterface(interfaceName);
                            enableInterface(wifiInterfaceConfig);
                        }
                    }
                }
                // * just enable interface
                if (!up) {
                    // FIXME if reloading fails it won't be retried.
                    if (interfacesToReconfigure.contains(interfaceName)) {
                        try {
                            s_logger.info("monitor() :: reload {} kernel module for WiFi mode {}", interfaceName, wifiConfig.getMode());
                            reloadKernelModule(interfaceName, wifiConfig.getMode());
                        } catch (KuraException e) {
                            s_logger.warn("monitor() :: failed to reload {} kernel module." + " FIXME: THIS WON'T BE RETRIED", interfaceName, e);
                            continue;
                        }
                    }
                    try {
                        if (WifiMode.MASTER.equals(wifiConfig.getMode())) {
                            s_logger.debug("monitor() :: enable {} in master mode", interfaceName);
                            enableInterface(wifiInterfaceConfig);
                        } else if (WifiMode.INFRA.equals(wifiConfig.getMode())) {
                            if (wifiConfig.ignoreSSID()) {
                                s_logger.info("monitor() :: enable {} in infra mode", interfaceName);
                                enableInterface(wifiInterfaceConfig);
                            } else {
                                if (isAccessPointAvailable(interfaceName, wifiConfig.getSSID())) {
                                    s_logger.info("monitor() :: found access point - enable {} in infra mode", interfaceName);
                                    enableInterface(wifiInterfaceConfig);
                                } else {
                                    s_logger.warn("monitor() :: {} - access point is not available", wifiConfig.getSSID());
                                }
                            }
                        }
                    } catch (KuraException e) {
                        s_logger.error("monitor() :: Error enabling {} interface, will try to reset wifi", interfaceName, e);
                        resetWifiDevice(interfaceName);
                    }
                }
            }
            // Check all interfaces configured to be disabled
            for (String interfaceName : this.m_disabledInterfaces) {
                InterfaceState wifiState = this.m_interfaceStatuses.get(interfaceName);
                if (wifiState != null && wifiState.isUp()) {
                    s_logger.debug("monitor() :: {} is currently up - disable interface", interfaceName);
                    disableInterface(interfaceName);
                }
            }
            // Shut down the monitor if no interface is configured to be enabled
            if (this.m_enabledInterfaces.isEmpty() && monitorTask != null) {
                s_logger.info("monitor() :: No enabled wifi interfaces - shutting down monitor thread");
                stopThread.set(true);
                monitorTask.cancel(true);
                monitorTask = null;
            }
        } catch (Exception e) {
            s_logger.warn("Error during WiFi Monitor handle event", e);
        }
    }
}
Also used : WifiConfig(org.eclipse.kura.net.wifi.WifiConfig) ArrayList(java.util.ArrayList) RouteConfig(org.eclipse.kura.net.route.RouteConfig) WifiAccessPoint(org.eclipse.kura.net.wifi.WifiAccessPoint) KuraException(org.eclipse.kura.KuraException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException) NetConfigIP4(org.eclipse.kura.net.NetConfigIP4) WifiInterfaceConfigImpl(org.eclipse.kura.core.net.WifiInterfaceConfigImpl) WifiClientMonitorListener(org.eclipse.kura.net.wifi.WifiClientMonitorListener) KuraException(org.eclipse.kura.KuraException) NetworkConfiguration(org.eclipse.kura.core.net.NetworkConfiguration) RouteService(org.eclipse.kura.linux.net.route.RouteService)

Aggregations

KuraException (org.eclipse.kura.KuraException)3 RouteService (org.eclipse.kura.linux.net.route.RouteService)3 RouteConfig (org.eclipse.kura.net.route.RouteConfig)3 IOException (java.io.IOException)2 UnknownHostException (java.net.UnknownHostException)2 NetConfigIP4 (org.eclipse.kura.net.NetConfigIP4)2 InetAddress (java.net.InetAddress)1 ArrayList (java.util.ArrayList)1 EthernetInterfaceConfigImpl (org.eclipse.kura.core.net.EthernetInterfaceConfigImpl)1 NetworkConfiguration (org.eclipse.kura.core.net.NetworkConfiguration)1 WifiInterfaceConfigImpl (org.eclipse.kura.core.net.WifiInterfaceConfigImpl)1 IP4Address (org.eclipse.kura.net.IP4Address)1 IPAddress (org.eclipse.kura.net.IPAddress)1 NetConfig (org.eclipse.kura.net.NetConfig)1 NetInterfaceAddressConfig (org.eclipse.kura.net.NetInterfaceAddressConfig)1 NetInterfaceStatus (org.eclipse.kura.net.NetInterfaceStatus)1 NetworkStatusChangeEvent (org.eclipse.kura.net.admin.event.NetworkStatusChangeEvent)1 DhcpServerConfig4 (org.eclipse.kura.net.dhcp.DhcpServerConfig4)1 WifiAccessPoint (org.eclipse.kura.net.wifi.WifiAccessPoint)1 WifiClientMonitorListener (org.eclipse.kura.net.wifi.WifiClientMonitorListener)1