Merge "update bpf_existence_test to enforce minimum kver" into main
diff --git a/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java b/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java
index 898b124..4c9460b 100644
--- a/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java
+++ b/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java
@@ -17,6 +17,7 @@
package com.android.networkstack.tethering.apishim.api30;
import android.net.INetd;
+import android.net.IpPrefix;
import android.net.MacAddress;
import android.net.TetherStatsParcel;
import android.os.RemoteException;
@@ -81,14 +82,14 @@
@Override
public boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
- @NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac,
- @NonNull MacAddress outDstMac, int mtu) {
+ @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac,
+ @NonNull MacAddress outSrcMac, @NonNull MacAddress outDstMac, int mtu) {
return true;
}
@Override
- public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex,
- int upstreamIfindex, @NonNull MacAddress inDstMac) {
+ public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
+ @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac) {
return true;
}
diff --git a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
index 3cad1c6..062ecc5 100644
--- a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
+++ b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
@@ -17,7 +17,9 @@
package com.android.networkstack.tethering.apishim.api31;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
+import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
+import android.net.IpPrefix;
import android.net.MacAddress;
import android.system.ErrnoException;
import android.system.Os;
@@ -48,6 +50,9 @@
import java.io.FileDescriptor;
import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Arrays;
/**
* Bpf coordinator class for API shims.
@@ -196,13 +201,23 @@
return true;
}
+ @NonNull
+ private TetherUpstream6Key makeUpstream6Key(int downstreamIfindex, @NonNull MacAddress inDstMac,
+ @NonNull IpPrefix sourcePrefix) {
+ byte[] prefixBytes = Arrays.copyOf(sourcePrefix.getRawAddress(), 8);
+ long prefix64 = ByteBuffer.wrap(prefixBytes).order(ByteOrder.BIG_ENDIAN).getLong();
+ return new TetherUpstream6Key(downstreamIfindex, inDstMac, prefix64);
+ }
+
@Override
public boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
- @NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac,
- @NonNull MacAddress outDstMac, int mtu) {
+ @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac,
+ @NonNull MacAddress outSrcMac, @NonNull MacAddress outDstMac, int mtu) {
if (!isInitialized()) return false;
+ // RFC7421_PREFIX_LENGTH = 64 which is the most commonly used IPv6 subnet prefix length.
+ if (sourcePrefix.getPrefixLength() != RFC7421_PREFIX_LENGTH) return false;
- final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfindex, inDstMac);
+ final TetherUpstream6Key key = makeUpstream6Key(downstreamIfindex, inDstMac, sourcePrefix);
final Tether6Value value = new Tether6Value(upstreamIfindex, outSrcMac,
outDstMac, OsConstants.ETH_P_IPV6, mtu);
try {
@@ -216,10 +231,12 @@
@Override
public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
- @NonNull MacAddress inDstMac) {
+ @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac) {
if (!isInitialized()) return false;
+ // RFC7421_PREFIX_LENGTH = 64 which is the most commonly used IPv6 subnet prefix length.
+ if (sourcePrefix.getPrefixLength() != RFC7421_PREFIX_LENGTH) return false;
- final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfindex, inDstMac);
+ final TetherUpstream6Key key = makeUpstream6Key(downstreamIfindex, inDstMac, sourcePrefix);
try {
mBpfUpstream6Map.deleteEntry(key);
} catch (ErrnoException e) {
diff --git a/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java b/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java
index 51cecfe..25fa8bc 100644
--- a/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java
+++ b/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java
@@ -16,6 +16,7 @@
package com.android.networkstack.tethering.apishim.common;
+import android.net.IpPrefix;
import android.net.MacAddress;
import android.util.SparseArray;
@@ -79,25 +80,27 @@
* @param downstreamIfindex the downstream interface index
* @param upstreamIfindex the upstream interface index
+ * @param sourcePrefix the source IPv6 prefix
* @param inDstMac the destination MAC address to use for XDP
* @param outSrcMac the source MAC address to use for packets
* @param outDstMac the destination MAC address to use for packets
* @return true if operation succeeded or was a no-op, false otherwise
*/
public abstract boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
- @NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac,
- @NonNull MacAddress outDstMac, int mtu);
+ @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac,
+ @NonNull MacAddress outSrcMac, @NonNull MacAddress outDstMac, int mtu);
/**
* Stops IPv6 forwarding between the specified interfaces.
* @param downstreamIfindex the downstream interface index
* @param upstreamIfindex the upstream interface index
+ * @param sourcePrefix the valid source IPv6 prefix
* @param inDstMac the destination MAC address to use for XDP
* @return true if operation succeeded or was a no-op, false otherwise
*/
- public abstract boolean stopUpstreamIpv6Forwarding(int downstreamIfindex,
- int upstreamIfindex, @NonNull MacAddress inDstMac);
+ public abstract boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
+ @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac);
/**
* Return BPF tethering offload statistics.
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 976f5df..f22ccbd 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -37,6 +37,7 @@
import android.app.usage.NetworkStatsManager;
import android.net.INetd;
+import android.net.IpPrefix;
import android.net.LinkProperties;
import android.net.MacAddress;
import android.net.NetworkStats;
@@ -119,6 +120,7 @@
private static final int DUMP_TIMEOUT_MS = 10_000;
private static final MacAddress NULL_MAC_ADDRESS = MacAddress.fromString(
"00:00:00:00:00:00");
+ private static final IpPrefix IPV6_ZERO_PREFIX64 = new IpPrefix("::/64");
private static final String TETHER_DOWNSTREAM4_MAP_PATH = makeMapPath(DOWNSTREAM, 4);
private static final String TETHER_UPSTREAM4_MAP_PATH = makeMapPath(UPSTREAM, 4);
private static final String TETHER_DOWNSTREAM6_FS_PATH = makeMapPath(DOWNSTREAM, 6);
@@ -615,8 +617,9 @@
final int upstream = rule.upstreamIfindex;
// TODO: support upstream forwarding on non-point-to-point interfaces.
// TODO: get the MTU from LinkProperties and update the rules when it changes.
- if (!mBpfCoordinatorShim.startUpstreamIpv6Forwarding(downstream, upstream, rule.srcMac,
- NULL_MAC_ADDRESS, NULL_MAC_ADDRESS, NetworkStackConstants.ETHER_MTU)) {
+ if (!mBpfCoordinatorShim.startUpstreamIpv6Forwarding(downstream, upstream,
+ IPV6_ZERO_PREFIX64, rule.srcMac, NULL_MAC_ADDRESS, NULL_MAC_ADDRESS,
+ NetworkStackConstants.ETHER_MTU)) {
mLog.e("Failed to enable upstream IPv6 forwarding from "
+ getIfName(downstream) + " to " + getIfName(upstream));
}
@@ -657,7 +660,7 @@
final int downstream = rule.downstreamIfindex;
final int upstream = rule.upstreamIfindex;
if (!mBpfCoordinatorShim.stopUpstreamIpv6Forwarding(downstream, upstream,
- rule.srcMac)) {
+ IPV6_ZERO_PREFIX64, rule.srcMac)) {
mLog.e("Failed to disable upstream IPv6 forwarding from "
+ getIfName(downstream) + " to " + getIfName(upstream));
}
diff --git a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
index de15c5b..53c80ae 100644
--- a/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
+++ b/Tethering/src/com/android/networkstack/tethering/OffloadHardwareInterface.java
@@ -283,13 +283,16 @@
private int initWithHandles(NativeHandle h1, NativeHandle h2) {
if (h1 == null || h2 == null) {
+ // Set mIOffload to null has two purposes:
+ // 1. NativeHandles can be closed after initWithHandles() fails
+ // 2. Prevent mIOffload.stopOffload() to be called in stopOffload()
+ mIOffload = null;
mLog.e("Failed to create socket.");
return OFFLOAD_HAL_VERSION_NONE;
}
requestSocketDump(h1);
if (!mIOffload.initOffload(h1, h2, mOffloadHalCallback)) {
- mIOffload.stopOffload();
mLog.e("Failed to initialize offload.");
return OFFLOAD_HAL_VERSION_NONE;
}
@@ -329,9 +332,9 @@
mOffloadHalCallback = offloadCb;
final int version = initWithHandles(h1, h2);
- // Explicitly close FDs for HIDL. AIDL will pass the original FDs to the service,
- // they shouldn't be closed here.
- if (version < OFFLOAD_HAL_VERSION_AIDL) {
+ // Explicitly close FDs for HIDL or when mIOffload is null (cleared in initWithHandles).
+ // AIDL will pass the original FDs to the service, they shouldn't be closed here.
+ if (mIOffload == null || mIOffload.getVersion() < OFFLOAD_HAL_VERSION_AIDL) {
maybeCloseFdInNativeHandles(h1, h2);
}
return version;
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java b/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
index 5893885..36a1c3c 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
@@ -29,13 +29,17 @@
@Field(order = 0, type = Type.S32)
public final int iif; // The input interface index.
- @Field(order = 1, type = Type.EUI48, padding = 2)
+ @Field(order = 1, type = Type.EUI48, padding = 6)
public final MacAddress dstMac; // Destination ethernet mac address (zeroed iff rawip ingress).
- public TetherUpstream6Key(int iif, @NonNull final MacAddress dstMac) {
+ @Field(order = 2, type = Type.S64)
+ public final long src64; // The top 64-bits of the source ip.
+
+ public TetherUpstream6Key(int iif, @NonNull final MacAddress dstMac, long src64) {
Objects.requireNonNull(dstMac);
this.iif = iif;
this.dstMac = dstMac;
+ this.src64 = src64;
}
}
diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 46e50ef..464778f 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -985,7 +985,7 @@
throws Exception {
if (!mBpfDeps.isAtLeastS()) return;
final TetherUpstream6Key key = new TetherUpstream6Key(TEST_IFACE_PARAMS.index,
- TEST_IFACE_PARAMS.macAddr);
+ TEST_IFACE_PARAMS.macAddr, 0);
final Tether6Value value = new Tether6Value(upstreamIfindex,
MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
@@ -996,7 +996,7 @@
throws Exception {
if (!mBpfDeps.isAtLeastS()) return;
final TetherUpstream6Key key = new TetherUpstream6Key(TEST_IFACE_PARAMS.index,
- TEST_IFACE_PARAMS.macAddr);
+ TEST_IFACE_PARAMS.macAddr, 0);
verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key);
}
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index 4f32f3c..8bc4c18 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -641,7 +641,7 @@
private void verifyStartUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int downstreamIfIndex,
MacAddress downstreamMac, int upstreamIfindex) throws Exception {
if (!mDeps.isAtLeastS()) return;
- final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac);
+ final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac, 0);
final Tether6Value value = new Tether6Value(upstreamIfindex,
MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
@@ -652,7 +652,7 @@
MacAddress downstreamMac)
throws Exception {
if (!mDeps.isAtLeastS()) return;
- final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac);
+ final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac, 0);
verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key);
}
@@ -2192,7 +2192,7 @@
mBpfDownstream6Map.insertEntry(rule.makeTetherDownstream6Key(), rule.makeTether6Value());
final TetherUpstream6Key upstream6Key = new TetherUpstream6Key(DOWNSTREAM_IFINDEX,
- DOWNSTREAM_MAC);
+ DOWNSTREAM_MAC, 0);
final Tether6Value upstream6Value = new Tether6Value(UPSTREAM_IFINDEX,
MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
diff --git a/bpf_progs/offload.c b/bpf_progs/offload.c
index 8645dd7..c752779 100644
--- a/bpf_progs/offload.c
+++ b/bpf_progs/offload.c
@@ -194,6 +194,7 @@
TetherUpstream6Key ku = {
.iif = skb->ifindex,
+ .src64 = 0,
};
if (is_ethernet) __builtin_memcpy(downstream ? kd.dstMac : ku.dstMac, eth->h_dest, ETH_ALEN);
diff --git a/bpf_progs/offload.h b/bpf_progs/offload.h
index 9dae6c9..1e28f01 100644
--- a/bpf_progs/offload.h
+++ b/bpf_progs/offload.h
@@ -135,10 +135,10 @@
typedef struct {
uint32_t iif; // The input interface index
uint8_t dstMac[ETH_ALEN]; // destination ethernet mac address (zeroed iff rawip ingress)
- uint8_t zero[2]; // zero pad for 8 byte alignment
- // TODO: extend this to include src ip /64 subnet
+ uint8_t zero[6]; // zero pad for 8 byte alignment
+ uint64_t src64; // Top 64-bits of the src ip
} TetherUpstream6Key;
-STRUCT_SIZE(TetherUpstream6Key, 12);
+STRUCT_SIZE(TetherUpstream6Key, 4 + 6 + 6 + 8); // 24
typedef struct {
uint32_t iif; // The input interface index
diff --git a/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java b/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java
index bcedbef..4594f71 100644
--- a/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java
+++ b/service-t/src/com/android/metrics/NetworkNsdReportedMetrics.java
@@ -66,7 +66,8 @@
event.getFoundServiceCount(),
event.getFoundCallbackCount(),
event.getLostCallbackCount(),
- event.getRepliedRequestsCount());
+ event.getRepliedRequestsCount(),
+ event.getSentQueryCount());
}
}
diff --git a/service-t/src/com/android/server/NsdService.java b/service-t/src/com/android/server/NsdService.java
index 53782ac..f7edbe4 100644
--- a/service-t/src/com/android/server/NsdService.java
+++ b/service-t/src/com/android/server/NsdService.java
@@ -1920,11 +1920,14 @@
@Override
public INsdServiceConnector connect(INsdManagerCallback cb, boolean useJavaBackend) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INTERNET, "NsdService");
+ final int uid = mDeps.getCallingUid();
+ if (cb == null) {
+ throw new IllegalArgumentException("Unknown client callback from uid=" + uid);
+ }
if (DBG) Log.d(TAG, "New client connect. useJavaBackend=" + useJavaBackend);
final INsdServiceConnector connector = new NsdServiceConnector();
mNsdStateMachine.sendMessage(mNsdStateMachine.obtainMessage(NsdManager.REGISTER_CLIENT,
- new ConnectorArgs((NsdServiceConnector) connector, cb, useJavaBackend,
- mDeps.getCallingUid())));
+ new ConnectorArgs((NsdServiceConnector) connector, cb, useJavaBackend, uid)));
return connector;
}
diff --git a/service/src/com/android/metrics/stats.proto b/service/src/com/android/metrics/stats.proto
index 006d20a..99afb90 100644
--- a/service/src/com/android/metrics/stats.proto
+++ b/service/src/com/android/metrics/stats.proto
@@ -61,6 +61,9 @@
// Record query service count before unregistered service
optional int32 replied_requests_count = 11;
+
+ // Record sent query count before stopped discovery
+ optional int32 sent_query_count = 12;
}
/**
diff --git a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
index 7731ac9..e4ee8de 100644
--- a/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
+++ b/tests/cts/net/src/android/net/cts/NsdManagerTest.kt
@@ -910,12 +910,16 @@
val record = NsdRegistrationRecord()
nsdManager.registerService(si, NsdManager.PROTOCOL_DNS_SD, record)
val addOrUpdateEvent = offloadEngine
- .expectCallback<TestNsdOffloadEngine.OffloadEvent.AddOrUpdateEvent>()
+ .expectCallbackEventually<TestNsdOffloadEngine.OffloadEvent.AddOrUpdateEvent> {
+ it.info.key.serviceName == serviceName
+ }
checkOffloadServiceInfo(addOrUpdateEvent.info)
nsdManager.unregisterService(record)
val unregisterEvent = offloadEngine
- .expectCallback<TestNsdOffloadEngine.OffloadEvent.RemoveEvent>()
+ .expectCallbackEventually<TestNsdOffloadEngine.OffloadEvent.RemoveEvent> {
+ it.info.key.serviceName == serviceName
+ }
checkOffloadServiceInfo(unregisterEvent.info)
runAsShell(NETWORK_SETTINGS) {
diff --git a/tests/unit/java/com/android/server/NsdServiceTest.java b/tests/unit/java/com/android/server/NsdServiceTest.java
index 55384b3..f778075 100644
--- a/tests/unit/java/com/android/server/NsdServiceTest.java
+++ b/tests/unit/java/com/android/server/NsdServiceTest.java
@@ -1585,6 +1585,20 @@
lockOrder.verify(mMulticastLock).release();
}
+ @Test
+ public void testNullINsdManagerCallback() {
+ final NsdService service = new NsdService(mContext, mHandler, CLEANUP_DELAY_MS, mDeps) {
+ @Override
+ public INsdServiceConnector connect(INsdManagerCallback baseCb,
+ boolean runNewMdnsBackend) {
+ // Pass null INsdManagerCallback
+ return super.connect(null /* cb */, runNewMdnsBackend);
+ }
+ };
+
+ assertThrows(IllegalArgumentException.class, () -> new NsdManager(mContext, service));
+ }
+
private void waitForIdle() {
HandlerUtils.waitForIdle(mHandler, TIMEOUT_MS);
}