Merge "Remove module for creating license for gn2bp script"
diff --git a/service/native/libs/libclat/Android.bp b/service/native/libs/libclat/Android.bp
index 54d40ac..996706e 100644
--- a/service/native/libs/libclat/Android.bp
+++ b/service/native/libs/libclat/Android.bp
@@ -23,6 +23,9 @@
         "clatutils.cpp",
     ],
     stl: "libc++_static",
+    header_libs: [
+        "bpf_headers",
+    ],
     static_libs: [
         "libip_checksum",
     ],
diff --git a/service/native/libs/libclat/clatutils.cpp b/service/native/libs/libclat/clatutils.cpp
index c6a9781..6c5c9e3 100644
--- a/service/native/libs/libclat/clatutils.cpp
+++ b/service/native/libs/libclat/clatutils.cpp
@@ -25,6 +25,8 @@
 #include <string.h>
 #include <unistd.h>
 
+#include <bpf/BpfClassic.h>
+
 extern "C" {
 #include "checksum.h"
 }
@@ -33,11 +35,9 @@
 namespace net {
 namespace clat {
 
-bool isIpv4AddressFree(in_addr_t addr) {
-    int s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
-    if (s == -1) {
-        return 0;
-    }
+bool isIpv4AddressFree(const in_addr_t addr) {
+    const int s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    if (s == -1) return 0;
 
     // Attempt to connect to the address. If the connection succeeds and getsockname returns the
     // same then the address is already assigned to the system and we can't use it.
@@ -47,9 +47,10 @@
             .sin_addr = {addr},
     };
     socklen_t len = sizeof(sin);
-    bool inuse = connect(s, (struct sockaddr*)&sin, sizeof(sin)) == 0 &&
-                 getsockname(s, (struct sockaddr*)&sin, &len) == 0 && (size_t)len >= sizeof(sin) &&
-                 sin.sin_addr.s_addr == addr;
+    const bool inuse = !connect(s, (struct sockaddr*)&sin, sizeof(sin)) &&
+                       !getsockname(s, (struct sockaddr*)&sin, &len) &&
+                       len == (socklen_t)sizeof(sin) &&
+                       sin.sin_addr.s_addr == addr;
 
     close(s);
     return !inuse;
@@ -59,36 +60,30 @@
 //   ip        - the IP address from the configuration file
 //   prefixlen - the length of the prefix from which addresses may be selected.
 //   returns: the IPv4 address, or INADDR_NONE if no addresses were available
-in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen) {
+in_addr_t selectIpv4Address(const in_addr ip, const int16_t prefixlen) {
     return selectIpv4AddressInternal(ip, prefixlen, isIpv4AddressFree);
 }
 
 // Only allow testing to use this function directly. Otherwise call selectIpv4Address(ip, pfxlen)
 // which has applied valid isIpv4AddressFree function pointer.
-in_addr_t selectIpv4AddressInternal(const in_addr ip, int16_t prefixlen,
-                                    isIpv4AddrFreeFn isIpv4AddressFreeFunc) {
+in_addr_t selectIpv4AddressInternal(const in_addr ip, const int16_t prefixlen,
+                                    const isIpv4AddrFreeFn isIpv4AddressFreeFunc) {
     // Impossible! Only test allows to apply fn.
-    if (isIpv4AddressFreeFunc == nullptr) {
-        return INADDR_NONE;
-    }
+    if (isIpv4AddressFreeFunc == nullptr) return INADDR_NONE;
 
     // Don't accept prefixes that are too large because we scan addresses one by one.
-    if (prefixlen < 16 || prefixlen > 32) {
-        return INADDR_NONE;
-    }
+    if (prefixlen < 16 || prefixlen > 32) return INADDR_NONE;
 
     // All these are in host byte order.
-    in_addr_t mask = 0xffffffff >> (32 - prefixlen) << (32 - prefixlen);
-    in_addr_t ipv4 = ntohl(ip.s_addr);
-    in_addr_t first_ipv4 = ipv4;
-    in_addr_t prefix = ipv4 & mask;
+    const uint32_t mask = 0xffffffff >> (32 - prefixlen) << (32 - prefixlen);
+    uint32_t ipv4 = ntohl(ip.s_addr);
+    const uint32_t first_ipv4 = ipv4;
+    const uint32_t prefix = ipv4 & mask;
 
     // Pick the first IPv4 address in the pool, wrapping around if necessary.
     // So, for example, 192.0.0.4 -> 192.0.0.5 -> 192.0.0.6 -> 192.0.0.7 -> 192.0.0.0.
     do {
-        if (isIpv4AddressFreeFunc(htonl(ipv4))) {
-            return htonl(ipv4);
-        }
+        if (isIpv4AddressFreeFunc(htonl(ipv4))) return htonl(ipv4);
         ipv4 = prefix | ((ipv4 + 1) & ~mask);
     } while (ipv4 != first_ipv4);
 
@@ -96,7 +91,7 @@
 }
 
 // Alters the bits in the IPv6 address to make them checksum neutral with v4 and nat64Prefix.
-void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix) {
+void makeChecksumNeutral(in6_addr* const v6, const in_addr v4, const in6_addr& nat64Prefix) {
     // Fill last 8 bytes of IPv6 address with random bits.
     arc4random_buf(&v6->s6_addr[8], 8);
 
@@ -118,33 +113,35 @@
 }
 
 // Picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix.
-int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
-                        in6_addr* v6, uint32_t mark) {
-    int s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+int generateIpv6Address(const char* const iface, const in_addr v4, const in6_addr& nat64Prefix,
+                        in6_addr* const v6, const uint32_t mark) {
+    const int s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
     if (s == -1) return -errno;
 
     // Socket's mark affects routing decisions (network selection)
     // An fwmark is necessary for clat to bypass the VPN during initialization.
     if (setsockopt(s, SOL_SOCKET, SO_MARK, &mark, sizeof(mark))) {
-        int ret = errno;
-        ALOGE("setsockopt(SOL_SOCKET, SO_MARK) failed: %s", strerror(errno));
+        const int err = errno;
+        ALOGE("setsockopt(SOL_SOCKET, SO_MARK) failed: %s", strerror(err));
         close(s);
-        return -ret;
+        return -err;
     }
 
-    if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1) == -1) {
+    if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1)) {
+        const int err = errno;
+        ALOGE("setsockopt(SOL_SOCKET, SO_BINDTODEVICE, '%s') failed: %s", iface, strerror(err));
         close(s);
-        return -errno;
+        return -err;
     }
 
     sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = nat64Prefix};
-    if (connect(s, reinterpret_cast<struct sockaddr*>(&sin6), sizeof(sin6)) == -1) {
+    if (connect(s, reinterpret_cast<struct sockaddr*>(&sin6), sizeof(sin6))) {
         close(s);
         return -errno;
     }
 
     socklen_t len = sizeof(sin6);
-    if (getsockname(s, reinterpret_cast<struct sockaddr*>(&sin6), &len) == -1) {
+    if (getsockname(s, reinterpret_cast<struct sockaddr*>(&sin6), &len)) {
         close(s);
         return -errno;
     }
@@ -163,21 +160,22 @@
     return 0;
 }
 
-int detect_mtu(const struct in6_addr* plat_subnet, uint32_t plat_suffix, uint32_t mark) {
+int detect_mtu(const struct in6_addr* const plat_subnet, const uint32_t plat_suffix,
+               const uint32_t mark) {
     // Create an IPv6 UDP socket.
-    int s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+    const int s = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
     if (s < 0) {
-        int ret = errno;
-        ALOGE("socket(AF_INET6, SOCK_DGRAM, 0) failed: %s", strerror(errno));
-        return -ret;
+        const int err = errno;
+        ALOGE("socket(AF_INET6, SOCK_DGRAM, 0) failed: %s", strerror(err));
+        return -err;
     }
 
     // Socket's mark affects routing decisions (network selection)
     if (setsockopt(s, SOL_SOCKET, SO_MARK, &mark, sizeof(mark))) {
-        int ret = errno;
-        ALOGE("setsockopt(SOL_SOCKET, SO_MARK) failed: %s", strerror(errno));
+        const int err = errno;
+        ALOGE("setsockopt(SOL_SOCKET, SO_MARK) failed: %s", strerror(err));
         close(s);
-        return -ret;
+        return -err;
     }
 
     // Try to connect udp socket to plat_subnet(96 bits):plat_suffix(32 bits)
@@ -187,20 +185,20 @@
     };
     dst.sin6_addr.s6_addr32[3] = plat_suffix;
     if (connect(s, (struct sockaddr*)&dst, sizeof(dst))) {
-        int ret = errno;
-        ALOGE("connect() failed: %s", strerror(errno));
+        const int err = errno;
+        ALOGE("connect() failed: %s", strerror(err));
         close(s);
-        return -ret;
+        return -err;
     }
 
     // Fetch the socket's IPv6 mtu - this is effectively fetching mtu from routing table
     int mtu;
     socklen_t sz_mtu = sizeof(mtu);
     if (getsockopt(s, SOL_IPV6, IPV6_MTU, &mtu, &sz_mtu)) {
-        int ret = errno;
-        ALOGE("getsockopt(SOL_IPV6, IPV6_MTU) failed: %s", strerror(errno));
+        const int err = errno;
+        ALOGE("getsockopt(SOL_IPV6, IPV6_MTU) failed: %s", strerror(err));
         close(s);
-        return -ret;
+        return -err;
     }
     if (sz_mtu != sizeof(mtu)) {
         ALOGE("getsockopt(SOL_IPV6, IPV6_MTU) returned unexpected size: %d", sz_mtu);
@@ -219,34 +217,26 @@
  *   ifindex - index of interface to add the filter to
  * returns: 0 on success, -errno on failure
  */
-int configure_packet_socket(int sock, in6_addr* addr, int ifindex) {
-    uint32_t* ipv6 = addr->s6_addr32;
-
+int configure_packet_socket(const int sock, const in6_addr* const addr, const int ifindex) {
     // clang-format off
     struct sock_filter filter_code[] = {
-    // Load the first four bytes of the IPv6 destination address (starts 24 bytes in).
-    // Compare it against the first four bytes of our IPv6 address, in host byte order (BPF loads
-    // are always in host byte order). If it matches, continue with next instruction (JMP 0). If it
-    // doesn't match, jump ahead to statement that returns 0 (ignore packet). Repeat for the other
-    // three words of the IPv6 address, and if they all match, return full packet (accept packet).
-        BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  24),
-        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[0]), 0, 7),
-        BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  28),
-        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[1]), 0, 5),
-        BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  32),
-        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[2]), 0, 3),
-        BPF_STMT(BPF_LD  | BPF_W   | BPF_ABS,  36),
-        BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K,    htonl(ipv6[3]), 0, 1),
-        BPF_STMT(BPF_RET | BPF_K,              0xFFFFFFFF),
-        BPF_STMT(BPF_RET | BPF_K,              0),
+        BPF_LOAD_IPV6_BE32(daddr.s6_addr32[0]),
+        BPF2_REJECT_IF_NOT_EQUAL(ntohl(addr->s6_addr32[0])),
+        BPF_LOAD_IPV6_BE32(daddr.s6_addr32[1]),
+        BPF2_REJECT_IF_NOT_EQUAL(ntohl(addr->s6_addr32[1])),
+        BPF_LOAD_IPV6_BE32(daddr.s6_addr32[2]),
+        BPF2_REJECT_IF_NOT_EQUAL(ntohl(addr->s6_addr32[2])),
+        BPF_LOAD_IPV6_BE32(daddr.s6_addr32[3]),
+        BPF2_REJECT_IF_NOT_EQUAL(ntohl(addr->s6_addr32[3])),
+        BPF_ACCEPT,
     };
     // clang-format on
     struct sock_fprog filter = {sizeof(filter_code) / sizeof(filter_code[0]), filter_code};
 
     if (setsockopt(sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter))) {
-        int res = errno;
-        ALOGE("attach packet filter failed: %s", strerror(errno));
-        return -res;
+        const int err = errno;
+        ALOGE("attach packet filter failed: %s", strerror(err));
+        return -err;
     }
 
     struct sockaddr_ll sll = {
@@ -257,9 +247,9 @@
                     PACKET_OTHERHOST,  // The 464xlat IPv6 address is not assigned to the kernel.
     };
     if (bind(sock, (struct sockaddr*)&sll, sizeof(sll))) {
-        int res = errno;
-        ALOGE("binding packet socket: %s", strerror(errno));
-        return -res;
+        const int err = errno;
+        ALOGE("binding packet socket: %s", strerror(err));
+        return -err;
     }
 
     return 0;
