summaryrefslogtreecommitdiff
path: root/common/device/com/android/net/module
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-09-02 21:02:14 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-09-02 21:02:14 +0000
commit46a57a347ec4b5c6974262ed8f88685a854a00af (patch)
treeefaf9e838b13caea604ccea565056c8a4f7f3630 /common/device/com/android/net/module
parentb24f26018c56b85f541aad78ae8d492848847bb3 (diff)
parentc28fc7974331b64aa2d4b96ce9871a7bb6b24f7f (diff)
downloadnet-46a57a347ec4b5c6974262ed8f88685a854a00af.tar.gz
Snap for 10755155 from c28fc7974331b64aa2d4b96ce9871a7bb6b24f7f to mainline-art-releaseaml_art_341110110aml_art_341110060
Change-Id: I2e5f018bbe03854a833e0bbe548d443b245b5c2f
Diffstat (limited to 'common/device/com/android/net/module')
-rw-r--r--common/device/com/android/net/module/util/BpfMap.java30
-rw-r--r--common/device/com/android/net/module/util/DeviceConfigUtils.java44
-rw-r--r--common/device/com/android/net/module/util/FeatureVersions.java21
-rw-r--r--common/device/com/android/net/module/util/arp/ArpPacket.java171
4 files changed, 232 insertions, 34 deletions
diff --git a/common/device/com/android/net/module/util/BpfMap.java b/common/device/com/android/net/module/util/BpfMap.java
index 9df2b035..d45caceb 100644
--- a/common/device/com/android/net/module/util/BpfMap.java
+++ b/common/device/com/android/net/module/util/BpfMap.java
@@ -194,9 +194,11 @@ public class BpfMap<K extends Struct, V extends Struct> implements IBpfMap<K, V>
}
private K getNextKeyInternal(@Nullable K key) throws ErrnoException {
- final byte[] rawKey = getNextRawKey(
- key == null ? null : key.writeToBytes());
- if (rawKey == null) return null;
+ byte[] rawKey = new byte[mKeySize];
+
+ if (!nativeGetNextMapKey(mMapFd.getFd(),
+ key == null ? null : key.writeToBytes(),
+ rawKey)) return null;
final ByteBuffer buffer = ByteBuffer.wrap(rawKey);
buffer.order(ByteOrder.nativeOrder());
@@ -215,13 +217,6 @@ public class BpfMap<K extends Struct, V extends Struct> implements IBpfMap<K, V>
return getNextKeyInternal(key);
}
- private byte[] getNextRawKey(@Nullable final byte[] key) throws ErrnoException {
- byte[] nextKey = new byte[mKeySize];
- if (nativeGetNextMapKey(mMapFd.getFd(), key, nextKey)) return nextKey;
-
- return null;
- }
-
/** Get the first key of eBpf map. */
@Override
public K getFirstKey() throws ErrnoException {
@@ -233,30 +228,23 @@ public class BpfMap<K extends Struct, V extends Struct> implements IBpfMap<K, V>
public boolean containsKey(@NonNull K key) throws ErrnoException {
Objects.requireNonNull(key);
- final byte[] rawValue = getRawValue(key.writeToBytes());
- return rawValue != null;
+ byte[] rawValue = new byte[mValueSize];
+ return nativeFindMapEntry(mMapFd.getFd(), key.writeToBytes(), rawValue);
}
/** Retrieve a value from the map. Return null if there is no such key. */
@Override
public V getValue(@NonNull K key) throws ErrnoException {
Objects.requireNonNull(key);
- final byte[] rawValue = getRawValue(key.writeToBytes());
- if (rawValue == null) return null;
+ byte[] rawValue = new byte[mValueSize];
+ if (!nativeFindMapEntry(mMapFd.getFd(), key.writeToBytes(), rawValue)) return null;
final ByteBuffer buffer = ByteBuffer.wrap(rawValue);
buffer.order(ByteOrder.nativeOrder());
return Struct.parse(mValueClass, buffer);
}
- private byte[] getRawValue(final byte[] key) throws ErrnoException {
- byte[] value = new byte[mValueSize];
- if (nativeFindMapEntry(mMapFd.getFd(), key, value)) return value;
-
- return null;
- }
-
/**
* Iterate through the map and handle each key -> value retrieved base on the given BiConsumer.
* The given BiConsumer may to delete the passed-in entry, but is not allowed to perform any
diff --git a/common/device/com/android/net/module/util/DeviceConfigUtils.java b/common/device/com/android/net/module/util/DeviceConfigUtils.java
index bea227d9..fb130f67 100644
--- a/common/device/com/android/net/module/util/DeviceConfigUtils.java
+++ b/common/device/com/android/net/module/util/DeviceConfigUtils.java
@@ -17,6 +17,7 @@
package com.android.net.module.util;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
+import static android.provider.DeviceConfig.NAMESPACE_CONNECTIVITY;
import static android.provider.DeviceConfig.NAMESPACE_TETHERING;
import static com.android.net.module.util.FeatureVersions.CONNECTIVITY_MODULE_ID;
@@ -207,8 +208,9 @@ public final class DeviceConfigUtils {
* null.
* @return true if this feature is enabled, or false if disabled.
*/
- public static boolean isFeatureEnabled(@NonNull Context context, @NonNull String namespace,
- @NonNull String name, @NonNull String moduleName, boolean defaultEnabled) {
+ public static boolean isTetheringFeatureEnabled(@NonNull Context context,
+ @NonNull String namespace, @NonNull String name, @NonNull String moduleName,
+ boolean defaultEnabled) {
// TODO: migrate callers to a non-generic isTetheringFeatureEnabled method.
if (!TETHERING_MODULE_NAME.equals(moduleName)) {
throw new IllegalArgumentException(
@@ -334,16 +336,42 @@ public final class DeviceConfigUtils {
}
/**
- * Check whether one specific experimental feature in tethering module from {@link DeviceConfig}
- * is disabled by setting a non-zero value in the property.
+ * Check whether one specific experimental feature in specific namespace from
+ * {@link DeviceConfig} is not disabled. Feature can be disabled by setting a non-zero
+ * value in the property. If the feature is enabled by default and disabled by flag push
+ * (kill switch), this method should be used. If the feature is disabled by default and
+ * enabled by flag push, {@link #isFeatureEnabled} should be used.
*
+ * @param namespace The namespace containing the property to look up.
* @param name The name of the property to look up.
- * @return true if this feature is force disabled, or false if not disabled.
+ * @return true if this feature is enabled, or false if disabled.
*/
- public static boolean isTetheringFeatureForceDisabled(String name) {
- final int propertyVersion = getDeviceConfigPropertyInt(NAMESPACE_TETHERING, name,
+ private static boolean isFeatureNotChickenedOut(String namespace, String name) {
+ final int propertyVersion = getDeviceConfigPropertyInt(namespace, name,
0 /* default value */);
- return propertyVersion != 0;
+ return propertyVersion == 0;
+ }
+
+ /**
+ * Check whether one specific experimental feature in Tethering module from {@link DeviceConfig}
+ * is not disabled.
+ *
+ * @param name The name of the property in tethering module to look up.
+ * @return true if this feature is enabled, or false if disabled.
+ */
+ public static boolean isTetheringFeatureNotChickenedOut(String name) {
+ return isFeatureNotChickenedOut(NAMESPACE_TETHERING, name);
+ }
+
+ /**
+ * Check whether one specific experimental feature in NetworkStack module from
+ * {@link DeviceConfig} is not disabled.
+ *
+ * @param name The name of the property in NetworkStack module to look up.
+ * @return true if this feature is enabled, or false if disabled.
+ */
+ public static boolean isNetworkStackFeatureNotChickenedOut(String name) {
+ return isFeatureNotChickenedOut(NAMESPACE_CONNECTIVITY, name);
}
/**
diff --git a/common/device/com/android/net/module/util/FeatureVersions.java b/common/device/com/android/net/module/util/FeatureVersions.java
index 4986a588..149756c3 100644
--- a/common/device/com/android/net/module/util/FeatureVersions.java
+++ b/common/device/com/android/net/module/util/FeatureVersions.java
@@ -22,13 +22,24 @@ package com.android.net.module.util;
* @hide
*/
public class FeatureVersions {
- public static final long MODULE_MASK = 0xFF00_000000000L;
- public static final long VERSION_MASK = 0x0000_FFFFFFFFFL;
- public static final long CONNECTIVITY_MODULE_ID = 0x0100_000000000L;
- public static final long NETWORK_STACK_MODULE_ID = 0x0200_000000000L;
+ /**
+ * This constant is used to do bitwise shift operation to create module ids.
+ * The module version is composed with 9 digits which is placed in the lower 36 bits.
+ */
+ private static final int MODULE_SHIFT = 36;
+ /**
+ * The bitmask to do bitwise-and(i.e. {@code &}) operation to get the module id.
+ */
+ public static final long MODULE_MASK = 0xFF0_0000_0000L;
+ /**
+ * The bitmask to do bitwise-and(i.e. {@code &}) operation to get the module version.
+ */
+ public static final long VERSION_MASK = 0x00F_FFFF_FFFFL;
+ public static final long CONNECTIVITY_MODULE_ID = 0x01L << MODULE_SHIFT;
+ public static final long NETWORK_STACK_MODULE_ID = 0x02L << MODULE_SHIFT;
// CLAT_ADDRESS_TRANSLATE is a feature of the network stack, which doesn't throw when system
// try to add a NAT-T keepalive packet filter with v6 address, introduced in version
// M-2023-Sept on July 3rd, 2023.
public static final long FEATURE_CLAT_ADDRESS_TRANSLATE =
- NETWORK_STACK_MODULE_ID + 340900000L;
+ NETWORK_STACK_MODULE_ID + 34_09_00_000L;
}
diff --git a/common/device/com/android/net/module/util/arp/ArpPacket.java b/common/device/com/android/net/module/util/arp/ArpPacket.java
new file mode 100644
index 00000000..dab9694b
--- /dev/null
+++ b/common/device/com/android/net/module/util/arp/ArpPacket.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.net.module.util.arp;
+
+import static android.system.OsConstants.ETH_P_ARP;
+import static android.system.OsConstants.ETH_P_IP;
+
+import static com.android.net.module.util.NetworkStackConstants.ARP_ETHER_IPV4_LEN;
+import static com.android.net.module.util.NetworkStackConstants.ARP_HWTYPE_ETHER;
+import static com.android.net.module.util.NetworkStackConstants.ARP_REPLY;
+import static com.android.net.module.util.NetworkStackConstants.ARP_REQUEST;
+import static com.android.net.module.util.NetworkStackConstants.ETHER_ADDR_LEN;
+import static com.android.net.module.util.NetworkStackConstants.IPV4_ADDR_LEN;
+
+import android.net.MacAddress;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+
+/**
+ * Defines basic data and operations needed to build and parse packets for the
+ * ARP protocol.
+ *
+ * @hide
+ */
+public class ArpPacket {
+ private static final String TAG = "ArpPacket";
+
+ public final short opCode;
+ public final Inet4Address senderIp;
+ public final Inet4Address targetIp;
+ public final MacAddress senderHwAddress;
+ public final MacAddress targetHwAddress;
+
+ ArpPacket(short opCode, MacAddress senderHwAddress, Inet4Address senderIp,
+ MacAddress targetHwAddress, Inet4Address targetIp) {
+ this.opCode = opCode;
+ this.senderHwAddress = senderHwAddress;
+ this.senderIp = senderIp;
+ this.targetHwAddress = targetHwAddress;
+ this.targetIp = targetIp;
+ }
+
+ /**
+ * Build an ARP packet from the required specified parameters.
+ */
+ @VisibleForTesting
+ public static ByteBuffer buildArpPacket(final byte[] dstMac, final byte[] srcMac,
+ final byte[] targetIp, final byte[] targetHwAddress, byte[] senderIp,
+ final short opCode) {
+ final ByteBuffer buf = ByteBuffer.allocate(ARP_ETHER_IPV4_LEN);
+
+ // Ether header
+ buf.put(dstMac);
+ buf.put(srcMac);
+ buf.putShort((short) ETH_P_ARP);
+
+ // ARP header
+ buf.putShort((short) ARP_HWTYPE_ETHER); // hrd
+ buf.putShort((short) ETH_P_IP); // pro
+ buf.put((byte) ETHER_ADDR_LEN); // hln
+ buf.put((byte) IPV4_ADDR_LEN); // pln
+ buf.putShort(opCode); // op
+ buf.put(srcMac); // sha
+ buf.put(senderIp); // spa
+ buf.put(targetHwAddress); // tha
+ buf.put(targetIp); // tpa
+ buf.flip();
+ return buf;
+ }
+
+ /**
+ * Parse an ARP packet from a ByteBuffer object.
+ */
+ @VisibleForTesting
+ public static ArpPacket parseArpPacket(final byte[] recvbuf, final int length)
+ throws ParseException {
+ try {
+ if (length < ARP_ETHER_IPV4_LEN || recvbuf.length < length) {
+ throw new ParseException("Invalid packet length: " + length);
+ }
+
+ final ByteBuffer buffer = ByteBuffer.wrap(recvbuf, 0, length);
+ byte[] l2dst = new byte[ETHER_ADDR_LEN];
+ byte[] l2src = new byte[ETHER_ADDR_LEN];
+ buffer.get(l2dst);
+ buffer.get(l2src);
+
+ final short etherType = buffer.getShort();
+ if (etherType != ETH_P_ARP) {
+ throw new ParseException("Incorrect Ether Type: " + etherType);
+ }
+
+ final short hwType = buffer.getShort();
+ if (hwType != ARP_HWTYPE_ETHER) {
+ throw new ParseException("Incorrect HW Type: " + hwType);
+ }
+
+ final short protoType = buffer.getShort();
+ if (protoType != ETH_P_IP) {
+ throw new ParseException("Incorrect Protocol Type: " + protoType);
+ }
+
+ final byte hwAddrLength = buffer.get();
+ if (hwAddrLength != ETHER_ADDR_LEN) {
+ throw new ParseException("Incorrect HW address length: " + hwAddrLength);
+ }
+
+ final byte ipAddrLength = buffer.get();
+ if (ipAddrLength != IPV4_ADDR_LEN) {
+ throw new ParseException("Incorrect Protocol address length: " + ipAddrLength);
+ }
+
+ final short opCode = buffer.getShort();
+ if (opCode != ARP_REQUEST && opCode != ARP_REPLY) {
+ throw new ParseException("Incorrect opCode: " + opCode);
+ }
+
+ byte[] senderHwAddress = new byte[ETHER_ADDR_LEN];
+ byte[] senderIp = new byte[IPV4_ADDR_LEN];
+ buffer.get(senderHwAddress);
+ buffer.get(senderIp);
+
+ byte[] targetHwAddress = new byte[ETHER_ADDR_LEN];
+ byte[] targetIp = new byte[IPV4_ADDR_LEN];
+ buffer.get(targetHwAddress);
+ buffer.get(targetIp);
+
+ return new ArpPacket(opCode, MacAddress.fromBytes(senderHwAddress),
+ (Inet4Address) InetAddress.getByAddress(senderIp),
+ MacAddress.fromBytes(targetHwAddress),
+ (Inet4Address) InetAddress.getByAddress(targetIp));
+ } catch (IndexOutOfBoundsException e) {
+ throw new ParseException("Invalid index when wrapping a byte array into a buffer");
+ } catch (BufferUnderflowException e) {
+ throw new ParseException("Invalid buffer position");
+ } catch (IllegalArgumentException e) {
+ throw new ParseException("Invalid MAC address representation");
+ } catch (UnknownHostException e) {
+ throw new ParseException("Invalid IP address of Host");
+ }
+ }
+
+ /**
+ * Thrown when parsing ARP packet failed.
+ */
+ public static class ParseException extends Exception {
+ ParseException(String message) {
+ super(message);
+ }
+ }
+}