Dynamically set MTU based on proposed algorithms
This change adds the relevant utilities and plumbing to ensure that MTUs are set dynamically based on the underlying network's MTU. Bug: 184697651 Test: atest FrameworksVcnTests Change-Id: I77e34a92eb4e81e83d20fe6019b38ea5f1af4765
This commit is contained in:
@@ -85,6 +85,7 @@ import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscription
|
||||
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkRecord;
|
||||
import com.android.server.vcn.UnderlyingNetworkTracker.UnderlyingNetworkTrackerCallback;
|
||||
import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
|
||||
import com.android.server.vcn.util.MtuUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.Inet4Address;
|
||||
@@ -449,6 +450,44 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
*/
|
||||
private static final int EVENT_SAFE_MODE_TIMEOUT_EXCEEDED = 10;
|
||||
|
||||
/**
|
||||
* Sent when an IKE has completed migration, and created updated transforms for application.
|
||||
*
|
||||
* <p>Only relevant in the Connected state.
|
||||
*
|
||||
* @param arg1 The session token for the IKE Session that completed migration, used to prevent
|
||||
* out-of-date signals from propagating.
|
||||
* @param obj @NonNull An EventMigrationCompletedInfo instance with relevant data.
|
||||
*/
|
||||
private static final int EVENT_MIGRATION_COMPLETED = 11;
|
||||
|
||||
private static class EventMigrationCompletedInfo implements EventInfo {
|
||||
@NonNull public final IpSecTransform inTransform;
|
||||
@NonNull public final IpSecTransform outTransform;
|
||||
|
||||
EventMigrationCompletedInfo(
|
||||
@NonNull IpSecTransform inTransform, @NonNull IpSecTransform outTransform) {
|
||||
this.inTransform = Objects.requireNonNull(inTransform);
|
||||
this.outTransform = Objects.requireNonNull(outTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(inTransform, outTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(@Nullable Object other) {
|
||||
if (!(other instanceof EventMigrationCompletedInfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final EventMigrationCompletedInfo rhs = (EventMigrationCompletedInfo) other;
|
||||
return Objects.equals(inTransform, rhs.inTransform)
|
||||
&& Objects.equals(outTransform, rhs.outTransform);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting(visibility = Visibility.PRIVATE)
|
||||
@NonNull
|
||||
final DisconnectedState mDisconnectedState = new DisconnectedState();
|
||||
@@ -1054,6 +1093,14 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
sendMessageAndAcquireWakeLock(EVENT_SESSION_CLOSED, token);
|
||||
}
|
||||
|
||||
private void migrationCompleted(
|
||||
int token, @NonNull IpSecTransform inTransform, @NonNull IpSecTransform outTransform) {
|
||||
sendMessageAndAcquireWakeLock(
|
||||
EVENT_MIGRATION_COMPLETED,
|
||||
token,
|
||||
new EventMigrationCompletedInfo(inTransform, outTransform));
|
||||
}
|
||||
|
||||
private void childTransformCreated(
|
||||
int token, @NonNull IpSecTransform transform, int direction) {
|
||||
sendMessageAndAcquireWakeLock(
|
||||
@@ -1149,7 +1196,9 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
case EVENT_SETUP_COMPLETED: // Fallthrough
|
||||
case EVENT_DISCONNECT_REQUESTED: // Fallthrough
|
||||
case EVENT_TEARDOWN_TIMEOUT_EXPIRED: // Fallthrough
|
||||
case EVENT_SUBSCRIPTIONS_CHANGED:
|
||||
case EVENT_SUBSCRIPTIONS_CHANGED: // Fallthrough
|
||||
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED: // Fallthrough
|
||||
case EVENT_MIGRATION_COMPLETED:
|
||||
logUnexpectedEvent(msg.what);
|
||||
break;
|
||||
default:
|
||||
@@ -1446,7 +1495,8 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
final NetworkCapabilities caps =
|
||||
buildNetworkCapabilities(mConnectionConfig, mUnderlying);
|
||||
final LinkProperties lp =
|
||||
buildConnectedLinkProperties(mConnectionConfig, tunnelIface, childConfig);
|
||||
buildConnectedLinkProperties(
|
||||
mConnectionConfig, tunnelIface, childConfig, mUnderlying);
|
||||
|
||||
agent.sendNetworkCapabilities(caps);
|
||||
agent.sendLinkProperties(lp);
|
||||
@@ -1458,7 +1508,8 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
final NetworkCapabilities caps =
|
||||
buildNetworkCapabilities(mConnectionConfig, mUnderlying);
|
||||
final LinkProperties lp =
|
||||
buildConnectedLinkProperties(mConnectionConfig, tunnelIface, childConfig);
|
||||
buildConnectedLinkProperties(
|
||||
mConnectionConfig, tunnelIface, childConfig, mUnderlying);
|
||||
final NetworkAgentConfig nac =
|
||||
new NetworkAgentConfig.Builder()
|
||||
.setLegacyType(ConnectivityManager.TYPE_MOBILE)
|
||||
@@ -1627,12 +1678,36 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED:
|
||||
handleSafeModeTimeoutExceeded();
|
||||
break;
|
||||
case EVENT_MIGRATION_COMPLETED:
|
||||
final EventMigrationCompletedInfo migrationCompletedInfo =
|
||||
(EventMigrationCompletedInfo) msg.obj;
|
||||
|
||||
handleMigrationCompleted(migrationCompletedInfo);
|
||||
break;
|
||||
default:
|
||||
logUnhandledMessage(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMigrationCompleted(EventMigrationCompletedInfo migrationCompletedInfo) {
|
||||
applyTransform(
|
||||
mCurrentToken,
|
||||
mTunnelIface,
|
||||
mUnderlying.network,
|
||||
migrationCompletedInfo.inTransform,
|
||||
IpSecManager.DIRECTION_IN);
|
||||
|
||||
applyTransform(
|
||||
mCurrentToken,
|
||||
mTunnelIface,
|
||||
mUnderlying.network,
|
||||
migrationCompletedInfo.outTransform,
|
||||
IpSecManager.DIRECTION_OUT);
|
||||
|
||||
updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig);
|
||||
}
|
||||
|
||||
private void handleUnderlyingNetworkChanged(@NonNull Message msg) {
|
||||
final UnderlyingNetworkRecord oldUnderlying = mUnderlying;
|
||||
mUnderlying = ((EventUnderlyingNetworkChangedInfo) msg.obj).newUnderlying;
|
||||
@@ -1822,7 +1897,10 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
private static LinkProperties buildConnectedLinkProperties(
|
||||
@NonNull VcnGatewayConnectionConfig gatewayConnectionConfig,
|
||||
@NonNull IpSecTunnelInterface tunnelIface,
|
||||
@NonNull VcnChildSessionConfiguration childConfig) {
|
||||
@NonNull VcnChildSessionConfiguration childConfig,
|
||||
@Nullable UnderlyingNetworkRecord underlying) {
|
||||
final VcnControlPlaneIkeConfig controlPlaneConfig =
|
||||
(VcnControlPlaneIkeConfig) gatewayConnectionConfig.getControlPlaneConfig();
|
||||
final LinkProperties lp = new LinkProperties();
|
||||
|
||||
lp.setInterfaceName(tunnelIface.getInterfaceName());
|
||||
@@ -1838,7 +1916,12 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
lp.addRoute(new RouteInfo(new IpPrefix(Inet6Address.ANY, 0), null /*gateway*/,
|
||||
null /*iface*/, RouteInfo.RTN_UNICAST));
|
||||
|
||||
lp.setMtu(gatewayConnectionConfig.getMaxMtu());
|
||||
final int underlyingMtu = (underlying == null) ? 0 : underlying.linkProperties.getMtu();
|
||||
lp.setMtu(
|
||||
MtuUtils.getMtu(
|
||||
controlPlaneConfig.getChildSessionParams().getSaProposals(),
|
||||
gatewayConnectionConfig.getMaxMtu(),
|
||||
underlyingMtu));
|
||||
|
||||
return lp;
|
||||
}
|
||||
@@ -1919,8 +2002,7 @@ public class VcnGatewayConnection extends StateMachine {
|
||||
@NonNull IpSecTransform inIpSecTransform,
|
||||
@NonNull IpSecTransform outIpSecTransform) {
|
||||
Slog.v(TAG, "ChildTransformsMigrated; token " + mToken);
|
||||
onIpSecTransformCreated(inIpSecTransform, IpSecManager.DIRECTION_IN);
|
||||
onIpSecTransformCreated(outIpSecTransform, IpSecManager.DIRECTION_OUT);
|
||||
migrationCompleted(mToken, inIpSecTransform, outIpSecTransform);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
155
services/core/java/com/android/server/vcn/util/MtuUtils.java
Normal file
155
services/core/java/com/android/server/vcn/util/MtuUtils.java
Normal file
@@ -0,0 +1,155 @@
|
||||
/*
|
||||
* Copyright (C) 2021 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.vcn.util;
|
||||
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_3DES;
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC;
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CTR;
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12;
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16;
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8;
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_CHACHA20_POLY1305;
|
||||
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_CMAC_96;
|
||||
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_AES_XCBC_96;
|
||||
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA1_96;
|
||||
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128;
|
||||
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_384_192;
|
||||
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_512_256;
|
||||
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_NONE;
|
||||
|
||||
import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
|
||||
|
||||
import static java.lang.Math.max;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.net.ipsec.ike.ChildSaProposal;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Pair;
|
||||
import android.util.Slog;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** @hide */
|
||||
public class MtuUtils {
|
||||
private static final String TAG = MtuUtils.class.getSimpleName();
|
||||
/**
|
||||
* Max ESP overhead possible
|
||||
*
|
||||
* <p>60 (Outer IPv4 + options) + 8 (UDP encap) + 4 (SPI) + 4 (Seq) + 2 (Pad + NextHeader)
|
||||
*/
|
||||
private static final int GENERIC_ESP_OVERHEAD_MAX = 78;
|
||||
|
||||
/** Maximum overheads of authentication algorithms, keyed on IANA-defined constants */
|
||||
private static final Map<Integer, Integer> AUTH_ALGORITHM_OVERHEAD;
|
||||
|
||||
static {
|
||||
final Map<Integer, Integer> map = new ArrayMap<>();
|
||||
map.put(INTEGRITY_ALGORITHM_NONE, 0);
|
||||
map.put(INTEGRITY_ALGORITHM_HMAC_SHA1_96, 12);
|
||||
map.put(INTEGRITY_ALGORITHM_AES_XCBC_96, 12);
|
||||
map.put(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128, 32);
|
||||
map.put(INTEGRITY_ALGORITHM_HMAC_SHA2_384_192, 48);
|
||||
map.put(INTEGRITY_ALGORITHM_HMAC_SHA2_512_256, 64);
|
||||
map.put(INTEGRITY_ALGORITHM_AES_CMAC_96, 12);
|
||||
|
||||
AUTH_ALGORITHM_OVERHEAD = unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/** Maximum overheads of encryption algorithms, keyed on IANA-defined constants */
|
||||
private static final Map<Integer, Integer> CRYPT_ALGORITHM_OVERHEAD;
|
||||
|
||||
static {
|
||||
final Map<Integer, Integer> map = new ArrayMap<>();
|
||||
map.put(ENCRYPTION_ALGORITHM_3DES, 15); // 8 (IV) + 7 (Max pad)
|
||||
map.put(ENCRYPTION_ALGORITHM_AES_CBC, 31); // 16 (IV) + 15 (Max pad)
|
||||
map.put(ENCRYPTION_ALGORITHM_AES_CTR, 11); // 8 (IV) + 3 (Max pad)
|
||||
|
||||
CRYPT_ALGORITHM_OVERHEAD = unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/** Maximum overheads of combined mode algorithms, keyed on IANA-defined constants */
|
||||
private static final Map<Integer, Integer> AUTHCRYPT_ALGORITHM_OVERHEAD;
|
||||
|
||||
static {
|
||||
final Map<Integer, Integer> map = new ArrayMap<>();
|
||||
map.put(ENCRYPTION_ALGORITHM_AES_GCM_8, 19); // 8 (IV) + 3 (Max pad) + 8 (ICV)
|
||||
map.put(ENCRYPTION_ALGORITHM_AES_GCM_12, 23); // 8 (IV) + 3 (Max pad) + 12 (ICV)
|
||||
map.put(ENCRYPTION_ALGORITHM_AES_GCM_16, 27); // 8 (IV) + 3 (Max pad) + 16 (ICV)
|
||||
map.put(ENCRYPTION_ALGORITHM_CHACHA20_POLY1305, 27); // 8 (IV) + 3 (Max pad) + 16 (ICV)
|
||||
|
||||
AUTHCRYPT_ALGORITHM_OVERHEAD = unmodifiableMap(map);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the MTU of the inner interface based on the parameters provided
|
||||
*
|
||||
* <p>The MTU of the inner interface will be the minimum of the following:
|
||||
*
|
||||
* <ul>
|
||||
* <li>The MTU of the outer interface, minus the greatest ESP overhead (based on proposed
|
||||
* algorithms).
|
||||
* <li>The maximum MTU as provided in the arguments.
|
||||
* </ul>
|
||||
*/
|
||||
public static int getMtu(
|
||||
@NonNull List<ChildSaProposal> childProposals, int maxMtu, int underlyingMtu) {
|
||||
if (underlyingMtu <= 0) {
|
||||
return IPV6_MIN_MTU;
|
||||
}
|
||||
|
||||
boolean hasUnknownAlgorithm = false;
|
||||
int maxAuthOverhead = 0;
|
||||
int maxCryptOverhead = 0;
|
||||
int maxAuthCryptOverhead = 0;
|
||||
|
||||
for (ChildSaProposal proposal : childProposals) {
|
||||
for (Pair<Integer, Integer> encryptionAlgoPair : proposal.getEncryptionAlgorithms()) {
|
||||
final int algo = encryptionAlgoPair.first;
|
||||
|
||||
if (AUTHCRYPT_ALGORITHM_OVERHEAD.containsKey(algo)) {
|
||||
maxAuthCryptOverhead =
|
||||
max(maxAuthCryptOverhead, AUTHCRYPT_ALGORITHM_OVERHEAD.get(algo));
|
||||
continue;
|
||||
} else if (CRYPT_ALGORITHM_OVERHEAD.containsKey(algo)) {
|
||||
maxCryptOverhead = max(maxCryptOverhead, CRYPT_ALGORITHM_OVERHEAD.get(algo));
|
||||
continue;
|
||||
}
|
||||
|
||||
Slog.wtf(TAG, "Unknown encryption algorithm requested: " + algo);
|
||||
return IPV6_MIN_MTU;
|
||||
}
|
||||
|
||||
for (int algo : proposal.getIntegrityAlgorithms()) {
|
||||
if (AUTH_ALGORITHM_OVERHEAD.containsKey(algo)) {
|
||||
maxAuthOverhead = max(maxAuthOverhead, AUTH_ALGORITHM_OVERHEAD.get(algo));
|
||||
continue;
|
||||
}
|
||||
|
||||
Slog.wtf(TAG, "Unknown integrity algorithm requested: " + algo);
|
||||
return IPV6_MIN_MTU;
|
||||
}
|
||||
}
|
||||
|
||||
// Return minimum of maxMtu, and the adjusted MTUs based on algorithms.
|
||||
final int combinedModeMtu = underlyingMtu - maxAuthCryptOverhead - GENERIC_ESP_OVERHEAD_MAX;
|
||||
final int normalModeMtu =
|
||||
underlyingMtu - maxCryptOverhead - maxAuthOverhead - GENERIC_ESP_OVERHEAD_MAX;
|
||||
return Math.min(Math.min(maxMtu, combinedModeMtu), normalModeMtu);
|
||||
}
|
||||
}
|
||||
@@ -47,15 +47,19 @@ import android.net.LinkAddress;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.NetworkAgent;
|
||||
import android.net.NetworkCapabilities;
|
||||
import android.net.ipsec.ike.ChildSaProposal;
|
||||
import android.net.ipsec.ike.exceptions.AuthenticationFailedException;
|
||||
import android.net.ipsec.ike.exceptions.IkeException;
|
||||
import android.net.ipsec.ike.exceptions.IkeInternalException;
|
||||
import android.net.ipsec.ike.exceptions.TemporaryFailureException;
|
||||
import android.net.vcn.VcnControlPlaneIkeConfig;
|
||||
import android.net.vcn.VcnManager.VcnErrorCode;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import com.android.server.vcn.util.MtuUtils;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -153,7 +157,9 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMigratedTransformsAreApplied() throws Exception {
|
||||
public void testMigration() throws Exception {
|
||||
triggerChildOpened();
|
||||
|
||||
getChildSessionCallback()
|
||||
.onIpSecTransformsMigrated(makeDummyIpSecTransform(), makeDummyIpSecTransform());
|
||||
mTestLooper.dispatchAll();
|
||||
@@ -171,6 +177,17 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
|
||||
}
|
||||
|
||||
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
|
||||
|
||||
final List<ChildSaProposal> saProposals =
|
||||
((VcnControlPlaneIkeConfig) mConfig.getControlPlaneConfig())
|
||||
.getChildSessionParams()
|
||||
.getSaProposals();
|
||||
final int expectedMtu =
|
||||
MtuUtils.getMtu(
|
||||
saProposals,
|
||||
mConfig.getMaxMtu(),
|
||||
TEST_UNDERLYING_NETWORK_RECORD_1.linkProperties.getMtu());
|
||||
verify(mNetworkAgent).sendLinkProperties(argThat(lp -> expectedMtu == lp.getMtu()));
|
||||
}
|
||||
|
||||
private void triggerChildOpened() {
|
||||
|
||||
@@ -90,12 +90,18 @@ public class VcnGatewayConnectionTestBase {
|
||||
protected static final int TEST_SUB_ID = 5;
|
||||
protected static final long ELAPSED_REAL_TIME = 123456789L;
|
||||
protected static final String TEST_IPSEC_TUNNEL_IFACE = "IPSEC_IFACE";
|
||||
|
||||
protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_1 =
|
||||
new UnderlyingNetworkRecord(
|
||||
new Network(0),
|
||||
new NetworkCapabilities(),
|
||||
new LinkProperties(),
|
||||
false /* blocked */);
|
||||
|
||||
static {
|
||||
TEST_UNDERLYING_NETWORK_RECORD_1.linkProperties.setMtu(1500);
|
||||
}
|
||||
|
||||
protected static final UnderlyingNetworkRecord TEST_UNDERLYING_NETWORK_RECORD_2 =
|
||||
new UnderlyingNetworkRecord(
|
||||
new Network(1),
|
||||
@@ -103,6 +109,10 @@ public class VcnGatewayConnectionTestBase {
|
||||
new LinkProperties(),
|
||||
false /* blocked */);
|
||||
|
||||
static {
|
||||
TEST_UNDERLYING_NETWORK_RECORD_2.linkProperties.setMtu(1460);
|
||||
}
|
||||
|
||||
protected static final TelephonySubscriptionSnapshot TEST_SUBSCRIPTION_SNAPSHOT =
|
||||
new TelephonySubscriptionSnapshot(
|
||||
Collections.singletonMap(TEST_SUB_ID, TEST_SUB_GRP), Collections.EMPTY_MAP);
|
||||
|
||||
92
tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java
Normal file
92
tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2020 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.vcn.util;
|
||||
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_CBC;
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_12;
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_16;
|
||||
import static android.net.ipsec.ike.SaProposal.ENCRYPTION_ALGORITHM_AES_GCM_8;
|
||||
import static android.net.ipsec.ike.SaProposal.INTEGRITY_ALGORITHM_HMAC_SHA2_256_128;
|
||||
import static android.net.ipsec.ike.SaProposal.KEY_LEN_AES_256;
|
||||
|
||||
import static com.android.net.module.util.NetworkStackConstants.ETHER_MTU;
|
||||
import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
|
||||
import static com.android.server.vcn.util.MtuUtils.getMtu;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import static java.util.Collections.emptyList;
|
||||
|
||||
import android.net.ipsec.ike.ChildSaProposal;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
@SmallTest
|
||||
public class MtuUtilsTest {
|
||||
@Test
|
||||
public void testUnderlyingMtuZero() {
|
||||
assertEquals(
|
||||
IPV6_MIN_MTU, getMtu(emptyList(), ETHER_MTU /* maxMtu */, 0 /* underlyingMtu */));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClampsToMaxMtu() {
|
||||
assertEquals(0, getMtu(emptyList(), 0 /* maxMtu */, IPV6_MIN_MTU /* underlyingMtu */));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNormalModeAlgorithmLessThanUnderlyingMtu() {
|
||||
final List<ChildSaProposal> saProposals =
|
||||
Arrays.asList(
|
||||
new ChildSaProposal.Builder()
|
||||
.addEncryptionAlgorithm(
|
||||
ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256)
|
||||
.addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
|
||||
.build());
|
||||
|
||||
final int actualMtu =
|
||||
getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */);
|
||||
assertTrue(ETHER_MTU > actualMtu);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCombinedModeAlgorithmLessThanUnderlyingMtu() {
|
||||
final List<ChildSaProposal> saProposals =
|
||||
Arrays.asList(
|
||||
new ChildSaProposal.Builder()
|
||||
.addEncryptionAlgorithm(
|
||||
ENCRYPTION_ALGORITHM_AES_GCM_16, KEY_LEN_AES_256)
|
||||
.addEncryptionAlgorithm(
|
||||
ENCRYPTION_ALGORITHM_AES_GCM_12, KEY_LEN_AES_256)
|
||||
.addEncryptionAlgorithm(
|
||||
ENCRYPTION_ALGORITHM_AES_GCM_8, KEY_LEN_AES_256)
|
||||
.build());
|
||||
|
||||
final int actualMtu =
|
||||
getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */);
|
||||
assertTrue(ETHER_MTU > actualMtu);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user