diff --git a/service/native/libs/libclat/include/libclat/clatutils.h b/service/native/libs/libclat/include/libclat/clatutils.h
index 991b193..6e17e67 100644
--- a/service/native/libs/libclat/include/libclat/clatutils.h
+++ b/service/native/libs/libclat/include/libclat/clatutils.h
@@ -20,17 +20,19 @@
 namespace net {
 namespace clat {
 
-bool isIpv4AddressFree(in_addr_t addr);
-in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen);
-void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix);
-int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
-                        in6_addr* v6, uint32_t mark);
-int detect_mtu(const struct in6_addr* plat_subnet, uint32_t plat_suffix, uint32_t mark);
-int configure_packet_socket(int sock, in6_addr* addr, int ifindex);
+bool isIpv4AddressFree(const in_addr_t addr);
+in_addr_t selectIpv4Address(const in_addr ip, const int16_t prefixlen);
+void makeChecksumNeutral(in6_addr* const v6, const in_addr v4, const in6_addr& nat64Prefix);
+int generateIpv6Address(const char* const iface, const in_addr v4, const in6_addr& nat64Prefix,
+                        in6_addr* const v6, const uint32_t mark);
+int detect_mtu(const struct in6_addr* const plat_subnet, const uint32_t plat_suffix,
+               const uint32_t mark);
+int configure_packet_socket(const int sock, const in6_addr* const addr, const int ifindex);
 
 // For testing
