Merge "Fix lint errors and adding nullability annotations in PacketReflector"
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 c07cec0..31c3a2e 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/RtNetlinkAddressMessage.java
@@ -58,12 +58,20 @@
@Nullable
private StructIfacacheInfo mIfacacheInfo;
- private RtNetlinkAddressMessage(@NonNull StructNlMsgHdr header) {
+ @VisibleForTesting
+ public RtNetlinkAddressMessage(@NonNull final StructNlMsgHdr header,
+ @NonNull final StructIfaddrMsg ifaddrMsg,
+ @NonNull final InetAddress ipAddress,
+ @Nullable final StructIfacacheInfo structIfacacheInfo,
+ int flags) {
super(header);
- mIfaddrmsg = null;
- mIpAddress = null;
- mIfacacheInfo = null;
- mFlags = 0;
+ mIfaddrmsg = ifaddrMsg;
+ mIpAddress = ipAddress;
+ mIfacacheInfo = structIfacacheInfo;
+ mFlags = flags;
+ }
+ private RtNetlinkAddressMessage(@NonNull StructNlMsgHdr header) {
+ this(header, null, null, null, 0);
}
public int getFlags() {
diff --git a/staticlibs/device/com/android/net/module/util/netlink/StructIfaddrMsg.java b/staticlibs/device/com/android/net/module/util/netlink/StructIfaddrMsg.java
index 9196feb..2802726 100644
--- a/staticlibs/device/com/android/net/module/util/netlink/StructIfaddrMsg.java
+++ b/staticlibs/device/com/android/net/module/util/netlink/StructIfaddrMsg.java
@@ -18,6 +18,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.annotation.VisibleForTesting;
import com.android.net.module.util.Struct;
import com.android.net.module.util.Struct.Field;
@@ -49,7 +50,8 @@
@Field(order = 4, type = Type.S32)
public final int index;
- StructIfaddrMsg(short family, short prefixLen, short flags, short scope, int index) {
+ @VisibleForTesting
+ public StructIfaddrMsg(short family, short prefixLen, short flags, short scope, int index) {
this.family = family;
this.prefixLen = prefixLen;
this.flags = flags;
diff --git a/staticlibs/device/com/android/net/module/util/structs/IaPdOption.java b/staticlibs/device/com/android/net/module/util/structs/IaPdOption.java
index 5a09c40..dbf79dc 100644
--- a/staticlibs/device/com/android/net/module/util/structs/IaPdOption.java
+++ b/staticlibs/device/com/android/net/module/util/structs/IaPdOption.java
@@ -50,15 +50,15 @@
public static final int LENGTH = 12; // option length excluding IA_PD options
@Field(order = 0, type = Type.S16)
- public short code;
+ public final short code;
@Field(order = 1, type = Type.S16)
- public short length;
+ public final short length;
@Field(order = 2, type = Type.U32)
- public long id;
+ public final long id;
@Field(order = 3, type = Type.U32)
- public long t1;
+ public final long t1;
@Field(order = 4, type = Type.U32)
- public long t2;
+ public final long t2;
IaPdOption(final short code, final short length, final long id, final long t1,
final long t2) {
diff --git a/staticlibs/device/com/android/net/module/util/structs/IaPrefixOption.java b/staticlibs/device/com/android/net/module/util/structs/IaPrefixOption.java
index 1ac21ff..cd974e6 100644
--- a/staticlibs/device/com/android/net/module/util/structs/IaPrefixOption.java
+++ b/staticlibs/device/com/android/net/module/util/structs/IaPrefixOption.java
@@ -55,17 +55,17 @@
public static final int LENGTH = 25; // option length excluding IAprefix-options
@Field(order = 0, type = Type.S16)
- public short code;
+ public final short code;
@Field(order = 1, type = Type.S16)
- public short length;
+ public final short length;
@Field(order = 2, type = Type.U32)
- public long preferred;
+ public final long preferred;
@Field(order = 3, type = Type.U32)
- public long valid;
+ public final long valid;
@Field(order = 4, type = Type.U8)
- public short prefixLen;
+ public final short prefixLen;
@Field(order = 5, type = Type.ByteArray, arraysize = 16)
- public byte[] prefix;
+ public final byte[] prefix;
IaPrefixOption(final short code, final short length, final long preferred,
final long valid, final short prefixLen, final byte[] prefix) {
diff --git a/staticlibs/native/bpf_headers/include/bpf/BpfClassic.h b/staticlibs/native/bpf_headers/include/bpf/BpfClassic.h
new file mode 100644
index 0000000..9b38dee
--- /dev/null
+++ b/staticlibs/native/bpf_headers/include/bpf/BpfClassic.h
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+// Accept the full packet
+#define BPF_ACCEPT BPF_STMT(BPF_RET | BPF_K, 0xFFFFFFFF)
+
+// Reject the packet
+#define BPF_REJECT BPF_STMT(BPF_RET | BPF_K, 0)
+
+// *TWO* instructions: compare and if equal jump over the reject statement
+#define BPF2_REJECT_IF_NOT_EQUAL(v) \
+ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, (v), 1, 0), \
+ BPF_REJECT
+
+// 8-bit load relative to start of link layer (mac/ethernet) header.
+#define BPF_LOAD_MAC_RELATIVE_U8(ofs) \
+ BPF_STMT(BPF_LD | BPF_B | BPF_ABS, (__u32)SKF_LL_OFF + (ofs))
+
+// Big/Network Endian 16-bit load relative to start of link layer (mac/ethernet) header.
+#define BPF_LOAD_MAC_RELATIVE_BE16(ofs) \
+ BPF_STMT(BPF_LD | BPF_H | BPF_ABS, (__u32)SKF_LL_OFF + (ofs))
+
+// Big/Network Endian 32-bit load relative to start of link layer (mac/ethernet) header.
+#define BPF_LOAD_MAC_RELATIVE_BE32(ofs) \
+ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (__u32)SKF_LL_OFF + (ofs))
+
+// 8-bit load relative to start of network (IPv4/IPv6) header.
+#define BPF_LOAD_NET_RELATIVE_U8(ofs) \
+ BPF_STMT(BPF_LD | BPF_B | BPF_ABS, (__u32)SKF_NET_OFF + (ofs))
+
+// Big/Network Endian 16-bit load relative to start of network (IPv4/IPv6) header.
+#define BPF_LOAD_NET_RELATIVE_BE16(ofs) \
+ BPF_STMT(BPF_LD | BPF_H | BPF_ABS, (__u32)SKF_NET_OFF + (ofs))
+
+// Big/Network Endian 32-bit load relative to start of network (IPv4/IPv6) header.
+#define BPF_LOAD_NET_RELATIVE_BE32(ofs) \
+ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (__u32)SKF_NET_OFF + (ofs))
+
+#define field_sizeof(struct_type,field) sizeof(((struct_type *)0)->field)
+
+// 8-bit load from IPv4 header field.
+#define BPF_LOAD_IPV4_U8(field) \
+ BPF_LOAD_NET_RELATIVE_U8(({ \
+ _Static_assert(field_sizeof(struct iphdr, field) == 1, "field of wrong size"); \
+ offsetof(iphdr, field); \
+ }))
+
+// Big/Network Endian 16-bit load from IPv4 header field.
+#define BPF_LOAD_IPV4_BE16(field) \
+ BPF_LOAD_NET_RELATIVE_BE16(({ \
+ _Static_assert(field_sizeof(struct iphdr, field) == 2, "field of wrong size"); \
+ offsetof(iphdr, field); \
+ }))
+
+// Big/Network Endian 32-bit load from IPv4 header field.
+#define BPF_LOAD_IPV4_BE32(field) \
+ BPF_LOAD_NET_RELATIVE_BE32(({ \
+ _Static_assert(field_sizeof(struct iphdr, field) == 4, "field of wrong size"); \
+ offsetof(iphdr, field); \
+ }))
+
+// 8-bit load from IPv6 header field.
+#define BPF_LOAD_IPV6_U8(field) \
+ BPF_LOAD_NET_RELATIVE_U8(({ \
+ _Static_assert(field_sizeof(struct ipv6hdr, field) == 1, "field of wrong size"); \
+ offsetof(ipv6hdr, field); \
+ }))
+
+// Big/Network Endian 16-bit load from IPv6 header field.
+#define BPF_LOAD_IPV6_BE16(field) \
+ BPF_LOAD_NET_RELATIVE_BE16(({ \
+ _Static_assert(field_sizeof(struct ipv6hdr, field) == 2, "field of wrong size"); \
+ offsetof(ipv6hdr, field); \
+ }))
+
+// Big/Network Endian 32-bit load from IPv6 header field.
+#define BPF_LOAD_IPV6_BE32(field) \
+ BPF_LOAD_NET_RELATIVE_BE32(({ \
+ _Static_assert(field_sizeof(struct ipv6hdr, field) == 4, "field of wrong size"); \
+ offsetof(ipv6hdr, field); \
+ }))
diff --git a/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h b/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h
index e2cb676..206acba 100644
--- a/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h
+++ b/staticlibs/native/bpf_headers/include/bpf/BpfUtils.h
@@ -33,17 +33,26 @@
namespace android {
namespace bpf {
+// See kernel's net/core/sock_diag.c __sock_gen_cookie()
+// the implementation of which guarantees 0 will never be returned,
+// primarily because 0 is used to mean not yet initialized,
+// and socket cookies are only assigned on first fetch.
constexpr const uint64_t NONEXISTENT_COOKIE = 0;
static inline uint64_t getSocketCookie(int sockFd) {
uint64_t sock_cookie;
socklen_t cookie_len = sizeof(sock_cookie);
- int res = getsockopt(sockFd, SOL_SOCKET, SO_COOKIE, &sock_cookie, &cookie_len);
- if (res < 0) {
- res = -errno;
- ALOGE("Failed to get socket cookie: %s\n", strerror(errno));
- errno = -res;
- // 0 is an invalid cookie. See sock_gen_cookie.
+ if (getsockopt(sockFd, SOL_SOCKET, SO_COOKIE, &sock_cookie, &cookie_len)) {
+ // Failure is almost certainly either EBADF or ENOTSOCK
+ const int err = errno;
+ ALOGE("Failed to get socket cookie: %s\n", strerror(err));
+ errno = err;
+ return NONEXISTENT_COOKIE;
+ }
+ if (cookie_len != sizeof(sock_cookie)) {
+ // This probably cannot actually happen, but...
+ ALOGE("Failed to get socket cookie: len %d != 8\n", cookie_len);
+ errno = 523; // EBADCOOKIE: kernel internal, seems reasonable enough...
return NONEXISTENT_COOKIE;
}
return sock_cookie;
@@ -56,19 +65,19 @@
//
// Linux 4.14/4.19/5.4/5.10/5.15 (and 5.18) still have this same behaviour.
// see net/key/af_key.c: pfkey_release() -> synchronize_rcu()
- int pfSocket = socket(AF_KEY, SOCK_RAW | SOCK_CLOEXEC, PF_KEY_V2);
+ const int pfSocket = socket(AF_KEY, SOCK_RAW | SOCK_CLOEXEC, PF_KEY_V2);
if (pfSocket < 0) {
- int ret = -errno;
- ALOGE("create PF_KEY socket failed: %s", strerror(errno));
- return ret;
+ const int err = errno;
+ ALOGE("create PF_KEY socket failed: %s", strerror(err));
+ return -err;
}
// When closing socket, synchronize_rcu() gets called in sock_release().
if (close(pfSocket)) {
- int ret = -errno;
- ALOGE("failed to close the PF_KEY socket: %s", strerror(errno));
- return ret;
+ const int err = errno;
+ ALOGE("failed to close the PF_KEY socket: %s", strerror(err));
+ return -err;
}
return 0;
}
@@ -79,10 +88,8 @@
.rlim_cur = 1073741824, // 1 GiB
.rlim_max = 1073741824, // 1 GiB
};
- int res = setrlimit(RLIMIT_MEMLOCK, &limit);
- if (res) {
- ALOGE("Failed to set the default MEMLOCK rlimit: %s", strerror(errno));
- }
+ const int res = setrlimit(RLIMIT_MEMLOCK, &limit);
+ if (res) ALOGE("Failed to set the default MEMLOCK rlimit: %s", strerror(errno));
return res;
}
diff --git a/staticlibs/native/ip_checksum/checksum.c b/staticlibs/native/ip_checksum/checksum.c
index 04217a7..5641fad 100644
--- a/staticlibs/native/ip_checksum/checksum.c
+++ b/staticlibs/native/ip_checksum/checksum.c
@@ -32,20 +32,16 @@
* len - length of data
*/
uint32_t ip_checksum_add(uint32_t current, const void* data, int len) {
- uint32_t checksum = current;
- int left = len;
const uint16_t* data_16 = data;
- while (left > 1) {
- checksum += *data_16;
+ while (len >= 2) {
+ current += *data_16;
data_16++;
- left -= 2;
+ len -= 2;
}
- if (left) {
- checksum += *(uint8_t*)data_16;
- }
+ if (len) current += *(uint8_t*)data_16; // assumes little endian!
- return checksum;
+ return current;
}
/* function: ip_checksum_fold
@@ -54,9 +50,8 @@
* returns: the folded checksum in network byte order
*/
uint16_t ip_checksum_fold(uint32_t temp_sum) {
- while (temp_sum > 0xffff) {
- temp_sum = (temp_sum >> 16) + (temp_sum & 0xFFFF);
- }
+ temp_sum = (temp_sum >> 16) + (temp_sum & 0xFFFF);
+ temp_sum = (temp_sum >> 16) + (temp_sum & 0xFFFF);
return temp_sum;
}
@@ -75,12 +70,7 @@
* len - length of data
*/
uint16_t ip_checksum(const void* data, int len) {
- // TODO: consider starting from 0xffff so the checksum of a buffer entirely consisting of zeros
- // is correctly calculated as 0.
- uint32_t temp_sum;
-
- temp_sum = ip_checksum_add(0, data, len);
- return ip_checksum_finish(temp_sum);
+ return ip_checksum_finish(ip_checksum_add(0xFFFF, data, len));
}
/* function: ipv6_pseudo_header_checksum
@@ -92,7 +82,6 @@
uint32_t ipv6_pseudo_header_checksum(const struct ip6_hdr* ip6, uint32_t len, uint8_t protocol) {
uint32_t checksum_len = htonl(len);
uint32_t checksum_next = htonl(protocol);
-
uint32_t current = 0;
current = ip_checksum_add(current, &(ip6->ip6_src), sizeof(struct in6_addr));
@@ -109,11 +98,8 @@
* len - the transport length (transport header + payload)
*/
uint32_t ipv4_pseudo_header_checksum(const struct iphdr* ip, uint16_t len) {
- uint16_t temp_protocol, temp_length;
-
- temp_protocol = htons(ip->protocol);
- temp_length = htons(len);
-
+ uint16_t temp_protocol = htons(ip->protocol);
+ uint16_t temp_length = htons(len);
uint32_t current = 0;
current = ip_checksum_add(current, &(ip->saddr), sizeof(uint32_t));
@@ -135,7 +121,7 @@
// Algorithm suggested in RFC 1624.
// http://tools.ietf.org/html/rfc1624#section-3
checksum = ~checksum;
- uint16_t folded_sum = ip_checksum_fold(checksum + new_hdr_sum);
+ uint16_t folded_sum = ip_checksum_fold(new_hdr_sum + checksum);
uint16_t folded_old = ip_checksum_fold(old_hdr_sum);
if (folded_sum > folded_old) {
return ~(folded_sum - folded_old);
diff --git a/staticlibs/native/ip_checksum/checksum.h b/staticlibs/native/ip_checksum/checksum.h
index 868217c..87393c9 100644
--- a/staticlibs/native/ip_checksum/checksum.h
+++ b/staticlibs/native/ip_checksum/checksum.h
@@ -12,11 +12,8 @@
* 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.
- *
- * checksum.h - checksum functions
*/
-#ifndef __CHECKSUM_H__
-#define __CHECKSUM_H__
+#pragma once
#include <netinet/ip.h>
#include <netinet/ip6.h>
@@ -30,5 +27,3 @@
uint32_t ipv4_pseudo_header_checksum(const struct iphdr* ip, uint16_t len);
uint16_t ip_checksum_adjust(uint16_t checksum, uint32_t old_hdr_sum, uint32_t new_hdr_sum);
-
-#endif /* __CHECKSUM_H__ */
diff --git a/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitychecker/ConnectivityCheckTest.kt b/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitychecker/ConnectivityCheckTest.kt
index f34ca22..f72938d 100644
--- a/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitychecker/ConnectivityCheckTest.kt
+++ b/staticlibs/testutils/app/connectivitychecker/src/com/android/testutils/connectivitychecker/ConnectivityCheckTest.kt
@@ -29,10 +29,10 @@
import com.android.testutils.RecorderCallback
import com.android.testutils.TestableNetworkCallback
import com.android.testutils.tryTest
-import org.junit.Test
-import org.junit.runner.RunWith
import kotlin.test.assertTrue
import kotlin.test.fail
+import org.junit.Test
+import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class ConnectivityCheckTest {
@@ -76,7 +76,7 @@
.addTransportType(TRANSPORT_CELLULAR)
.addCapability(NET_CAPABILITY_INTERNET).build(), cb)
tryTest {
- cb.eventuallyExpectOrNull<RecorderCallback.CallbackEntry.Available>()
+ cb.poll { it is RecorderCallback.CallbackEntry.Available }
?: fail("The device does not have mobile data available. Check that it is " +
"setup with a SIM card that has a working data plan, and that the " +
"APN configuration is valid.")
@@ -84,4 +84,4 @@
cm.unregisterNetworkCallback(cb)
}
}
-}
\ No newline at end of file
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt b/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt
index 7b5ad01..71f7877 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/ConnectUtil.kt
@@ -32,6 +32,7 @@
import android.os.SystemClock
import android.util.Log
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
+import com.android.testutils.RecorderCallback.CallbackEntry
import java.util.concurrent.CompletableFuture
import java.util.concurrent.TimeUnit
import kotlin.test.assertNotNull
@@ -72,9 +73,7 @@
val config = getOrCreateWifiConfiguration()
connectToWifiConfig(config)
}
- val cb = callback.eventuallyExpectOrNull<RecorderCallback.CallbackEntry.Available>(
- timeoutMs = WIFI_CONNECT_TIMEOUT_MS)
-
+ val cb = callback.poll(WIFI_CONNECT_TIMEOUT_MS) { it is CallbackEntry.Available }
assertNotNull(cb, "Could not connect to a wifi access point within " +
"$WIFI_CONNECT_TIMEOUT_MS ms. Check that the test device has a wifi network " +
"configured, and that the test access point is functioning properly.")
@@ -201,4 +200,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt
index 485799c..e7d86e0 100644
--- a/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt
+++ b/staticlibs/testutils/devicetests/com/android/testutils/TestableNetworkCallback.kt
@@ -220,7 +220,8 @@
* Long.MAX_VALUE.
*/
@JvmOverloads
- fun poll(timeoutMs: Long = defaultTimeoutMs): CallbackEntry? = history.poll(timeoutMs)
+ fun poll(timeoutMs: Long = defaultTimeoutMs, predicate: (CallbackEntry) -> Boolean = { true }) =
+ history.poll(timeoutMs, predicate)
/**
* Get the next callback or throw if timeout.
@@ -385,7 +386,7 @@
timeoutMs: Long = defaultTimeoutMs,
from: Int = mark,
crossinline predicate: (T) -> Boolean = { true }
- ): T = eventuallyExpectOrNull(timeoutMs, from, predicate).also {
+ ): T = history.poll(timeoutMs, from) { it is T && predicate(it) }.also {
assertNotNull(it, "Callback ${T::class} not received within ${timeoutMs}ms")
} as T
@@ -407,7 +408,7 @@
assertNotNull(it, "Callback ${type.java} not received within ${timeoutMs}ms")
} as T
- // TODO (b/157405399) straighten and unify the method names
+ // TODO (b/157405399) remove this method when there are no longer any uses of it.
inline fun <reified T : CallbackEntry> eventuallyExpectOrNull(
timeoutMs: Long = defaultTimeoutMs,
from: Int = mark,