11eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline/* 21eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * Copyright (C) 2016 The Android Open Source Project 31eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * 41eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * Licensed under the Apache License, Version 2.0 (the "License"); 51eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * you may not use this file except in compliance with the License. 61eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * You may obtain a copy of the License at 71eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * 81eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * http://www.apache.org/licenses/LICENSE-2.0 91eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * 101eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * Unless required by applicable law or agreed to in writing, software 111eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * distributed under the License is distributed on an "AS IS" BASIS, 121eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * See the License for the specific language governing permissions and 141eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * limitations under the License. 151eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline */ 161eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 171eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klinepackage com.android.server.connectivity.tethering; 181eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 191eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport android.net.ConnectivityManager; 201eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport android.net.IpPrefix; 211eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport android.net.LinkAddress; 221eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport android.net.LinkProperties; 231eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport android.net.Network; 241eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport android.net.NetworkCapabilities; 251eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport android.net.NetworkState; 261eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport android.net.RouteInfo; 271eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport android.util.Log; 281eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 291eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport java.net.Inet6Address; 301eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport java.net.InetAddress; 311eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klineimport java.util.ArrayList; 326e29bf0069caceb38806101c150acb477df99989Erik Klineimport java.util.LinkedList; 331eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 341eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 351eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline/** 361eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * IPv6 tethering is rather different from IPv4 owing to the absence of NAT. 371eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * This coordinator is responsible for evaluating the dedicated prefixes 381eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * assigned to the device and deciding how to divvy them up among downstream 391eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * interfaces. 401eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * 411eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline * @hide 421eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline */ 431eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Klinepublic class IPv6TetheringCoordinator { 441eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private static final String TAG = IPv6TetheringCoordinator.class.getSimpleName(); 451eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private static final boolean DBG = false; 461eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private static final boolean VDBG = false; 471eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 481eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private final ArrayList<TetherInterfaceStateMachine> mNotifyList; 496e29bf0069caceb38806101c150acb477df99989Erik Kline private final LinkedList<TetherInterfaceStateMachine> mActiveDownstreams; 501eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private NetworkState mUpstreamNetworkState; 511eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 521eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline public IPv6TetheringCoordinator(ArrayList<TetherInterfaceStateMachine> notifyList) { 531eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline mNotifyList = notifyList; 546e29bf0069caceb38806101c150acb477df99989Erik Kline mActiveDownstreams = new LinkedList<>(); 556e29bf0069caceb38806101c150acb477df99989Erik Kline } 566e29bf0069caceb38806101c150acb477df99989Erik Kline 576e29bf0069caceb38806101c150acb477df99989Erik Kline public void addActiveDownstream(TetherInterfaceStateMachine downstream) { 586e29bf0069caceb38806101c150acb477df99989Erik Kline if (mActiveDownstreams.indexOf(downstream) == -1) { 596e29bf0069caceb38806101c150acb477df99989Erik Kline // Adding a new downstream appends it to the list. Adding a 606e29bf0069caceb38806101c150acb477df99989Erik Kline // downstream a second time without first removing it has no effect. 616e29bf0069caceb38806101c150acb477df99989Erik Kline mActiveDownstreams.offer(downstream); 626e29bf0069caceb38806101c150acb477df99989Erik Kline updateIPv6TetheringInterfaces(); 636e29bf0069caceb38806101c150acb477df99989Erik Kline } 646e29bf0069caceb38806101c150acb477df99989Erik Kline } 656e29bf0069caceb38806101c150acb477df99989Erik Kline 666e29bf0069caceb38806101c150acb477df99989Erik Kline public void removeActiveDownstream(TetherInterfaceStateMachine downstream) { 676e29bf0069caceb38806101c150acb477df99989Erik Kline stopIPv6TetheringOn(downstream); 686e29bf0069caceb38806101c150acb477df99989Erik Kline if (mActiveDownstreams.remove(downstream)) { 696e29bf0069caceb38806101c150acb477df99989Erik Kline updateIPv6TetheringInterfaces(); 706e29bf0069caceb38806101c150acb477df99989Erik Kline } 711eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 721eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 731eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline public void updateUpstreamNetworkState(NetworkState ns) { 741eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (VDBG) { 751eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline Log.d(TAG, "updateUpstreamNetworkState: " + toDebugString(ns)); 761eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 77fa37b2f6135a532742ef8242e70dbf499abe8d95Erik Kline if (!canTetherIPv6(ns)) { 781eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline stopIPv6TetheringOnAllInterfaces(); 791eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline setUpstreamNetworkState(null); 801eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline return; 811eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 821eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 831eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (mUpstreamNetworkState != null && 841eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline !ns.network.equals(mUpstreamNetworkState.network)) { 851eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline stopIPv6TetheringOnAllInterfaces(); 861eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 87fa37b2f6135a532742ef8242e70dbf499abe8d95Erik Kline 881eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline setUpstreamNetworkState(ns); 89fa37b2f6135a532742ef8242e70dbf499abe8d95Erik Kline updateIPv6TetheringInterfaces(); 901eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 911eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 921eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private void stopIPv6TetheringOnAllInterfaces() { 931eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline for (TetherInterfaceStateMachine sm : mNotifyList) { 946e29bf0069caceb38806101c150acb477df99989Erik Kline stopIPv6TetheringOn(sm); 951eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 961eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 971eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 981eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private void setUpstreamNetworkState(NetworkState ns) { 99fa37b2f6135a532742ef8242e70dbf499abe8d95Erik Kline if (ns == null) { 1001eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline mUpstreamNetworkState = null; 1011eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } else { 102fa37b2f6135a532742ef8242e70dbf499abe8d95Erik Kline // Make a deep copy of the parts we need. 1031eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline mUpstreamNetworkState = new NetworkState( 1041eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline null, 1051eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline new LinkProperties(ns.linkProperties), 1061eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline new NetworkCapabilities(ns.networkCapabilities), 1071eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline new Network(ns.network), 1081eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline null, 1091eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline null); 1101eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1111eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 1121eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (DBG) { 1131eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline Log.d(TAG, "setUpstreamNetworkState: " + toDebugString(mUpstreamNetworkState)); 1141eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1151eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1161eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 117fa37b2f6135a532742ef8242e70dbf499abe8d95Erik Kline private void updateIPv6TetheringInterfaces() { 1181eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline for (TetherInterfaceStateMachine sm : mNotifyList) { 1196e29bf0069caceb38806101c150acb477df99989Erik Kline final LinkProperties lp = getInterfaceIPv6LinkProperties(sm); 120fa37b2f6135a532742ef8242e70dbf499abe8d95Erik Kline sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, lp); 1211eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline break; 1221eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1231eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1241eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 1256e29bf0069caceb38806101c150acb477df99989Erik Kline private LinkProperties getInterfaceIPv6LinkProperties(TetherInterfaceStateMachine sm) { 126fa37b2f6135a532742ef8242e70dbf499abe8d95Erik Kline if (mUpstreamNetworkState == null) return null; 127fa37b2f6135a532742ef8242e70dbf499abe8d95Erik Kline 1286e29bf0069caceb38806101c150acb477df99989Erik Kline if (sm.interfaceType() == ConnectivityManager.TETHERING_BLUETOOTH) { 1296e29bf0069caceb38806101c150acb477df99989Erik Kline // TODO: Figure out IPv6 support on PAN interfaces. 1306e29bf0069caceb38806101c150acb477df99989Erik Kline return null; 1316e29bf0069caceb38806101c150acb477df99989Erik Kline } 1326e29bf0069caceb38806101c150acb477df99989Erik Kline 1331eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // NOTE: Here, in future, we would have policies to decide how to divvy 1341eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // up the available dedicated prefixes among downstream interfaces. 1351eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // At this time we have no such mechanism--we only support tethering 1366e29bf0069caceb38806101c150acb477df99989Erik Kline // IPv6 toward the oldest (first requested) active downstream. 1376e29bf0069caceb38806101c150acb477df99989Erik Kline 1386e29bf0069caceb38806101c150acb477df99989Erik Kline final TetherInterfaceStateMachine currentActive = mActiveDownstreams.peek(); 1396e29bf0069caceb38806101c150acb477df99989Erik Kline if (currentActive != null && currentActive == sm) { 1406e29bf0069caceb38806101c150acb477df99989Erik Kline final LinkProperties lp = getIPv6OnlyLinkProperties( 1416e29bf0069caceb38806101c150acb477df99989Erik Kline mUpstreamNetworkState.linkProperties); 1426e29bf0069caceb38806101c150acb477df99989Erik Kline if (lp.hasIPv6DefaultRoute() && lp.hasGlobalIPv6Address()) { 1436e29bf0069caceb38806101c150acb477df99989Erik Kline return lp; 1446e29bf0069caceb38806101c150acb477df99989Erik Kline } 1451eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1461eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 1471eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline return null; 1481eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1491eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 1501eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private static boolean canTetherIPv6(NetworkState ns) { 1511eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // Broadly speaking: 1521eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // 1531eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // [1] does the upstream have an IPv6 default route? 1541eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // 1551eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // and 1561eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // 1571eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // [2] does the upstream have one or more global IPv6 /64s 1581eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // dedicated to this device? 1591eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // 1601eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // In lieu of Prefix Delegation and other evaluation of whether a 1611eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // prefix may or may not be dedicated to this device, for now just 1621eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // check whether the upstream is TRANSPORT_CELLULAR. This works 1631eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // because "[t]he 3GPP network allocates each default bearer a unique 1641eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // /64 prefix", per RFC 6459, Section 5.2. 1651eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 1661eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline final boolean canTether = 1671eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline (ns != null) && (ns.network != null) && 1681eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline (ns.linkProperties != null) && (ns.networkCapabilities != null) && 1691eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // At least one upstream DNS server: 1701eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline ns.linkProperties.isProvisioned() && 1711eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // Minimal amount of IPv6 provisioning: 1721eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline ns.linkProperties.hasIPv6DefaultRoute() && 1731eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline ns.linkProperties.hasGlobalIPv6Address() && 1741eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // Temporary approximation of "dedicated prefix": 1751eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline ns.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR); 1761eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 1771eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // For now, we do not support separate IPv4 and IPv6 upstreams (e.g. 1781eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // tethering with 464xlat involved). TODO: Rectify this shortcoming, 1791eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // likely by calling NetworkManagementService#startInterfaceForwarding() 1801eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // for all upstream interfaces. 1811eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline RouteInfo v4default = null; 1821eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline RouteInfo v6default = null; 1831eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (canTether) { 1841eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline for (RouteInfo r : ns.linkProperties.getAllRoutes()) { 1851eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (r.isIPv4Default()) { 1861eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline v4default = r; 1871eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } else if (r.isIPv6Default()) { 1881eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline v6default = r; 1891eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1901eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 1911eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (v4default != null && v6default != null) { 1921eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline break; 1931eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1941eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1951eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 1961eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 1971eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline final boolean supportedConfiguration = 1981eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline (v4default != null) && (v6default != null) && 1991eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline (v4default.getInterface() != null) && 2001eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline v4default.getInterface().equals(v6default.getInterface()); 2011eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2021eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline final boolean outcome = canTether && supportedConfiguration; 2031eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2041eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (VDBG) { 2051eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (ns == null) { 2061eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline Log.d(TAG, "No available upstream."); 2071eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } else { 2081eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline Log.d(TAG, String.format("IPv6 tethering is %s for upstream: %s", 2091eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline (outcome ? "available" : "not available"), toDebugString(ns))); 2101eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2111eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2121eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2131eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline return outcome; 2141eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2151eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2161eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private static LinkProperties getIPv6OnlyLinkProperties(LinkProperties lp) { 2171eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline final LinkProperties v6only = new LinkProperties(); 2181eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (lp == null) { 2191eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline return v6only; 2201eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2211eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2221eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // NOTE: At this time we don't copy over any information about any 2231eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // stacked links. No current stacked link configuration has IPv6. 2241eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2251eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline v6only.setInterfaceName(lp.getInterfaceName()); 2261eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2271eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline v6only.setMtu(lp.getMtu()); 2281eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2291eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline for (LinkAddress linkAddr : lp.getLinkAddresses()) { 2301eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (linkAddr.isGlobalPreferred() && linkAddr.getPrefixLength() == 64) { 2311eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline v6only.addLinkAddress(linkAddr); 2321eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2331eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2341eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2351eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline for (RouteInfo routeInfo : lp.getRoutes()) { 2361eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline final IpPrefix destination = routeInfo.getDestination(); 2371eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if ((destination.getAddress() instanceof Inet6Address) && 2381eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline (destination.getPrefixLength() <= 64)) { 2391eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline v6only.addRoute(routeInfo); 2401eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2411eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2421eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2431eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline for (InetAddress dnsServer : lp.getDnsServers()) { 2441eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (isIPv6GlobalAddress(dnsServer)) { 2451eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // For now we include ULAs. 2461eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline v6only.addDnsServer(dnsServer); 2471eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2481eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2491eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2501eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline v6only.setDomains(lp.getDomains()); 2511eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2521eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline return v6only; 2531eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2541eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2551eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // TODO: Delete this and switch to LinkAddress#isGlobalPreferred once we 2561eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline // announce our own IPv6 address as DNS server. 2571eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private static boolean isIPv6GlobalAddress(InetAddress ip) { 2581eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline return (ip instanceof Inet6Address) && 2591eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline !ip.isAnyLocalAddress() && 2601eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline !ip.isLoopbackAddress() && 2611eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline !ip.isLinkLocalAddress() && 2621eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline !ip.isSiteLocalAddress() && 2631eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline !ip.isMulticastAddress(); 2641eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2651eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline 2661eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline private static String toDebugString(NetworkState ns) { 2671eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline if (ns == null) { 2681eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline return "NetworkState{null}"; 2691eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2701eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline return String.format("NetworkState{%s, %s, %s}", 2711eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline ns.network, 2721eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline ns.networkCapabilities, 2731eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline ns.linkProperties); 2741eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline } 2756e29bf0069caceb38806101c150acb477df99989Erik Kline 2766e29bf0069caceb38806101c150acb477df99989Erik Kline private static void stopIPv6TetheringOn(TetherInterfaceStateMachine sm) { 2776e29bf0069caceb38806101c150acb477df99989Erik Kline sm.sendMessage(TetherInterfaceStateMachine.CMD_IPV6_TETHER_UPDATE, 0, 0, null); 2786e29bf0069caceb38806101c150acb477df99989Erik Kline } 2791eb8c69bed1615e9502e94b1a676773ed28abfd9Erik Kline} 280