Bug 1584089 - Use only global routes for network ID calculation, r=valentin
authorMichal Novotny <michal.novotny@gmail.com>
Tue, 01 Oct 2019 12:58:18 +0000
changeset 495796 053b16ef71e8a55eb5f31173a59304f8cad4685f
parent 495795 f472f9a312c98519c9e7efe2a8633455798b2356
child 495797 046a8c9987d95355780330e6c9a66523b8a5e235
push id114140
push userdvarga@mozilla.com
push dateWed, 02 Oct 2019 18:04:51 +0000
treeherdermozilla-inbound@32eb0ea893f3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvalentin
bugs1584089
milestone71.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1584089 - Use only global routes for network ID calculation, r=valentin Although local link addresses are not routable, some Android versions have default route for such prefix. We need to ignore any non-global routes when calculating ID. Differential Revision: https://phabricator.services.mozilla.com/D47578
netwerk/system/netlink/NetlinkService.cpp
--- a/netwerk/system/netlink/NetlinkService.cpp
+++ b/netwerk/system/netlink/NetlinkService.cpp
@@ -11,16 +11,17 @@
 #include <linux/rtnetlink.h>
 
 #include "nsThreadUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "NetlinkService.h"
 #include "nsString.h"
 #include "nsPrintfCString.h"
 #include "mozilla/Logging.h"
+#include "../../base/IPv6Utils.h"
 
 #include "mozilla/Base64.h"
 #include "mozilla/FileUtils.h"
 #include "mozilla/Preferences.h"
 #include "mozilla/Services.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/DebugOnly.h"
@@ -253,16 +254,17 @@ class NetlinkRoute {
   NetlinkRoute()
       : mHasGWAddr(false),
         mHasPrefSrcAddr(false),
         mHasDstAddr(false),
         mHasOif(false),
         mHasPrio(false) {}
 
   bool IsUnicast() const { return mRtm.rtm_type == RTN_UNICAST; }
+  bool ScopeIsUniverse() const { return mRtm.rtm_scope == RT_SCOPE_UNIVERSE; }
   bool IsDefault() const { return mRtm.rtm_dst_len == 0; }
   bool HasOif() const { return mHasOif; }
   uint8_t Oif() const { return mOif; }
   uint8_t Family() const { return mRtm.rtm_family; }
   bool HasPrefSrcAddr() const { return mHasPrefSrcAddr; }
   const in_common_addr* GetGWAddrPtr() const {
     return mHasGWAddr ? &mGWAddr : nullptr;
   }
@@ -336,16 +338,18 @@ class NetlinkRoute {
 
 #ifdef NL_DEBUG_LOG
   void GetAsString(nsACString& _retval) const {
     nsAutoCString addrStr;
     _retval.Assign("table=");
     _retval.AppendInt(mRtm.rtm_table);
     _retval.Append(" type=");
     _retval.AppendInt(mRtm.rtm_type);
+    _retval.Append(" scope=");
+    _retval.AppendInt(mRtm.rtm_scope);
     if (mRtm.rtm_family == AF_INET) {
       _retval.Append(" family=AF_INET dst=");
       addrStr.Assign("0.0.0.0/");
     } else {
       _retval.Append(" family=AF_INET6 dst=");
       addrStr.Assign("::/");
     }
     if (mHasDstAddr) {
@@ -814,22 +818,22 @@ void NetlinkService::OnRouteMessage(stru
     return;
   }
 
 #ifdef NL_DEBUG_LOG
   nsAutoCString routeDbgStr;
   route->GetAsString(routeDbgStr);
 #endif
 
-  if (!route->IsUnicast()) {
+  if (!route->IsUnicast() || !route->ScopeIsUniverse()) {
     // Use only unicast routes
 #ifdef NL_DEBUG_LOG
-    LOG(("Ignoring non-unicast route: %s", routeDbgStr.get()));
+    LOG(("Not an unicast global route: %s", routeDbgStr.get()));
 #else
-    LOG(("Ignoring non-unicast route"));
+    LOG(("Not an unicast global route"));
 #endif
     return;
   }
 
   // Adding/removing any unicast route might change network ID
   TriggerNetworkIDCalculation();
 
   if (!route->IsDefault()) {
@@ -936,23 +940,23 @@ void NetlinkService::OnNeighborMessage(s
 void NetlinkService::OnRouteCheckResult(struct nlmsghdr* aNlh) {
   LOG(("NetlinkService::OnRouteCheckResult"));
   nsAutoPtr<NetlinkRoute> route;
 
   if (aNlh) {
     route = new NetlinkRoute();
     if (!route->Init(aNlh)) {
       route = nullptr;
-    } else if (!route->IsUnicast()) {
+    } else if (!route->IsUnicast() || !route->ScopeIsUniverse()) {
 #ifdef NL_DEBUG_LOG
       nsAutoCString routeDbgStr;
       route->GetAsString(routeDbgStr);
-      LOG(("Ignoring non-unicast route: %s", routeDbgStr.get()));
+      LOG(("Not an unicast global route: %s", routeDbgStr.get()));
 #else
-      LOG(("Ignoring non-unicast route"));
+      LOG(("Not an unicast global route"));
 #endif
       route = nullptr;
     }
   }
 
   nsAutoPtr<NetlinkRoute>* routeCheckResultPtr;
   if (mOutgoingMessages[0]->Family() == AF_INET) {
     routeCheckResultPtr = &mIPv4RouteCheckResult;
@@ -1261,16 +1265,23 @@ bool NetlinkService::CalculateIDForFamil
 
     nsAutoCString neighKey;
     const in_common_addr* addrPtr = (*routesPtr)[i]->GetGWAddrPtr();
     if (!addrPtr) {
       LOG(("There is no GW address in default route."));
       continue;
     }
 
+    if (aFamily == AF_INET6 &&
+        net::utils::ipv6_scope((const unsigned char*)addrPtr) !=
+            IPV6_SCOPE_GLOBAL) {
+      LOG(("Scope of GW isn't global."));
+      continue;
+    }
+
     GetNeighborKey(addrPtr, (*routesPtr)[i]->Family(), (*routesPtr)[i]->Oif(),
                    neighKey);
 
     NetlinkNeighbor* neigh = nullptr;
     if (!mNeighbors.Get(neighKey, &neigh)) {
       LOG(("Neighbor %s not found in hashtable.", neighKey.get()));
       continue;
     }