Merge "Add the name of the expected callback"
diff --git a/staticlibs/Android.bp b/staticlibs/Android.bp
index f4997a1..63c8b4e 100644
--- a/staticlibs/Android.bp
+++ b/staticlibs/Android.bp
@@ -70,6 +70,7 @@
libs: [
"androidx.annotation_annotation",
"framework-annotations-lib",
+ "framework-configinfrastructure",
"framework-connectivity.stubs.module_lib",
],
lint: { strict_updatability_linting: true },
diff --git a/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java b/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
index f7b0d02..3748e46 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
@@ -16,6 +16,10 @@
package com.android.net.module.util.netlink;
+import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_ACK;
+import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REPLACE;
+import static com.android.net.module.util.netlink.StructNlMsgHdr.NLM_F_REQUEST;
+
import android.system.OsConstants;
import androidx.annotation.NonNull;
@@ -24,8 +28,10 @@
import com.android.net.module.util.HexDump;
+import java.net.Inet6Address;
import java.net.InetAddress;
import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
/**
* A NetlinkMessage subclass for rtnetlink address messages.
@@ -145,6 +151,47 @@
flags.pack(byteBuffer);
}
+ /**
+ * A convenience method to create an RTM_NEWADDR message.
+ */
+ public static byte[] newRtmNewAddressMessage(int seqNo, final InetAddress ip, short prefixlen,
+ byte flags, byte scope, int ifIndex, long preferred, long valid) {
+ final StructNlMsgHdr nlmsghdr = new StructNlMsgHdr();
+ nlmsghdr.nlmsg_type = NetlinkConstants.RTM_NEWADDR;
+ nlmsghdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | NLM_F_REPLACE;
+ nlmsghdr.nlmsg_seq = seqNo;
+
+ final RtNetlinkAddressMessage msg = new RtNetlinkAddressMessage(nlmsghdr);
+ final byte family =
+ (byte) ((ip instanceof Inet6Address) ? OsConstants.AF_INET6 : OsConstants.AF_INET);
+ msg.mIfaddrmsg = new StructIfaddrMsg(family, prefixlen, flags, scope, ifIndex);
+ msg.mIpAddress = ip;
+ msg.mIfacacheInfo = new StructIfacacheInfo(preferred, valid, 0 /* cstamp */,
+ 0 /* tstamp */);
+ msg.mFlags = (int) (flags & 0xFF);
+
+ final byte[] bytes = new byte[msg.getRequiredSpace()];
+ nlmsghdr.nlmsg_len = bytes.length;
+ final ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
+ byteBuffer.order(ByteOrder.nativeOrder());
+ msg.pack(byteBuffer);
+ return bytes;
+ }
+
+ private int getRequiredSpace() {
+ int spaceRequired = StructNlMsgHdr.STRUCT_SIZE + StructIfaddrMsg.STRUCT_SIZE;
+ if (mIpAddress != null) {
+ spaceRequired += NetlinkConstants.alignedLengthOf(
+ StructNlAttr.NLA_HEADERLEN + mIpAddress.getAddress().length);
+ }
+ if (mIfacacheInfo != null) {
+ spaceRequired += NetlinkConstants.alignedLengthOf(
+ StructNlAttr.NLA_HEADERLEN + StructIfacacheInfo.STRUCT_SIZE);
+ }
+ spaceRequired += StructNlAttr.NLA_HEADERLEN + 4; // IFA_FLAGS "u32" attr
+ return spaceRequired;
+ }
+
@Override
public String toString() {
return "RtNetlinkAddressMessage{ "
diff --git a/staticlibs/framework/com/android/net/module/util/BinderUtils.java b/staticlibs/framework/com/android/net/module/util/BinderUtils.java
index eb695d1..e4d14ea 100644
--- a/staticlibs/framework/com/android/net/module/util/BinderUtils.java
+++ b/staticlibs/framework/com/android/net/module/util/BinderUtils.java
@@ -19,6 +19,8 @@
import android.annotation.NonNull;
import android.os.Binder;
+import java.util.function.Supplier;
+
/**
* Collection of utilities for {@link Binder} and related classes.
* @hide
@@ -56,4 +58,39 @@
/** @see java.lang.Runnable */
void run() throws T;
}
+
+ /**
+ * Convenience method for running the provided action enclosed in
+ * {@link Binder#clearCallingIdentity}/{@link Binder#restoreCallingIdentity} returning the
+ * result.
+ *
+ * <p>Any exception thrown by the given action will be caught and rethrown after
+ * the call to {@link Binder#restoreCallingIdentity}.
+ *
+ * Note that this is copied from Binder#withCleanCallingIdentity with minor changes
+ * since it is not public.
+ *
+ * @hide
+ */
+ public static final <T, E extends Exception> T withCleanCallingIdentity(
+ @NonNull ThrowingSupplier<T, E> action) throws E {
+ final long callingIdentity = Binder.clearCallingIdentity();
+ try {
+ return action.get();
+ } finally {
+ Binder.restoreCallingIdentity(callingIdentity);
+ }
+ }
+
+ /**
+ * An equivalent of {@link Supplier}
+ *
+ * @param <T> The class which is declared to be returned.
+ * @param <E> The exception class which is declared to be thrown.
+ */
+ @FunctionalInterface
+ public interface ThrowingSupplier<T, E extends Exception> {
+ /** @see java.util.function.Supplier */
+ T get() throws E;
+ }
}
diff --git a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
index c652c76..ea56593 100644
--- a/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
+++ b/staticlibs/native/bpf_headers/include/bpf/bpf_helpers.h
@@ -137,6 +137,14 @@
BPF_FUNC_map_update_elem;
static int (*bpf_map_delete_elem_unsafe)(const struct bpf_map_def* map,
const void* key) = (void*)BPF_FUNC_map_delete_elem;
+static int (*bpf_ringbuf_output_unsafe)(const struct bpf_map_def* ringbuf,
+ const void* data, __u64 size, __u64 flags) = (void*)
+ BPF_FUNC_ringbuf_output;
+static void* (*bpf_ringbuf_reserve_unsafe)(const struct bpf_map_def* ringbuf,
+ __u64 size, __u64 flags) = (void*)
+ BPF_FUNC_ringbuf_reserve;
+static void (*bpf_ringbuf_submit_unsafe)(const void* data, __u64 flags) = (void*)
+ BPF_FUNC_ringbuf_submit;
#define BPF_ANNOTATE_KV_PAIR(name, type_key, type_val) \
struct ____btf_map_##name { \
@@ -147,6 +155,50 @@
__attribute__ ((section(".maps." #name), used)) \
____btf_map_##name = { }
+#define DEFINE_BPF_MAP_BASE(the_map, TYPE, keysize, valuesize, num_entries, \
+ usr, grp, md, selinux, pindir, share, minkver, \
+ maxkver) \
+ const struct bpf_map_def SECTION("maps") the_map = { \
+ .type = BPF_MAP_TYPE_##TYPE, \
+ .key_size = (keysize), \
+ .value_size = (valuesize), \
+ .max_entries = (num_entries), \
+ .map_flags = 0, \
+ .uid = (usr), \
+ .gid = (grp), \
+ .mode = (md), \
+ .bpfloader_min_ver = DEFAULT_BPFLOADER_MIN_VER, \
+ .bpfloader_max_ver = DEFAULT_BPFLOADER_MAX_VER, \
+ .min_kver = (minkver), \
+ .max_kver = (maxkver), \
+ .selinux_context = (selinux), \
+ .pin_subdir = (pindir), \
+ .shared = (share), \
+ };
+
+// Type safe macro to declare a ring buffer and related output functions.
+// Compatibility:
+// * BPF ring buffers are only available kernels 5.8 and above. Any program
+// accessing the ring buffer should set a program level min_kver >= 5.8.
+// * The definition below sets a map min_kver of 5.8 which requires targeting
+// a BPFLOADER_MIN_VER >= BPFLOADER_S_VERSION.
+#define DEFINE_BPF_RINGBUF(the_map, ValueType, size_bytes, usr, grp, md, \
+ selinux, pindir, share) \
+ DEFINE_BPF_MAP_BASE(the_map, RINGBUF, 0, 0, size_bytes, usr, grp, md, \
+ selinux, pindir, share, KVER(5, 8, 0), KVER_INF); \
+ static inline __always_inline __unused int bpf_##the_map##_output( \
+ const ValueType* v) { \
+ return bpf_ringbuf_output_unsafe(&the_map, v, sizeof(*v), 0); \
+ } \
+ static inline __always_inline __unused \
+ ValueType* bpf_##the_map##_reserve() { \
+ return bpf_ringbuf_reserve_unsafe(&the_map, sizeof(ValueType), 0); \
+ } \
+ static inline __always_inline __unused void bpf_##the_map##_submit( \
+ const ValueType* v) { \
+ bpf_ringbuf_submit_unsafe(v, 0); \
+ }
+
/* There exist buggy kernels with pre-T OS, that due to
* kernel patch "[ALPS05162612] bpf: fix ubsan error"
* do not support userspace writes into non-zero index of bpf map arrays.
@@ -167,23 +219,9 @@
/* type safe macro to declare a map and related accessor functions */
#define DEFINE_BPF_MAP_EXT(the_map, TYPE, KeyType, ValueType, num_entries, usr, grp, md, \
selinux, pindir, share) \
- const struct bpf_map_def SECTION("maps") the_map = { \
- .type = BPF_MAP_TYPE_##TYPE, \
- .key_size = sizeof(KeyType), \
- .value_size = sizeof(ValueType), \
- .max_entries = (num_entries), \
- .map_flags = 0, \
- .uid = (usr), \
- .gid = (grp), \
- .mode = (md), \
- .bpfloader_min_ver = DEFAULT_BPFLOADER_MIN_VER, \
- .bpfloader_max_ver = DEFAULT_BPFLOADER_MAX_VER, \
- .min_kver = KVER_NONE, \
- .max_kver = KVER_INF, \
- .selinux_context = selinux, \
- .pin_subdir = pindir, \
- .shared = share, \
- }; \
+ DEFINE_BPF_MAP_BASE(the_map, TYPE, sizeof(KeyType), sizeof(ValueType), \
+ num_entries, usr, grp, md, selinux, pindir, share, \
+ KVER_NONE, KVER_INF); \
BPF_MAP_ASSERT_OK(BPF_MAP_TYPE_##TYPE, (num_entries), (md)); \
BPF_ANNOTATE_KV_PAIR(the_map, KeyType, ValueType); \
\
diff --git a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java
index 7d8dbd2..b21e060 100644
--- a/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java
+++ b/staticlibs/tests/unit/src/com/android/net/module/util/netlink/RtNetlinkAddressMessageTest.java
@@ -16,8 +16,11 @@
package com.android.net.module.util.netlink;
+import static android.system.OsConstants.IFA_F_PERMANENT;
import static android.system.OsConstants.NETLINK_ROUTE;
+import static android.system.OsConstants.RT_SCOPE_LINK;
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
@@ -31,6 +34,8 @@
import com.android.net.module.util.HexDump;
+import libcore.util.HexEncoding;
+
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -42,7 +47,7 @@
@SmallTest
public class RtNetlinkAddressMessageTest {
private static final Inet6Address TEST_LINK_LOCAL =
- (Inet6Address) InetAddresses.parseNumericAddress("fe80::2C41:5CFF:FE09:6665");
+ (Inet6Address) InetAddresses.parseNumericAddress("FE80::2C41:5CFF:FE09:6665");
// An example of the full RTM_NEWADDR message.
private static final String RTM_NEWADDR_HEX =
@@ -128,6 +133,47 @@
}
@Test
+ public void testCreateRtmNewAddressMessage() {
+ // Hexadecimal representation of our created packet.
+ final String expectedNewAddressHex =
+ // struct nlmsghdr
+ "48000000" + // length = 72
+ "1400" + // type = 20 (RTM_NEWADDR)
+ "0501" + // flags = NLM_F_ACK | NLM_F_REQUEST | NLM_F_REPLACE
+ "01000000" + // seqno = 1
+ "00000000" + // pid = 0 (send to kernel)
+ // struct IfaddrMsg
+ "0A" + // family = inet6
+ "40" + // prefix len = 64
+ "80" + // flags = IFA_F_PERMANENT
+ "FD" + // scope = RT_SCOPE_LINK
+ "17000000" + // ifindex = 23
+ // struct nlattr: IFA_ADDRESS
+ "1400" + // len
+ "0100" + // type
+ "FE800000000000002C415CFFFE096665" + // IP address = fe80::2C41:5cff:fe09:6665
+ // struct nlattr: IFA_CACHEINFO
+ "1400" + // len
+ "0600" + // type
+ "FFFFFFFF" + // preferred = infinite
+ "FFFFFFFF" + // valid = infinite
+ "00000000" + // cstamp
+ "00000000" + // tstamp
+ // struct nlattr: IFA_FLAGS
+ "0800" + // len
+ "0800" + // type
+ "80000000"; // flags = IFA_F_PERMANENT
+ final byte[] expectedNewAddress =
+ HexEncoding.decode(expectedNewAddressHex.toCharArray(), false);
+
+ final byte[] bytes = RtNetlinkAddressMessage.newRtmNewAddressMessage(1 /* seqno */,
+ TEST_LINK_LOCAL, (short) 64 /* prefix len */, (byte) IFA_F_PERMANENT /* flags */,
+ (byte) RT_SCOPE_LINK /* scope */, 23 /* ifindex */,
+ (long) 0xFFFFFFFF /* preferred */, (long) 0xFFFFFFFF /* valid */);
+ assertArrayEquals(expectedNewAddress, bytes);
+ }
+
+ @Test
public void testToString() {
final ByteBuffer byteBuffer = toByteBuffer(RTM_NEWADDR_HEX);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN); // For testing.