Merge "Log bpf rc file if it differs from the template files." into main
diff --git a/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java b/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java
index 6c0ca82..6f3e865 100644
--- a/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/PrivateAddressCoordinator.java
@@ -79,6 +79,7 @@
private final TetheringConfiguration mConfig;
// keyed by downstream type(TetheringManager.TETHERING_*).
private final ArrayMap<AddressKey, LinkAddress> mCachedAddresses;
+ private final Random mRandom;
public PrivateAddressCoordinator(Context context, TetheringConfiguration config) {
mDownstreams = new ArraySet<>();
@@ -95,6 +96,7 @@
mTetheringPrefixes = new ArrayList<>(Arrays.asList(new IpPrefix("192.168.0.0/16"),
new IpPrefix("172.16.0.0/12"), new IpPrefix("10.0.0.0/8")));
+ mRandom = new Random();
}
/**
@@ -263,12 +265,13 @@
// is less than 127.0.0.0 = 0x7f000000 = 2130706432.
//
// Additionally, it makes debug output easier to read by making the numbers smaller.
- final int randomPrefixStart = getRandomInt() & ~prefixRangeMask & prefixMask;
+ final int randomInt = getRandomInt();
+ final int randomPrefixStart = randomInt & ~prefixRangeMask & prefixMask;
// A random offset within the prefix. Used to determine the local address once the prefix
// is selected. It does not result in an IPv4 address ending in .0, .1, or .255
- // For a PREFIX_LENGTH of 255, this is a number between 2 and 254.
- final int subAddress = getSanitizedSubAddr(~prefixMask);
+ // For a PREFIX_LENGTH of 24, this is a number between 2 and 254.
+ final int subAddress = getSanitizedSubAddr(randomInt, ~prefixMask);
// Find a prefix length PREFIX_LENGTH between randomPrefixStart and the end of the block,
// such that the prefix does not conflict with any upstream.
@@ -310,12 +313,12 @@
/** Get random int which could be used to generate random address. */
@VisibleForTesting
public int getRandomInt() {
- return (new Random()).nextInt();
+ return mRandom.nextInt();
}
/** Get random subAddress and avoid selecting x.x.x.0, x.x.x.1 and x.x.x.255 address. */
- private int getSanitizedSubAddr(final int subAddrMask) {
- final int randomSubAddr = getRandomInt() & subAddrMask;
+ private int getSanitizedSubAddr(final int randomInt, final int subAddrMask) {
+ final int randomSubAddr = randomInt & subAddrMask;
// If prefix length > 30, the selecting speace would be less than 4 which may be hard to
// avoid 3 consecutive address.
if (PREFIX_LENGTH > 30) return randomSubAddr;
diff --git a/netd/BpfHandler.cpp b/netd/BpfHandler.cpp
index a7a4059..2a9892f 100644
--- a/netd/BpfHandler.cpp
+++ b/netd/BpfHandler.cpp
@@ -76,23 +76,43 @@
}
static Status initPrograms(const char* cg2_path) {
+ if (!cg2_path) {
+ ALOGE("cg2_path is NULL");
+ return statusFromErrno(EINVAL, "cg2_path is NULL");
+ }
+
// This code was mainlined in T, so this should be trivially satisfied.
- if (!modules::sdklevel::IsAtLeastT()) abort();
+ if (!modules::sdklevel::IsAtLeastT()) {
+ ALOGE("S- platform is unsupported");
+ abort();
+ }
// S requires eBPF support which was only added in 4.9, so this should be satisfied.
- if (!bpf::isAtLeastKernelVersion(4, 9, 0)) abort();
+ if (!bpf::isAtLeastKernelVersion(4, 9, 0)) {
+ ALOGE("kernel version < 4.9.0 is unsupported");
+ abort();
+ }
// U bumps the kernel requirement up to 4.14
- if (modules::sdklevel::IsAtLeastU() && !bpf::isAtLeastKernelVersion(4, 14, 0)) abort();
+ if (modules::sdklevel::IsAtLeastU() && !bpf::isAtLeastKernelVersion(4, 14, 0)) {
+ ALOGE("U+ platform with kernel version < 4.14.0 is unsupported");
+ abort();
+ }
if (modules::sdklevel::IsAtLeastV()) {
// V bumps the kernel requirement up to 4.19
// see also: //system/netd/tests/kernel_test.cpp TestKernel419
- if (!bpf::isAtLeastKernelVersion(4, 19, 0)) abort();
+ if (!bpf::isAtLeastKernelVersion(4, 19, 0)) {
+ ALOGE("V+ platform with kernel version < 4.19.0 is unsupported");
+ abort();
+ }
// Technically already required by U, but only enforce on V+
// see also: //system/netd/tests/kernel_test.cpp TestKernel64Bit
- if (bpf::isKernel32Bit() && bpf::isAtLeastKernelVersion(5, 16, 0)) abort();
+ if (bpf::isKernel32Bit() && bpf::isAtLeastKernelVersion(5, 16, 0)) {
+ ALOGE("V+ platform with 32 bit kernel, version >= 5.16.0 is unsupported");
+ abort();
+ }
}
// Linux 6.1 is highest version supported by U, starting with V new kernels,
@@ -102,10 +122,16 @@
// it does not affect unprivileged apps, the 32-on-64 compatibility
// problems are AFAIK limited to various CAP_NET_ADMIN protected interfaces.
// see also: //system/bpf/bpfloader/BpfLoader.cpp main()
- if (bpf::isUserspace32bit() && bpf::isAtLeastKernelVersion(6, 2, 0)) abort();
+ if (bpf::isUserspace32bit() && bpf::isAtLeastKernelVersion(6, 2, 0)) {
+ ALOGE("32 bit userspace with Kernel version >= 6.2.0 is unsupported");
+ abort();
+ }
// U mandates this mount point (though it should also be the case on T)
- if (modules::sdklevel::IsAtLeastU() && !!strcmp(cg2_path, "/sys/fs/cgroup")) abort();
+ if (modules::sdklevel::IsAtLeastU() && !!strcmp(cg2_path, "/sys/fs/cgroup")) {
+ ALOGE("U+ platform with cg2_path != /sys/fs/cgroup is unsupported");
+ abort();
+ }
unique_fd cg_fd(open(cg2_path, O_DIRECTORY | O_RDONLY | O_CLOEXEC));
if (!cg_fd.ok()) {
diff --git a/service-t/src/com/android/server/ethernet/EthernetTracker.java b/service-t/src/com/android/server/ethernet/EthernetTracker.java
index 01b8de7..48e86d8 100644
--- a/service-t/src/com/android/server/ethernet/EthernetTracker.java
+++ b/service-t/src/com/android/server/ethernet/EthernetTracker.java
@@ -48,7 +48,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
-import com.android.modules.utils.build.SdkLevel;
import com.android.net.module.util.NetdUtils;
import com.android.net.module.util.PermissionUtils;
import com.android.net.module.util.SharedLog;
@@ -238,18 +237,7 @@
mDeps = deps;
// Interface match regex.
- String ifaceMatchRegex = mDeps.getInterfaceRegexFromResource(mContext);
- // "*" is a magic string to indicate "pick the default".
- if (ifaceMatchRegex.equals("*")) {
- if (SdkLevel.isAtLeastU()) {
- // On U+, include both usb%d and eth%d interfaces.
- ifaceMatchRegex = "(usb|eth)\\d+";
- } else {
- // On T, include only eth%d interfaces.
- ifaceMatchRegex = "eth\\d+";
- }
- }
- mIfaceMatch = ifaceMatchRegex;
+ mIfaceMatch = mDeps.getInterfaceRegexFromResource(mContext);
// Read default Ethernet interface configuration from resources
final String[] interfaceConfigs = mDeps.getInterfaceConfigFromResource(context);
diff --git a/service/ServiceConnectivityResources/res/values/config.xml b/service/ServiceConnectivityResources/res/values/config.xml
index 045d707f..f30abc6 100644
--- a/service/ServiceConnectivityResources/res/values/config.xml
+++ b/service/ServiceConnectivityResources/res/values/config.xml
@@ -194,11 +194,8 @@
-->
</string-array>
- <!-- Regex of wired ethernet ifaces. Network interfaces that match this regex will be tracked
- by ethernet service.
- If set to "*", ethernet service uses "(eth|usb)\\d+" on Android U+ and eth\\d+ on
- Android T. -->
- <string translatable="false" name="config_ethernet_iface_regex">*</string>
+ <!-- Regex of wired ethernet ifaces -->
+ <string translatable="false" name="config_ethernet_iface_regex">eth\\d</string>
<!-- Ignores Wi-Fi validation failures after roam.
If validation fails on a Wi-Fi network after a roam to a new BSSID,
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index f2279f8..9268da5 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -4790,7 +4790,7 @@
// If the Private DNS mode is opportunistic, reprogram the DNS servers
// in order to restart a validation pass from within netd.
final PrivateDnsConfig cfg = mDnsManager.getPrivateDnsConfig();
- if (cfg.useTls && TextUtils.isEmpty(cfg.hostname)) {
+ if (cfg.inOpportunisticMode()) {
updateDnses(nai.linkProperties, null, nai.network.getNetId());
}
}
diff --git a/service/src/com/android/server/connectivity/DnsManager.java b/service/src/com/android/server/connectivity/DnsManager.java
index 894bcc4..8e6854a 100644
--- a/service/src/com/android/server/connectivity/DnsManager.java
+++ b/service/src/com/android/server/connectivity/DnsManager.java
@@ -302,7 +302,7 @@
final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.getOrDefault(netId,
PRIVATE_DNS_OFF);
- final boolean useTls = privateDnsCfg.useTls;
+ final boolean useTls = privateDnsCfg.mode != PRIVATE_DNS_MODE_OFF;
final PrivateDnsValidationStatuses statuses =
useTls ? mPrivateDnsValidationMap.get(netId) : null;
final boolean validated = (null != statuses) && statuses.hasValidatedServer();
@@ -370,7 +370,7 @@
// networks like IMS.
final PrivateDnsConfig privateDnsCfg = mPrivateDnsMap.getOrDefault(netId,
PRIVATE_DNS_OFF);
- final boolean useTls = privateDnsCfg.useTls;
+ final boolean useTls = privateDnsCfg.mode != PRIVATE_DNS_MODE_OFF;
final boolean strictMode = privateDnsCfg.inStrictMode();
paramsParcel.netId = netId;
diff --git a/staticlibs/device/com/android/net/module/util/netlink/NetlinkMessage.java b/staticlibs/device/com/android/net/module/util/netlink/NetlinkMessage.java
index 9e1e26e..111e0ba 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/NetlinkMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/NetlinkMessage.java
@@ -16,12 +16,17 @@
package com.android.net.module.util.netlink;
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.NETLINK_XFRM;
+
import android.system.OsConstants;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage;
+
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
/**
* NetlinkMessage base class for other, more specific netlink message types.
@@ -75,6 +80,8 @@
parsed = parseInetDiagMessage(nlmsghdr, byteBuffer);
} else if (nlFamily == OsConstants.NETLINK_NETFILTER) {
parsed = parseNfMessage(nlmsghdr, byteBuffer);
+ } else if (nlFamily == NETLINK_XFRM) {
+ parsed = parseXfrmMessage(nlmsghdr, byteBuffer);
} else {
parsed = null;
}
@@ -168,4 +175,19 @@
default: return null;
}
}
+
+ @Nullable
+ private static NetlinkMessage parseXfrmMessage(
+ @NonNull final StructNlMsgHdr nlmsghdr, @NonNull final ByteBuffer byteBuffer) {
+ return (NetlinkMessage) XfrmNetlinkMessage.parseXfrmInternal(nlmsghdr, byteBuffer);
+ }
+
+ /** A convenient method to create a ByteBuffer for encoding a new message */
+ protected static ByteBuffer newNlMsgByteBuffer(int payloadLen) {
+ final int length = StructNlMsgHdr.STRUCT_SIZE + payloadLen;
+ final ByteBuffer byteBuffer = ByteBuffer.allocate(length);
+ byteBuffer.order(ByteOrder.nativeOrder());
+
+ return byteBuffer;
+ }
}
diff --git a/staticlibs/device/com/android/net/module/util/netlink/StructNlMsgHdr.java b/staticlibs/device/com/android/net/module/util/netlink/StructNlMsgHdr.java
index 5052cb8..ff37639 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/StructNlMsgHdr.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/StructNlMsgHdr.java
@@ -128,6 +128,14 @@
nlmsg_pid = 0;
}
+ public StructNlMsgHdr(int payloadLen, short type, short flags, int seq) {
+ nlmsg_len = StructNlMsgHdr.STRUCT_SIZE + payloadLen;
+ nlmsg_type = type;
+ nlmsg_flags = flags;
+ nlmsg_seq = seq;
+ nlmsg_pid = 0;
+ }
+
/**
* Write netlink message header to ByteBuffer.
*/
diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/OWNERS b/staticlibs/device/com/android/net/module/util/netlink/xfrm/OWNERS
index 97b4da0..fca70aa 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/xfrm/OWNERS
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/OWNERS
@@ -1,3 +1,2 @@
-# Bug component: 1364804
-
-per-file **Xfrm* = file:platform/frameworks/base:main:/services/core/java/com/android/server/vcn/OWNERS
+# Bug component: 685852
+file:platform/frameworks/base:main:/services/core/java/com/android/server/vcn/OWNERS
diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmId.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmId.java
new file mode 100644
index 0000000..bdcdcd8
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmId.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2023 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.netlink.xfrm;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+
+import java.net.InetAddress;
+
+/**
+ * Struct xfrm_id
+ *
+ * <p>see include/uapi/linux/xfrm.h
+ *
+ * <pre>
+ * struct xfrm_id {
+ * xfrm_address_t daddr;
+ * __be32 spi;
+ * __u8 proto;
+ * };
+ * </pre>
+ *
+ * @hide
+ */
+public class StructXfrmId extends Struct {
+ public static final int STRUCT_SIZE = 24;
+
+ @Field(order = 0, type = Type.ByteArray, arraysize = 16)
+ public final byte[] nestedStructDAddr;
+
+ @Field(order = 1, type = Type.UBE32)
+ public final long spi;
+
+ @Field(order = 2, type = Type.U8, padding = 3)
+ public final short proto;
+
+ @Computed private final StructXfrmAddressT mDestXfrmAddressT;
+
+ // Constructor that allows Strutc.parse(Class<T>, ByteBuffer) to work
+ public StructXfrmId(@NonNull final byte[] nestedStructDAddr, long spi, short proto) {
+ this.nestedStructDAddr = nestedStructDAddr.clone();
+ this.spi = spi;
+ this.proto = proto;
+
+ mDestXfrmAddressT = new StructXfrmAddressT(this.nestedStructDAddr);
+ }
+
+ // Constructor to build a new message
+ public StructXfrmId(@NonNull final InetAddress destAddress, long spi, short proto) {
+ this(new StructXfrmAddressT(destAddress).writeToBytes(), spi, proto);
+ }
+
+ /** Return the destination address */
+ public InetAddress getDestAddress(int family) {
+ return mDestXfrmAddressT.getAddress(family);
+ }
+}
diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCfg.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCfg.java
new file mode 100644
index 0000000..12f68c8
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCfg.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2023 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.netlink.xfrm;
+
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.XFRM_INF;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+
+import java.math.BigInteger;
+
+/**
+ * Struct xfrm_lifetime_cfg
+ *
+ * <p>see include/uapi/linux/xfrm.h
+ *
+ * <pre>
+ * struct xfrm_lifetime_cfg {
+ * __u64 soft_byte_limit;
+ * __u64 hard_byte_limit;
+ * __u64 soft_packet_limit;
+ * __u64 hard_packet_limit;
+ * __u64 soft_add_expires_seconds;
+ * __u64 hard_add_expires_seconds;
+ * __u64 soft_use_expires_seconds;
+ * __u64 hard_use_expires_seconds;
+ * };
+ * </pre>
+ *
+ * @hide
+ */
+public class StructXfrmLifetimeCfg extends Struct {
+ public static final int STRUCT_SIZE = 64;
+
+ @Field(order = 0, type = Type.U64)
+ public final BigInteger softByteLimit;
+
+ @Field(order = 1, type = Type.U64)
+ public final BigInteger hardByteLimit;
+
+ @Field(order = 2, type = Type.U64)
+ public final BigInteger softPacketLimit;
+
+ @Field(order = 3, type = Type.U64)
+ public final BigInteger hardPacketLimit;
+
+ @Field(order = 4, type = Type.U64)
+ public final BigInteger softAddExpiresSeconds;
+
+ @Field(order = 5, type = Type.U64)
+ public final BigInteger hardAddExpiresSeconds;
+
+ @Field(order = 6, type = Type.U64)
+ public final BigInteger softUseExpiresSeconds;
+
+ @Field(order = 7, type = Type.U64)
+ public final BigInteger hardUseExpiresSeconds;
+
+ // Constructor that allows Strutc.parse(Class<T>, ByteBuffer) to work
+ public StructXfrmLifetimeCfg(
+ @NonNull final BigInteger softByteLimit,
+ @NonNull final BigInteger hardByteLimit,
+ @NonNull final BigInteger softPacketLimit,
+ @NonNull final BigInteger hardPacketLimit,
+ @NonNull final BigInteger softAddExpiresSeconds,
+ @NonNull final BigInteger hardAddExpiresSeconds,
+ @NonNull final BigInteger softUseExpiresSeconds,
+ @NonNull final BigInteger hardUseExpiresSeconds) {
+ this.softByteLimit = softByteLimit;
+ this.hardByteLimit = hardByteLimit;
+ this.softPacketLimit = softPacketLimit;
+ this.hardPacketLimit = hardPacketLimit;
+ this.softAddExpiresSeconds = softAddExpiresSeconds;
+ this.hardAddExpiresSeconds = hardAddExpiresSeconds;
+ this.softUseExpiresSeconds = softUseExpiresSeconds;
+ this.hardUseExpiresSeconds = hardUseExpiresSeconds;
+ }
+
+ // Constructor to build a new message
+ public StructXfrmLifetimeCfg() {
+ this(
+ XFRM_INF,
+ XFRM_INF,
+ XFRM_INF,
+ XFRM_INF,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO,
+ BigInteger.ZERO);
+ }
+}
diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCur.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCur.java
new file mode 100644
index 0000000..6a539c7
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCur.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2023 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.netlink.xfrm;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+
+import java.math.BigInteger;
+
+/**
+ * Struct xfrm_lifetime_cur
+ *
+ * <p>see include/uapi/linux/xfrm.h
+ *
+ * <pre>
+ * struct xfrm_lifetime_cur {
+ * __u64 bytes;
+ * __u64 packets;
+ * __u64 add_time;
+ * __u64 use_time;
+ * };
+ * </pre>
+ *
+ * @hide
+ */
+public class StructXfrmLifetimeCur extends Struct {
+ public static final int STRUCT_SIZE = 32;
+
+ @Field(order = 0, type = Type.U64)
+ public final BigInteger bytes;
+
+ @Field(order = 1, type = Type.U64)
+ public final BigInteger packets;
+
+ @Field(order = 2, type = Type.U64)
+ public final BigInteger addTime;
+
+ @Field(order = 3, type = Type.U64)
+ public final BigInteger useTime;
+
+ public StructXfrmLifetimeCur(
+ @NonNull final BigInteger bytes,
+ @NonNull final BigInteger packets,
+ @NonNull final BigInteger addTime,
+ @NonNull final BigInteger useTime) {
+ this.bytes = bytes;
+ this.packets = packets;
+ this.addTime = addTime;
+ this.useTime = useTime;
+ }
+}
diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmSelector.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmSelector.java
new file mode 100644
index 0000000..7bd2ca1
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/StructXfrmSelector.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2023 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.netlink.xfrm;
+
+import androidx.annotation.NonNull;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.Struct.Field;
+import com.android.net.module.util.Struct.Type;
+
+/**
+ * Struct xfrm_selector
+ *
+ * <p>see include/uapi/linux/xfrm.h
+ *
+ * <pre>
+ * struct xfrm_selector {
+ * xfrm_address_t daddr;
+ * xfrm_address_t saddr;
+ * __be16 dport;
+ * __be16 dport_mask;
+ * __be16 sport;
+ * __be16 sport_mask;
+ * __u16 family;
+ * __u8 prefixlen_d;
+ * __u8 prefixlen_s;
+ * __u8 proto;
+ * int ifindex;
+ * __kernel_uid32_t user;
+ * };
+ * </pre>
+ *
+ * @hide
+ */
+public class StructXfrmSelector extends Struct {
+ public static final int STRUCT_SIZE = 56;
+
+ @Field(order = 0, type = Type.ByteArray, arraysize = 16)
+ public final byte[] nestedStructDAddr;
+
+ @Field(order = 1, type = Type.ByteArray, arraysize = 16)
+ public final byte[] nestedStructSAddr;
+
+ @Field(order = 2, type = Type.UBE16)
+ public final int dPort;
+
+ @Field(order = 3, type = Type.UBE16)
+ public final int dPortMask;
+
+ @Field(order = 4, type = Type.UBE16)
+ public final int sPort;
+
+ @Field(order = 5, type = Type.UBE16)
+ public final int sPortMask;
+
+ @Field(order = 6, type = Type.U16)
+ public final int selectorFamily;
+
+ @Field(order = 7, type = Type.U8, padding = 1)
+ public final short prefixlenD;
+
+ @Field(order = 8, type = Type.U8, padding = 1)
+ public final short prefixlenS;
+
+ @Field(order = 9, type = Type.U8, padding = 1)
+ public final short proto;
+
+ @Field(order = 10, type = Type.S32)
+ public final int ifIndex;
+
+ @Field(order = 11, type = Type.S32)
+ public final int user;
+
+ // Constructor that allows Strutc.parse(Class<T>, ByteBuffer) to work
+ public StructXfrmSelector(
+ @NonNull final byte[] nestedStructDAddr,
+ @NonNull final byte[] nestedStructSAddr,
+ int dPort,
+ int dPortMask,
+ int sPort,
+ int sPortMask,
+ int selectorFamily,
+ short prefixlenD,
+ short prefixlenS,
+ short proto,
+ int ifIndex,
+ int user) {
+ this.nestedStructDAddr = nestedStructDAddr.clone();
+ this.nestedStructSAddr = nestedStructSAddr.clone();
+ this.dPort = dPort;
+ this.dPortMask = dPortMask;
+ this.sPort = sPort;
+ this.sPortMask = sPortMask;
+ this.selectorFamily = selectorFamily;
+ this.prefixlenD = prefixlenD;
+ this.prefixlenS = prefixlenS;
+ this.proto = proto;
+ this.ifIndex = ifIndex;
+ this.user = user;
+ }
+
+ // Constructor to build a new message
+ public StructXfrmSelector(int selectorFamily) {
+ this(
+ new byte[StructXfrmAddressT.STRUCT_SIZE],
+ new byte[StructXfrmAddressT.STRUCT_SIZE],
+ 0 /* dPort */,
+ 0 /* dPortMask */,
+ 0 /* sPort */,
+ 0 /* sPortMask */,
+ selectorFamily,
+ (short) 0 /* prefixlenD */,
+ (short) 0 /* prefixlenS */,
+ (short) 0 /* proto */,
+ 0 /* ifIndex */,
+ 0 /* user */);
+ }
+}
diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkGetSaMessage.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkGetSaMessage.java
new file mode 100644
index 0000000..680a7ca
--- /dev/null
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkGetSaMessage.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2023 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.netlink.xfrm;
+
+import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.XFRM_MSG_GETSA;
+
+import android.system.OsConstants;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.net.module.util.Struct;
+import com.android.net.module.util.netlink.StructNlMsgHdr;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+
+/**
+ * An XfrmNetlinkMessage subclass for XFRM_MSG_GETSA messages.
+ *
+ * <p>see include/uapi/linux/xfrm.h
+ *
+ * <p>XFRM_MSG_GETSA syntax
+ *
+ * <ul>
+ * <li>TLV: xfrm_usersa_id
+ * <li>Optional Attributes: XFRMA_MARK, XFRMA_SRCADDR
+ * </ul>
+ *
+ * @hide
+ */
+public class XfrmNetlinkGetSaMessage extends XfrmNetlinkMessage {
+ @NonNull private final StructXfrmUsersaId mXfrmUsersaId;
+
+ private XfrmNetlinkGetSaMessage(
+ @NonNull final StructNlMsgHdr header, @NonNull final StructXfrmUsersaId xfrmUsersaId) {
+ super(header);
+ mXfrmUsersaId = xfrmUsersaId;
+ }
+
+ private XfrmNetlinkGetSaMessage(
+ @NonNull final StructNlMsgHdr header,
+ @NonNull final InetAddress destAddress,
+ long spi,
+ short proto) {
+ super(header);
+
+ final int family =
+ destAddress instanceof Inet4Address ? OsConstants.AF_INET : OsConstants.AF_INET6;
+ mXfrmUsersaId = new StructXfrmUsersaId(destAddress, spi, family, proto);
+ }
+
+ @Override
+ protected void packPayload(@NonNull final ByteBuffer byteBuffer) {
+ mXfrmUsersaId.writeToByteBuffer(byteBuffer);
+ }
+
+ /**
+ * Parse XFRM_MSG_GETSA message from ByteBuffer.
+ *
+ * <p>This method should be called from NetlinkMessage#parse(ByteBuffer, int) for generic
+ * message validation and processing
+ *
+ * @param nlmsghdr netlink message header.
+ * @param byteBuffer the ByteBuffer instance that wraps the raw netlink message bytes. MUST be
+ * host order
+ */
+ @Nullable
+ static XfrmNetlinkGetSaMessage parseInternal(
+ @NonNull final StructNlMsgHdr nlmsghdr, @NonNull final ByteBuffer byteBuffer) {
+ final StructXfrmUsersaId xfrmUsersaId = Struct.parse(StructXfrmUsersaId.class, byteBuffer);
+ if (xfrmUsersaId == null) {
+ return null;
+ }
+
+ // Attributes not supported. Don't bother handling them.
+
+ return new XfrmNetlinkGetSaMessage(nlmsghdr, xfrmUsersaId);
+ }
+
+ /** A convenient method to create a XFRM_MSG_GETSA message. */
+ public static byte[] newXfrmNetlinkGetSaMessage(
+ @NonNull final InetAddress destAddress, long spi, short proto) {
+ final int payloadLen = StructXfrmUsersaId.STRUCT_SIZE;
+
+ final StructNlMsgHdr nlmsghdr =
+ new StructNlMsgHdr(payloadLen, XFRM_MSG_GETSA, NLM_F_REQUEST, 0);
+ final XfrmNetlinkGetSaMessage message =
+ new XfrmNetlinkGetSaMessage(nlmsghdr, destAddress, spi, proto);
+
+ final ByteBuffer byteBuffer = newNlMsgByteBuffer(payloadLen);
+ message.pack(byteBuffer);
+
+ return byteBuffer.array();
+ }
+
+ public StructXfrmUsersaId getStructXfrmUsersaId() {
+ return mXfrmUsersaId;
+ }
+}
diff --git a/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java b/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java
index ee34e57..9773cd6 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/xfrm/XfrmNetlinkMessage.java
@@ -17,10 +17,14 @@
package com.android.net.module.util.netlink.xfrm;
import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
import com.android.net.module.util.netlink.NetlinkMessage;
import com.android.net.module.util.netlink.StructNlMsgHdr;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+
/** Base calss for XFRM netlink messages */
// Developer notes: The Linux kernel includes a number of XFRM structs that are not standard netlink
// attributes (e.g., xfrm_usersa_id). These structs are unlikely to change size, so this XFRM
@@ -28,12 +32,47 @@
// struct size changes, it should be caught by CTS and then developers should add
// kernel-version-based behvaiours.
public abstract class XfrmNetlinkMessage extends NetlinkMessage {
- // TODO: STOPSHIP: b/308011229 Remove it when OsConstants.IPPROTO_ESP is exposed
+ // TODO: b/312498032 Remove it when OsConstants.IPPROTO_ESP is stable
public static final int IPPROTO_ESP = 50;
+ // TODO: b/312498032 Remove it when OsConstants.NETLINK_XFRM is stable
+ public static final int NETLINK_XFRM = 6;
+
+ /* see include/uapi/linux/xfrm.h */
+ public static final short XFRM_MSG_NEWSA = 16;
+ public static final short XFRM_MSG_GETSA = 18;
+
+ public static final BigInteger XFRM_INF = new BigInteger("FFFFFFFFFFFFFFFF", 16);
public XfrmNetlinkMessage(@NonNull final StructNlMsgHdr header) {
super(header);
}
- // TODO: Add the support for parsing messages
+ /**
+ * Parse XFRM message from ByteBuffer.
+ *
+ * <p>This method should be called from NetlinkMessage#parse(ByteBuffer, int) for generic
+ * message validation and processing
+ *
+ * @param nlmsghdr netlink message header.
+ * @param byteBuffer the ByteBuffer instance that wraps the raw netlink message bytes. MUST be
+ * host order
+ */
+ @Nullable
+ public static XfrmNetlinkMessage parseXfrmInternal(
+ @NonNull final StructNlMsgHdr nlmsghdr, @NonNull final ByteBuffer byteBuffer) {
+ switch (nlmsghdr.nlmsg_type) {
+ case XFRM_MSG_GETSA:
+ return XfrmNetlinkGetSaMessage.parseInternal(nlmsghdr, byteBuffer);
+ default:
+ return null;
+ }
+ }
+
+ protected abstract void packPayload(@NonNull final ByteBuffer byteBuffer);
+
+ /** Write a XFRM message to {@link ByteBuffer}. */
+ public void pack(@NonNull final ByteBuffer byteBuffer) {
+ getHeader().pack(byteBuffer);
+ packPayload(byteBuffer);
+ }
}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/OWNERS b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/OWNERS
new file mode 100644
index 0000000..fca70aa
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/OWNERS
@@ -0,0 +1,2 @@
+# Bug component: 685852
+file:platform/frameworks/base:main:/services/core/java/com/android/server/vcn/OWNERS
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmIdTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmIdTest.java
new file mode 100644
index 0000000..c9741cf
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmIdTest.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2023 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.netlink.xfrm;
+
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.IPPROTO_ESP;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.net.InetAddresses;
+import android.system.OsConstants;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.HexDump;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class StructXfrmIdTest {
+ private static final String EXPECTED_HEX_STRING =
+ "C0000201000000000000000000000000" + "53FA0FDD32000000";
+ private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
+ private static final InetAddress DEST_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1");
+ private static final long SPI = 0x53fa0fdd;
+ private static final short PROTO = IPPROTO_ESP;
+
+ @Test
+ public void testEncode() throws Exception {
+ final StructXfrmId struct = new StructXfrmId(DEST_ADDRESS, SPI, PROTO);
+
+ final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
+ buffer.order(ByteOrder.nativeOrder());
+ struct.writeToByteBuffer(buffer);
+
+ assertArrayEquals(EXPECTED_HEX, buffer.array());
+ }
+
+ @Test
+ public void testDecode() throws Exception {
+ final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
+ buffer.order(ByteOrder.nativeOrder());
+ final StructXfrmId struct = StructXfrmId.parse(StructXfrmId.class, buffer);
+
+ assertEquals(DEST_ADDRESS, struct.getDestAddress(OsConstants.AF_INET));
+ assertEquals(SPI, struct.spi);
+ assertEquals(PROTO, struct.proto);
+ }
+}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCfgTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCfgTest.java
new file mode 100644
index 0000000..69360f6
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCfgTest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 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.netlink.xfrm;
+
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.XFRM_INF;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.HexDump;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class StructXfrmLifetimeCfgTest {
+ private static final String EXPECTED_HEX_STRING =
+ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+ + "00000000000000000000000000000000"
+ + "00000000000000000000000000000000";
+ private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
+
+ @Test
+ public void testEncode() throws Exception {
+ final StructXfrmLifetimeCfg struct = new StructXfrmLifetimeCfg();
+
+ final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
+ buffer.order(ByteOrder.nativeOrder());
+ struct.writeToByteBuffer(buffer);
+
+ assertArrayEquals(EXPECTED_HEX, buffer.array());
+ }
+
+ @Test
+ public void testDecode() throws Exception {
+ final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
+ buffer.order(ByteOrder.nativeOrder());
+ final StructXfrmLifetimeCfg struct =
+ StructXfrmLifetimeCfg.parse(StructXfrmLifetimeCfg.class, buffer);
+
+ assertEquals(XFRM_INF, struct.softByteLimit);
+ assertEquals(XFRM_INF, struct.hardByteLimit);
+ assertEquals(XFRM_INF, struct.softPacketLimit);
+ assertEquals(XFRM_INF, struct.hardPacketLimit);
+ assertEquals(BigInteger.ZERO, struct.softAddExpiresSeconds);
+ assertEquals(BigInteger.ZERO, struct.hardAddExpiresSeconds);
+ assertEquals(BigInteger.ZERO, struct.softUseExpiresSeconds);
+ assertEquals(BigInteger.ZERO, struct.hardUseExpiresSeconds);
+ }
+}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCurTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCurTest.java
new file mode 100644
index 0000000..008c922
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmLifetimeCurTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 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.netlink.xfrm;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.HexDump;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Calendar;
+import java.util.TimeZone;
+import java.util.concurrent.TimeUnit;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class StructXfrmLifetimeCurTest {
+ private static final String EXPECTED_HEX_STRING =
+ "00000000000000000000000000000000" + "8CFE4265000000000000000000000000";
+ private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
+ private static final BigInteger ADD_TIME;
+
+ static {
+ final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ cal.set(2023, Calendar.NOVEMBER, 2, 1, 42, 36);
+ final long timestampSeconds = TimeUnit.MILLISECONDS.toSeconds(cal.getTimeInMillis());
+ ADD_TIME = BigInteger.valueOf(timestampSeconds);
+ }
+
+ @Test
+ public void testEncode() throws Exception {
+ final StructXfrmLifetimeCur struct =
+ new StructXfrmLifetimeCur(
+ BigInteger.ZERO, BigInteger.ZERO, ADD_TIME, BigInteger.ZERO);
+
+ final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
+ buffer.order(ByteOrder.nativeOrder());
+ struct.writeToByteBuffer(buffer);
+
+ assertArrayEquals(EXPECTED_HEX, buffer.array());
+ }
+
+ @Test
+ public void testDecode() throws Exception {
+ final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
+ buffer.order(ByteOrder.nativeOrder());
+ final StructXfrmLifetimeCur struct =
+ StructXfrmLifetimeCur.parse(StructXfrmLifetimeCur.class, buffer);
+
+ assertEquals(BigInteger.ZERO, struct.bytes);
+ assertEquals(BigInteger.ZERO, struct.packets);
+ assertEquals(ADD_TIME, struct.addTime);
+ assertEquals(BigInteger.ZERO, struct.useTime);
+ }
+}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmSelectorTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmSelectorTest.java
new file mode 100644
index 0000000..99f3b2a
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmSelectorTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2023 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.netlink.xfrm;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.system.OsConstants;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.HexDump;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class StructXfrmSelectorTest {
+ private static final String EXPECTED_HEX_STRING =
+ "00000000000000000000000000000000"
+ + "00000000000000000000000000000000"
+ + "00000000000000000200000000000000"
+ + "0000000000000000";
+ private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
+
+ private static final byte[] XFRM_ADDRESS_T_ANY_BYTES = new byte[16];
+ private static final int FAMILY = OsConstants.AF_INET;
+
+ @Test
+ public void testEncode() throws Exception {
+ final StructXfrmSelector struct = new StructXfrmSelector(FAMILY);
+
+ final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
+ buffer.order(ByteOrder.nativeOrder());
+ struct.writeToByteBuffer(buffer);
+
+ assertArrayEquals(EXPECTED_HEX, buffer.array());
+ }
+
+ @Test
+ public void testDecode() throws Exception {
+ final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
+ buffer.order(ByteOrder.nativeOrder());
+ final StructXfrmSelector struct =
+ StructXfrmSelector.parse(StructXfrmSelector.class, buffer);
+
+ assertArrayEquals(XFRM_ADDRESS_T_ANY_BYTES, struct.nestedStructDAddr);
+ assertArrayEquals(XFRM_ADDRESS_T_ANY_BYTES, struct.nestedStructSAddr);
+ assertEquals(0, struct.dPort);
+ assertEquals(0, struct.dPortMask);
+ assertEquals(0, struct.sPort);
+ assertEquals(0, struct.sPortMask);
+ assertEquals(FAMILY, struct.selectorFamily);
+ assertEquals(0, struct.prefixlenD);
+ assertEquals(0, struct.prefixlenS);
+ assertEquals(0, struct.proto);
+ assertEquals(0, struct.ifIndex);
+ assertEquals(0, struct.user);
+ }
+}
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmUsersaIdTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmUsersaIdTest.java
index 52fd591..b659f62 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmUsersaIdTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/StructXfrmUsersaIdTest.java
@@ -52,7 +52,7 @@
public void testEncode() throws Exception {
final StructXfrmUsersaId struct = new StructXfrmUsersaId(DEST_ADDRESS, SPI, FAMILY, PROTO);
- ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
+ final ByteBuffer buffer = ByteBuffer.allocate(EXPECTED_HEX.length);
buffer.order(ByteOrder.nativeOrder());
struct.writeToByteBuffer(buffer);
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/XfrmNetlinkGetSaMessageTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/XfrmNetlinkGetSaMessageTest.java
new file mode 100644
index 0000000..0ab36e7
--- /dev/null
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/xfrm/XfrmNetlinkGetSaMessageTest.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2023 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.netlink.xfrm;
+
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.IPPROTO_ESP;
+import static com.android.net.module.util.netlink.xfrm.XfrmNetlinkMessage.NETLINK_XFRM;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+
+import android.net.InetAddresses;
+import android.system.OsConstants;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.net.module.util.HexDump;
+import com.android.net.module.util.netlink.NetlinkMessage;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class XfrmNetlinkGetSaMessageTest {
+ private static final String EXPECTED_HEX_STRING =
+ "28000000120001000000000000000000"
+ + "C0000201000000000000000000000000"
+ + "7768440002003200";
+ private static final byte[] EXPECTED_HEX = HexDump.hexStringToByteArray(EXPECTED_HEX_STRING);
+ private static final InetAddress DEST_ADDRESS = InetAddresses.parseNumericAddress("192.0.2.1");
+ private static final long SPI = 0x77684400;
+ private static final int FAMILY = OsConstants.AF_INET;
+ private static final short PROTO = IPPROTO_ESP;
+
+ @Test
+ public void testEncode() throws Exception {
+ final byte[] result =
+ XfrmNetlinkGetSaMessage.newXfrmNetlinkGetSaMessage(DEST_ADDRESS, SPI, PROTO);
+ assertArrayEquals(EXPECTED_HEX, result);
+ }
+
+ @Test
+ public void testDecode() throws Exception {
+ final ByteBuffer buffer = ByteBuffer.wrap(EXPECTED_HEX);
+ buffer.order(ByteOrder.nativeOrder());
+ final XfrmNetlinkGetSaMessage message =
+ (XfrmNetlinkGetSaMessage) NetlinkMessage.parse(buffer, NETLINK_XFRM);
+ final StructXfrmUsersaId struct = message.getStructXfrmUsersaId();
+
+ assertEquals(DEST_ADDRESS, struct.getDestAddress());
+ assertEquals(SPI, struct.spi);
+ assertEquals(FAMILY, struct.family);
+ assertEquals(PROTO, struct.proto);
+ assertEquals(0, buffer.remaining());
+ }
+}
diff --git a/tests/cts/hostside/AndroidTest.xml b/tests/cts/hostside/AndroidTest.xml
index 90b7875..0ffe81e 100644
--- a/tests/cts/hostside/AndroidTest.xml
+++ b/tests/cts/hostside/AndroidTest.xml
@@ -36,6 +36,7 @@
<target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
<option name="force-skip-system-props" value="true" />
<option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
+ <option name="set-global-setting" key="low_power_standby_enabled" value="0" />
</target_preparer>
<test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
diff --git a/tests/cts/net/src/android/net/cts/DnsResolverTest.java b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
index 308aead..9ff0f2f 100644
--- a/tests/cts/net/src/android/net/cts/DnsResolverTest.java
+++ b/tests/cts/net/src/android/net/cts/DnsResolverTest.java
@@ -860,4 +860,9 @@
assertEquals(DnsResolver.ERROR_SYSTEM, e.code);
}
}
+
+ @Test
+ public void testNoRawBinderAccess() {
+ assertNull(mContext.getSystemService("dnsresolver"));
+ }
}
diff --git a/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java b/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
index afb9abd..44512bb 100644
--- a/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
+++ b/tests/unit/java/com/android/server/connectivity/DnsManagerTest.java
@@ -19,6 +19,7 @@
import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_DEFAULT_MODE;
import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE;
import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OFF;
+import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_OPPORTUNISTIC;
import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_MODE_PROVIDER_HOSTNAME;
import static android.net.ConnectivitySettingsManager.PRIVATE_DNS_SPECIFIER;
import static android.net.NetworkCapabilities.MAX_TRANSPORT;
@@ -329,14 +330,14 @@
public void testOverrideDefaultMode() throws Exception {
// Hard-coded default is opportunistic mode.
final PrivateDnsConfig cfgAuto = DnsManager.getPrivateDnsConfig(mCtx);
- assertTrue(cfgAuto.useTls);
+ assertEquals(PRIVATE_DNS_MODE_OPPORTUNISTIC, cfgAuto.mode);
assertEquals("", cfgAuto.hostname);
assertEquals(new InetAddress[0], cfgAuto.ips);
// Pretend a gservices push sets the default to "off".
ConnectivitySettingsManager.setPrivateDnsDefaultMode(mCtx, PRIVATE_DNS_MODE_OFF);
final PrivateDnsConfig cfgOff = DnsManager.getPrivateDnsConfig(mCtx);
- assertFalse(cfgOff.useTls);
+ assertEquals(PRIVATE_DNS_MODE_OFF, cfgOff.mode);
assertEquals("", cfgOff.hostname);
assertEquals(new InetAddress[0], cfgOff.ips);
@@ -344,7 +345,7 @@
ConnectivitySettingsManager.setPrivateDnsMode(mCtx, PRIVATE_DNS_MODE_PROVIDER_HOSTNAME);
ConnectivitySettingsManager.setPrivateDnsHostname(mCtx, "strictmode.com");
final PrivateDnsConfig cfgStrict = DnsManager.getPrivateDnsConfig(mCtx);
- assertTrue(cfgStrict.useTls);
+ assertEquals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, cfgStrict.mode);
assertEquals("strictmode.com", cfgStrict.hostname);
assertEquals(new InetAddress[0], cfgStrict.ips);
}
@@ -419,7 +420,7 @@
// The PrivateDnsConfig map is empty, so the default PRIVATE_DNS_OFF is returned.
PrivateDnsConfig privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
- assertFalse(privateDnsCfg.useTls);
+ assertEquals(PRIVATE_DNS_MODE_OFF, privateDnsCfg.mode);
assertEquals("", privateDnsCfg.hostname);
assertEquals(new InetAddress[0], privateDnsCfg.ips);
@@ -431,7 +432,7 @@
VALIDATION_RESULT_SUCCESS));
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
- assertTrue(privateDnsCfg.useTls);
+ assertEquals(PRIVATE_DNS_MODE_OPPORTUNISTIC, privateDnsCfg.mode);
assertEquals("", privateDnsCfg.hostname);
assertEquals(new InetAddress[0], privateDnsCfg.ips);
@@ -439,14 +440,14 @@
mDnsManager.updatePrivateDns(network, new PrivateDnsConfig(tlsName, tlsAddrs));
mDnsManager.updatePrivateDnsStatus(TEST_NETID, lp);
privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
- assertTrue(privateDnsCfg.useTls);
+ assertEquals(PRIVATE_DNS_MODE_PROVIDER_HOSTNAME, privateDnsCfg.mode);
assertEquals(tlsName, privateDnsCfg.hostname);
assertEquals(tlsAddrs, privateDnsCfg.ips);
// The network is removed, so the PrivateDnsConfig map becomes empty again.
mDnsManager.removeNetwork(network);
privateDnsCfg = mDnsManager.getPrivateDnsConfig(network);
- assertFalse(privateDnsCfg.useTls);
+ assertEquals(PRIVATE_DNS_MODE_OFF, privateDnsCfg.mode);
assertEquals("", privateDnsCfg.hostname);
assertEquals(new InetAddress[0], privateDnsCfg.ips);
}