Passing isLocalRoute to netd add,remove and update route.
ConnectivityService would be centralized location for deciding local network so for this effort passing isLocalRoute parameter to routecontroller in netd for route addition, removal and modification. Bug: 394308861 Test: Manually tested. Test: atest ConnectivityCoverageTests Test: atest ConnectivityCoverageTests:android.net.connectivity.com.android.server.connectivityservice.CSLocalRouteTest Test: atest netd_integration_test Flag: EXEMPT Using device config kill-switch Change-Id: I9f11882665375bba10fa369c2e25f374b5e63661
This commit is contained in:
parent
9111ff26d4
commit
169a584691
2 changed files with 172 additions and 21 deletions
|
|
@ -81,6 +81,7 @@ import static android.net.ConnectivityManager.TYPE_WIFI_P2P;
|
|||
import static android.net.ConnectivityManager.getNetworkTypeName;
|
||||
import static android.net.ConnectivityManager.isNetworkTypeValid;
|
||||
import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
|
||||
import static android.net.INetd.LOCAL_NET_ID;
|
||||
import static android.net.INetd.PERMISSION_INTERNET;
|
||||
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
|
||||
import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
|
||||
|
|
@ -149,6 +150,7 @@ import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP4_RECVMSG;
|
|||
import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP4_SENDMSG;
|
||||
import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP6_RECVMSG;
|
||||
import static com.android.net.module.util.BpfUtils.BPF_CGROUP_UDP6_SENDMSG;
|
||||
import static com.android.net.module.util.NetdUtils.toRouteInfoParcel;
|
||||
import static com.android.net.module.util.NetworkMonitorUtils.isPrivateDnsValidationRequired;
|
||||
import static com.android.net.module.util.NetworkStackConstants.IPV4_LOCAL_PREFIXES;
|
||||
import static com.android.net.module.util.NetworkStackConstants.MULTICAST_AND_BROADCAST_PREFIXES;
|
||||
|
|
@ -267,6 +269,7 @@ import android.net.QosFilter;
|
|||
import android.net.QosSocketFilter;
|
||||
import android.net.QosSocketInfo;
|
||||
import android.net.RouteInfo;
|
||||
import android.net.RouteInfoParcel;
|
||||
import android.net.SocketKeepalive;
|
||||
import android.net.TetheringManager;
|
||||
import android.net.TransportInfo;
|
||||
|
|
@ -362,7 +365,6 @@ import com.android.net.module.util.LinkPropertiesUtils;
|
|||
import com.android.net.module.util.LinkPropertiesUtils.CompareOrUpdateResult;
|
||||
import com.android.net.module.util.LinkPropertiesUtils.CompareResult;
|
||||
import com.android.net.module.util.LocationPermissionChecker;
|
||||
import com.android.net.module.util.NetdUtils;
|
||||
import com.android.net.module.util.PerUidCounter;
|
||||
import com.android.net.module.util.PermissionUtils;
|
||||
import com.android.net.module.util.RoutingCoordinatorService;
|
||||
|
|
@ -3620,7 +3622,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
final String nextHop = bestRoute.hasGateway()
|
||||
? bestRoute.getGateway().getHostAddress() : "";
|
||||
try {
|
||||
mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop , uid);
|
||||
mNetd.networkAddLegacyRoute(netId, bestRoute.getInterface(), dst, nextHop, uid);
|
||||
} catch (RemoteException | ServiceSpecificException e) {
|
||||
if (DBG) loge("Exception trying to add a route: " + e);
|
||||
return false;
|
||||
|
|
@ -10515,8 +10517,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
for (LinkProperties linkProperty : linkPropertiesDiff.added) {
|
||||
final List<IpPrefix> unicastLocalPrefixesToBeAdded = new ArrayList<>();
|
||||
for (LinkAddress linkAddress : linkProperty.getLinkAddresses()) {
|
||||
unicastLocalPrefixesToBeAdded.addAll(
|
||||
getLocalNetworkPrefixesForAddress(linkAddress));
|
||||
unicastLocalPrefixesToBeAdded.addAll(getLocalNetworkPrefixesForAddress(
|
||||
linkAddress.getAddress(), linkAddress.getPrefixLength()));
|
||||
}
|
||||
addLocalAddressesToBpfMap(linkProperty.getInterfaceName(),
|
||||
unicastLocalPrefixesToBeAdded, linkProperty);
|
||||
|
|
@ -10535,8 +10537,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
linkProperty.getInterfaceName(), Collections.emptyList());
|
||||
|
||||
for (LinkAddress linkAddress : linkProperty.getLinkAddresses()) {
|
||||
unicastLocalPrefixesToBeRemoved.addAll(
|
||||
getLocalNetworkPrefixesForAddress(linkAddress));
|
||||
unicastLocalPrefixesToBeRemoved.addAll(getLocalNetworkPrefixesForAddress(
|
||||
linkAddress.getAddress(), linkAddress.getPrefixLength()));
|
||||
}
|
||||
|
||||
// This is to ensure if 10.0.10.0/24 was added and 10.0.11.0/24 was removed both will
|
||||
|
|
@ -10551,23 +10553,24 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
|
||||
/**
|
||||
* Filters IpPrefix that are local prefixes and LinkAddress is part of them.
|
||||
* @param linkAddress link address used for filtering
|
||||
* @param prefix address used for filtering
|
||||
* @param prefixLength prefix length of address
|
||||
* @return list of IpPrefix that are local addresses.
|
||||
*/
|
||||
private List<IpPrefix> getLocalNetworkPrefixesForAddress(LinkAddress linkAddress) {
|
||||
public static List<IpPrefix> getLocalNetworkPrefixesForAddress(InetAddress prefix,
|
||||
int prefixLength) {
|
||||
List<IpPrefix> localPrefixes = new ArrayList<>();
|
||||
if (linkAddress.isIpv6()) {
|
||||
if (prefix instanceof Inet6Address) {
|
||||
// For IPv6, if the prefix length is greater than zero then they are part of local
|
||||
// network
|
||||
if (linkAddress.getPrefixLength() != 0) {
|
||||
if (prefixLength != 0) {
|
||||
localPrefixes.add(
|
||||
new IpPrefix(linkAddress.getAddress(), linkAddress.getPrefixLength()));
|
||||
new IpPrefix(prefix, prefixLength));
|
||||
}
|
||||
} else {
|
||||
// For IPv4, if the linkAddress is part of IpPrefix adding prefix to result.
|
||||
for (IpPrefix ipv4LocalPrefix : IPV4_LOCAL_PREFIXES) {
|
||||
if (ipv4LocalPrefix.containsPrefix(
|
||||
new IpPrefix(linkAddress.getAddress(), linkAddress.getPrefixLength()))) {
|
||||
if (ipv4LocalPrefix.containsPrefix(new IpPrefix(prefix, prefixLength))) {
|
||||
localPrefixes.add(ipv4LocalPrefix);
|
||||
}
|
||||
}
|
||||
|
|
@ -10695,8 +10698,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
if (route.hasGateway()) continue;
|
||||
if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
|
||||
try {
|
||||
mRoutingCoordinatorService.addRouteParcel(netId,
|
||||
NetdUtils.toRouteInfoParcel(route));
|
||||
final RouteInfoParcel routeParcel = toRouteInfoParcel(route);
|
||||
routeParcel.isLocalRoute = isLocalRoute(routeParcel, netId);
|
||||
mRoutingCoordinatorService.addRouteParcel(netId, routeParcel);
|
||||
} catch (Exception e) {
|
||||
if ((route.getDestination().getAddress() instanceof Inet4Address) || VDBG) {
|
||||
loge("Exception in addRoute for non-gateway: " + e);
|
||||
|
|
@ -10707,8 +10711,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
if (!route.hasGateway()) continue;
|
||||
if (VDBG || DDBG) log("Adding Route [" + route + "] to network " + netId);
|
||||
try {
|
||||
mRoutingCoordinatorService.addRouteParcel(netId,
|
||||
NetdUtils.toRouteInfoParcel(route));
|
||||
final RouteInfoParcel routeParcel = toRouteInfoParcel(route);
|
||||
routeParcel.isLocalRoute = isLocalRoute(routeParcel, netId);
|
||||
mRoutingCoordinatorService.addRouteParcel(netId, routeParcel);
|
||||
} catch (Exception e) {
|
||||
if ((route.getGateway() instanceof Inet4Address) || VDBG) {
|
||||
loge("Exception in addRoute for gateway: " + e);
|
||||
|
|
@ -10719,8 +10724,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
for (RouteInfo route : routeDiff.removed) {
|
||||
if (VDBG || DDBG) log("Removing Route [" + route + "] from network " + netId);
|
||||
try {
|
||||
mRoutingCoordinatorService.removeRouteParcel(netId,
|
||||
NetdUtils.toRouteInfoParcel(route));
|
||||
final RouteInfoParcel routeParcel = toRouteInfoParcel(route);
|
||||
routeParcel.isLocalRoute = isLocalRoute(routeParcel, netId);
|
||||
mRoutingCoordinatorService.removeRouteParcel(netId, routeParcel);
|
||||
} catch (Exception e) {
|
||||
loge("Exception in removeRoute: " + e);
|
||||
}
|
||||
|
|
@ -10729,8 +10735,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
for (RouteInfo route : routeDiff.updated) {
|
||||
if (VDBG || DDBG) log("Updating Route [" + route + "] from network " + netId);
|
||||
try {
|
||||
mRoutingCoordinatorService.updateRouteParcel(netId,
|
||||
NetdUtils.toRouteInfoParcel(route));
|
||||
final RouteInfoParcel routeParcel = toRouteInfoParcel(route);
|
||||
routeParcel.isLocalRoute = isLocalRoute(routeParcel, netId);
|
||||
mRoutingCoordinatorService.updateRouteParcel(netId, routeParcel);
|
||||
} catch (Exception e) {
|
||||
loge("Exception in updateRoute: " + e);
|
||||
}
|
||||
|
|
@ -10757,6 +10764,23 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides if the route on netId is local.
|
||||
* @param route route information
|
||||
* @param netId network id.
|
||||
* @return true if route is local network route.
|
||||
*/
|
||||
public static boolean isLocalRoute(RouteInfoParcel route, int netId) {
|
||||
if (route.nextHop != INetd.NEXTHOP_NONE) return false;
|
||||
// LOCAL_NET_ID does not support local routes. It only looks up the
|
||||
// LOCAL_NETWORK routing table, which has no corresponding local table for
|
||||
// local routes to be added to.
|
||||
if (netId == LOCAL_NET_ID) return false;
|
||||
IpPrefix routeDestination = new IpPrefix(route.destination);
|
||||
return !getLocalNetworkPrefixesForAddress(routeDestination.getAddress(),
|
||||
routeDestination.getPrefixLength()).isEmpty();
|
||||
}
|
||||
|
||||
private void updateVpnFiltering(@NonNull LinkProperties newLp, @Nullable LinkProperties oldLp,
|
||||
@NonNull NetworkAgentInfo nai) {
|
||||
final String oldIface = getVpnIsolationInterface(nai, nai.networkCapabilities, oldLp);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License")
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.connectivityservice
|
||||
|
||||
import android.net.INetd
|
||||
import android.net.InetAddresses
|
||||
import android.net.IpPrefix
|
||||
import android.net.RouteInfo
|
||||
import android.os.Build
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.net.module.util.NetdUtils
|
||||
import com.android.server.ConnectivityService
|
||||
import com.android.testutils.DevSdkIgnoreRule
|
||||
import com.android.testutils.DevSdkIgnoreRunner
|
||||
import java.net.Inet6Address
|
||||
import org.junit.Assert
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
private const val WIFI_IFNAME = "wlan0"
|
||||
private const val NON_LOCAL_NET_ID = 102
|
||||
|
||||
@DevSdkIgnoreRunner.MonitorThreadLeak
|
||||
@RunWith(DevSdkIgnoreRunner::class)
|
||||
@SmallTest
|
||||
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
|
||||
class CSLocalRouteTest {
|
||||
private val LOCAL_IPV6_IP_ADDRESS_PREFIX = IpPrefix("2001:db8:1234:abcd::/64")
|
||||
private val LOCAL_IPV4_IP_ADDRESS_PREFIX = IpPrefix("10.0.0.0/24")
|
||||
private val IPV4_GATEWAY = InetAddresses.parseNumericAddress("10.0.0.1")
|
||||
private val IPV6_GATEWAY = InetAddresses.parseNumericAddress("fe80::1") as Inet6Address
|
||||
private val NON_LOCAL_IPV4_IP_ADDRESS_PREFIX = IpPrefix("8.8.0.0/24")
|
||||
|
||||
@Test
|
||||
fun testIsLocalRouteForLocalIPv6_TrueForLocalRoute() {
|
||||
val route = NetdUtils.toRouteInfoParcel(RouteInfo(
|
||||
LOCAL_IPV6_IP_ADDRESS_PREFIX,
|
||||
null,
|
||||
WIFI_IFNAME
|
||||
))
|
||||
Assert.assertTrue(ConnectivityService.isLocalRoute(route, NON_LOCAL_NET_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsLocalRouteWithNextHopForLocalIPv6_FalseForLocalRoute() {
|
||||
val route = NetdUtils.toRouteInfoParcel(RouteInfo(
|
||||
LOCAL_IPV6_IP_ADDRESS_PREFIX,
|
||||
IPV6_GATEWAY,
|
||||
WIFI_IFNAME
|
||||
))
|
||||
Assert.assertFalse(ConnectivityService.isLocalRoute(route, NON_LOCAL_NET_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsLocalRouteWithLocalNetIdForLocalIPv6_FalseForLocalRoute() {
|
||||
val route = NetdUtils.toRouteInfoParcel(RouteInfo(
|
||||
LOCAL_IPV6_IP_ADDRESS_PREFIX,
|
||||
null,
|
||||
WIFI_IFNAME
|
||||
))
|
||||
Assert.assertFalse(ConnectivityService.isLocalRoute(route, INetd.LOCAL_NET_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsLocalRouteForLocalIPv4_TrueForLocalRoute() {
|
||||
val route = NetdUtils.toRouteInfoParcel(RouteInfo(
|
||||
LOCAL_IPV4_IP_ADDRESS_PREFIX,
|
||||
null,
|
||||
WIFI_IFNAME
|
||||
))
|
||||
Assert.assertTrue(ConnectivityService.isLocalRoute(route, NON_LOCAL_NET_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsLocalRouteForNonLocalIPv4_FalseForLocalRoute() {
|
||||
val route = NetdUtils.toRouteInfoParcel(RouteInfo(
|
||||
NON_LOCAL_IPV4_IP_ADDRESS_PREFIX,
|
||||
null,
|
||||
WIFI_IFNAME
|
||||
))
|
||||
Assert.assertFalse(ConnectivityService.isLocalRoute(route, NON_LOCAL_NET_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsLocalRouteWithNextHopForLocalIPv4_FalseForLocalRoute() {
|
||||
val route = NetdUtils.toRouteInfoParcel(RouteInfo(
|
||||
LOCAL_IPV4_IP_ADDRESS_PREFIX,
|
||||
IPV4_GATEWAY,
|
||||
WIFI_IFNAME
|
||||
))
|
||||
Assert.assertFalse(ConnectivityService.isLocalRoute(route, NON_LOCAL_NET_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsLocalRouteWithNextHopForNonLocalIPv4_FalseForLocalRoute() {
|
||||
val route = NetdUtils.toRouteInfoParcel(RouteInfo(
|
||||
NON_LOCAL_IPV4_IP_ADDRESS_PREFIX,
|
||||
IPV4_GATEWAY,
|
||||
WIFI_IFNAME
|
||||
))
|
||||
Assert.assertFalse(ConnectivityService.isLocalRoute(route, NON_LOCAL_NET_ID))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testIsLocalRouteWithLocalNetIdForLocalIPv4_FalseForLocalRoute() {
|
||||
val route = NetdUtils.toRouteInfoParcel(RouteInfo(
|
||||
LOCAL_IPV4_IP_ADDRESS_PREFIX,
|
||||
null,
|
||||
WIFI_IFNAME
|
||||
))
|
||||
Assert.assertFalse(ConnectivityService.isLocalRoute(route, INetd.LOCAL_NET_ID))
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue