summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/android/net/ip/IpClient.java39
-rw-r--r--src/com/android/server/util/NetworkStackConstants.java2
-rw-r--r--tests/integration/Android.bp1
-rw-r--r--tests/integration/src/android/net/ip/IpClientIntegrationTest.java70
-rw-r--r--tests/unit/src/android/net/ip/IpClientTest.java2
5 files changed, 93 insertions, 21 deletions
diff --git a/src/android/net/ip/IpClient.java b/src/android/net/ip/IpClient.java
index 799184e..bff30b6 100644
--- a/src/android/net/ip/IpClient.java
+++ b/src/android/net/ip/IpClient.java
@@ -19,6 +19,7 @@ package android.net.ip;
import static android.net.RouteInfo.RTN_UNICAST;
import static android.net.shared.IpConfigurationParcelableUtil.toStableParcelable;
+import static com.android.server.util.NetworkStackConstants.ETHER_MTU;
import static com.android.server.util.PermissionUtil.checkNetworkStackCallingPermission;
import android.annotation.NonNull;
@@ -48,6 +49,7 @@ import android.os.ConditionVariable;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
+import android.os.ServiceSpecificException;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.LocalLog;
@@ -69,6 +71,8 @@ import com.android.server.NetworkStackService.NetworkStackServiceManager;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
@@ -380,6 +384,8 @@ public class IpClient extends StateMachine {
private final ConditionVariable mApfDataSnapshotComplete = new ConditionVariable();
public static class Dependencies {
+ private static final String TAG = "IpClient.Dependencies";
+
/**
* Get interface parameters for the specified interface.
*/
@@ -388,6 +394,18 @@ public class IpClient extends StateMachine {
}
/**
+ * Get the current MTU for the specified interface.
+ */
+ public int getInterfaceMtu(String ifname) {
+ try {
+ return NetworkInterface.getByName(ifname).getMTU();
+ } catch (SocketException e) {
+ Log.e(TAG, "unexpected failure to get the interface MTU");
+ return ETHER_MTU;
+ }
+ }
+
+ /**
* Get a INetd connector.
*/
public INetd getNetd(Context context) {
@@ -850,10 +868,14 @@ public class IpClient extends StateMachine {
return shouldLog;
}
- private void logError(String fmt, Object... args) {
+ private void logError(String fmt, Throwable e, Object... args) {
final String msg = "ERROR " + String.format(fmt, args);
- Log.e(mTag, msg);
- mLog.log(msg);
+ Log.e(mTag, msg, e);
+ mLog.e(msg, e);
+ }
+
+ private void logError(String fmt, Object... args) {
+ logError(fmt, null, args);
}
// This needs to be called with care to ensure that our LinkProperties
@@ -1351,6 +1373,17 @@ public class IpClient extends StateMachine {
// There's no DHCPv4 for which to wait; proceed to stopped.
deferMessage(obtainMessage(CMD_JUMP_STOPPING_TO_STOPPED));
}
+
+ // Restore the interface MTU to initial value if it has changed.
+ final int mtu = mDependencies.getInterfaceMtu(mInterfaceName);
+ try {
+ if (mtu != mInterfaceParams.defaultMtu) {
+ mNetd.interfaceSetMtu(mInterfaceName, mInterfaceParams.defaultMtu);
+ }
+ } catch (RemoteException | ServiceSpecificException e) {
+ logError("Couldn't reset MTU from "
+ + mtu + " to " + mInterfaceParams.defaultMtu + ": " + e);
+ }
}
@Override
diff --git a/src/com/android/server/util/NetworkStackConstants.java b/src/com/android/server/util/NetworkStackConstants.java
index 804765e..3174a9b 100644
--- a/src/com/android/server/util/NetworkStackConstants.java
+++ b/src/com/android/server/util/NetworkStackConstants.java
@@ -54,6 +54,7 @@ public final class NetworkStackConstants {
public static final int ETHER_TYPE_IPV4 = 0x0800;
public static final int ETHER_TYPE_IPV6 = 0x86dd;
public static final int ETHER_HEADER_LEN = 14;
+ public static final int ETHER_MTU = 1500;
/**
* ARP constants.
@@ -97,6 +98,7 @@ public final class NetworkStackConstants {
public static final int IPV6_PROTOCOL_OFFSET = 6;
public static final int IPV6_SRC_ADDR_OFFSET = 8;
public static final int IPV6_DST_ADDR_OFFSET = 24;
+ public static final int IPV6_MIN_MTU = 1280;
/**
* ICMPv6 constants.
diff --git a/tests/integration/Android.bp b/tests/integration/Android.bp
index ec8257f..ec16467 100644
--- a/tests/integration/Android.bp
+++ b/tests/integration/Android.bp
@@ -23,6 +23,7 @@ android_test {
"androidx.annotation_annotation",
"androidx.test.rules",
"mockito-target-extended-minus-junit4",
+ "net-tests-utils",
"NetworkStackBase",
"testables",
],
diff --git a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
index 16e92ef..48fd7da 100644
--- a/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
+++ b/tests/integration/src/android/net/ip/IpClientIntegrationTest.java
@@ -77,6 +77,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.server.NetworkObserverRegistry;
import com.android.server.NetworkStackService.NetworkStackServiceManager;
import com.android.server.connectivity.ipmemorystore.IpMemoryStoreService;
+import com.android.testutils.HandlerUtilsKt;
import org.junit.After;
import org.junit.Before;
@@ -158,7 +159,8 @@ public class IpClientIntegrationTest {
private static final Inet4Address BROADCAST_ADDR = getBroadcastAddress(
SERVER_ADDR, PREFIX_LENGTH);
private static final String HOSTNAME = "testhostname";
- private static final short MTU = 1500;
+ private static final int TEST_DEFAULT_MTU = 1500;
+ private static final int TEST_MIN_MTU = 1280;
private static class TapPacketReader extends PacketReader {
private final ParcelFileDescriptor mTapFd;
@@ -203,6 +205,7 @@ public class IpClientIntegrationTest {
private class Dependencies extends IpClient.Dependencies {
private boolean mIsDhcpLeaseCacheEnabled;
private boolean mIsDhcpRapidCommitEnabled;
+ private int mMtu = TEST_DEFAULT_MTU;
public void setDhcpLeaseCacheEnabled(final boolean enable) {
mIsDhcpLeaseCacheEnabled = enable;
@@ -212,6 +215,10 @@ public class IpClientIntegrationTest {
mIsDhcpRapidCommitEnabled = enable;
}
+ public void setMtu(final int mtu) {
+ mMtu = mtu;
+ }
+
@Override
public INetd getNetd(Context context) {
return mNetd;
@@ -242,6 +249,11 @@ public class IpClientIntegrationTest {
}
};
}
+
+ @Override
+ public int getInterfaceMtu(String ifName) {
+ return mMtu;
+ }
}
@Before
@@ -345,7 +357,7 @@ public class IpClientIntegrationTest {
}
private static ByteBuffer buildDhcpOfferPacket(final DhcpPacket packet,
- final Integer leaseTimeSec) {
+ final Integer leaseTimeSec, final short mtu) {
return DhcpPacket.buildOfferPacket(DhcpPacket.ENCAP_L2, packet.getTransactionId(),
false /* broadcast */, SERVER_ADDR, INADDR_ANY /* relayIp */,
CLIENT_ADDR /* yourIp */, packet.getClientMac(), leaseTimeSec,
@@ -353,11 +365,11 @@ public class IpClientIntegrationTest {
Collections.singletonList(SERVER_ADDR) /* gateways */,
Collections.singletonList(SERVER_ADDR) /* dnsServers */,
SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, HOSTNAME,
- false /* metered */, MTU);
+ false /* metered */, mtu);
}
private static ByteBuffer buildDhcpAckPacket(final DhcpPacket packet,
- final Integer leaseTimeSec) {
+ final Integer leaseTimeSec, final short mtu) {
return DhcpPacket.buildAckPacket(DhcpPacket.ENCAP_L2, packet.getTransactionId(),
false /* broadcast */, SERVER_ADDR, INADDR_ANY /* relayIp */,
CLIENT_ADDR /* yourIp */, CLIENT_ADDR /* requestIp */, packet.getClientMac(),
@@ -365,7 +377,7 @@ public class IpClientIntegrationTest {
Collections.singletonList(SERVER_ADDR) /* gateways */,
Collections.singletonList(SERVER_ADDR) /* dnsServers */,
SERVER_ADDR /* dhcpServerIdentifier */, null /* domainName */, HOSTNAME,
- false /* metered */, MTU);
+ false /* metered */, mtu);
}
private static ByteBuffer buildDhcpNakPacket(final DhcpPacket packet) {
@@ -397,7 +409,7 @@ public class IpClientIntegrationTest {
}
private void assertIpMemoryStoreNetworkAttributes(final Integer leaseTimeSec,
- final long startTime) {
+ final long startTime, final int mtu) {
final ArgumentCaptor<NetworkAttributes> networkAttributes =
ArgumentCaptor.forClass(NetworkAttributes.class);
@@ -416,7 +428,7 @@ public class IpClientIntegrationTest {
assertTrue(lowerBound < expiry);
}
assertEquals(Collections.singletonList(SERVER_ADDR), naValueCaptured.dnsAddresses);
- assertEquals(new Integer((int) MTU), naValueCaptured.mtu);
+ assertEquals(new Integer(mtu), naValueCaptured.mtu);
}
private void assertIpMemoryNeverStoreNetworkAttributes() {
@@ -433,13 +445,16 @@ public class IpClientIntegrationTest {
while ((packet = getNextDhcpPacket()) != null) {
if (packet instanceof DhcpDiscoverPacket) {
if (isDhcpRapidCommitEnabled) {
- sendResponse(buildDhcpAckPacket(packet, leaseTimeSec));
+ sendResponse(buildDhcpAckPacket(packet, leaseTimeSec,
+ (short) mDependencies.getInterfaceMtu(mIfaceName)));
} else {
- sendResponse(buildDhcpOfferPacket(packet, leaseTimeSec));
+ sendResponse(buildDhcpOfferPacket(packet, leaseTimeSec,
+ (short) mDependencies.getInterfaceMtu(mIfaceName)));
}
} else if (packet instanceof DhcpRequestPacket) {
final ByteBuffer byteBuffer = isSuccessLease
- ? buildDhcpAckPacket(packet, leaseTimeSec)
+ ? buildDhcpAckPacket(packet, leaseTimeSec,
+ (short) mDependencies.getInterfaceMtu(mIfaceName))
: buildDhcpNakPacket(packet);
sendResponse(byteBuffer);
} else {
@@ -487,7 +502,7 @@ public class IpClientIntegrationTest {
final long currentTime = System.currentTimeMillis();
performDhcpHandshake(true /* isSuccessLease */, TEST_LEASE_DURATION_S,
true /* isDhcpLeaseCacheEnabled */, false /* isDhcpRapidCommitEnabled */);
- assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime);
+ assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime, TEST_DEFAULT_MTU);
}
@Test
@@ -502,7 +517,7 @@ public class IpClientIntegrationTest {
final long currentTime = System.currentTimeMillis();
performDhcpHandshake(true /* isSuccessLease */, INFINITE_LEASE,
true /* isDhcpLeaseCacheEnabled */, false /* isDhcpRapidCommitEnabled */);
- assertIpMemoryStoreNetworkAttributes(INFINITE_LEASE, currentTime);
+ assertIpMemoryStoreNetworkAttributes(INFINITE_LEASE, currentTime, TEST_DEFAULT_MTU);
}
@Test
@@ -510,7 +525,7 @@ public class IpClientIntegrationTest {
final long currentTime = System.currentTimeMillis();
performDhcpHandshake(true /* isSuccessLease */, null /* no lease time */,
true /* isDhcpLeaseCacheEnabled */, false /* isDhcpRapidCommitEnabled */);
- assertIpMemoryStoreNetworkAttributes(null, currentTime);
+ assertIpMemoryStoreNetworkAttributes(null, currentTime, TEST_DEFAULT_MTU);
}
@Test
@@ -527,7 +542,7 @@ public class IpClientIntegrationTest {
final long currentTime = System.currentTimeMillis();
performDhcpHandshake(true /* isSuccessLease */, TEST_LEASE_DURATION_S,
true /* isDhcpLeaseCacheEnabled */, true /* isDhcpRapidCommitEnabled */);
- assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime);
+ assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime, TEST_DEFAULT_MTU);
}
@Test
@@ -536,7 +551,7 @@ public class IpClientIntegrationTest {
new NetworkAttributes.Builder()
.setAssignedV4Address(CLIENT_ADDR)
.setAssignedV4AddressExpiry(Long.MAX_VALUE) // lease is always valid
- .setMtu(new Integer(MTU))
+ .setMtu(new Integer(TEST_DEFAULT_MTU))
.setGroupHint(TEST_GROUPHINT)
.setDnsAddresses(Collections.singletonList(SERVER_ADDR))
.build(), false /* timeout */);
@@ -549,7 +564,7 @@ public class IpClientIntegrationTest {
new NetworkAttributes.Builder()
.setAssignedV4Address(CLIENT_ADDR)
.setAssignedV4AddressExpiry(EXPIRED_LEASE)
- .setMtu(new Integer(MTU))
+ .setMtu(new Integer(TEST_DEFAULT_MTU))
.setGroupHint(TEST_GROUPHINT)
.setDnsAddresses(Collections.singletonList(SERVER_ADDR))
.build(), false /* timeout */);
@@ -568,7 +583,7 @@ public class IpClientIntegrationTest {
new NetworkAttributes.Builder()
.setAssignedV4Address(CLIENT_ADDR)
.setAssignedV4AddressExpiry(System.currentTimeMillis() + 3_600_000)
- .setMtu(new Integer(MTU))
+ .setMtu(new Integer(TEST_DEFAULT_MTU))
.setGroupHint(TEST_GROUPHINT)
.setDnsAddresses(Collections.singletonList(SERVER_ADDR))
.build(), true /* timeout */);
@@ -579,7 +594,7 @@ public class IpClientIntegrationTest {
public void testDhcpClientStartWithCachedLeaseWithoutIPAddress() throws Exception {
final DhcpPacket packet = getReplyFromDhcpLease(
new NetworkAttributes.Builder()
- .setMtu(new Integer(MTU))
+ .setMtu(new Integer(TEST_DEFAULT_MTU))
.setGroupHint(TEST_GROUPHINT)
.setDnsAddresses(Collections.singletonList(SERVER_ADDR))
.build(), false /* timeout */);
@@ -593,4 +608,23 @@ public class IpClientIntegrationTest {
final DhcpPacket packet = getNextDhcpPacket();
assertTrue(DhcpDiscoverPacket.class.isInstance(packet));
}
+
+ @Test
+ public void testRestoreInitialInterfaceMtu() throws Exception {
+ final long currentTime = System.currentTimeMillis();
+
+ // check the initial interface MTU
+ assertTrue(mDependencies.getInterfaceMtu(mIfaceName) == TEST_DEFAULT_MTU);
+
+ // change the MTU and pass the new MTU into DHCPOFFER and DHCPACK packet
+ mDependencies.setMtu(TEST_MIN_MTU);
+ performDhcpHandshake(true /* isSuccessLease */, TEST_LEASE_DURATION_S,
+ true /* isDhcpLeaseCacheEnabled */, false /* isDhcpRapidCommitEnabled */);
+ assertIpMemoryStoreNetworkAttributes(TEST_LEASE_DURATION_S, currentTime, TEST_MIN_MTU);
+
+ mIpc.shutdown();
+ HandlerUtilsKt.waitForIdle(mIpc.getHandler(), TEST_TIMEOUT_MS);
+ // verify that mtu indeed has been restored
+ verify(mNetd, times(1)).interfaceSetMtu(mIfaceName, TEST_DEFAULT_MTU);
+ }
}
diff --git a/tests/unit/src/android/net/ip/IpClientTest.java b/tests/unit/src/android/net/ip/IpClientTest.java
index 1d6ce6e..212e0ed 100644
--- a/tests/unit/src/android/net/ip/IpClientTest.java
+++ b/tests/unit/src/android/net/ip/IpClientTest.java
@@ -83,6 +83,7 @@ public class IpClientTest {
private static final String INVALID = "INVALID";
private static final String TEST_IFNAME = "test_wlan0";
private static final int TEST_IFINDEX = 1001;
+ private static final int TEST_MTU = 1500;
// See RFC 7042#section-2.1.2 for EUI-48 documentation values.
private static final MacAddress TEST_MAC = MacAddress.fromString("00:00:5E:00:53:01");
private static final int TEST_TIMEOUT_MS = 400;
@@ -122,6 +123,7 @@ public class IpClientTest {
when(mDependencies.getInterfaceParams(any())).thenReturn(mInterfaceParams);
when(mDependencies.getIpMemoryStore(mContext, mNetworkStackServiceManager))
.thenReturn(mIpMemoryStore);
+ when(mDependencies.getInterfaceMtu(TEST_IFNAME)).thenReturn(TEST_MTU);
mIfParams = null;
}