Merge "Maximize VCN MTU when using IPv6" am: 6d70c7f36a am: 8f8e80779a am: 30ac2c94d3
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/2063435
Change-Id: I0de762eeadbb7218f1b41c18d2475b459c722a85
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
index cefd8ef..05df22f 100644
--- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
+++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java
@@ -61,6 +61,7 @@
import android.net.ipsec.ike.IkeSession;
import android.net.ipsec.ike.IkeSessionCallback;
import android.net.ipsec.ike.IkeSessionConfiguration;
+import android.net.ipsec.ike.IkeSessionConnectionInfo;
import android.net.ipsec.ike.IkeSessionParams;
import android.net.ipsec.ike.IkeTunnelConnectionParams;
import android.net.ipsec.ike.exceptions.IkeException;
@@ -509,6 +510,42 @@
}
}
+ /**
+ * Sent when an IKE session connection information has changed.
+ *
+ * <p>This signal is always fired before EVENT_SETUP_COMPLETED and EVENT_MIGRATION_COMPLETED.
+ *
+ * <p>Only relevant in the Connecting and Connected state.
+ *
+ * @param arg1 The session token for the IKE Session whose connection information has changed,
+ * used to prevent out-of-date signals from propagating.
+ * @param obj @NonNull An EventIkeConnectionInfoChangedInfo instance with relevant data.
+ */
+ private static final int EVENT_IKE_CONNECTION_INFO_CHANGED = 12;
+
+ private static class EventIkeConnectionInfoChangedInfo implements EventInfo {
+ @NonNull public final IkeSessionConnectionInfo ikeConnectionInfo;
+
+ EventIkeConnectionInfoChangedInfo(@NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
+ this.ikeConnectionInfo = ikeConnectionInfo;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(ikeConnectionInfo);
+ }
+
+ @Override
+ public boolean equals(@Nullable Object other) {
+ if (!(other instanceof EventIkeConnectionInfoChangedInfo)) {
+ return false;
+ }
+
+ final EventIkeConnectionInfoChangedInfo rhs = (EventIkeConnectionInfoChangedInfo) other;
+ return Objects.equals(ikeConnectionInfo, rhs.ikeConnectionInfo);
+ }
+ }
+
@VisibleForTesting(visibility = Visibility.PRIVATE)
@NonNull
final DisconnectedState mDisconnectedState = new DisconnectedState();
@@ -624,6 +661,14 @@
private UnderlyingNetworkRecord mUnderlying;
/**
+ * The current IKE Session connection information
+ *
+ * <p>Set in Connected and Migrating states, always @NonNull in Connected, Migrating
+ * states, @Nullable otherwise.
+ */
+ private IkeSessionConnectionInfo mIkeConnectionInfo;
+
+ /**
* The active IKE session.
*
* <p>Set in Connecting or Migrating States, always @NonNull in Connecting, Connected, and
@@ -1197,6 +1242,14 @@
exceptionMessage);
}
+ private void ikeConnectionInfoChanged(
+ int token, @NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
+ sendMessageAndAcquireWakeLock(
+ EVENT_IKE_CONNECTION_INFO_CHANGED,
+ token,
+ new EventIkeConnectionInfoChangedInfo(ikeConnectionInfo));
+ }
+
private void sessionClosed(int token, @Nullable Exception exception) {
if (exception != null) {
notifyStatusCallbackForSessionClosed(exception);
@@ -1313,7 +1366,8 @@
case EVENT_TEARDOWN_TIMEOUT_EXPIRED: // Fallthrough
case EVENT_SUBSCRIPTIONS_CHANGED: // Fallthrough
case EVENT_SAFE_MODE_TIMEOUT_EXCEEDED: // Fallthrough
- case EVENT_MIGRATION_COMPLETED:
+ case EVENT_MIGRATION_COMPLETED: // Fallthrough
+ case EVENT_IKE_CONNECTION_INFO_CHANGED:
logUnexpectedEvent(msg.what);
break;
default:
@@ -1592,6 +1646,7 @@
transitionTo(mDisconnectingState);
break;
case EVENT_SETUP_COMPLETED: // fallthrough
+ case EVENT_IKE_CONNECTION_INFO_CHANGED: // fallthrough
case EVENT_TRANSFORM_CREATED:
// Child setup complete; move to ConnectedState for NetworkAgent registration
deferMessage(msg);
@@ -1614,12 +1669,17 @@
protected void updateNetworkAgent(
@NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnNetworkAgent agent,
- @NonNull VcnChildSessionConfiguration childConfig) {
+ @NonNull VcnChildSessionConfiguration childConfig,
+ @NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
final NetworkCapabilities caps =
buildNetworkCapabilities(mConnectionConfig, mUnderlying, mIsMobileDataEnabled);
final LinkProperties lp =
buildConnectedLinkProperties(
- mConnectionConfig, tunnelIface, childConfig, mUnderlying);
+ mConnectionConfig,
+ tunnelIface,
+ childConfig,
+ mUnderlying,
+ ikeConnectionInfo);
agent.sendNetworkCapabilities(caps);
agent.sendLinkProperties(lp);
@@ -1630,12 +1690,17 @@
protected VcnNetworkAgent buildNetworkAgent(
@NonNull IpSecTunnelInterface tunnelIface,
- @NonNull VcnChildSessionConfiguration childConfig) {
+ @NonNull VcnChildSessionConfiguration childConfig,
+ @NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
final NetworkCapabilities caps =
buildNetworkCapabilities(mConnectionConfig, mUnderlying, mIsMobileDataEnabled);
final LinkProperties lp =
buildConnectedLinkProperties(
- mConnectionConfig, tunnelIface, childConfig, mUnderlying);
+ mConnectionConfig,
+ tunnelIface,
+ childConfig,
+ mUnderlying,
+ ikeConnectionInfo);
final NetworkAgentConfig nac =
new NetworkAgentConfig.Builder()
.setLegacyType(ConnectivityManager.TYPE_MOBILE)
@@ -1838,7 +1903,11 @@
mChildConfig = ((EventSetupCompletedInfo) msg.obj).childSessionConfig;
setupInterfaceAndNetworkAgent(
- mCurrentToken, mTunnelIface, mChildConfig, oldChildConfig);
+ mCurrentToken,
+ mTunnelIface,
+ mChildConfig,
+ oldChildConfig,
+ mIkeConnectionInfo);
break;
case EVENT_DISCONNECT_REQUESTED:
handleDisconnectRequested((EventDisconnectRequestedInfo) msg.obj);
@@ -1852,6 +1921,10 @@
handleMigrationCompleted(migrationCompletedInfo);
break;
+ case EVENT_IKE_CONNECTION_INFO_CHANGED:
+ mIkeConnectionInfo =
+ ((EventIkeConnectionInfoChangedInfo) msg.obj).ikeConnectionInfo;
+ break;
default:
logUnhandledMessage(msg);
break;
@@ -1875,7 +1948,7 @@
migrationCompletedInfo.outTransform,
IpSecManager.DIRECTION_OUT);
- updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig);
+ updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig, mIkeConnectionInfo);
// Trigger re-validation after migration events.
mConnectivityManager.reportNetworkConnectivity(
@@ -1906,7 +1979,8 @@
// Network not yet set up, or child not yet connected.
if (mNetworkAgent != null && mChildConfig != null) {
// If only network properties changed and agent is active, update properties
- updateNetworkAgent(mTunnelIface, mNetworkAgent, mChildConfig);
+ updateNetworkAgent(
+ mTunnelIface, mNetworkAgent, mChildConfig, mIkeConnectionInfo);
}
}
}
@@ -1915,13 +1989,14 @@
int token,
@NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnChildSessionConfiguration childConfig,
- @NonNull VcnChildSessionConfiguration oldChildConfig) {
+ @NonNull VcnChildSessionConfiguration oldChildConfig,
+ @NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
setupInterface(token, tunnelIface, childConfig, oldChildConfig);
if (mNetworkAgent == null) {
- mNetworkAgent = buildNetworkAgent(tunnelIface, childConfig);
+ mNetworkAgent = buildNetworkAgent(tunnelIface, childConfig, ikeConnectionInfo);
} else {
- updateNetworkAgent(tunnelIface, mNetworkAgent, childConfig);
+ updateNetworkAgent(tunnelIface, mNetworkAgent, childConfig, ikeConnectionInfo);
// mNetworkAgent not null, so the VCN Network has already been established. Clear
// the failed attempt counter and safe mode alarm since this transition is complete.
@@ -2098,7 +2173,8 @@
@NonNull VcnGatewayConnectionConfig gatewayConnectionConfig,
@NonNull IpSecTunnelInterface tunnelIface,
@NonNull VcnChildSessionConfiguration childConfig,
- @Nullable UnderlyingNetworkRecord underlying) {
+ @Nullable UnderlyingNetworkRecord underlying,
+ @NonNull IkeSessionConnectionInfo ikeConnectionInfo) {
final IkeTunnelConnectionParams ikeTunnelParams =
gatewayConnectionConfig.getTunnelConnectionParams();
final LinkProperties lp = new LinkProperties();
@@ -2139,7 +2215,8 @@
MtuUtils.getMtu(
ikeTunnelParams.getTunnelModeChildSessionParams().getSaProposals(),
gatewayConnectionConfig.getMaxMtu(),
- underlyingMtu));
+ underlyingMtu,
+ ikeConnectionInfo.getLocalAddress() instanceof Inet4Address));
return lp;
}
@@ -2154,7 +2231,7 @@
@Override
public void onOpened(@NonNull IkeSessionConfiguration ikeSessionConfig) {
logDbg("IkeOpened for token " + mToken);
- // Nothing to do here.
+ ikeConnectionInfoChanged(mToken, ikeSessionConfig.getIkeSessionConnectionInfo());
}
@Override
@@ -2174,6 +2251,13 @@
logInfo("IkeError for token " + mToken, exception);
// Non-fatal, log and continue.
}
+
+ @Override
+ public void onIkeSessionConnectionInfoChanged(
+ @NonNull IkeSessionConnectionInfo connectionInfo) {
+ logDbg("onIkeSessionConnectionInfoChanged for token " + mToken);
+ ikeConnectionInfoChanged(mToken, connectionInfo);
+ }
}
/** Implementation of ChildSessionCallback, exposed for testing. */
@@ -2350,6 +2434,11 @@
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
+ IkeSessionConnectionInfo getIkeConnectionInfo() {
+ return mIkeConnectionInfo;
+ }
+
+ @VisibleForTesting(visibility = Visibility.PRIVATE)
boolean isQuitting() {
return mIsQuitting.getValue();
}
diff --git a/services/core/java/com/android/server/vcn/util/MtuUtils.java b/services/core/java/com/android/server/vcn/util/MtuUtils.java
index 5d40cca..356c71f 100644
--- a/services/core/java/com/android/server/vcn/util/MtuUtils.java
+++ b/services/core/java/com/android/server/vcn/util/MtuUtils.java
@@ -51,9 +51,20 @@
/**
* Max ESP overhead possible
*
- * <p>60 (Outer IPv4 + options) + 8 (UDP encap) + 4 (SPI) + 4 (Seq) + 2 (Pad + NextHeader)
+ * <p>60 (Outer IPv4 + options) + 8 (UDP encap) + 4 (SPI) + 4 (Seq) + 2 (Pad Length + Next
+ * Header). Note: Payload data, Pad Length and Next Header will need to be padded to be multiple
+ * of the block size of a cipher, and at the same time be aligned on a 4-byte boundary.
*/
- private static final int GENERIC_ESP_OVERHEAD_MAX = 78;
+ private static final int GENERIC_ESP_OVERHEAD_MAX_V4 = 78;
+
+ /**
+ * Max ESP overhead possible
+ *
+ * <p>40 (Outer IPv6) + 4 (SPI) + 4 (Seq) + 2 (Pad Length + Next Header). Note: Payload data,
+ * Pad Length and Next Header will need to be padded to be multiple of the block size of a
+ * cipher, and at the same time be aligned on a 4-byte boundary.
+ */
+ private static final int GENERIC_ESP_OVERHEAD_MAX_V6 = 50;
/** Maximum overheads of authentication algorithms, keyed on IANA-defined constants */
private static final Map<Integer, Integer> AUTH_ALGORITHM_OVERHEAD;
@@ -108,7 +119,10 @@
* </ul>
*/
public static int getMtu(
- @NonNull List<ChildSaProposal> childProposals, int maxMtu, int underlyingMtu) {
+ @NonNull List<ChildSaProposal> childProposals,
+ int maxMtu,
+ int underlyingMtu,
+ boolean isIpv4) {
if (underlyingMtu <= 0) {
return IPV6_MIN_MTU;
}
@@ -145,10 +159,13 @@
}
}
+ final int genericEspOverheadMax =
+ isIpv4 ? GENERIC_ESP_OVERHEAD_MAX_V4 : GENERIC_ESP_OVERHEAD_MAX_V6;
+
// Return minimum of maxMtu, and the adjusted MTUs based on algorithms.
- final int combinedModeMtu = underlyingMtu - maxAuthCryptOverhead - GENERIC_ESP_OVERHEAD_MAX;
+ final int combinedModeMtu = underlyingMtu - maxAuthCryptOverhead - genericEspOverheadMax;
final int normalModeMtu =
- underlyingMtu - maxCryptOverhead - maxAuthOverhead - GENERIC_ESP_OVERHEAD_MAX;
+ underlyingMtu - maxCryptOverhead - maxAuthOverhead - genericEspOverheadMax;
return Math.min(Math.min(maxMtu, combinedModeMtu), normalModeMtu);
}
}
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index 841b81c..15d4f10 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -56,6 +56,7 @@
import android.net.NetworkAgent;
import android.net.NetworkCapabilities;
import android.net.ipsec.ike.ChildSaProposal;
+import android.net.ipsec.ike.IkeSessionConnectionInfo;
import android.net.ipsec.ike.exceptions.IkeException;
import android.net.ipsec.ike.exceptions.IkeInternalException;
import android.net.ipsec.ike.exceptions.IkeProtocolException;
@@ -216,14 +217,23 @@
@Test
public void testMigration() throws Exception {
triggerChildOpened();
+ mTestLooper.dispatchAll();
+ assertEquals(mIkeConnectionInfo, mGatewayConnection.getIkeConnectionInfo());
mGatewayConnection
.getUnderlyingNetworkControllerCallback()
.onSelectedUnderlyingNetworkChanged(TEST_UNDERLYING_NETWORK_RECORD_2);
+
+ final IkeSessionConnectionInfo newIkeConnectionInfo =
+ new IkeSessionConnectionInfo(
+ TEST_ADDR_V4, TEST_ADDR_V4_2, TEST_UNDERLYING_NETWORK_RECORD_2.network);
+ getIkeSessionCallback().onIkeSessionConnectionInfoChanged(newIkeConnectionInfo);
getChildSessionCallback()
.onIpSecTransformsMigrated(makeDummyIpSecTransform(), makeDummyIpSecTransform());
mTestLooper.dispatchAll();
+ assertEquals(newIkeConnectionInfo, mGatewayConnection.getIkeConnectionInfo());
+
verify(mIpSecSvc, times(2))
.setNetworkForTunnelInterface(
eq(TEST_IPSEC_TUNNEL_RESOURCE_ID),
@@ -246,7 +256,8 @@
MtuUtils.getMtu(
saProposals,
mConfig.getMaxMtu(),
- TEST_UNDERLYING_NETWORK_RECORD_2.linkProperties.getMtu());
+ TEST_UNDERLYING_NETWORK_RECORD_2.linkProperties.getMtu(),
+ true /* isIpv4 */);
verify(mNetworkAgent).sendLinkProperties(
argThat(lp -> expectedMtu == lp.getMtu()
&& TEST_TCP_BUFFER_SIZES_2.equals(lp.getTcpBufferSizes())));
@@ -269,6 +280,7 @@
.when(mMockChildSessionConfig)
.getInternalDnsServers();
+ getIkeSessionCallback().onOpened(mIkeSessionConfiguration);
getChildSessionCallback().onOpened(mMockChildSessionConfig);
}
@@ -298,6 +310,7 @@
mTestLooper.dispatchAll();
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
+ assertEquals(mIkeConnectionInfo, mGatewayConnection.getIkeConnectionInfo());
final ArgumentCaptor<LinkProperties> lpCaptor =
ArgumentCaptor.forClass(LinkProperties.class);
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index b9dfda3..6a9a1e2 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -213,7 +213,8 @@
VcnGatewayConnectionConfigTest.buildTestConfig(),
tunnelIface,
childSessionConfig,
- record);
+ record,
+ mIkeConnectionInfo);
verify(mDeps).getUnderlyingIfaceMtu(LOOPBACK_IFACE);
@@ -226,7 +227,8 @@
VcnGatewayConnectionConfigTest.buildTestConfig(),
tunnelIface,
childSessionConfig,
- record);
+ record,
+ mIkeConnectionInfo);
verify(mDeps, times(2)).getUnderlyingIfaceMtu(LOOPBACK_IFACE);
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
index 5628321..3d95a9b 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTestBase.java
@@ -47,6 +47,8 @@
import android.net.NetworkCapabilities;
import android.net.ipsec.ike.ChildSessionCallback;
import android.net.ipsec.ike.IkeSessionCallback;
+import android.net.ipsec.ike.IkeSessionConfiguration;
+import android.net.ipsec.ike.IkeSessionConnectionInfo;
import android.net.vcn.VcnGatewayConnectionConfig;
import android.net.vcn.VcnGatewayConnectionConfigTest;
import android.os.ParcelUuid;
@@ -80,6 +82,13 @@
doReturn(TEST_SUB_GRP).when(TEST_SUB_INFO).getGroupUuid();
}
+ protected static final InetAddress TEST_ADDR = InetAddresses.parseNumericAddress("2001:db8::1");
+ protected static final InetAddress TEST_ADDR_2 =
+ InetAddresses.parseNumericAddress("2001:db8::2");
+ protected static final InetAddress TEST_ADDR_V4 =
+ InetAddresses.parseNumericAddress("192.0.2.1");
+ protected static final InetAddress TEST_ADDR_V4_2 =
+ InetAddresses.parseNumericAddress("192.0.2.2");
protected static final InetAddress TEST_DNS_ADDR =
InetAddresses.parseNumericAddress("2001:DB8:0:1::");
protected static final InetAddress TEST_DNS_ADDR_2 =
@@ -148,6 +157,9 @@
@NonNull protected final IpSecService mIpSecSvc;
@NonNull protected final ConnectivityManager mConnMgr;
+ @NonNull protected final IkeSessionConnectionInfo mIkeConnectionInfo;
+ @NonNull protected final IkeSessionConfiguration mIkeSessionConfiguration;
+
protected VcnIkeSession mMockIkeSession;
protected VcnGatewayConnection mGatewayConnection;
@@ -173,6 +185,10 @@
VcnTestUtils.setupSystemService(
mContext, mConnMgr, Context.CONNECTIVITY_SERVICE, ConnectivityManager.class);
+ mIkeConnectionInfo =
+ new IkeSessionConnectionInfo(TEST_ADDR, TEST_ADDR_2, mock(Network.class));
+ mIkeSessionConfiguration = new IkeSessionConfiguration.Builder(mIkeConnectionInfo).build();
+
doReturn(mContext).when(mVcnContext).getContext();
doReturn(mTestLooper.getLooper()).when(mVcnContext).getLooper();
doReturn(mVcnNetworkProvider).when(mVcnContext).getVcnNetworkProvider();
diff --git a/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java b/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java
index 29511f7..e9e7078 100644
--- a/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java
+++ b/tests/vcn/java/com/android/server/vcn/util/MtuUtilsTest.java
@@ -46,34 +46,85 @@
@RunWith(AndroidJUnit4.class)
@SmallTest
public class MtuUtilsTest {
- @Test
- public void testUnderlyingMtuZero() {
+ private void verifyUnderlyingMtuZero(boolean isIpv4) {
assertEquals(
- IPV6_MIN_MTU, getMtu(emptyList(), ETHER_MTU /* maxMtu */, 0 /* underlyingMtu */));
+ IPV6_MIN_MTU,
+ getMtu(emptyList(), ETHER_MTU /* maxMtu */, 0 /* underlyingMtu */, isIpv4));
}
@Test
- public void testClampsToMaxMtu() {
- assertEquals(0, getMtu(emptyList(), 0 /* maxMtu */, IPV6_MIN_MTU /* underlyingMtu */));
+ public void testUnderlyingMtuZeroV4() {
+ verifyUnderlyingMtuZero(true /* isIpv4 */);
}
@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());
+ public void testUnderlyingMtuZeroV6() {
+ verifyUnderlyingMtuZero(false /* isIpv4 */);
+ }
+ private void verifyClampsToMaxMtu(boolean isIpv4) {
+ assertEquals(
+ 0, getMtu(emptyList(), 0 /* maxMtu */, IPV6_MIN_MTU /* underlyingMtu */, isIpv4));
+ }
+
+ @Test
+ public void testClampsToMaxMtuV4() {
+ verifyClampsToMaxMtu(true /* isIpv4 */);
+ }
+
+ @Test
+ public void testClampsToMaxMtuV6() {
+ verifyClampsToMaxMtu(false /* isIpv4 */);
+ }
+
+ private List<ChildSaProposal> buildChildSaProposalsWithNormalModeAlgo() {
+ return Arrays.asList(
+ new ChildSaProposal.Builder()
+ .addEncryptionAlgorithm(ENCRYPTION_ALGORITHM_AES_CBC, KEY_LEN_AES_256)
+ .addIntegrityAlgorithm(INTEGRITY_ALGORITHM_HMAC_SHA2_256_128)
+ .build());
+ }
+
+ private void verifyNormalModeAlgorithmLessThanUnderlyingMtu(boolean isIpv4) {
final int actualMtu =
- getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */);
+ getMtu(
+ buildChildSaProposalsWithNormalModeAlgo(),
+ ETHER_MTU /* maxMtu */,
+ ETHER_MTU /* underlyingMtu */,
+ isIpv4);
assertTrue(ETHER_MTU > actualMtu);
}
@Test
- public void testCombinedModeAlgorithmLessThanUnderlyingMtu() {
+ public void testNormalModeAlgorithmLessThanUnderlyingMtuV4() {
+ verifyNormalModeAlgorithmLessThanUnderlyingMtu(true /* isIpv4 */);
+ }
+
+ @Test
+ public void testNormalModeAlgorithmLessThanUnderlyingMtuV6() {
+ verifyNormalModeAlgorithmLessThanUnderlyingMtu(false /* isIpv4 */);
+ }
+
+ @Test
+ public void testMtuIpv4LessThanMtuIpv6() {
+ final int actualMtuV4 =
+ getMtu(
+ buildChildSaProposalsWithNormalModeAlgo(),
+ ETHER_MTU /* maxMtu */,
+ ETHER_MTU /* underlyingMtu */,
+ true /* isIpv4 */);
+
+ final int actualMtuV6 =
+ getMtu(
+ buildChildSaProposalsWithNormalModeAlgo(),
+ ETHER_MTU /* maxMtu */,
+ ETHER_MTU /* underlyingMtu */,
+ false /* isIpv4 */);
+
+ assertTrue(actualMtuV4 < actualMtuV6);
+ }
+
+ private void verifyCombinedModeAlgorithmLessThanUnderlyingMtu(boolean isIpv4) {
final List<ChildSaProposal> saProposals =
Arrays.asList(
new ChildSaProposal.Builder()
@@ -86,7 +137,17 @@
.build());
final int actualMtu =
- getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */);
+ getMtu(saProposals, ETHER_MTU /* maxMtu */, ETHER_MTU /* underlyingMtu */, isIpv4);
assertTrue(ETHER_MTU > actualMtu);
}
+
+ @Test
+ public void testCombinedModeAlgorithmLessThanUnderlyingMtuV4() {
+ verifyCombinedModeAlgorithmLessThanUnderlyingMtu(true /* isIpv4 */);
+ }
+
+ @Test
+ public void testCombinedModeAlgorithmLessThanUnderlyingMtuV6() {
+ verifyCombinedModeAlgorithmLessThanUnderlyingMtu(false /* isIpv4 */);
+ }
}