Add field trial WebRTC-AllowMACBasedIPv6

Bug: webrtc:12268
Change-Id: I6fad191a12aa2834eb2f38b437781cba23785d5e
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/196506
Commit-Queue: Jonas Oreland <jonaso@webrtc.org>
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32782}
diff --git a/rtc_base/network.cc b/rtc_base/network.cc
index 8aabdcb..07c39ae 100644
--- a/rtc_base/network.cc
+++ b/rtc_base/network.cc
@@ -131,7 +131,7 @@
 }
 
 #if !defined(__native_client__)
-bool IsIgnoredIPv6(const InterfaceAddress& ip) {
+bool IsIgnoredIPv6(bool allow_mac_based_ipv6, const InterfaceAddress& ip) {
   if (ip.family() != AF_INET6) {
     return false;
   }
@@ -144,7 +144,7 @@
   }
 
   // Any MAC based IPv6 should be avoided to prevent the MAC tracking.
-  if (IPIsMacBased(ip)) {
+  if (IPIsMacBased(ip) && !allow_mac_based_ipv6) {
     return true;
   }
 
@@ -478,11 +478,15 @@
   return nullptr;
 }
 
-BasicNetworkManager::BasicNetworkManager() {}
+BasicNetworkManager::BasicNetworkManager()
+    : allow_mac_based_ipv6_(
+          webrtc::field_trial::IsEnabled("WebRTC-AllowMACBasedIPv6")) {}
 
 BasicNetworkManager::BasicNetworkManager(
     NetworkMonitorFactory* network_monitor_factory)
-    : network_monitor_factory_(network_monitor_factory) {}
+    : network_monitor_factory_(network_monitor_factory),
+      allow_mac_based_ipv6_(
+          webrtc::field_trial::IsEnabled("WebRTC-AllowMACBasedIPv6")) {}
 
 BasicNetworkManager::~BasicNetworkManager() {}
 
@@ -535,7 +539,7 @@
 
     // Special case for IPv6 address.
     if (cursor->ifa_addr->sa_family == AF_INET6) {
-      if (IsIgnoredIPv6(ip)) {
+      if (IsIgnoredIPv6(allow_mac_based_ipv6_, ip)) {
         continue;
       }
       scope_id =
@@ -713,7 +717,7 @@
             scope_id = v6_addr->sin6_scope_id;
             ip = IPAddress(v6_addr->sin6_addr);
 
-            if (IsIgnoredIPv6(InterfaceAddress(ip))) {
+            if (IsIgnoredIPv6(allow_mac_based_ipv6_, InterfaceAddress(ip))) {
               continue;
             }
 
diff --git a/rtc_base/network.h b/rtc_base/network.h
index 7103f0f..3107b72 100644
--- a/rtc_base/network.h
+++ b/rtc_base/network.h
@@ -293,6 +293,7 @@
       nullptr;
   std::unique_ptr<NetworkMonitorInterface> network_monitor_
       RTC_GUARDED_BY(thread_);
+  bool allow_mac_based_ipv6_ = false;
 };
 
 // Represents a Unix-type network interface, with a name and single address.
diff --git a/rtc_base/network_unittest.cc b/rtc_base/network_unittest.cc
index 13f888e..73ddd81 100644
--- a/rtc_base/network_unittest.cc
+++ b/rtc_base/network_unittest.cc
@@ -33,6 +33,7 @@
 #if defined(WEBRTC_WIN)
 #include "rtc_base/logging.h"  // For RTC_LOG_GLE
 #endif
+#include "test/field_trial.h"
 
 using ::testing::Contains;
 using ::testing::Not;
@@ -1240,4 +1241,42 @@
   }
 }
 
+#if defined(WEBRTC_POSIX)
+TEST_F(NetworkTest, IgnoresMACBasedIPv6Address) {
+  std::string ipv6_address = "2607:fc20:f340:1dc8:214:22ff:fe01:2345";
+  std::string ipv6_mask = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+  BasicNetworkManager manager;
+  manager.StartUpdating();
+
+  // IPSec interface; name is in form "ipsec<index>".
+  char if_name[20] = "ipsec11";
+  ifaddrs* addr_list =
+      InstallIpv6Network(if_name, ipv6_address, ipv6_mask, manager);
+
+  BasicNetworkManager::NetworkList list;
+  manager.GetNetworks(&list);
+  EXPECT_EQ(list.size(), 0u);
+  ReleaseIfAddrs(addr_list);
+}
+
+TEST_F(NetworkTest, WebRTC_AllowMACBasedIPv6Address) {
+  webrtc::test::ScopedFieldTrials field_trials(
+      "WebRTC-AllowMACBasedIPv6/Enabled/");
+  std::string ipv6_address = "2607:fc20:f340:1dc8:214:22ff:fe01:2345";
+  std::string ipv6_mask = "FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF";
+  BasicNetworkManager manager;
+  manager.StartUpdating();
+
+  // IPSec interface; name is in form "ipsec<index>".
+  char if_name[20] = "ipsec11";
+  ifaddrs* addr_list =
+      InstallIpv6Network(if_name, ipv6_address, ipv6_mask, manager);
+
+  BasicNetworkManager::NetworkList list;
+  manager.GetNetworks(&list);
+  EXPECT_EQ(list.size(), 1u);
+  ReleaseIfAddrs(addr_list);
+}
+#endif
+
 }  // namespace rtc