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);
}
}
}
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;
}
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);
}
}
}
Aggregations