bpf netd: Add local_net_access bpf map along with lookup method.

local_net_access is of type BPF_MAP_TYPE_LPM_TRIE (longest prefix
matching map) which stores interface index, remote address, protocol
and remote port. Lookup method is_local_net_access_allowed() returns
false if the arguments are found in the map and disallowed, otherwise
it returns true.

Test: Locally tested by adding values from userspace and querying the
bpf map.

Bug: 373608779
Change-Id: Ia34b3cb5613b56f6db5b224ec03f8c9909a49fe1
diff --git a/bpf/progs/netd.c b/bpf/progs/netd.c
index 8897627..41ea82d 100644
--- a/bpf/progs/netd.c
+++ b/bpf/progs/netd.c
@@ -99,6 +99,11 @@
 DEFINE_BPF_MAP_RO_NETD(data_saver_enabled_map, ARRAY, uint32_t, bool,
                        DATA_SAVER_ENABLED_MAP_SIZE)
 
+DEFINE_BPF_MAP_EXT(local_net_access_map, LPM_TRIE, LocalNetAccessKey, bool, 1000,
+                   AID_ROOT, AID_NET_BW_ACCT, 0060, "fs_bpf_net_shared", "", PRIVATE,
+                   BPFLOADER_MAINLINE_25Q2_VERSION, BPFLOADER_MAX_VER, LOAD_ON_ENG, LOAD_ON_USER,
+                   LOAD_ON_USERDEBUG, 0)
+
 // iptables xt_bpf programs need to be usable by both netd and netutils_wrappers
 // selinux contexts, because even non-xt_bpf iptables mutations are implemented as
 // a full table dump, followed by an update in userspace, and then a reload into the kernel,
@@ -230,6 +235,23 @@
         : bpf_skb_load_bytes(skb, L3_off, to, len);
 }
 
+/*
+ * False iff arguments are found with longest prefix match lookup and disallowed.
+ */
+static inline __always_inline __unused bool is_local_net_access_allowed(const uint32_t if_index,
+        const struct in6_addr* remote_ip6, const uint16_t protocol, const __be16 remote_port) {
+    LocalNetAccessKey query_key = {
+        .lpm_bitlen = 8 * (sizeof(if_index) + sizeof(*remote_ip6) + sizeof(protocol)
+            + sizeof(remote_port)),
+        .if_index = if_index,
+        .remote_ip6 = *remote_ip6,
+        .protocol = protocol,
+        .remote_port = remote_port
+    };
+    bool* v = bpf_local_net_access_map_lookup_elem(&query_key);
+    return v ? *v : true;
+}
+
 static __always_inline inline void do_packet_tracing(
         const struct __sk_buff* const skb, const struct egress_bool egress, const uint32_t uid,
         const uint32_t tag, const struct kver_uint kver) {