Apply multicast routing configs

Applies multicast routing configs when they are updated in
LocalNetworkConfig, or when local network/upstream network
status changes.

Bug: 281217735

Test: atest CSLocalAgentTests
Change-Id: Ib1c43c645a367d0f91e5cf0a0d9f8e5883be2c40
This commit is contained in:
Yang Sun 2023-12-04 10:31:58 +08:00
commit 29037f6046
3 changed files with 391 additions and 12 deletions

View file

@ -171,6 +171,7 @@ import android.net.LinkProperties;
import android.net.LocalNetworkConfig;
import android.net.LocalNetworkInfo;
import android.net.MatchAllNetworkSpecifier;
import android.net.MulticastRoutingConfig;
import android.net.NativeNetworkConfig;
import android.net.NativeNetworkType;
import android.net.NattSocketKeepalive;
@ -320,6 +321,7 @@ import com.android.server.connectivity.KeepaliveResourceUtil;
import com.android.server.connectivity.KeepaliveTracker;
import com.android.server.connectivity.LingerMonitor;
import com.android.server.connectivity.MockableSystemProperties;
import com.android.server.connectivity.MulticastRoutingCoordinatorService;
import com.android.server.connectivity.MultinetworkPolicyTracker;
import com.android.server.connectivity.NetworkAgentInfo;
import com.android.server.connectivity.NetworkDiagnostics;
@ -347,6 +349,7 @@ import java.io.InterruptedIOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
@ -361,6 +364,7 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Set;
@ -496,6 +500,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
@GuardedBy("mTNSLock")
private TestNetworkService mTNS;
private final CompanionDeviceManagerProxyService mCdmps;
private final MulticastRoutingCoordinatorService mMulticastRoutingCoordinatorService;
private final RoutingCoordinatorService mRoutingCoordinatorService;
private final Object mTNSLock = new Object();
@ -1421,6 +1426,17 @@ public class ConnectivityService extends IConnectivityManager.Stub
return new AutomaticOnOffKeepaliveTracker(c, h);
}
public MulticastRoutingCoordinatorService makeMulticastRoutingCoordinatorService(
@NonNull Handler h) {
try {
return new MulticastRoutingCoordinatorService(h);
} catch (UnsupportedOperationException e) {
// Multicast routing is not supported by the kernel
Log.i(TAG, "Skipping unsupported MulticastRoutingCoordinatorService");
return null;
}
}
/**
* @see BatteryStatsManager
*/
@ -1859,6 +1875,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
mRoutingCoordinatorService = new RoutingCoordinatorService(netd);
mMulticastRoutingCoordinatorService =
mDeps.makeMulticastRoutingCoordinatorService(mHandler);
mDestroyFrozenSockets = mDeps.isAtLeastU()
&& mDeps.isFeatureEnabled(context, KEY_DESTROY_FROZEN_SOCKETS_VERSION);
@ -5175,9 +5193,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
private void removeLocalNetworkUpstream(@NonNull final NetworkAgentInfo localAgent,
@NonNull final NetworkAgentInfo upstream) {
try {
final String localNetworkInterfaceName = localAgent.linkProperties.getInterfaceName();
final String upstreamNetworkInterfaceName = upstream.linkProperties.getInterfaceName();
mRoutingCoordinatorService.removeInterfaceForward(
localAgent.linkProperties.getInterfaceName(),
upstream.linkProperties.getInterfaceName());
localNetworkInterfaceName,
upstreamNetworkInterfaceName);
disableMulticastRouting(localNetworkInterfaceName, upstreamNetworkInterfaceName);
} catch (RemoteException e) {
loge("Couldn't remove interface forward for "
+ localAgent.linkProperties.getInterfaceName() + " to "
@ -9095,6 +9116,61 @@ public class ConnectivityService extends IConnectivityManager.Stub
updateCapabilities(nai.getScore(), nai, nai.networkCapabilities);
}
private void maybeApplyMulticastRoutingConfig(@NonNull final NetworkAgentInfo nai,
final LocalNetworkConfig oldConfig,
final LocalNetworkConfig newConfig) {
final MulticastRoutingConfig oldUpstreamConfig =
oldConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE :
oldConfig.getUpstreamMulticastRoutingConfig();
final MulticastRoutingConfig oldDownstreamConfig =
oldConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE :
oldConfig.getDownstreamMulticastRoutingConfig();
final MulticastRoutingConfig newUpstreamConfig =
newConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE :
newConfig.getUpstreamMulticastRoutingConfig();
final MulticastRoutingConfig newDownstreamConfig =
newConfig == null ? MulticastRoutingConfig.CONFIG_FORWARD_NONE :
newConfig.getDownstreamMulticastRoutingConfig();
if (oldUpstreamConfig.equals(newUpstreamConfig) &&
oldDownstreamConfig.equals(newDownstreamConfig)) {
return;
}
final String downstreamNetworkName = nai.linkProperties.getInterfaceName();
final LocalNetworkInfo lni = localNetworkInfoForNai(nai);
final Network upstreamNetwork = lni.getUpstreamNetwork();
if (upstreamNetwork != null) {
final String upstreamNetworkName =
getLinkProperties(upstreamNetwork).getInterfaceName();
applyMulticastRoutingConfig(downstreamNetworkName, upstreamNetworkName, newConfig);
}
}
private void applyMulticastRoutingConfig(@NonNull String localNetworkInterfaceName,
@NonNull String upstreamNetworkInterfaceName,
@NonNull final LocalNetworkConfig config) {
if (mMulticastRoutingCoordinatorService == null) return;
mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig(localNetworkInterfaceName,
upstreamNetworkInterfaceName, config.getUpstreamMulticastRoutingConfig());
mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig
(upstreamNetworkInterfaceName, localNetworkInterfaceName,
config.getDownstreamMulticastRoutingConfig());
}
private void disableMulticastRouting(@NonNull String localNetworkInterfaceName,
@NonNull String upstreamNetworkInterfaceName) {
if (mMulticastRoutingCoordinatorService == null) return;
mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig(localNetworkInterfaceName,
upstreamNetworkInterfaceName, MulticastRoutingConfig.CONFIG_FORWARD_NONE);
mMulticastRoutingCoordinatorService.applyMulticastRoutingConfig
(upstreamNetworkInterfaceName, localNetworkInterfaceName,
MulticastRoutingConfig.CONFIG_FORWARD_NONE);
}
// oldConfig is null iff this is the original registration of the local network config
private void handleUpdateLocalNetworkConfig(@NonNull final NetworkAgentInfo nai,
@Nullable final LocalNetworkConfig oldConfig,
@ -9108,7 +9184,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
Log.v(TAG, "Update local network config " + nai.network.netId + " : " + newConfig);
}
final LocalNetworkConfig.Builder configBuilder = new LocalNetworkConfig.Builder();
// TODO : apply the diff for multicast routing.
configBuilder.setUpstreamMulticastRoutingConfig(
newConfig.getUpstreamMulticastRoutingConfig());
configBuilder.setDownstreamMulticastRoutingConfig(
@ -9167,6 +9242,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
configBuilder.setUpstreamSelector(oldRequest);
nai.localNetworkConfig = configBuilder.build();
}
maybeApplyMulticastRoutingConfig(nai, oldConfig, newConfig);
}
/**
@ -10166,6 +10242,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (null != change.mOldNetwork) {
mRoutingCoordinatorService.removeInterfaceForward(fromIface,
change.mOldNetwork.linkProperties.getInterfaceName());
disableMulticastRouting(fromIface,
change.mOldNetwork.linkProperties.getInterfaceName());
}
// If the new upstream is already destroyed, there is no point in setting up
// a forward (in fact, it might forward to the interface for some new network !)
@ -10174,6 +10252,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (null != change.mNewNetwork && !change.mNewNetwork.isDestroyed()) {
mRoutingCoordinatorService.addInterfaceForward(fromIface,
change.mNewNetwork.linkProperties.getInterfaceName());
applyMulticastRoutingConfig(fromIface,
change.mNewNetwork.linkProperties.getInterfaceName(),
nai.localNetworkConfig);
}
} catch (final RemoteException e) {
loge("Can't update forwarding rules", e);

View file

@ -20,6 +20,8 @@ import android.net.IpPrefix
import android.net.LinkAddress
import android.net.LinkProperties
import android.net.LocalNetworkConfig
import android.net.MulticastRoutingConfig
import android.net.MulticastRoutingConfig.CONFIG_FORWARD_NONE
import android.net.NetworkCapabilities
import android.net.NetworkCapabilities.NET_CAPABILITY_DUN
import android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET
@ -45,6 +47,7 @@ import com.android.testutils.TestableNetworkCallback
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.eq
import org.mockito.Mockito.inOrder
import org.mockito.Mockito.never
import org.mockito.Mockito.timeout
@ -82,6 +85,24 @@ private fun keepScore() = FromS(
@RunWith(DevSdkIgnoreRunner::class)
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
class CSLocalAgentTests : CSTest() {
val multicastRoutingConfigMinScope =
MulticastRoutingConfig.Builder(MulticastRoutingConfig.FORWARD_WITH_MIN_SCOPE, 4)
.build();
val multicastRoutingConfigSelected =
MulticastRoutingConfig.Builder(MulticastRoutingConfig.FORWARD_SELECTED)
.build();
val upstreamSelectorAny = NetworkRequest.Builder()
.addForbiddenCapability(NET_CAPABILITY_LOCAL_NETWORK)
.build()
val upstreamSelectorWifi = NetworkRequest.Builder()
.addForbiddenCapability(NET_CAPABILITY_LOCAL_NETWORK)
.addTransportType(TRANSPORT_WIFI)
.build()
val upstreamSelectorCell = NetworkRequest.Builder()
.addForbiddenCapability(NET_CAPABILITY_LOCAL_NETWORK)
.addTransportType(TRANSPORT_CELLULAR)
.build()
@Test
fun testBadAgents() {
deps.setBuildSdk(VERSION_V)
@ -177,6 +198,266 @@ class CSLocalAgentTests : CSTest() {
localAgent.disconnect()
}
private fun createLocalAgent(name: String, localNetworkConfig: FromS<LocalNetworkConfig>):
CSAgentWrapper {
val localAgent = Agent(
nc = nc(TRANSPORT_THREAD, NET_CAPABILITY_LOCAL_NETWORK),
lp = lp(name),
lnc = localNetworkConfig,
)
return localAgent
}
private fun createWifiAgent(name: String): CSAgentWrapper {
return Agent(score = keepScore(), lp = lp(name),
nc = nc(TRANSPORT_WIFI, NET_CAPABILITY_INTERNET))
}
private fun createCellAgent(name: String): CSAgentWrapper {
return Agent(score = keepScore(), lp = lp(name),
nc = nc(TRANSPORT_CELLULAR, NET_CAPABILITY_INTERNET))
}
private fun sendLocalNetworkConfig(localAgent: CSAgentWrapper,
upstreamSelector: NetworkRequest?, upstreamConfig: MulticastRoutingConfig,
downstreamConfig: MulticastRoutingConfig) {
val newLnc = LocalNetworkConfig.Builder()
.setUpstreamSelector(upstreamSelector)
.setUpstreamMulticastRoutingConfig(upstreamConfig)
.setDownstreamMulticastRoutingConfig(downstreamConfig)
.build()
localAgent.sendLocalNetworkConfig(newLnc)
}
@Test
fun testMulticastRoutingConfig() {
deps.setBuildSdk(VERSION_V)
val cb = TestableNetworkCallback()
cm.registerNetworkCallback(NetworkRequest.Builder().clearCapabilities().build(), cb)
val inOrder = inOrder(multicastRoutingCoordinatorService)
val lnc = FromS(LocalNetworkConfig.Builder()
.setUpstreamSelector(upstreamSelectorWifi)
.setUpstreamMulticastRoutingConfig(multicastRoutingConfigMinScope)
.setDownstreamMulticastRoutingConfig(multicastRoutingConfigSelected)
.build()
)
val localAgent = createLocalAgent("local0", lnc)
localAgent.connect()
cb.expectAvailableCallbacks(localAgent.network, validated = false)
val wifiAgent = createWifiAgent("wifi0")
wifiAgent.connect()
cb.expectAvailableCallbacks(wifiAgent.network, validated = false)
cb.expect<LocalInfoChanged>(localAgent.network) {
it.info.upstreamNetwork == wifiAgent.network
}
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"local0", "wifi0", multicastRoutingConfigMinScope)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"wifi0", "local0", multicastRoutingConfigSelected)
wifiAgent.disconnect()
inOrder.verify(multicastRoutingCoordinatorService)
.applyMulticastRoutingConfig("local0", "wifi0", CONFIG_FORWARD_NONE)
inOrder.verify(multicastRoutingCoordinatorService)
.applyMulticastRoutingConfig("wifi0", "local0", CONFIG_FORWARD_NONE)
localAgent.disconnect()
}
@Test
fun testMulticastRoutingConfig_2LocalNetworks() {
deps.setBuildSdk(VERSION_V)
val inOrder = inOrder(multicastRoutingCoordinatorService)
val lnc = FromS(LocalNetworkConfig.Builder()
.setUpstreamSelector(upstreamSelectorWifi)
.setUpstreamMulticastRoutingConfig(multicastRoutingConfigMinScope)
.setDownstreamMulticastRoutingConfig(multicastRoutingConfigSelected)
.build()
)
val localAgent0 = createLocalAgent("local0", lnc)
localAgent0.connect()
val wifiAgent = createWifiAgent("wifi0")
wifiAgent.connect()
waitForIdle()
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"local0", "wifi0", multicastRoutingConfigMinScope)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"wifi0", "local0", multicastRoutingConfigSelected)
val localAgent1 = createLocalAgent("local1", lnc)
localAgent1.connect()
waitForIdle()
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"local1", "wifi0", multicastRoutingConfigMinScope)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"wifi0", "local1", multicastRoutingConfigSelected)
localAgent0.disconnect()
localAgent1.disconnect()
wifiAgent.disconnect()
}
@Test
fun testMulticastRoutingConfig_UpstreamNetworkCellToWifi() {
deps.setBuildSdk(VERSION_V)
val cb = TestableNetworkCallback()
cm.registerNetworkCallback(NetworkRequest.Builder().clearCapabilities()
.addCapability(NET_CAPABILITY_LOCAL_NETWORK)
.build(), cb)
val inOrder = inOrder(multicastRoutingCoordinatorService)
val lnc = FromS(LocalNetworkConfig.Builder()
.setUpstreamSelector(upstreamSelectorAny)
.setUpstreamMulticastRoutingConfig(multicastRoutingConfigMinScope)
.setDownstreamMulticastRoutingConfig(multicastRoutingConfigSelected)
.build()
)
val localAgent = createLocalAgent("local0", lnc)
val wifiAgent = createWifiAgent("wifi0")
val cellAgent = createCellAgent("cell0")
localAgent.connect()
cb.expectAvailableCallbacks(localAgent.network, validated = false)
cellAgent.connect()
cb.expect<LocalInfoChanged>(localAgent.network) {
it.info.upstreamNetwork == cellAgent.network
}
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"local0", "cell0", multicastRoutingConfigMinScope)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"cell0", "local0", multicastRoutingConfigSelected)
wifiAgent.connect()
cb.expect<LocalInfoChanged>(localAgent.network) {
it.info.upstreamNetwork == wifiAgent.network
}
// upstream should have been switched to wifi
inOrder.verify(multicastRoutingCoordinatorService)
.applyMulticastRoutingConfig("local0", "cell0", CONFIG_FORWARD_NONE)
inOrder.verify(multicastRoutingCoordinatorService)
.applyMulticastRoutingConfig("cell0", "local0", CONFIG_FORWARD_NONE)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"local0", "wifi0", multicastRoutingConfigMinScope)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"wifi0", "local0", multicastRoutingConfigSelected)
localAgent.disconnect()
cellAgent.disconnect()
wifiAgent.disconnect()
}
@Test
fun testMulticastRoutingConfig_UpstreamSelectorCellToWifi() {
deps.setBuildSdk(VERSION_V)
val cb = TestableNetworkCallback()
cm.registerNetworkCallback(NetworkRequest.Builder().clearCapabilities()
.addCapability(NET_CAPABILITY_LOCAL_NETWORK)
.build(), cb)
val inOrder = inOrder(multicastRoutingCoordinatorService)
val lnc = FromS(LocalNetworkConfig.Builder()
.setUpstreamSelector(upstreamSelectorCell)
.setUpstreamMulticastRoutingConfig(multicastRoutingConfigMinScope)
.setDownstreamMulticastRoutingConfig(multicastRoutingConfigSelected)
.build()
)
val localAgent = createLocalAgent("local0", lnc)
val wifiAgent = createWifiAgent("wifi0")
val cellAgent = createCellAgent("cell0")
localAgent.connect()
cellAgent.connect()
wifiAgent.connect()
cb.expectAvailableCallbacks(localAgent.network, validated = false)
cb.expect<LocalInfoChanged>(localAgent.network) {
it.info.upstreamNetwork == cellAgent.network
}
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"local0", "cell0", multicastRoutingConfigMinScope)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"cell0", "local0", multicastRoutingConfigSelected)
sendLocalNetworkConfig(localAgent, upstreamSelectorWifi, multicastRoutingConfigMinScope,
multicastRoutingConfigSelected)
cb.expect<LocalInfoChanged>(localAgent.network) {
it.info.upstreamNetwork == wifiAgent.network
}
// upstream should have been switched to wifi
inOrder.verify(multicastRoutingCoordinatorService)
.applyMulticastRoutingConfig("local0", "cell0", CONFIG_FORWARD_NONE)
inOrder.verify(multicastRoutingCoordinatorService)
.applyMulticastRoutingConfig("cell0", "local0", CONFIG_FORWARD_NONE)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"local0", "wifi0", multicastRoutingConfigMinScope)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"wifi0", "local0", multicastRoutingConfigSelected)
localAgent.disconnect()
cellAgent.disconnect()
wifiAgent.disconnect()
}
@Test
fun testMulticastRoutingConfig_UpstreamSelectorWifiToNull() {
deps.setBuildSdk(VERSION_V)
val cb = TestableNetworkCallback()
cm.registerNetworkCallback(NetworkRequest.Builder().clearCapabilities()
.addCapability(NET_CAPABILITY_LOCAL_NETWORK)
.build(), cb)
val inOrder = inOrder(multicastRoutingCoordinatorService)
val lnc = FromS(LocalNetworkConfig.Builder()
.setUpstreamSelector(upstreamSelectorWifi)
.setUpstreamMulticastRoutingConfig(multicastRoutingConfigMinScope)
.setDownstreamMulticastRoutingConfig(multicastRoutingConfigSelected)
.build()
)
val localAgent = createLocalAgent("local0", lnc)
localAgent.connect()
val wifiAgent = createWifiAgent("wifi0")
wifiAgent.connect()
cb.expectAvailableCallbacks(localAgent.network, validated = false)
cb.expect<LocalInfoChanged>(localAgent.network) {
it.info.upstreamNetwork == wifiAgent.network
}
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"local0", "wifi0", multicastRoutingConfigMinScope)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"wifi0", "local0", multicastRoutingConfigSelected)
sendLocalNetworkConfig(localAgent, null, multicastRoutingConfigMinScope,
multicastRoutingConfigSelected)
cb.expect<LocalInfoChanged>(localAgent.network) {
it.info.upstreamNetwork == null
}
// upstream should have been switched to null
inOrder.verify(multicastRoutingCoordinatorService)
.applyMulticastRoutingConfig("local0", "wifi0", CONFIG_FORWARD_NONE)
inOrder.verify(multicastRoutingCoordinatorService)
.applyMulticastRoutingConfig("wifi0", "local0", CONFIG_FORWARD_NONE)
inOrder.verify(multicastRoutingCoordinatorService, never()).applyMulticastRoutingConfig(
eq("local0"), any(), eq(multicastRoutingConfigMinScope))
inOrder.verify(multicastRoutingCoordinatorService, never()).applyMulticastRoutingConfig(
any(), eq("local0"), eq(multicastRoutingConfigSelected))
localAgent.disconnect()
wifiAgent.disconnect()
}
@Test
fun testUnregisterUpstreamAfterReplacement_SameIfaceName() {
doTestUnregisterUpstreamAfterReplacement(true)
@ -196,11 +477,10 @@ class CSLocalAgentTests : CSTest() {
val localAgent = Agent(nc = nc(TRANSPORT_WIFI, NET_CAPABILITY_LOCAL_NETWORK),
lp = lp("local0"),
lnc = FromS(LocalNetworkConfig.Builder()
.setUpstreamSelector(NetworkRequest.Builder()
.addForbiddenCapability(NET_CAPABILITY_LOCAL_NETWORK)
.addTransportType(TRANSPORT_WIFI)
.build())
.build()),
.setUpstreamSelector(upstreamSelectorWifi)
.setUpstreamMulticastRoutingConfig(multicastRoutingConfigMinScope)
.setDownstreamMulticastRoutingConfig(multicastRoutingConfigSelected)
.build()),
score = FromS(NetworkScore.Builder()
.setKeepConnectedReason(KEEP_CONNECTED_LOCAL_NETWORK)
.build())
@ -219,10 +499,15 @@ class CSLocalAgentTests : CSTest() {
}
clearInvocations(netd)
val inOrder = inOrder(netd)
clearInvocations(multicastRoutingCoordinatorService)
val inOrder = inOrder(netd, multicastRoutingCoordinatorService)
wifiAgent.unregisterAfterReplacement(LONG_TIMEOUT_MS)
waitForIdle()
inOrder.verify(netd).ipfwdRemoveInterfaceForward("local0", "wifi0")
inOrder.verify(multicastRoutingCoordinatorService)
.applyMulticastRoutingConfig("local0", "wifi0", CONFIG_FORWARD_NONE)
inOrder.verify(multicastRoutingCoordinatorService)
.applyMulticastRoutingConfig("wifi0", "local0", CONFIG_FORWARD_NONE)
inOrder.verify(netd).networkDestroy(wifiAgent.network.netId)
val wifiIface2 = if (sameIfaceName) "wifi0" else "wifi1"
@ -235,9 +520,16 @@ class CSLocalAgentTests : CSTest() {
cb.expect<Lost> { it.network == wifiAgent.network }
inOrder.verify(netd).ipfwdAddInterfaceForward("local0", wifiIface2)
if (sameIfaceName) {
inOrder.verify(netd, never()).ipfwdRemoveInterfaceForward(any(), any())
}
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
"local0", wifiIface2, multicastRoutingConfigMinScope)
inOrder.verify(multicastRoutingCoordinatorService).applyMulticastRoutingConfig(
wifiIface2, "local0", multicastRoutingConfigSelected)
inOrder.verify(netd, never()).ipfwdRemoveInterfaceForward(any(), any())
inOrder.verify(multicastRoutingCoordinatorService, never())
.applyMulticastRoutingConfig("local0", "wifi0", CONFIG_FORWARD_NONE)
inOrder.verify(multicastRoutingCoordinatorService, never())
.applyMulticastRoutingConfig("wifi0", "local0", CONFIG_FORWARD_NONE)
}
@Test

View file

@ -61,9 +61,11 @@ import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker
import com.android.server.connectivity.CarrierPrivilegeAuthenticator
import com.android.server.connectivity.ClatCoordinator
import com.android.server.connectivity.ConnectivityFlags
import com.android.server.connectivity.MulticastRoutingCoordinatorService
import com.android.server.connectivity.MultinetworkPolicyTracker
import com.android.server.connectivity.MultinetworkPolicyTrackerTestDependencies
import com.android.server.connectivity.ProxyTracker
import com.android.server.connectivity.RoutingCoordinatorService
import com.android.testutils.visibleOnHandlerThread
import com.android.testutils.waitForIdle
import java.util.concurrent.Executors
@ -166,6 +168,8 @@ open class CSTest {
doReturn(true).`when`(it).isDataCapable()
}
val multicastRoutingCoordinatorService = mock<MulticastRoutingCoordinatorService>()
val deps = CSDeps()
val service = makeConnectivityService(context, netd, deps).also { it.systemReadyInternal() }
val cm = ConnectivityManager(context, service)
@ -179,6 +183,8 @@ open class CSTest {
override fun makeHandlerThread(tag: String) = csHandlerThread
override fun makeProxyTracker(context: Context, connServiceHandler: Handler) = proxyTracker
override fun makeMulticastRoutingCoordinatorService(handler: Handler) =
this@CSTest.multicastRoutingCoordinatorService
override fun makeCarrierPrivilegeAuthenticator(
context: Context,