-typedef bool (*isIpv4AddrFreeFn)(in_addr_t);
-in_addr_t selectIpv4AddressInternal(const in_addr ip, int16_t prefixlen, isIpv4AddrFreeFn fn);
+typedef bool (*isIpv4AddrFreeFn)(const in_addr_t);
+in_addr_t selectIpv4AddressInternal(const in_addr ip, const int16_t prefixlen,
+                                    const isIpv4AddrFreeFn fn);
 
 }  // namespace clat
 }  // namespace net
diff --git a/service/src/com/android/server/ConnectivityService.java b/service/src/com/android/server/ConnectivityService.java
index 5f51971..e969cd6 100755
--- a/service/src/com/android/server/ConnectivityService.java
+++ b/service/src/com/android/server/ConnectivityService.java
@@ -911,7 +911,7 @@
 
     // This is the cache for the packageName -> ApplicationSelfCertifiedNetworkCapabilities. This
     // value can be accessed from both handler thread and any random binder thread. Therefore,
-    // accessing this value requires holding a lock.
+    // accessing this value requires holding a lock. The cache is the same across all the users.
     @GuardedBy("mSelfCertifiedCapabilityCache")
     private final Map<String, ApplicationSelfCertifiedNetworkCapabilities>
             mSelfCertifiedCapabilityCache = new HashMap<>();
