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

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);