bpf netd: Add blocking for ingress local network calls.

Blocking ingress traffic which is disallowed in
local_net_access_map. The permission check will be
introduced in subsequent changes.

Test: Tested locally by temporarily allowing egress traffic but
blocking ingress.

Bug: 381099600
Change-Id: If796c5232640da162442ca5c114b94b18a6c9b0d
diff --git a/bpf/progs/netd.c b/bpf/progs/netd.c
index 88aa490..4ff68da 100644
--- a/bpf/progs/netd.c
+++ b/bpf/progs/netd.c
@@ -235,10 +235,8 @@
         : 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,
+// False iff arguments are found with longest prefix match lookup and disallowed.
+static inline __always_inline 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)
@@ -252,40 +250,44 @@
     return v ? *v : true;
 }
 
-static __always_inline inline bool should_block_local_network_packets(struct __sk_buff *skb,
-                                   const struct kver_uint kver) {
+static __always_inline inline
+bool should_block_local_network_packets(struct __sk_buff *skb,
+                                        const struct egress_bool egress,
+                                        const struct kver_uint kver) {
     struct in6_addr remote_ip6;
     uint8_t ip_proto;
     uint8_t L4_off;
     if (skb->protocol == htons(ETH_P_IP)) {
+        int remote_ip_ofs = egress.egress ? IP4_OFFSET(daddr) : IP4_OFFSET(saddr);
         remote_ip6.s6_addr32[0] = 0;
         remote_ip6.s6_addr32[1] = 0;
         remote_ip6.s6_addr32[2] = htonl(0xFFFF);
-        (void)bpf_skb_load_bytes_net(skb, IP4_OFFSET(daddr), &remote_ip6.s6_addr32[3], 4, kver);
+        (void)bpf_skb_load_bytes_net(skb, remote_ip_ofs, &remote_ip6.s6_addr32[3], 4, kver);
         (void)bpf_skb_load_bytes_net(skb, IP4_OFFSET(protocol), &ip_proto, sizeof(ip_proto), kver);
         uint8_t ihl;
         (void)bpf_skb_load_bytes_net(skb, IPPROTO_IHL_OFF, &ihl, sizeof(ihl), kver);
         L4_off = (ihl & 0x0F) * 4;  // IHL calculation.
     } else if (skb->protocol == htons(ETH_P_IPV6)) {
-        (void)bpf_skb_load_bytes_net(skb, IP6_OFFSET(daddr), &remote_ip6, sizeof(remote_ip6), kver);
+        int remote_ip_ofs = egress.egress ? IP6_OFFSET(daddr) : IP6_OFFSET(saddr);
+        (void)bpf_skb_load_bytes_net(skb, remote_ip_ofs, &remote_ip6, sizeof(remote_ip6), kver);
         (void)bpf_skb_load_bytes_net(skb, IP6_OFFSET(nexthdr), &ip_proto, sizeof(ip_proto), kver);
         L4_off = sizeof(struct ipv6hdr);
     } else {
         return false;
     }
 
-    __be16 port = 0;
+    __be16 remote_port = 0;
     switch (ip_proto) {
       case IPPROTO_TCP:
       case IPPROTO_DCCP:
       case IPPROTO_UDP:
       case IPPROTO_UDPLITE:
       case IPPROTO_SCTP:
-        (void)bpf_skb_load_bytes_net(skb, L4_off + 2, &port, sizeof(port), kver);
+        (void)bpf_skb_load_bytes_net(skb, L4_off + (egress.egress ? 2 : 0), &remote_port, sizeof(remote_port), kver);
         break;
     }
 
-    return !is_local_net_access_allowed(skb->ifindex, &remote_ip6, ip_proto, port);
+    return !is_local_net_access_allowed(skb->ifindex, &remote_ip6, ip_proto, remote_port);
 }
 
 static __always_inline inline void do_packet_tracing(
@@ -546,7 +548,7 @@
     }
 
     if (SDK_LEVEL_IS_AT_LEAST(lvl, 25Q2) && (match != DROP)) {
-        if (egress.egress && should_block_local_network_packets(skb, kver)) match = DROP;
+        if (should_block_local_network_packets(skb, egress, kver)) match = DROP;
     }
 
     // If an outbound packet is going to be dropped, we do not count that traffic.