From 5b43cea3c8185425fa43cb817ab26fecfd13708c Mon Sep 17 00:00:00 2001 From: Erik Kline Date: Thu, 6 Sep 2018 11:10:03 +0900 Subject: [PATCH] Tighten up neighbor timers if IpReachabilityMonitor is in use Currently the kernel sends 3 probes, 1000ms apart when a neighbor is in NUD_PROBE state (either naturally or artificially moved to that state when, for example, confirming network configuration following an AP association/roam). With this change the device sends 5 probes at 750ms apart. This gives the network infrastructure a chance to respond to any of 5 probes instead of any of only 3, at a cost of increasing the total probe time from 3s to 3.75s. Future changes may read these values from settings (or from somewhere else) so that experiments may be conducted or values adjusted based on other information. Test: as follows - built, flashed, booted - runtest frameworks-net passes - examinaton of /proc settings on wifi shows updated values - connected to a test network, disconnected the backhaul, ran "adb shell dumpsys wifi ipclient confirm" while watching "adb shell tcpdump -n -i wlan0 -l -vv arp", and observed 5 ARP who-has ("solicits") ~750ms apart. Bug: 62476366 Bug: 62845299 Change-Id: Ib805531b08624805bb63703a5b338b9ff48171d4 --- .../net/java/android/net/ip/IpClient.java | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/services/net/java/android/net/ip/IpClient.java b/services/net/java/android/net/ip/IpClient.java index 3cdef1e73ae49..ccc092d3b0e7e 100644 --- a/services/net/java/android/net/ip/IpClient.java +++ b/services/net/java/android/net/ip/IpClient.java @@ -1384,6 +1384,20 @@ public class IpClient extends StateMachine { } private boolean startIpReachabilityMonitor() { + try { + // TODO: Fetch these parameters from settings, and install a + // settings observer to watch for update and re-program these + // parameters (Q: is this level of dynamic updatability really + // necessary or does reading from settings at startup suffice?). + final int NUM_SOLICITS = 5; + final int INTER_SOLICIT_INTERVAL_MS = 750; + setNeighborParameters(mDependencies.getNetd(), mInterfaceName, + NUM_SOLICITS, INTER_SOLICIT_INTERVAL_MS); + } catch (Exception e) { + mLog.e("Failed to adjust neighbor parameters", e); + // Carry on using the system defaults (currently: 3, 1000); + } + try { mIpReachabilityMonitor = new IpReachabilityMonitor( mContext, @@ -1863,6 +1877,20 @@ public class IpClient extends StateMachine { } } + private static void setNeighborParameters( + INetd netd, String ifName, int num_solicits, int inter_solicit_interval_ms) + throws RemoteException, IllegalArgumentException { + Preconditions.checkNotNull(netd); + Preconditions.checkArgument(!TextUtils.isEmpty(ifName)); + Preconditions.checkArgument(num_solicits > 0); + Preconditions.checkArgument(inter_solicit_interval_ms > 0); + + for (int family : new Integer[]{INetd.IPV4, INetd.IPV6}) { + netd.setProcSysNet(family, INetd.NEIGH, ifName, "retrans_time_ms", Integer.toString(inter_solicit_interval_ms)); + netd.setProcSysNet(family, INetd.NEIGH, ifName, "ucast_solicit", Integer.toString(num_solicits)); + } + } + // TODO: extract out into CollectionUtils. static boolean any(Iterable coll, Predicate fn) { for (T t : coll) {