Maximize VCN MTU when using IPv6

This commit maximizes VCN MTU by considering IP version. Specifically,
VcnGateWayConnection stores/updates the IkeSessionConnectionInfo passed
out from the IKE library during IKE setup and migration. By looking into
the addresses stored in the IkeSessionConnectionInfo, VCN is able to
know the IP family of the VCN tunnels.

Bug: 222331693
Test: atest FrameworksVcnTests(new tests), CtsVcnTestCases
Change-Id: I9a2839d7827f1d6451546ec222129f286e94ae36
This commit is contained in:
Yan Yan
2022-04-12 16:40:37 -07:00
parent e3a1682e0b
commit eb00e3c77a
6 changed files with 236 additions and 38 deletions

View File

@@ -61,6 +61,7 @@ import android.net.ipsec.ike.ChildSessionParams;
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 @@ public class VcnGatewayConnection extends StateMachine {
}
}
/**
* 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();
@@ -623,6 +660,14 @@ public class VcnGatewayConnection extends StateMachine {
*/
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.
*
@@ -1197,6 +1242,14 @@ public class VcnGatewayConnection extends StateMachine {
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 @@ public class VcnGatewayConnection extends StateMachine {
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 @@ public class VcnGatewayConnection extends StateMachine {
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 @@ public class VcnGatewayConnection extends StateMachine {
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 @@ public class VcnGatewayConnection extends StateMachine {
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 @@ public class VcnGatewayConnection extends StateMachine {
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 @@ public class VcnGatewayConnection extends StateMachine {
handleMigrationCompleted(migrationCompletedInfo);
break;
case EVENT_IKE_CONNECTION_INFO_CHANGED:
mIkeConnectionInfo =
((EventIkeConnectionInfoChangedInfo) msg.obj).ikeConnectionInfo;
break;
default:
logUnhandledMessage(msg);
break;
@@ -1875,7 +1948,7 @@ public class VcnGatewayConnection extends StateMachine {
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 @@ public class VcnGatewayConnection extends StateMachine {
// 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 @@ public class VcnGatewayConnection extends StateMachine {
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 @@ public class VcnGatewayConnection extends StateMachine {
@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 @@ public class VcnGatewayConnection extends StateMachine {
MtuUtils.getMtu(
ikeTunnelParams.getTunnelModeChildSessionParams().getSaProposals(),
gatewayConnectionConfig.getMaxMtu(),
underlyingMtu));
underlyingMtu,
ikeConnectionInfo.getLocalAddress() instanceof Inet4Address));
return lp;
}
@@ -2154,7 +2231,7 @@ public class VcnGatewayConnection extends StateMachine {
@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 @@ public class VcnGatewayConnection extends StateMachine {
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. */
@@ -2349,6 +2433,11 @@ public class VcnGatewayConnection extends StateMachine {
mUnderlying = record;
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
IkeSessionConnectionInfo getIkeConnectionInfo() {
return mIkeConnectionInfo;
}
@VisibleForTesting(visibility = Visibility.PRIVATE)
boolean isQuitting() {
return mIsQuitting.getValue();

View File

@@ -51,9 +51,20 @@ public class MtuUtils {
/**
* 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 @@ public class MtuUtils {
* </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 @@ public class MtuUtils {
}
}
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);
}
}

View File

@@ -56,6 +56,7 @@ import android.net.LinkProperties;
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 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
@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 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
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 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
.when(mMockChildSessionConfig)
.getInternalDnsServers();
getIkeSessionCallback().onOpened(mIkeSessionConfiguration);
getChildSessionCallback().onOpened(mMockChildSessionConfig);
}
@@ -298,6 +310,7 @@ public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnection
mTestLooper.dispatchAll();
assertEquals(mGatewayConnection.mConnectedState, mGatewayConnection.getCurrentState());
assertEquals(mIkeConnectionInfo, mGatewayConnection.getIkeConnectionInfo());
final ArgumentCaptor<LinkProperties> lpCaptor =
ArgumentCaptor.forClass(LinkProperties.class);

View File

@@ -213,7 +213,8 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
VcnGatewayConnectionConfigTest.buildTestConfig(),
tunnelIface,
childSessionConfig,
record);
record,
mIkeConnectionInfo);
verify(mDeps).getUnderlyingIfaceMtu(LOOPBACK_IFACE);
@@ -226,7 +227,8 @@ public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
VcnGatewayConnectionConfigTest.buildTestConfig(),
tunnelIface,
childSessionConfig,
record);
record,
mIkeConnectionInfo);
verify(mDeps, times(2)).getUnderlyingIfaceMtu(LOOPBACK_IFACE);

View File

@@ -47,6 +47,8 @@ import android.net.Network;
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 @@ public class VcnGatewayConnectionTestBase {
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 @@ public class VcnGatewayConnectionTestBase {
@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 @@ public class VcnGatewayConnectionTestBase {
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();

View File

@@ -46,34 +46,85 @@ import java.util.List;
@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 @@ public class MtuUtilsTest {
.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 */);
}
}