@@ -7001,6 +7001,7 @@
             return;
         }
         ApplicationSelfCertifiedNetworkCapabilities applicationNetworkCapabilities;
+        final long ident = Binder.clearCallingIdentity();
         try {
             synchronized (mSelfCertifiedCapabilityCache) {
                 applicationNetworkCapabilities = mSelfCertifiedCapabilityCache.get(
@@ -7027,6 +7028,8 @@
                             + " property");
         } catch (XmlPullParserException | IOException | InvalidTagException e) {
             throw new SecurityException(e.getMessage());
+        } finally {
+            Binder.restoreCallingIdentity(ident);
         }
 
         applicationNetworkCapabilities.enforceSelfCertifiedNetworkCapabilitiesDeclared(
@@ -8467,6 +8470,7 @@
         exemptUids[1] = nai.networkCapabilities.getOwnerUid();
         UidRangeParcel[] ranges = toUidRangeStableParcels(uidRanges);
 
+        // Close sockets before modifying uid ranges so that RST packets can reach to the server.
         maybeCloseSockets(nai, ranges, exemptUids);
         try {
             if (add) {
@@ -8480,6 +8484,7 @@
             loge("Exception while " + (add ? "adding" : "removing") + " uid ranges " + uidRanges +
                     " on netId " + nai.network.netId + ". " + e);
         }
+        // Close sockets that established connection while requesting netd.
         maybeCloseSockets(nai, ranges, exemptUids);
     }
 
diff --git a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
index 0bb6000..1bed83d 100644
--- a/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
+++ b/tests/cts/net/src/android/net/cts/ConnectivityManagerTest.java
@@ -3406,6 +3406,9 @@
 
     private static final boolean EXPECT_PASS = false;
     private static final boolean EXPECT_BLOCK = true;
+
+    // ALLOWLIST means the firewall denies all by default, uids must be explicitly allowed
+    // DENYLIST means the firewall allows all by default, uids must be explicitly denyed
     private static final boolean ALLOWLIST = true;
     private static final boolean DENYLIST = false;
 
@@ -3471,17 +3474,49 @@
 
     @Test @IgnoreUpTo(SC_V2) @ConnectivityModuleTest
     @AppModeFull(reason = "Socket cannot bind in instant app mode")
-    public void testFirewallBlocking() {
-        // ALLOWLIST means the firewall denies all by default, uids must be explicitly allowed
+    public void testFirewallBlockingDozable() {
         doTestFirewallBlocking(FIREWALL_CHAIN_DOZABLE, ALLOWLIST);
-        doTestFirewallBlocking(FIREWALL_CHAIN_POWERSAVE, ALLOWLIST);
-        doTestFirewallBlocking(FIREWALL_CHAIN_RESTRICTED, ALLOWLIST);
-        doTestFirewallBlocking(FIREWALL_CHAIN_LOW_POWER_STANDBY, ALLOWLIST);
+    }
 
-        // DENYLIST means the firewall allows all by default, uids must be explicitly denyed
+    @Test @IgnoreUpTo(SC_V2) @ConnectivityModuleTest
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
+    public void testFirewallBlockingPowersave() {
+        doTestFirewallBlocking(FIREWALL_CHAIN_POWERSAVE, ALLOWLIST);
+    }
+
+    @Test @IgnoreUpTo(SC_V2) @ConnectivityModuleTest
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
+    public void testFirewallBlockingRestricted() {
+        doTestFirewallBlocking(FIREWALL_CHAIN_RESTRICTED, ALLOWLIST);
+    }
+
+    @Test @IgnoreUpTo(SC_V2) @ConnectivityModuleTest
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
+    public void testFirewallBlockingLowPowerStandby() {
+        doTestFirewallBlocking(FIREWALL_CHAIN_LOW_POWER_STANDBY, ALLOWLIST);
+    }
+
+    @Test @IgnoreUpTo(SC_V2) @ConnectivityModuleTest
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
+    public void testFirewallBlockingStandby() {
         doTestFirewallBlocking(FIREWALL_CHAIN_STANDBY, DENYLIST);
+    }
+
+    @Test @IgnoreUpTo(SC_V2) @ConnectivityModuleTest
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
+    public void testFirewallBlockingOemDeny1() {
         doTestFirewallBlocking(FIREWALL_CHAIN_OEM_DENY_1, DENYLIST);
+    }
+
+    @Test @IgnoreUpTo(SC_V2) @ConnectivityModuleTest
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
+    public void testFirewallBlockingOemDeny2() {
         doTestFirewallBlocking(FIREWALL_CHAIN_OEM_DENY_2, DENYLIST);
+    }
+
+    @Test @IgnoreUpTo(SC_V2) @ConnectivityModuleTest
+    @AppModeFull(reason = "Socket cannot bind in instant app mode")
+    public void testFirewallBlockingOemDeny3() {
         doTestFirewallBlocking(FIREWALL_CHAIN_OEM_DENY_3, DENYLIST);
     }