diff --git a/dom/system/gonk/NetworkManager.js b/dom/system/gonk/NetworkManager.js index 81e69560deb4..589d781c5e92 100644 --- a/dom/system/gonk/NetworkManager.js +++ b/dom/system/gonk/NetworkManager.js @@ -259,6 +259,10 @@ NetworkManager.prototype = { network.type == Ci.nsINetworkInterface.NETWORK_TYPE_MOBILE_SUPL) { this.removeHostRoute(network); } + // Remove routing table in /proc/net/route + if (network.type == Ci.nsINetworkInterface.NETWORK_TYPE_WIFI) { + this.resetRoutingTable(this._activeInfo); + } // Abort ongoing captive portal detection on the wifi interface CaptivePortalDetectionHelper.notify(CaptivePortalDetectionHelper.EVENT_DISCONNECT, network); this.setAndConfigureActive(); @@ -354,6 +358,9 @@ NetworkManager.prototype = { active: null, _overriddenActive: null, + // Clone network info so we can still get information when network is disconnected + _activeInfo: null, + overrideActive: function overrideActive(network) { this._overriddenActive = network; this.setAndConfigureActive(); @@ -442,6 +449,7 @@ NetworkManager.prototype = { // Find a suitable network interface to activate. this.active = null; + this._activeInfo = Object.create(null); for each (let network in this.networkInterfaces) { if (network.state != Ci.nsINetworkInterface.NETWORK_STATE_CONNECTED) { continue; @@ -450,6 +458,7 @@ NetworkManager.prototype = { defaultDataNetwork = network; } this.active = network; + this._activeInfo = {name:network.name, ip:network.ip, netmask:network.netmask}; if (network.type == this.preferredNetworkType) { debug("Found our preferred type of network: " + network.name); break; @@ -476,6 +485,16 @@ NetworkManager.prototype = { } }, + resetRoutingTable: function resetRoutingTable(network) { + let options = { + cmd: "removeNetworkRoute", + ifname: network.name, + ip : network.ip, + netmask: network.netmask, + }; + this.worker.postMessage(options); + }, + setDefaultRouteAndDNS: function setDefaultRouteAndDNS(oldInterface) { debug("Going to change route and DNS to " + this.active.name); let options = { diff --git a/dom/system/gonk/net_worker.js b/dom/system/gonk/net_worker.js index a0fcc1e69363..eea4d28f8c4b 100644 --- a/dom/system/gonk/net_worker.js +++ b/dom/system/gonk/net_worker.js @@ -245,6 +245,18 @@ function removeHostRoute(options) { libnetutils.ifc_remove_route(options.ifname, options.mmsproxy, 32, options.gateway); } +function removeNetworkRoute(options) { + let ipvalue = netHelpers.stringToIP(options.ip); + let netmaskvalue = netHelpers.stringToIP(options.netmask); + let subnet = netmaskvalue & ipvalue; + let dst = netHelpers.ipToString(subnet); + let prefixLength = netHelpers.getMaskLength(netmaskvalue); + let gateway = "0.0.0.0"; + + libnetutils.ifc_remove_default_route(options.ifname); + libnetutils.ifc_remove_route(options.ifname, dst, prefixLength, gateway); +} + let gCommandQueue = []; let gCurrentCommand = null; let gCurrentCallback = null; diff --git a/dom/system/gonk/systemlibs.js b/dom/system/gonk/systemlibs.js index 9c42da0a37ec..ce9a0751bea0 100644 --- a/dom/system/gonk/systemlibs.js +++ b/dom/system/gonk/systemlibs.js @@ -404,5 +404,18 @@ this.netHelpers = { mask |= (0x80000000 >> i); } return this.ntohl(mask); + }, + + /** + * Get Mask length from given mask address + */ + getMaskLength: function getMaskLength(mask) { + let len = 0; + let netmask = this.ntohl(mask); + while (netmask & 0x80000000) { + len++; + netmask = netmask << 1; + } + return len; } }; diff --git a/dom/wifi/WifiWorker.js b/dom/wifi/WifiWorker.js index 9a5e2e7690b0..0c2fe7dbd445 100644 --- a/dom/wifi/WifiWorker.js +++ b/dom/wifi/WifiWorker.js @@ -747,6 +747,10 @@ var WifiManager = (function() { } manager.connectionDropped = function(callback) { + // Reset network interface when connection drop + configureInterface(manager.ifname, 0, 0, 0, 0, 0, function (data) { + }); + // If we got disconnected, kill the DHCP client in preparation for // reconnection. resetConnections(manager.ifname, function() {