[NFCT.TETHER.8] Prepare the upstream information for IPv4 offload rule
Add upstream interface index and its IPv4 address mapping
Required for building IPv4 forwarding rule when a conntrack event is
received.
Test: atest TetheringCoverageTests
Change-Id: I73f304777704f09481b80d18751e0bab5bab2edc
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 8ef0def..3268e94 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -30,6 +30,7 @@
import android.app.usage.NetworkStatsManager;
import android.net.INetd;
+import android.net.LinkProperties;
import android.net.MacAddress;
import android.net.NetworkStats;
import android.net.NetworkStats.Entry;
@@ -38,6 +39,7 @@
import android.net.ip.ConntrackMonitor.ConntrackEventConsumer;
import android.net.ip.IpServer;
import android.net.netstats.provider.NetworkStatsProvider;
+import android.net.util.InterfaceParams;
import android.net.util.SharedLog;
import android.net.util.TetheringUtils.ForwardedStats;
import android.os.ConditionVariable;
@@ -58,7 +60,9 @@
import java.net.Inet4Address;
import java.net.Inet6Address;
+import java.net.InetAddress;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -176,6 +180,11 @@
// Set for which downstream is monitoring the conntrack netlink message.
private final Set<IpServer> mMonitoringIpServers = new HashSet<>();
+ // Map of upstream interface IPv4 address to interface index.
+ // TODO: consider making the key to be unique because the upstream address is not unique. It
+ // is okay for now because there have only one upstream generally.
+ private final HashMap<Inet4Address, Integer> mIpv4UpstreamIndices = new HashMap<>();
+
// Runnable that used by scheduling next polling of stats.
private final Runnable mScheduledPollingTask = () -> {
updateForwardedStats();
@@ -551,6 +560,39 @@
}
/**
+ * Call when UpstreamNetworkState may be changed.
+ * If upstream has ipv4 for tethering, update this new UpstreamNetworkState to map. The
+ * upstream interface index and its address mapping is prepared for building IPv4
+ * offload rule.
+ *
+ * TODO: Delete the unused upstream interface mapping.
+ * TODO: Support ether ip upstream interface.
+ */
+ public void addUpstreamIfindexToMap(LinkProperties lp) {
+ if (!mPollingStarted) return;
+
+ // This will not work on a network that is using 464xlat because hasIpv4Address will not be
+ // true.
+ // TODO: need to consider 464xlat.
+ if (lp == null || !lp.hasIpv4Address()) return;
+
+ // Support raw ip upstream interface only.
+ final InterfaceParams params = InterfaceParams.getByName(lp.getInterfaceName());
+ if (params == null || params.hasMacAddress) return;
+
+ Collection<InetAddress> addresses = lp.getAddresses();
+ for (InetAddress addr: addresses) {
+ if (addr instanceof Inet4Address) {
+ Inet4Address i4addr = (Inet4Address) addr;
+ if (!i4addr.isAnyLocalAddress() && !i4addr.isLinkLocalAddress()
+ && !i4addr.isLoopbackAddress() && !i4addr.isMulticastAddress()) {
+ mIpv4UpstreamIndices.put(i4addr, params.index);
+ }
+ }
+ }
+ }
+
+ /**
* Dump information.
* Block the function until all the data are dumped on the handler thread or timed-out. The
* reason is that dumpsys invokes this function on the thread of caller and the data may only
diff --git a/Tethering/src/com/android/networkstack/tethering/Tethering.java b/Tethering/src/com/android/networkstack/tethering/Tethering.java
index fdd1c40..2354c2d 100644
--- a/Tethering/src/com/android/networkstack/tethering/Tethering.java
+++ b/Tethering/src/com/android/networkstack/tethering/Tethering.java
@@ -1636,6 +1636,13 @@
protected void handleNewUpstreamNetworkState(UpstreamNetworkState ns) {
mIPv6TetheringCoordinator.updateUpstreamNetworkState(ns);
mOffload.updateUpstreamNetworkState(ns);
+
+ // TODO: Delete all related offload rules which are using this upstream.
+ if (ns != null) {
+ // Add upstream index to the map. The upstream interface index is required while
+ // the conntrack event builds the offload rules.
+ mBpfCoordinator.addUpstreamIfindexToMap(ns.linkProperties);
+ }
}
private void handleInterfaceServingStateActive(int mode, IpServer who) {