[automerger skipped] dns_tls_frontend.cpp: set queries_ to 0 in startServer am: 3fff84ade0 -s ours am: c8860724ad -s ours am: f74fc01e97 -s ours am: e035fae1dc -s ours
am skip reason: Change-Id I9ce9314c34420b346703500f4120304dfa58b9af with SHA-1 589bd52d90 is in history
Original change: https://android-review.googlesource.com/c/platform/system/netd/+/1112480
Change-Id: Id2526e4184c7869a5ad4d44dd857ae6413aa708f
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/Android.bp b/Android.bp
index 0838a8d..8fe83f0 100644
--- a/Android.bp
+++ b/Android.bp
@@ -20,7 +20,6 @@
export_include_dirs: ["include"],
apex_available: [
"//apex_available:platform",
- "com.android.tethering",
],
}
@@ -74,16 +73,14 @@
"-misc-non-private-member-variables-in-classes", // Also complains about structs
"-performance-noexcept-move-constructor",
"-performance-unnecessary-value-param",
- "-performance-no-int-to-ptr",
],
- tidy_flags: [
- "-warnings-as-errors="
- + "android-*,"
- + "bugprone-*,"
- + "cert-*,"
- + "clang-analyzer-security*,"
- + "google-*,"
- + "misc-*,"
- + "performance-*"
+ tidy_checks_as_errors: [
+ "android-*",
+ "bugprone-*",
+ "cert-*",
+ "clang-analyzer-security*",
+ "google-*",
+ "misc-*",
+ "performance-*",
],
}
diff --git a/OWNERS b/OWNERS
index 94e70d5..a29a33b 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,11 +1,4 @@
-cken@google.com
-codewiz@google.com
-huangluke@google.com
-jchalard@google.com
-lorenzo@google.com
-maze@google.com
-nuccachen@google.com
-reminv@google.com
-satk@google.com
-xiaom@google.com
-yumike@google.com
\ No newline at end of file
+set noparent
+file:platform/packages/modules/Connectivity:master:/OWNERS_core_networking
+
+per-file **Xfrm* = file:platform/frameworks/base:master:/services/core/java/com/android/server/vcn/OWNERS
\ No newline at end of file
diff --git a/TEST_MAPPING b/TEST_MAPPING
index 095fa7d..5e200e9 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -1,14 +1,11 @@
{
"presubmit": [
- { "name": "libnetdbpf_test" },
{ "name": "netd_integration_test" },
{ "name": "netd_unit_test" },
{ "name": "netdclient_test" },
{ "name": "netdutils_test" }
],
"postsubmit": [
- { "name": "libnetdbpf_test",
- "keywords": ["netd-device-kernel-4.9", "netd-device-kernel-4.14"]},
{ "name": "netd_integration_test",
"keywords": ["netd-device-kernel-4.9", "netd-device-kernel-4.14"]},
{ "name": "netd_unit_test",
@@ -16,5 +13,11 @@
],
"imports": [
{ "path": "packages/modules/DnsResolver" }
+ ],
+ "hwasan-presubmit": [
+ { "name": "netd_integration_test" },
+ { "name": "netd_unit_test" },
+ { "name": "netdclient_test" },
+ { "name": "netdutils_test" }
]
}
diff --git a/bpf_progs/Android.bp b/bpf_progs/Android.bp
deleted file mode 100644
index 1311ca9..0000000
--- a/bpf_progs/Android.bp
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Copyright (C) 2019 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.
-//
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_netd_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_netd_license"],
-}
-
-cc_library_headers {
- name: "netd_bpf_progs_headers",
- export_include_dirs: ["."],
-}
-
-//
-// bpf kernel programs
-//
-bpf {
- name: "clatd.o",
- srcs: ["clatd.c"],
- cflags: [
- "-Wall",
- "-Werror",
- ],
- include_dirs: [
- "system/netd/libnetdbpf/include",
- "system/netd/libnetdutils/include",
- ],
-}
-
-bpf {
- name: "netd.o",
- srcs: ["netd.c"],
- cflags: [
- "-Wall",
- "-Werror",
- ],
- include_dirs: [
- "system/netd/libnetdbpf/include",
- "system/netd/libnetdutils/include",
- ],
-}
diff --git a/bpf_progs/bpf_net_helpers.h b/bpf_progs/bpf_net_helpers.h
deleted file mode 100644
index d978f3a..0000000
--- a/bpf_progs/bpf_net_helpers.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#ifndef NETDBPF_BPF_NET_HELPERS_H
-#define NETDBPF_BPF_NET_HELPERS_H
-
-#include <linux/bpf.h>
-#include <linux/if_packet.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-// this returns 0 iff skb->sk is NULL
-static uint64_t (*bpf_get_socket_cookie)(struct __sk_buff* skb) = (void*)BPF_FUNC_get_socket_cookie;
-
-static uint32_t (*bpf_get_socket_uid)(struct __sk_buff* skb) = (void*)BPF_FUNC_get_socket_uid;
-
-static int (*bpf_skb_pull_data)(struct __sk_buff* skb, __u32 len) = (void*)BPF_FUNC_skb_pull_data;
-
-static int (*bpf_skb_load_bytes)(struct __sk_buff* skb, int off, void* to,
- int len) = (void*)BPF_FUNC_skb_load_bytes;
-
-static int (*bpf_skb_store_bytes)(struct __sk_buff* skb, __u32 offset, const void* from, __u32 len,
- __u64 flags) = (void*)BPF_FUNC_skb_store_bytes;
-
-static int64_t (*bpf_csum_diff)(__be32* from, __u32 from_size, __be32* to, __u32 to_size,
- __wsum seed) = (void*)BPF_FUNC_csum_diff;
-
-static int64_t (*bpf_csum_update)(struct __sk_buff* skb, __wsum csum) = (void*)BPF_FUNC_csum_update;
-
-static int (*bpf_skb_change_proto)(struct __sk_buff* skb, __be16 proto,
- __u64 flags) = (void*)BPF_FUNC_skb_change_proto;
-static int (*bpf_l3_csum_replace)(struct __sk_buff* skb, __u32 offset, __u64 from, __u64 to,
- __u64 flags) = (void*)BPF_FUNC_l3_csum_replace;
-static int (*bpf_l4_csum_replace)(struct __sk_buff* skb, __u32 offset, __u64 from, __u64 to,
- __u64 flags) = (void*)BPF_FUNC_l4_csum_replace;
-static int (*bpf_redirect)(__u32 ifindex, __u64 flags) = (void*)BPF_FUNC_redirect;
-static int (*bpf_redirect_map)(const struct bpf_map_def* map, __u32 key,
- __u64 flags) = (void*)BPF_FUNC_redirect_map;
-
-static int (*bpf_skb_change_head)(struct __sk_buff* skb, __u32 head_room,
- __u64 flags) = (void*)BPF_FUNC_skb_change_head;
-static int (*bpf_skb_adjust_room)(struct __sk_buff* skb, __s32 len_diff, __u32 mode,
- __u64 flags) = (void*)BPF_FUNC_skb_adjust_room;
-
-// Android only supports little endian architectures
-#define htons(x) (__builtin_constant_p(x) ? ___constant_swab16(x) : __builtin_bswap16(x))
-#define htonl(x) (__builtin_constant_p(x) ? ___constant_swab32(x) : __builtin_bswap32(x))
-#define ntohs(x) htons(x)
-#define ntohl(x) htonl(x)
-
-static inline __always_inline __unused bool is_received_skb(struct __sk_buff* skb) {
- return skb->pkt_type == PACKET_HOST || skb->pkt_type == PACKET_BROADCAST ||
- skb->pkt_type == PACKET_MULTICAST;
-}
-
-// try to make the first 'len' header bytes readable via direct packet access
-static inline __always_inline void try_make_readable(struct __sk_buff* skb, int len) {
- if (len > skb->len) len = skb->len;
- if (skb->data_end - skb->data < len) bpf_skb_pull_data(skb, len);
-}
-
-#endif // NETDBPF_BPF_NET_HELPERS_H
diff --git a/bpf_progs/clatd.c b/bpf_progs/clatd.c
deleted file mode 100644
index 31e0522..0000000
--- a/bpf_progs/clatd.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#include <linux/bpf.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/in.h>
-#include <linux/in6.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/pkt_cls.h>
-#include <linux/swab.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-// bionic kernel uapi linux/udp.h header is munged...
-#define __kernel_udphdr udphdr
-#include <linux/udp.h>
-
-#include "bpf_helpers.h"
-#include "bpf_net_helpers.h"
-#include "netdbpf/bpf_shared.h"
-
-// From kernel:include/net/ip.h
-#define IP_DF 0x4000 // Flag: "Don't Fragment"
-
-DEFINE_BPF_MAP(clat_ingress6_map, HASH, ClatIngress6Key, ClatIngress6Value, 16)
-
-static inline __always_inline int nat64(struct __sk_buff* skb, bool is_ethernet) {
- const int l2_header_size = is_ethernet ? sizeof(struct ethhdr) : 0;
- void* data = (void*)(long)skb->data;
- const void* data_end = (void*)(long)skb->data_end;
- const struct ethhdr* const eth = is_ethernet ? data : NULL; // used iff is_ethernet
- const struct ipv6hdr* const ip6 = is_ethernet ? (void*)(eth + 1) : data;
-
- // Require ethernet dst mac address to be our unicast address.
- if (is_ethernet && (skb->pkt_type != PACKET_HOST)) return TC_ACT_OK;
-
- // Must be meta-ethernet IPv6 frame
- if (skb->protocol != htons(ETH_P_IPV6)) return TC_ACT_OK;
-
- // Must have (ethernet and) ipv6 header
- if (data + l2_header_size + sizeof(*ip6) > data_end) return TC_ACT_OK;
-
- // Ethertype - if present - must be IPv6
- if (is_ethernet && (eth->h_proto != htons(ETH_P_IPV6))) return TC_ACT_OK;
-
- // IP version must be 6
- if (ip6->version != 6) return TC_ACT_OK;
-
- // Maximum IPv6 payload length that can be translated to IPv4
- if (ntohs(ip6->payload_len) > 0xFFFF - sizeof(struct iphdr)) return TC_ACT_OK;
-
- switch (ip6->nexthdr) {
- case IPPROTO_TCP: // For TCP & UDP the checksum neutrality of the chosen IPv6
- case IPPROTO_UDP: // address means there is no need to update their checksums.
- case IPPROTO_GRE: // We do not need to bother looking at GRE/ESP headers,
- case IPPROTO_ESP: // since there is never a checksum to update.
- break;
-
- default: // do not know how to handle anything else
- return TC_ACT_OK;
- }
-
- ClatIngress6Key k = {
- .iif = skb->ifindex,
- .pfx96.in6_u.u6_addr32 =
- {
- ip6->saddr.in6_u.u6_addr32[0],
- ip6->saddr.in6_u.u6_addr32[1],
- ip6->saddr.in6_u.u6_addr32[2],
- },
- .local6 = ip6->daddr,
- };
-
- ClatIngress6Value* v = bpf_clat_ingress6_map_lookup_elem(&k);
-
- if (!v) return TC_ACT_OK;
-
- struct ethhdr eth2; // used iff is_ethernet
- if (is_ethernet) {
- eth2 = *eth; // Copy over the ethernet header (src/dst mac)
- eth2.h_proto = htons(ETH_P_IP); // But replace the ethertype
- }
-
- struct iphdr ip = {
- .version = 4, // u4
- .ihl = sizeof(struct iphdr) / sizeof(__u32), // u4
- .tos = (ip6->priority << 4) + (ip6->flow_lbl[0] >> 4), // u8
- .tot_len = htons(ntohs(ip6->payload_len) + sizeof(struct iphdr)), // u16
- .id = 0, // u16
- .frag_off = htons(IP_DF), // u16
- .ttl = ip6->hop_limit, // u8
- .protocol = ip6->nexthdr, // u8
- .check = 0, // u16
- .saddr = ip6->saddr.in6_u.u6_addr32[3], // u32
- .daddr = v->local4.s_addr, // u32
- };
-
- // Calculate the IPv4 one's complement checksum of the IPv4 header.
- __wsum sum4 = 0;
- for (int i = 0; i < sizeof(ip) / sizeof(__u16); ++i) {
- sum4 += ((__u16*)&ip)[i];
- }
- // Note that sum4 is guaranteed to be non-zero by virtue of ip.version == 4
- sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse u32 into range 1 .. 0x1FFFE
- sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse any potential carry into u16
- ip.check = (__u16)~sum4; // sum4 cannot be zero, so this is never 0xFFFF
-
- // Calculate the *negative* IPv6 16-bit one's complement checksum of the IPv6 header.
- __wsum sum6 = 0;
- // We'll end up with a non-zero sum due to ip6->version == 6 (which has '0' bits)
- for (int i = 0; i < sizeof(*ip6) / sizeof(__u16); ++i) {
- sum6 += ~((__u16*)ip6)[i]; // note the bitwise negation
- }
-
- // Note that there is no L4 checksum update: we are relying on the checksum neutrality
- // of the ipv6 address chosen by netd's ClatdController.
-
- // Packet mutations begin - point of no return, but if this first modification fails
- // the packet is probably still pristine, so let clatd handle it.
- if (bpf_skb_change_proto(skb, htons(ETH_P_IP), 0)) return TC_ACT_OK;
-
- // This takes care of updating the skb->csum field for a CHECKSUM_COMPLETE packet.
- //
- // In such a case, skb->csum is a 16-bit one's complement sum of the entire payload,
- // thus we need to subtract out the ipv6 header's sum, and add in the ipv4 header's sum.
- // However, by construction of ip.check above the checksum of an ipv4 header is zero.
- // Thus we only need to subtract the ipv6 header's sum, which is the same as adding
- // in the sum of the bitwise negation of the ipv6 header.
- //
- // bpf_csum_update() always succeeds if the skb is CHECKSUM_COMPLETE and returns an error
- // (-ENOTSUPP) if it isn't. So we just ignore the return code.
- //
- // if (skb->ip_summed == CHECKSUM_COMPLETE)
- // return (skb->csum = csum_add(skb->csum, csum));
- // else
- // return -ENOTSUPP;
- bpf_csum_update(skb, sum6);
-
- // bpf_skb_change_proto() invalidates all pointers - reload them.
- data = (void*)(long)skb->data;
- data_end = (void*)(long)skb->data_end;
-
- // I cannot think of any valid way for this error condition to trigger, however I do
- // believe the explicit check is required to keep the in kernel ebpf verifier happy.
- if (data + l2_header_size + sizeof(struct iphdr) > data_end) return TC_ACT_SHOT;
-
- if (is_ethernet) {
- struct ethhdr* new_eth = data;
-
- // Copy over the updated ethernet header
- *new_eth = eth2;
-
- // Copy over the new ipv4 header.
- *(struct iphdr*)(new_eth + 1) = ip;
- } else {
- // Copy over the new ipv4 header without an ethernet header.
- *(struct iphdr*)data = ip;
- }
-
- // Redirect, possibly back to same interface, so tcpdump sees packet twice.
- if (v->oif) return bpf_redirect(v->oif, BPF_F_INGRESS);
-
- // Just let it through, tcpdump will not see IPv4 packet.
- return TC_ACT_OK;
-}
-
-DEFINE_BPF_PROG("schedcls/ingress6/clat_ether", AID_ROOT, AID_ROOT, sched_cls_ingress6_clat_ether)
-(struct __sk_buff* skb) {
- return nat64(skb, true);
-}
-
-DEFINE_BPF_PROG("schedcls/ingress6/clat_rawip", AID_ROOT, AID_ROOT, sched_cls_ingress6_clat_rawip)
-(struct __sk_buff* skb) {
- return nat64(skb, false);
-}
-
-DEFINE_BPF_MAP(clat_egress4_map, HASH, ClatEgress4Key, ClatEgress4Value, 16)
-
-DEFINE_BPF_PROG("schedcls/egress4/clat_ether", AID_ROOT, AID_ROOT, sched_cls_egress4_clat_ether)
-(struct __sk_buff* skb) {
- return TC_ACT_OK;
-}
-
-DEFINE_BPF_PROG("schedcls/egress4/clat_rawip", AID_ROOT, AID_ROOT, sched_cls_egress4_clat_rawip)
-(struct __sk_buff* skb) {
- void* data = (void*)(long)skb->data;
- const void* data_end = (void*)(long)skb->data_end;
- const struct iphdr* const ip4 = data;
-
- // Must be meta-ethernet IPv4 frame
- if (skb->protocol != htons(ETH_P_IP)) return TC_ACT_OK;
-
- // Must have ipv4 header
- if (data + sizeof(*ip4) > data_end) return TC_ACT_OK;
-
- // IP version must be 4
- if (ip4->version != 4) return TC_ACT_OK;
-
- // We cannot handle IP options, just standard 20 byte == 5 dword minimal IPv4 header
- if (ip4->ihl != 5) return TC_ACT_OK;
-
- // Calculate the IPv4 one's complement checksum of the IPv4 header.
- __wsum sum4 = 0;
- for (int i = 0; i < sizeof(*ip4) / sizeof(__u16); ++i) {
- sum4 += ((__u16*)ip4)[i];
- }
- // Note that sum4 is guaranteed to be non-zero by virtue of ip4->version == 4
- sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse u32 into range 1 .. 0x1FFFE
- sum4 = (sum4 & 0xFFFF) + (sum4 >> 16); // collapse any potential carry into u16
- // for a correct checksum we should get *a* zero, but sum4 must be positive, ie 0xFFFF
- if (sum4 != 0xFFFF) return TC_ACT_OK;
-
- // Minimum IPv4 total length is the size of the header
- if (ntohs(ip4->tot_len) < sizeof(*ip4)) return TC_ACT_OK;
-
- // We are incapable of dealing with IPv4 fragments
- if (ip4->frag_off & ~htons(IP_DF)) return TC_ACT_OK;
-
- switch (ip4->protocol) {
- case IPPROTO_TCP: // For TCP & UDP the checksum neutrality of the chosen IPv6
- case IPPROTO_GRE: // address means there is no need to update their checksums.
- case IPPROTO_ESP: // We do not need to bother looking at GRE/ESP headers,
- break; // since there is never a checksum to update.
-
- case IPPROTO_UDP: // See above comment, but must also have UDP header...
- if (data + sizeof(*ip4) + sizeof(struct udphdr) > data_end) return TC_ACT_OK;
- const struct udphdr* uh = (const struct udphdr*)(ip4 + 1);
- // If IPv4/UDP checksum is 0 then fallback to clatd so it can calculate the
- // checksum. Otherwise the network or more likely the NAT64 gateway might
- // drop the packet because in most cases IPv6/UDP packets with a zero checksum
- // are invalid. See RFC 6935. TODO: calculate checksum via bpf_csum_diff()
- if (!uh->check) return TC_ACT_OK;
- break;
-
- default: // do not know how to handle anything else
- return TC_ACT_OK;
- }
-
- ClatEgress4Key k = {
- .iif = skb->ifindex,
- .local4.s_addr = ip4->saddr,
- };
-
- ClatEgress4Value* v = bpf_clat_egress4_map_lookup_elem(&k);
-
- if (!v) return TC_ACT_OK;
-
- // Translating without redirecting doesn't make sense.
- if (!v->oif) return TC_ACT_OK;
-
- // This implementation is currently limited to rawip.
- if (v->oifIsEthernet) return TC_ACT_OK;
-
- struct ipv6hdr ip6 = {
- .version = 6, // __u8:4
- .priority = ip4->tos >> 4, // __u8:4
- .flow_lbl = {(ip4->tos & 0xF) << 4, 0, 0}, // __u8[3]
- .payload_len = htons(ntohs(ip4->tot_len) - 20), // __be16
- .nexthdr = ip4->protocol, // __u8
- .hop_limit = ip4->ttl, // __u8
- .saddr = v->local6, // struct in6_addr
- .daddr = v->pfx96, // struct in6_addr
- };
- ip6.daddr.in6_u.u6_addr32[3] = ip4->daddr;
-
- // Calculate the IPv6 16-bit one's complement checksum of the IPv6 header.
- __wsum sum6 = 0;
- // We'll end up with a non-zero sum due to ip6.version == 6
- for (int i = 0; i < sizeof(ip6) / sizeof(__u16); ++i) {
- sum6 += ((__u16*)&ip6)[i];
- }
-
- // Note that there is no L4 checksum update: we are relying on the checksum neutrality
- // of the ipv6 address chosen by netd's ClatdController.
-
- // Packet mutations begin - point of no return, but if this first modification fails
- // the packet is probably still pristine, so let clatd handle it.
- if (bpf_skb_change_proto(skb, htons(ETH_P_IPV6), 0)) return TC_ACT_OK;
-
- // This takes care of updating the skb->csum field for a CHECKSUM_COMPLETE packet.
- //
- // In such a case, skb->csum is a 16-bit one's complement sum of the entire payload,
- // thus we need to subtract out the ipv4 header's sum, and add in the ipv6 header's sum.
- // However, we've already verified the ipv4 checksum is correct and thus 0.
- // Thus we only need to add the ipv6 header's sum.
- //
- // bpf_csum_update() always succeeds if the skb is CHECKSUM_COMPLETE and returns an error
- // (-ENOTSUPP) if it isn't. So we just ignore the return code (see above for more details).
- bpf_csum_update(skb, sum6);
-
- // bpf_skb_change_proto() invalidates all pointers - reload them.
- data = (void*)(long)skb->data;
- data_end = (void*)(long)skb->data_end;
-
- // I cannot think of any valid way for this error condition to trigger, however I do
- // believe the explicit check is required to keep the in kernel ebpf verifier happy.
- if (data + sizeof(ip6) > data_end) return TC_ACT_SHOT;
-
- // Copy over the new ipv6 header without an ethernet header.
- *(struct ipv6hdr*)data = ip6;
-
- // Redirect to non v4-* interface. Tcpdump only sees packet after this redirect.
- return bpf_redirect(v->oif, 0 /* this is effectively BPF_F_EGRESS */);
-}
-
-LICENSE("Apache 2.0");
-CRITICAL("netd");
diff --git a/bpf_progs/netd.c b/bpf_progs/netd.c
deleted file mode 100644
index e9e1477..0000000
--- a/bpf_progs/netd.c
+++ /dev/null
@@ -1,370 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include <bpf_helpers.h>
-#include <linux/bpf.h>
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/if_packet.h>
-#include <linux/in.h>
-#include <linux/in6.h>
-#include <linux/ip.h>
-#include <linux/ipv6.h>
-#include <linux/tcp.h>
-#include <stdbool.h>
-#include <stdint.h>
-#include "bpf_net_helpers.h"
-#include "netdbpf/bpf_shared.h"
-
-// This is defined for cgroup bpf filter only.
-#define BPF_DROP_UNLESS_DNS 2
-#define BPF_PASS 1
-#define BPF_DROP 0
-
-// This is used for xt_bpf program only.
-#define BPF_NOMATCH 0
-#define BPF_MATCH 1
-
-#define BPF_EGRESS 0
-#define BPF_INGRESS 1
-
-#define IP_PROTO_OFF offsetof(struct iphdr, protocol)
-#define IPV6_PROTO_OFF offsetof(struct ipv6hdr, nexthdr)
-#define IPPROTO_IHL_OFF 0
-#define TCP_FLAG_OFF 13
-#define RST_OFFSET 2
-
-DEFINE_BPF_MAP_GRO(cookie_tag_map, HASH, uint64_t, UidTagValue, COOKIE_UID_MAP_SIZE,
- AID_NET_BW_ACCT)
-DEFINE_BPF_MAP_GRO(uid_counterset_map, HASH, uint32_t, uint8_t, UID_COUNTERSET_MAP_SIZE,
- AID_NET_BW_ACCT)
-DEFINE_BPF_MAP_GRO(app_uid_stats_map, HASH, uint32_t, StatsValue, APP_STATS_MAP_SIZE,
- AID_NET_BW_STATS)
-DEFINE_BPF_MAP_GRW(stats_map_A, HASH, StatsKey, StatsValue, STATS_MAP_SIZE, AID_NET_BW_STATS)
-DEFINE_BPF_MAP_GRW(stats_map_B, HASH, StatsKey, StatsValue, STATS_MAP_SIZE, AID_NET_BW_STATS)
-DEFINE_BPF_MAP_GRO(iface_stats_map, HASH, uint32_t, StatsValue, IFACE_STATS_MAP_SIZE,
- AID_NET_BW_STATS)
-DEFINE_BPF_MAP_GRO(configuration_map, HASH, uint32_t, uint8_t, CONFIGURATION_MAP_SIZE,
- AID_NET_BW_STATS)
-DEFINE_BPF_MAP(uid_owner_map, HASH, uint32_t, UidOwnerValue, UID_OWNER_MAP_SIZE)
-
-/* never actually used from ebpf */
-DEFINE_BPF_MAP_GRO(iface_index_name_map, HASH, uint32_t, IfaceValue, IFACE_INDEX_NAME_MAP_SIZE,
- AID_NET_BW_STATS)
-
-static __always_inline int is_system_uid(uint32_t uid) {
- return (uid <= MAX_SYSTEM_UID) && (uid >= MIN_SYSTEM_UID);
-}
-
-/*
- * Note: this blindly assumes an MTU of 1500, and that packets > MTU are always TCP,
- * and that TCP is using the Linux default settings with TCP timestamp option enabled
- * which uses 12 TCP option bytes per frame.
- *
- * These are not unreasonable assumptions:
- *
- * The internet does not really support MTUs greater than 1500, so most TCP traffic will
- * be at that MTU, or slightly below it (worst case our upwards adjustment is too small).
- *
- * The chance our traffic isn't IP at all is basically zero, so the IP overhead correction
- * is bound to be needed.
- *
- * Furthermore, the likelyhood that we're having to deal with GSO (ie. > MTU) packets that
- * are not IP/TCP is pretty small (few other things are supported by Linux) and worse case
- * our extra overhead will be slightly off, but probably still better than assuming none.
- *
- * Most servers are also Linux and thus support/default to using TCP timestamp option
- * (and indeed TCP timestamp option comes from RFC 1323 titled "TCP Extensions for High
- * Performance" which also defined TCP window scaling and are thus absolutely ancient...).
- *
- * All together this should be more correct than if we simply ignored GSO frames
- * (ie. counted them as single packets with no extra overhead)
- *
- * Especially since the number of packets is important for any future clat offload correction.
- * (which adjusts upward by 20 bytes per packet to account for ipv4 -> ipv6 header conversion)
- */
-#define DEFINE_UPDATE_STATS(the_stats_map, TypeOfKey) \
- static __always_inline inline void update_##the_stats_map(struct __sk_buff* skb, \
- int direction, TypeOfKey* key) { \
- StatsValue* value = bpf_##the_stats_map##_lookup_elem(key); \
- if (!value) { \
- StatsValue newValue = {}; \
- bpf_##the_stats_map##_update_elem(key, &newValue, BPF_NOEXIST); \
- value = bpf_##the_stats_map##_lookup_elem(key); \
- } \
- if (value) { \
- const int mtu = 1500; \
- uint64_t packets = 1; \
- uint64_t bytes = skb->len; \
- if (bytes > mtu) { \
- bool is_ipv6 = (skb->protocol == htons(ETH_P_IPV6)); \
- int ip_overhead = (is_ipv6 ? sizeof(struct ipv6hdr) : sizeof(struct iphdr)); \
- int tcp_overhead = ip_overhead + sizeof(struct tcphdr) + 12; \
- int mss = mtu - tcp_overhead; \
- uint64_t payload = bytes - tcp_overhead; \
- packets = (payload + mss - 1) / mss; \
- bytes = tcp_overhead * packets + payload; \
- } \
- if (direction == BPF_EGRESS) { \
- __sync_fetch_and_add(&value->txPackets, packets); \
- __sync_fetch_and_add(&value->txBytes, bytes); \
- } else if (direction == BPF_INGRESS) { \
- __sync_fetch_and_add(&value->rxPackets, packets); \
- __sync_fetch_and_add(&value->rxBytes, bytes); \
- } \
- } \
- }
-
-DEFINE_UPDATE_STATS(app_uid_stats_map, uint32_t)
-DEFINE_UPDATE_STATS(iface_stats_map, uint32_t)
-DEFINE_UPDATE_STATS(stats_map_A, StatsKey)
-DEFINE_UPDATE_STATS(stats_map_B, StatsKey)
-
-static inline bool skip_owner_match(struct __sk_buff* skb) {
- int offset = -1;
- int ret = 0;
- if (skb->protocol == htons(ETH_P_IP)) {
- offset = IP_PROTO_OFF;
- uint8_t proto, ihl;
- uint8_t flag;
- ret = bpf_skb_load_bytes(skb, offset, &proto, 1);
- if (!ret) {
- if (proto == IPPROTO_ESP) {
- return true;
- } else if (proto == IPPROTO_TCP) {
- ret = bpf_skb_load_bytes(skb, IPPROTO_IHL_OFF, &ihl, 1);
- ihl = ihl & 0x0F;
- ret = bpf_skb_load_bytes(skb, ihl * 4 + TCP_FLAG_OFF, &flag, 1);
- if (ret == 0 && (flag >> RST_OFFSET & 1)) {
- return true;
- }
- }
- }
- } else if (skb->protocol == htons(ETH_P_IPV6)) {
- offset = IPV6_PROTO_OFF;
- uint8_t proto;
- ret = bpf_skb_load_bytes(skb, offset, &proto, 1);
- if (!ret) {
- if (proto == IPPROTO_ESP) {
- return true;
- } else if (proto == IPPROTO_TCP) {
- uint8_t flag;
- ret = bpf_skb_load_bytes(skb, sizeof(struct ipv6hdr) + TCP_FLAG_OFF, &flag, 1);
- if (ret == 0 && (flag >> RST_OFFSET & 1)) {
- return true;
- }
- }
- }
- }
- return false;
-}
-
-static __always_inline BpfConfig getConfig(uint32_t configKey) {
- uint32_t mapSettingKey = configKey;
- BpfConfig* config = bpf_configuration_map_lookup_elem(&mapSettingKey);
- if (!config) {
- // Couldn't read configuration entry. Assume everything is disabled.
- return DEFAULT_CONFIG;
- }
- return *config;
-}
-
-static inline int bpf_owner_match(struct __sk_buff* skb, uint32_t uid, int direction) {
- if (skip_owner_match(skb)) return BPF_PASS;
-
- if (is_system_uid(uid)) return BPF_PASS;
-
- BpfConfig enabledRules = getConfig(UID_RULES_CONFIGURATION_KEY);
-
- UidOwnerValue* uidEntry = bpf_uid_owner_map_lookup_elem(&uid);
- uint8_t uidRules = uidEntry ? uidEntry->rule : 0;
- uint32_t allowed_iif = uidEntry ? uidEntry->iif : 0;
-
- if (enabledRules) {
- if ((enabledRules & DOZABLE_MATCH) && !(uidRules & DOZABLE_MATCH)) {
- return BPF_DROP;
- }
- if ((enabledRules & STANDBY_MATCH) && (uidRules & STANDBY_MATCH)) {
- return BPF_DROP;
- }
- if ((enabledRules & POWERSAVE_MATCH) && !(uidRules & POWERSAVE_MATCH)) {
- return BPF_DROP;
- }
- if ((enabledRules & RESTRICTED_MATCH) && !(uidRules & RESTRICTED_MATCH)) {
- return BPF_DROP;
- }
- }
- if (direction == BPF_INGRESS && (uidRules & IIF_MATCH)) {
- // Drops packets not coming from lo nor the allowlisted interface
- if (allowed_iif && skb->ifindex != 1 && skb->ifindex != allowed_iif) {
- return BPF_DROP_UNLESS_DNS;
- }
- }
- return BPF_PASS;
-}
-
-static __always_inline inline void update_stats_with_config(struct __sk_buff* skb, int direction,
- StatsKey* key, uint8_t selectedMap) {
- if (selectedMap == SELECT_MAP_A) {
- update_stats_map_A(skb, direction, key);
- } else if (selectedMap == SELECT_MAP_B) {
- update_stats_map_B(skb, direction, key);
- }
-}
-
-static __always_inline inline int bpf_traffic_account(struct __sk_buff* skb, int direction) {
- uint32_t sock_uid = bpf_get_socket_uid(skb);
- // Always allow and never count clat traffic. Only the IPv4 traffic on the stacked
- // interface is accounted for and subject to usage restrictions.
- if (sock_uid == AID_CLAT) {
- return BPF_PASS;
- }
-
- int match = bpf_owner_match(skb, sock_uid, direction);
- if ((direction == BPF_EGRESS) && (match == BPF_DROP)) {
- // If an outbound packet is going to be dropped, we do not count that
- // traffic.
- return match;
- }
-
- uint64_t cookie = bpf_get_socket_cookie(skb);
- UidTagValue* utag = bpf_cookie_tag_map_lookup_elem(&cookie);
- uint32_t uid, tag;
- if (utag) {
- uid = utag->uid;
- tag = utag->tag;
- } else {
- uid = sock_uid;
- tag = 0;
- }
-
-// Workaround for secureVPN with VpnIsolation enabled, refer to b/159994981 for details.
-// Keep TAG_SYSTEM_DNS in sync with DnsResolver/include/netd_resolv/resolv.h
-// and TrafficStatsConstants.java
-#define TAG_SYSTEM_DNS 0xFFFFFF82
- if (tag == TAG_SYSTEM_DNS && uid == AID_DNS) {
- uid = sock_uid;
- if (match == BPF_DROP_UNLESS_DNS) match = BPF_PASS;
- } else {
- if (match == BPF_DROP_UNLESS_DNS) match = BPF_DROP;
- }
-
- StatsKey key = {.uid = uid, .tag = tag, .counterSet = 0, .ifaceIndex = skb->ifindex};
-
- uint8_t* counterSet = bpf_uid_counterset_map_lookup_elem(&uid);
- if (counterSet) key.counterSet = (uint32_t)*counterSet;
-
- uint32_t mapSettingKey = CURRENT_STATS_MAP_CONFIGURATION_KEY;
- uint8_t* selectedMap = bpf_configuration_map_lookup_elem(&mapSettingKey);
- if (!selectedMap) {
- return match;
- }
-
- if (key.tag) {
- update_stats_with_config(skb, direction, &key, *selectedMap);
- key.tag = 0;
- }
-
- update_stats_with_config(skb, direction, &key, *selectedMap);
- update_app_uid_stats_map(skb, direction, &uid);
- return match;
-}
-
-DEFINE_BPF_PROG("cgroupskb/ingress/stats", AID_ROOT, AID_ROOT, bpf_cgroup_ingress)
-(struct __sk_buff* skb) {
- return bpf_traffic_account(skb, BPF_INGRESS);
-}
-
-DEFINE_BPF_PROG("cgroupskb/egress/stats", AID_ROOT, AID_ROOT, bpf_cgroup_egress)
-(struct __sk_buff* skb) {
- return bpf_traffic_account(skb, BPF_EGRESS);
-}
-
-DEFINE_BPF_PROG("skfilter/egress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_egress_prog)
-(struct __sk_buff* skb) {
- // Clat daemon does not generate new traffic, all its traffic is accounted for already
- // on the v4-* interfaces (except for the 20 (or 28) extra bytes of IPv6 vs IPv4 overhead,
- // but that can be corrected for later when merging v4-foo stats into interface foo's).
- uint32_t sock_uid = bpf_get_socket_uid(skb);
- if (sock_uid == AID_CLAT) return BPF_NOMATCH;
-
- uint32_t key = skb->ifindex;
- update_iface_stats_map(skb, BPF_EGRESS, &key);
- return BPF_MATCH;
-}
-
-DEFINE_BPF_PROG("skfilter/ingress/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_ingress_prog)
-(struct __sk_buff* skb) {
- // Clat daemon traffic is not accounted by virtue of iptables raw prerouting drop rule
- // (in clat_raw_PREROUTING chain), which triggers before this (in bw_raw_PREROUTING chain).
- // It will be accounted for on the v4-* clat interface instead.
- // Keep that in mind when moving this out of iptables xt_bpf and into tc ingress (or xdp).
-
- uint32_t key = skb->ifindex;
- update_iface_stats_map(skb, BPF_INGRESS, &key);
- return BPF_MATCH;
-}
-
-DEFINE_BPF_PROG("skfilter/allowlist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_allowlist_prog)
-(struct __sk_buff* skb) {
- uint32_t sock_uid = bpf_get_socket_uid(skb);
- if (is_system_uid(sock_uid)) return BPF_MATCH;
-
- // 65534 is the overflow 'nobody' uid, usually this being returned means
- // that skb->sk is NULL during RX (early decap socket lookup failure),
- // which commonly happens for incoming packets to an unconnected udp socket.
- // Additionally bpf_get_socket_cookie() returns 0 if skb->sk is NULL
- if ((sock_uid == 65534) && !bpf_get_socket_cookie(skb) && is_received_skb(skb))
- return BPF_MATCH;
-
- UidOwnerValue* allowlistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
- if (allowlistMatch) return allowlistMatch->rule & HAPPY_BOX_MATCH ? BPF_MATCH : BPF_NOMATCH;
- return BPF_NOMATCH;
-}
-
-DEFINE_BPF_PROG("skfilter/denylist/xtbpf", AID_ROOT, AID_NET_ADMIN, xt_bpf_denylist_prog)
-(struct __sk_buff* skb) {
- uint32_t sock_uid = bpf_get_socket_uid(skb);
- UidOwnerValue* denylistMatch = bpf_uid_owner_map_lookup_elem(&sock_uid);
- if (denylistMatch) return denylistMatch->rule & PENALTY_BOX_MATCH ? BPF_MATCH : BPF_NOMATCH;
- return BPF_NOMATCH;
-}
-
-DEFINE_BPF_MAP(uid_permission_map, HASH, uint32_t, uint8_t, UID_OWNER_MAP_SIZE)
-
-DEFINE_BPF_PROG_KVER("cgroupsock/inet/create", AID_ROOT, AID_ROOT, inet_socket_create,
- KVER(4, 14, 0))
-(struct bpf_sock* sk) {
- uint64_t gid_uid = bpf_get_current_uid_gid();
- /*
- * A given app is guaranteed to have the same app ID in all the profiles in
- * which it is installed, and install permission is granted to app for all
- * user at install time so we only check the appId part of a request uid at
- * run time. See UserHandle#isSameApp for detail.
- */
- uint32_t appId = (gid_uid & 0xffffffff) % PER_USER_RANGE;
- uint8_t* permissions = bpf_uid_permission_map_lookup_elem(&appId);
- if (!permissions) {
- // UID not in map. Default to just INTERNET permission.
- return 1;
- }
-
- // A return value of 1 means allow, everything else means deny.
- return (*permissions & BPF_PERMISSION_INTERNET) == BPF_PERMISSION_INTERNET;
-}
-
-LICENSE("Apache 2.0");
-CRITICAL("netd");
diff --git a/client/Android.bp b/client/Android.bp
index b8eb56c..22cb5c1 100644
--- a/client/Android.bp
+++ b/client/Android.bp
@@ -34,7 +34,7 @@
],
export_header_lib_headers: ["libnetd_client_headers"],
include_dirs: [
- "system/netd/libnetdutils/include",
+ "frameworks/libs/net/common/netd/libnetdutils/include",
],
defaults: ["netd_defaults"],
sanitize: {
@@ -42,7 +42,6 @@
},
apex_available: [
"//apex_available:platform",
- "com.android.tethering",
],
}
diff --git a/client/FwmarkClient.cpp b/client/FwmarkClient.cpp
index 592fe31..c56e767 100644
--- a/client/FwmarkClient.cpp
+++ b/client/FwmarkClient.cpp
@@ -37,9 +37,7 @@
const sockaddr_un FWMARK_SERVER_PATH = {AF_UNIX, "/dev/socket/fwmarkd"};
bool commandHasFd(int cmdId) {
- return (cmdId != FwmarkCommand::QUERY_USER_ACCESS) &&
- (cmdId != FwmarkCommand::SET_COUNTERSET) &&
- (cmdId != FwmarkCommand::DELETE_TAGDATA);
+ return (cmdId != FwmarkCommand::QUERY_USER_ACCESS);
}
} // namespace
diff --git a/client/NetdClient.cpp b/client/NetdClient.cpp
index 0105a04..2a09a44 100644
--- a/client/NetdClient.cpp
+++ b/client/NetdClient.cpp
@@ -516,14 +516,12 @@
return FwmarkClient().send(&command, socketFd, nullptr);
}
-extern "C" int setCounterSet(uint32_t counterSet, uid_t uid) {
- FwmarkCommand command = {FwmarkCommand::SET_COUNTERSET, 0, uid, counterSet};
- return FwmarkClient().send(&command, -1, nullptr);
+extern "C" int setCounterSet(uint32_t, uid_t) {
+ return -ENOTSUP;
}
-extern "C" int deleteTagData(uint32_t tag, uid_t uid) {
- FwmarkCommand command = {FwmarkCommand::DELETE_TAGDATA, 0, uid, tag};
- return FwmarkClient().send(&command, -1, nullptr);
+extern "C" int deleteTagData(uint32_t, uid_t) {
+ return -ENOTSUP;
}
extern "C" int resNetworkQuery(unsigned netId, const char* dname, int ns_class, int ns_type,
diff --git a/include/FwmarkCommand.h b/include/FwmarkCommand.h
index 83e62d3..c215ed4 100644
--- a/include/FwmarkCommand.h
+++ b/include/FwmarkCommand.h
@@ -64,11 +64,8 @@
ON_CONNECT_COMPLETE,
TAG_SOCKET,
UNTAG_SOCKET,
- // TODO: use binder to pass the following two request in future after we
- // completely get rid of qtaguid module, since these are privileged
- // command.
- SET_COUNTERSET,
- DELETE_TAGDATA,
+ _UNUSED_SET_COUNTERSET, // unsupported, do not use this command
+ _UNUSED_DELETE_TAGDATA, // unsupported, do not use this command
ON_SENDMMSG,
ON_SENDMSG,
ON_SENDTO,
diff --git a/include/NetdClient.h b/include/NetdClient.h
index cc835ed..9e722f4 100644
--- a/include/NetdClient.h
+++ b/include/NetdClient.h
@@ -46,10 +46,6 @@
int untagSocket(int socketFd);
-int setCounterSet(uint32_t counterSet, uid_t uid);
-
-int deleteTagData(uint32_t tag, uid_t uid);
-
int resNetworkQuery(unsigned netId, const char* dname, int ns_class, int ns_type, uint32_t flags);
int resNetworkResult(int query_fd, int* rcode, uint8_t* answer, size_t anslen);
diff --git a/include/binder_utils/BinderUtil.h b/include/binder_utils/BinderUtil.h
index 469fa68..92754c8 100644
--- a/include/binder_utils/BinderUtil.h
+++ b/include/binder_utils/BinderUtil.h
@@ -16,8 +16,15 @@
#pragma once
+#include "NetdPermissions.h"
+
+#include <android-base/stringprintf.h>
#include <android-base/strings.h>
+#include <binder/IPCThreadState.h>
+#include <binder/IServiceManager.h>
+#include <binder/Status.h>
#include <fmt/format.h>
+#include <private/android_filesystem_config.h>
#ifdef ANDROID_BINDER_STATUS_H
#define IS_BINDER_OK(__ex__) (__ex__ == ::android::binder::Status::EX_NONE)
@@ -39,7 +46,7 @@
#endif
-std::string exceptionToString(int32_t exception) {
+inline std::string exceptionToString(int32_t exception) {
switch (exception) {
EXCEPTION_TO_STRING(EX_SECURITY, "SecurityException")
EXCEPTION_TO_STRING(EX_BAD_PARCELABLE, "BadParcelableException")
@@ -100,3 +107,54 @@
// escape newline characters to avoid multiline log entries
logFn(::android::base::StringReplace(output, "\n", "\\n", true));
}
+
+// The input permissions should be equivalent that this function would return ok if any of them is
+// granted.
+inline android::binder::Status checkAnyPermission(const std::vector<const char*>& permissions) {
+ pid_t pid = android::IPCThreadState::self()->getCallingPid();
+ uid_t uid = android::IPCThreadState::self()->getCallingUid();
+
+ // TODO: Do the pure permission check in this function. Have another method
+ // (e.g. checkNetworkStackPermission) to wrap AID_SYSTEM and
+ // AID_NETWORK_STACK uid check.
+ // If the caller is the system UID, don't check permissions.
+ // Otherwise, if the system server's binder thread pool is full, and all the threads are
+ // blocked on a thread that's waiting for us to complete, we deadlock. http://b/69389492
+ //
+ // From a security perspective, there is currently no difference, because:
+ // 1. The system server has the NETWORK_STACK permission, which grants access to all the
+ // IPCs in this file.
+ // 2. AID_SYSTEM always has all permissions. See ActivityManager#checkComponentPermission.
+ if (uid == AID_SYSTEM) {
+ return android::binder::Status::ok();
+ }
+ // AID_NETWORK_STACK own MAINLINE_NETWORK_STACK permission, don't IPC to system server to check
+ // MAINLINE_NETWORK_STACK permission. Cross-process(netd, networkstack and system server)
+ // deadlock: http://b/149766727
+ if (uid == AID_NETWORK_STACK) {
+ for (const char* permission : permissions) {
+ if (std::strcmp(permission, PERM_MAINLINE_NETWORK_STACK) == 0) {
+ return android::binder::Status::ok();
+ }
+ }
+ }
+
+ for (const char* permission : permissions) {
+ if (checkPermission(android::String16(permission), pid, uid)) {
+ return android::binder::Status::ok();
+ }
+ }
+
+ auto err = android::base::StringPrintf(
+ "UID %d / PID %d does not have any of the following permissions: %s", uid, pid,
+ android::base::Join(permissions, ',').c_str());
+ return android::binder::Status::fromExceptionCode(android::binder::Status::EX_SECURITY,
+ err.c_str());
+}
+
+inline android::binder::Status statusFromErrcode(int ret) {
+ if (ret) {
+ return android::binder::Status::fromServiceSpecificError(-ret, strerror(-ret));
+ }
+ return android::binder::Status::ok();
+}
diff --git a/libnetdbpf/Android.bp b/libnetdbpf/Android.bp
deleted file mode 100644
index 7c0207c..0000000
--- a/libnetdbpf/Android.bp
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright (C) 2017 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.
-//
-
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_netd_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_netd_license"],
-}
-
-cc_library {
- name: "libnetdbpf",
- vendor_available: false,
- host_supported: false,
- srcs: [
- "BpfNetworkStats.cpp"
- ],
- shared_libs: [
- "libbase",
- "libbpf_android",
- "liblog",
- "libnetdutils",
- ],
- export_include_dirs: ["include"],
- defaults: ["netd_defaults"],
- sanitize: {
- cfi: true,
- },
-}
-
-cc_test {
- name: "libnetdbpf_test",
- test_suites: ["device-tests"],
- require_root: true,
- srcs: [
- "BpfNetworkStatsTest.cpp",
- ],
- defaults: ["netd_defaults"],
- static_libs: ["libgmock"],
- shared_libs: [
- "libbase",
- "libbpf_android",
- "liblog",
- "libnetdbpf",
- "libnetdutils",
- "libutils",
- ],
-}
diff --git a/libnetdbpf/BpfNetworkStats.cpp b/libnetdbpf/BpfNetworkStats.cpp
deleted file mode 100644
index a77f6f9..0000000
--- a/libnetdbpf/BpfNetworkStats.cpp
+++ /dev/null
@@ -1,350 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <inttypes.h>
-#include <net/if.h>
-#include <string.h>
-#include <unordered_set>
-
-#include <utils/Log.h>
-#include <utils/misc.h>
-
-#include "android-base/file.h"
-#include "android-base/strings.h"
-#include "android-base/unique_fd.h"
-#include "bpf/BpfMap.h"
-#include "netdbpf/BpfNetworkStats.h"
-#include "netdbpf/bpf_shared.h"
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-
-#define LOG_TAG "BpfNetworkStats"
-
-namespace android {
-namespace bpf {
-
-using base::Result;
-
-// The target map for stats reading should be the inactive map, which is oppsite
-// from the config value.
-static constexpr char const* STATS_MAP_PATH[] = {STATS_MAP_B_PATH, STATS_MAP_A_PATH};
-
-int bpfGetUidStatsInternal(uid_t uid, Stats* stats,
- const BpfMap<uint32_t, StatsValue>& appUidStatsMap) {
- auto statsEntry = appUidStatsMap.readValue(uid);
- if (statsEntry.ok()) {
- stats->rxPackets = statsEntry.value().rxPackets;
- stats->txPackets = statsEntry.value().txPackets;
- stats->rxBytes = statsEntry.value().rxBytes;
- stats->txBytes = statsEntry.value().txBytes;
- }
- return (statsEntry.ok() || statsEntry.error().code() == ENOENT) ? 0
- : -statsEntry.error().code();
-}
-
-int bpfGetUidStats(uid_t uid, Stats* stats) {
- BpfMapRO<uint32_t, StatsValue> appUidStatsMap(APP_UID_STATS_MAP_PATH);
-
- if (!appUidStatsMap.isValid()) {
- int ret = -errno;
- ALOGE("Opening appUidStatsMap(%s) failed: %s", APP_UID_STATS_MAP_PATH, strerror(errno));
- return ret;
- }
- return bpfGetUidStatsInternal(uid, stats, appUidStatsMap);
-}
-
-int bpfGetIfaceStatsInternal(const char* iface, Stats* stats,
- const BpfMap<uint32_t, StatsValue>& ifaceStatsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceNameMap) {
- int64_t unknownIfaceBytesTotal = 0;
- stats->tcpRxPackets = -1;
- stats->tcpTxPackets = -1;
- const auto processIfaceStats =
- [iface, stats, &ifaceNameMap, &unknownIfaceBytesTotal](
- const uint32_t& key,
- const BpfMap<uint32_t, StatsValue>& ifaceStatsMap) -> Result<void> {
- char ifname[IFNAMSIZ];
- if (getIfaceNameFromMap(ifaceNameMap, ifaceStatsMap, key, ifname, key,
- &unknownIfaceBytesTotal)) {
- return Result<void>();
- }
- if (!iface || !strcmp(iface, ifname)) {
- Result<StatsValue> statsEntry = ifaceStatsMap.readValue(key);
- if (!statsEntry.ok()) {
- return statsEntry.error();
- }
- stats->rxPackets += statsEntry.value().rxPackets;
- stats->txPackets += statsEntry.value().txPackets;
- stats->rxBytes += statsEntry.value().rxBytes;
- stats->txBytes += statsEntry.value().txBytes;
- }
- return Result<void>();
- };
- auto res = ifaceStatsMap.iterate(processIfaceStats);
- return res.ok() ? 0 : -res.error().code();
-}
-
-int bpfGetIfaceStats(const char* iface, Stats* stats) {
- BpfMapRO<uint32_t, StatsValue> ifaceStatsMap(IFACE_STATS_MAP_PATH);
- int ret;
- if (!ifaceStatsMap.isValid()) {
- ret = -errno;
- ALOGE("get ifaceStats map fd failed: %s", strerror(errno));
- return ret;
- }
- BpfMapRO<uint32_t, IfaceValue> ifaceIndexNameMap(IFACE_INDEX_NAME_MAP_PATH);
- if (!ifaceIndexNameMap.isValid()) {
- ret = -errno;
- ALOGE("get ifaceIndexName map fd failed: %s", strerror(errno));
- return ret;
- }
- return bpfGetIfaceStatsInternal(iface, stats, ifaceStatsMap, ifaceIndexNameMap);
-}
-
-stats_line populateStatsEntry(const StatsKey& statsKey, const StatsValue& statsEntry,
- const char* ifname) {
- stats_line newLine;
- strlcpy(newLine.iface, ifname, sizeof(newLine.iface));
- newLine.uid = (int32_t)statsKey.uid;
- newLine.set = (int32_t)statsKey.counterSet;
- newLine.tag = (int32_t)statsKey.tag;
- newLine.rxPackets = statsEntry.rxPackets;
- newLine.txPackets = statsEntry.txPackets;
- newLine.rxBytes = statsEntry.rxBytes;
- newLine.txBytes = statsEntry.txBytes;
- return newLine;
-}
-
-int parseBpfNetworkStatsDetailInternal(std::vector<stats_line>* lines,
- const std::vector<std::string>& limitIfaces, int limitTag,
- int limitUid, const BpfMap<StatsKey, StatsValue>& statsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceMap) {
- int64_t unknownIfaceBytesTotal = 0;
- const auto processDetailUidStats =
- [lines, &limitIfaces, &limitTag, &limitUid, &unknownIfaceBytesTotal, &ifaceMap](
- const StatsKey& key,
- const BpfMap<StatsKey, StatsValue>& statsMap) -> Result<void> {
- char ifname[IFNAMSIZ];
- if (getIfaceNameFromMap(ifaceMap, statsMap, key.ifaceIndex, ifname, key,
- &unknownIfaceBytesTotal)) {
- return Result<void>();
- }
- std::string ifnameStr(ifname);
- if (limitIfaces.size() > 0 &&
- std::find(limitIfaces.begin(), limitIfaces.end(), ifnameStr) == limitIfaces.end()) {
- // Nothing matched; skip this line.
- return Result<void>();
- }
- if (limitTag != TAG_ALL && uint32_t(limitTag) != key.tag) {
- return Result<void>();
- }
- if (limitUid != UID_ALL && uint32_t(limitUid) != key.uid) {
- return Result<void>();
- }
- Result<StatsValue> statsEntry = statsMap.readValue(key);
- if (!statsEntry.ok()) {
- return base::ResultError(statsEntry.error().message(), statsEntry.error().code());
- }
- lines->push_back(populateStatsEntry(key, statsEntry.value(), ifname));
- return Result<void>();
- };
- Result<void> res = statsMap.iterate(processDetailUidStats);
- if (!res.ok()) {
- ALOGE("failed to iterate per uid Stats map for detail traffic stats: %s",
- strerror(res.error().code()));
- return -res.error().code();
- }
-
- // Since eBPF use hash map to record stats, network stats collected from
- // eBPF will be out of order. And the performance of findIndexHinted in
- // NetworkStats will also be impacted.
- //
- // Furthermore, since the StatsKey contains iface index, the network stats
- // reported to framework would create items with the same iface, uid, tag
- // and set, which causes NetworkStats maps wrong item to subtract.
- //
- // Thus, the stats needs to be properly sorted and grouped before reported.
- groupNetworkStats(lines);
- return 0;
-}
-
-int parseBpfNetworkStatsDetail(std::vector<stats_line>* lines,
- const std::vector<std::string>& limitIfaces, int limitTag,
- int limitUid) {
- BpfMapRO<uint32_t, IfaceValue> ifaceIndexNameMap(IFACE_INDEX_NAME_MAP_PATH);
- if (!ifaceIndexNameMap.isValid()) {
- int ret = -errno;
- ALOGE("get ifaceIndexName map fd failed: %s", strerror(errno));
- return ret;
- }
-
- BpfMapRO<uint32_t, uint8_t> configurationMap(CONFIGURATION_MAP_PATH);
- if (!configurationMap.isValid()) {
- int ret = -errno;
- ALOGE("get configuration map fd failed: %s", strerror(errno));
- return ret;
- }
- auto configuration = configurationMap.readValue(CURRENT_STATS_MAP_CONFIGURATION_KEY);
- if (!configuration.ok()) {
- ALOGE("Cannot read the old configuration from map: %s",
- configuration.error().message().c_str());
- return -configuration.error().code();
- }
- const char* statsMapPath = STATS_MAP_PATH[configuration.value()];
- BpfMap<StatsKey, StatsValue> statsMap(statsMapPath);
- if (!statsMap.isValid()) {
- int ret = -errno;
- ALOGE("get stats map fd failed: %s, path: %s", strerror(errno), statsMapPath);
- return ret;
- }
-
- // It is safe to read and clear the old map now since the
- // networkStatsFactory should call netd to swap the map in advance already.
- int ret = parseBpfNetworkStatsDetailInternal(lines, limitIfaces, limitTag, limitUid, statsMap,
- ifaceIndexNameMap);
- if (ret) {
- ALOGE("parse detail network stats failed: %s", strerror(errno));
- return ret;
- }
-
- Result<void> res = statsMap.clear();
- if (!res.ok()) {
- ALOGE("Clean up current stats map failed: %s", strerror(res.error().code()));
- return -res.error().code();
- }
-
- return 0;
-}
-
-int parseBpfNetworkStatsDevInternal(std::vector<stats_line>* lines,
- const BpfMap<uint32_t, StatsValue>& statsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceMap) {
- int64_t unknownIfaceBytesTotal = 0;
- const auto processDetailIfaceStats = [lines, &unknownIfaceBytesTotal, &ifaceMap, &statsMap](
- const uint32_t& key, const StatsValue& value,
- const BpfMap<uint32_t, StatsValue>&) {
- char ifname[IFNAMSIZ];
- if (getIfaceNameFromMap(ifaceMap, statsMap, key, ifname, key, &unknownIfaceBytesTotal)) {
- return Result<void>();
- }
- StatsKey fakeKey = {
- .uid = (uint32_t)UID_ALL,
- .tag = (uint32_t)TAG_NONE,
- .counterSet = (uint32_t)SET_ALL,
- };
- lines->push_back(populateStatsEntry(fakeKey, value, ifname));
- return Result<void>();
- };
- Result<void> res = statsMap.iterateWithValue(processDetailIfaceStats);
- if (!res.ok()) {
- ALOGE("failed to iterate per uid Stats map for detail traffic stats: %s",
- strerror(res.error().code()));
- return -res.error().code();
- }
-
- groupNetworkStats(lines);
- return 0;
-}
-
-int parseBpfNetworkStatsDev(std::vector<stats_line>* lines) {
- int ret = 0;
- BpfMapRO<uint32_t, IfaceValue> ifaceIndexNameMap(IFACE_INDEX_NAME_MAP_PATH);
- if (!ifaceIndexNameMap.isValid()) {
- ret = -errno;
- ALOGE("get ifaceIndexName map fd failed: %s", strerror(errno));
- return ret;
- }
-
- BpfMapRO<uint32_t, StatsValue> ifaceStatsMap(IFACE_STATS_MAP_PATH);
- if (!ifaceStatsMap.isValid()) {
- ret = -errno;
- ALOGE("get ifaceStats map fd failed: %s", strerror(errno));
- return ret;
- }
- return parseBpfNetworkStatsDevInternal(lines, ifaceStatsMap, ifaceIndexNameMap);
-}
-
-uint64_t combineUidTag(const uid_t uid, const uint32_t tag) {
- return (uint64_t)uid << 32 | tag;
-}
-
-void groupNetworkStats(std::vector<stats_line>* lines) {
- if (lines->size() <= 1) return;
- std::sort(lines->begin(), lines->end());
-
- // Similar to std::unique(), but aggregates the duplicates rather than discarding them.
- size_t nextOutput = 0;
- for (size_t i = 1; i < lines->size(); i++) {
- if (lines->at(nextOutput) == lines->at(i)) {
- lines->at(nextOutput) += lines->at(i);
- } else {
- nextOutput++;
- if (nextOutput != i) {
- lines->at(nextOutput) = lines->at(i);
- }
- }
- }
-
- if (lines->size() != nextOutput + 1) {
- lines->resize(nextOutput + 1);
- }
-}
-
-// True if lhs equals to rhs, only compare iface, uid, tag and set.
-bool operator==(const stats_line& lhs, const stats_line& rhs) {
- return ((lhs.uid == rhs.uid) && (lhs.tag == rhs.tag) && (lhs.set == rhs.set) &&
- !strncmp(lhs.iface, rhs.iface, sizeof(lhs.iface)));
-}
-
-// True if lhs is smaller then rhs, only compare iface, uid, tag and set.
-bool operator<(const stats_line& lhs, const stats_line& rhs) {
- int ret = strncmp(lhs.iface, rhs.iface, sizeof(lhs.iface));
- if (ret != 0) return ret < 0;
- if (lhs.uid < rhs.uid) return true;
- if (lhs.uid > rhs.uid) return false;
- if (lhs.tag < rhs.tag) return true;
- if (lhs.tag > rhs.tag) return false;
- if (lhs.set < rhs.set) return true;
- if (lhs.set > rhs.set) return false;
- return false;
-}
-
-stats_line& stats_line::operator=(const stats_line& rhs) {
- if (this == &rhs) return *this;
-
- strlcpy(iface, rhs.iface, sizeof(iface));
- uid = rhs.uid;
- set = rhs.set;
- tag = rhs.tag;
- rxPackets = rhs.rxPackets;
- txPackets = rhs.txPackets;
- rxBytes = rhs.rxBytes;
- txBytes = rhs.txBytes;
- return *this;
-}
-
-stats_line& stats_line::operator+=(const stats_line& rhs) {
- rxPackets += rhs.rxPackets;
- txPackets += rhs.txPackets;
- rxBytes += rhs.rxBytes;
- txBytes += rhs.txBytes;
- return *this;
-}
-
-} // namespace bpf
-} // namespace android
diff --git a/libnetdbpf/BpfNetworkStatsTest.cpp b/libnetdbpf/BpfNetworkStatsTest.cpp
deleted file mode 100644
index fb8f0ec..0000000
--- a/libnetdbpf/BpfNetworkStatsTest.cpp
+++ /dev/null
@@ -1,570 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include <fstream>
-#include <iostream>
-#include <string>
-#include <vector>
-
-#include <fcntl.h>
-#include <inttypes.h>
-#include <linux/inet_diag.h>
-#include <linux/sock_diag.h>
-#include <net/if.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <gtest/gtest.h>
-
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include <netdutils/MockSyscalls.h>
-#include "bpf/BpfMap.h"
-#include "bpf/BpfUtils.h"
-#include "netdbpf/BpfNetworkStats.h"
-
-using ::testing::Test;
-
-namespace android {
-namespace bpf {
-
-using base::Result;
-using base::unique_fd;
-
-constexpr int TEST_MAP_SIZE = 10;
-constexpr uid_t TEST_UID1 = 10086;
-constexpr uid_t TEST_UID2 = 12345;
-constexpr uint32_t TEST_TAG = 42;
-constexpr int TEST_COUNTERSET0 = 0;
-constexpr int TEST_COUNTERSET1 = 1;
-constexpr uint64_t TEST_BYTES0 = 1000;
-constexpr uint64_t TEST_BYTES1 = 2000;
-constexpr uint64_t TEST_PACKET0 = 100;
-constexpr uint64_t TEST_PACKET1 = 200;
-constexpr const char IFACE_NAME1[] = "lo";
-constexpr const char IFACE_NAME2[] = "wlan0";
-constexpr const char IFACE_NAME3[] = "rmnet_data0";
-// A iface name that the size is bigger then IFNAMSIZ
-constexpr const char LONG_IFACE_NAME[] = "wlanWithALongName";
-constexpr const char TRUNCATED_IFACE_NAME[] = "wlanWithALongNa";
-constexpr uint32_t IFACE_INDEX1 = 1;
-constexpr uint32_t IFACE_INDEX2 = 2;
-constexpr uint32_t IFACE_INDEX3 = 3;
-constexpr uint32_t IFACE_INDEX4 = 4;
-constexpr uint32_t UNKNOWN_IFACE = 0;
-
-class BpfNetworkStatsHelperTest : public testing::Test {
- protected:
- BpfNetworkStatsHelperTest() {}
- BpfMap<uint64_t, UidTagValue> mFakeCookieTagMap;
- BpfMap<uint32_t, StatsValue> mFakeAppUidStatsMap;
- BpfMap<StatsKey, StatsValue> mFakeStatsMap;
- BpfMap<uint32_t, IfaceValue> mFakeIfaceIndexNameMap;
- BpfMap<uint32_t, StatsValue> mFakeIfaceStatsMap;
-
- void SetUp() {
- ASSERT_EQ(0, setrlimitForTest());
-
- mFakeCookieTagMap = BpfMap<uint64_t, UidTagValue>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
- ASSERT_LE(0, mFakeCookieTagMap.getMap());
-
- mFakeAppUidStatsMap = BpfMap<uint32_t, StatsValue>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
- ASSERT_LE(0, mFakeAppUidStatsMap.getMap());
-
- mFakeStatsMap = BpfMap<StatsKey, StatsValue>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
- ASSERT_LE(0, mFakeStatsMap.getMap());
-
- mFakeIfaceIndexNameMap = BpfMap<uint32_t, IfaceValue>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
- ASSERT_LE(0, mFakeIfaceIndexNameMap.getMap());
-
- mFakeIfaceStatsMap = BpfMap<uint32_t, StatsValue>(BPF_MAP_TYPE_HASH, TEST_MAP_SIZE, 0);
- ASSERT_LE(0, mFakeIfaceStatsMap.getMap());
- }
-
- void expectUidTag(uint64_t cookie, uid_t uid, uint32_t tag) {
- auto tagResult = mFakeCookieTagMap.readValue(cookie);
- EXPECT_RESULT_OK(tagResult);
- EXPECT_EQ(uid, tagResult.value().uid);
- EXPECT_EQ(tag, tagResult.value().tag);
- }
-
- void populateFakeStats(uid_t uid, uint32_t tag, uint32_t ifaceIndex, uint32_t counterSet,
- StatsValue value, BpfMap<StatsKey, StatsValue>& map) {
- StatsKey key = {
- .uid = (uint32_t)uid, .tag = tag, .counterSet = counterSet, .ifaceIndex = ifaceIndex};
- EXPECT_RESULT_OK(map.writeValue(key, value, BPF_ANY));
- }
-
- void updateIfaceMap(const char* ifaceName, uint32_t ifaceIndex) {
- IfaceValue iface;
- strlcpy(iface.name, ifaceName, IFNAMSIZ);
- EXPECT_RESULT_OK(mFakeIfaceIndexNameMap.writeValue(ifaceIndex, iface, BPF_ANY));
- }
-
- void expectStatsEqual(const StatsValue& target, const Stats& result) {
- EXPECT_EQ(target.rxPackets, result.rxPackets);
- EXPECT_EQ(target.rxBytes, result.rxBytes);
- EXPECT_EQ(target.txPackets, result.txPackets);
- EXPECT_EQ(target.txBytes, result.txBytes);
- }
-
- void expectStatsLineEqual(const StatsValue target, const char* iface, uint32_t uid,
- int counterSet, uint32_t tag, const stats_line& result) {
- EXPECT_EQ(0, strcmp(iface, result.iface));
- EXPECT_EQ(uid, (uint32_t)result.uid);
- EXPECT_EQ((uint32_t) counterSet, result.set);
- EXPECT_EQ(tag, (uint32_t)result.tag);
- EXPECT_EQ(target.rxPackets, (uint64_t)result.rxPackets);
- EXPECT_EQ(target.rxBytes, (uint64_t)result.rxBytes);
- EXPECT_EQ(target.txPackets, (uint64_t)result.txPackets);
- EXPECT_EQ(target.txBytes, (uint64_t)result.txBytes);
- }
-};
-
-// TEST to verify the behavior of bpf map when cocurrent deletion happens when
-// iterating the same map.
-TEST_F(BpfNetworkStatsHelperTest, TestIterateMapWithDeletion) {
- for (int i = 0; i < 5; i++) {
- uint64_t cookie = i + 1;
- UidTagValue tag = {.uid = TEST_UID1, .tag = TEST_TAG};
- EXPECT_RESULT_OK(mFakeCookieTagMap.writeValue(cookie, tag, BPF_ANY));
- }
- uint64_t curCookie = 0;
- auto nextCookie = mFakeCookieTagMap.getNextKey(curCookie);
- EXPECT_RESULT_OK(nextCookie);
- uint64_t headOfMap = nextCookie.value();
- curCookie = nextCookie.value();
- // Find the second entry in the map, then immediately delete it.
- nextCookie = mFakeCookieTagMap.getNextKey(curCookie);
- EXPECT_RESULT_OK(nextCookie);
- EXPECT_RESULT_OK(mFakeCookieTagMap.deleteValue((nextCookie.value())));
- // Find the entry that is now immediately after headOfMap, then delete that.
- nextCookie = mFakeCookieTagMap.getNextKey(curCookie);
- EXPECT_RESULT_OK(nextCookie);
- EXPECT_RESULT_OK(mFakeCookieTagMap.deleteValue((nextCookie.value())));
- // Attempting to read an entry that has been deleted fails with ENOENT.
- curCookie = nextCookie.value();
- auto tagResult = mFakeCookieTagMap.readValue(curCookie);
- EXPECT_EQ(ENOENT, tagResult.error().code());
- // Finding the entry after our deleted entry restarts iteration from the beginning of the map.
- nextCookie = mFakeCookieTagMap.getNextKey(curCookie);
- EXPECT_RESULT_OK(nextCookie);
- EXPECT_EQ(headOfMap, nextCookie.value());
-}
-
-TEST_F(BpfNetworkStatsHelperTest, TestBpfIterateMap) {
- for (int i = 0; i < 5; i++) {
- uint64_t cookie = i + 1;
- UidTagValue tag = {.uid = TEST_UID1, .tag = TEST_TAG};
- EXPECT_RESULT_OK(mFakeCookieTagMap.writeValue(cookie, tag, BPF_ANY));
- }
- int totalCount = 0;
- int totalSum = 0;
- const auto iterateWithoutDeletion =
- [&totalCount, &totalSum](const uint64_t& key, const BpfMap<uint64_t, UidTagValue>&) {
- EXPECT_GE((uint64_t)5, key);
- totalCount++;
- totalSum += key;
- return Result<void>();
- };
- EXPECT_RESULT_OK(mFakeCookieTagMap.iterate(iterateWithoutDeletion));
- EXPECT_EQ(5, totalCount);
- EXPECT_EQ(1 + 2 + 3 + 4 + 5, totalSum);
-}
-
-TEST_F(BpfNetworkStatsHelperTest, TestUidStatsNoTraffic) {
- StatsValue value1 = {
- .rxPackets = 0,
- .rxBytes = 0,
- .txPackets = 0,
- .txBytes = 0,
- };
- Stats result1 = {};
- ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID1, &result1, mFakeAppUidStatsMap));
- expectStatsEqual(value1, result1);
-}
-
-TEST_F(BpfNetworkStatsHelperTest, TestGetUidStatsTotal) {
- updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
- updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
- updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
- StatsValue value1 = {
- .rxPackets = TEST_PACKET0,
- .rxBytes = TEST_BYTES0,
- .txPackets = TEST_PACKET1,
- .txBytes = TEST_BYTES1,
- };
- StatsValue value2 = {
- .rxPackets = TEST_PACKET0 * 2,
- .rxBytes = TEST_BYTES0 * 2,
- .txPackets = TEST_PACKET1 * 2,
- .txBytes = TEST_BYTES1 * 2,
- };
- ASSERT_RESULT_OK(mFakeAppUidStatsMap.writeValue(TEST_UID1, value1, BPF_ANY));
- ASSERT_RESULT_OK(mFakeAppUidStatsMap.writeValue(TEST_UID2, value2, BPF_ANY));
- Stats result1 = {};
- ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID1, &result1, mFakeAppUidStatsMap));
- expectStatsEqual(value1, result1);
-
- Stats result2 = {};
- ASSERT_EQ(0, bpfGetUidStatsInternal(TEST_UID2, &result2, mFakeAppUidStatsMap));
- expectStatsEqual(value2, result2);
- std::vector<stats_line> lines;
- std::vector<std::string> ifaces;
- populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET1, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID2, 0, IFACE_INDEX3, TEST_COUNTERSET1, value1, mFakeStatsMap);
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
- mFakeStatsMap, mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)2, lines.size());
- lines.clear();
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID2,
- mFakeStatsMap, mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)1, lines.size());
- expectStatsLineEqual(value1, IFACE_NAME3, TEST_UID2, TEST_COUNTERSET1, 0, lines.front());
-}
-
-TEST_F(BpfNetworkStatsHelperTest, TestGetIfaceStatsInternal) {
- updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
- updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
- updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
- StatsValue value1 = {
- .rxPackets = TEST_PACKET0,
- .rxBytes = TEST_BYTES0,
- .txPackets = TEST_PACKET1,
- .txBytes = TEST_BYTES1,
- };
- StatsValue value2 = {
- .rxPackets = TEST_PACKET1,
- .rxBytes = TEST_BYTES1,
- .txPackets = TEST_PACKET0,
- .txBytes = TEST_BYTES0,
- };
- uint32_t ifaceStatsKey = IFACE_INDEX1;
- EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY));
- ifaceStatsKey = IFACE_INDEX2;
- EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value2, BPF_ANY));
- ifaceStatsKey = IFACE_INDEX3;
- EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY));
-
- Stats result1 = {};
- ASSERT_EQ(0, bpfGetIfaceStatsInternal(IFACE_NAME1, &result1, mFakeIfaceStatsMap,
- mFakeIfaceIndexNameMap));
- expectStatsEqual(value1, result1);
- Stats result2 = {};
- ASSERT_EQ(0, bpfGetIfaceStatsInternal(IFACE_NAME2, &result2, mFakeIfaceStatsMap,
- mFakeIfaceIndexNameMap));
- expectStatsEqual(value2, result2);
- Stats totalResult = {};
- ASSERT_EQ(0, bpfGetIfaceStatsInternal(NULL, &totalResult, mFakeIfaceStatsMap,
- mFakeIfaceIndexNameMap));
- StatsValue totalValue = {
- .rxPackets = TEST_PACKET0 * 2 + TEST_PACKET1,
- .rxBytes = TEST_BYTES0 * 2 + TEST_BYTES1,
- .txPackets = TEST_PACKET1 * 2 + TEST_PACKET0,
- .txBytes = TEST_BYTES1 * 2 + TEST_BYTES0,
- };
- expectStatsEqual(totalValue, totalResult);
-}
-
-TEST_F(BpfNetworkStatsHelperTest, TestGetStatsDetail) {
- updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
- updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
- StatsValue value1 = {
- .rxPackets = TEST_PACKET0,
- .rxBytes = TEST_BYTES0,
- .txPackets = TEST_PACKET1,
- .txBytes = TEST_BYTES1,
- };
- populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX2, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID1, TEST_TAG + 1, IFACE_INDEX1, TEST_COUNTERSET0, value1,
- mFakeStatsMap);
- populateFakeStats(TEST_UID2, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- std::vector<stats_line> lines;
- std::vector<std::string> ifaces;
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL, mFakeStatsMap,
- mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)4, lines.size());
- lines.clear();
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
- mFakeStatsMap, mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)3, lines.size());
- lines.clear();
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TEST_TAG, TEST_UID1,
- mFakeStatsMap, mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)2, lines.size());
- lines.clear();
- ifaces.push_back(std::string(IFACE_NAME1));
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TEST_TAG, TEST_UID1,
- mFakeStatsMap, mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)1, lines.size());
- expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, TEST_TAG, lines.front());
-}
-
-TEST_F(BpfNetworkStatsHelperTest, TestGetStatsWithSkippedIface) {
- updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
- updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
- StatsValue value1 = {
- .rxPackets = TEST_PACKET0,
- .rxBytes = TEST_BYTES0,
- .txPackets = TEST_PACKET1,
- .txBytes = TEST_BYTES1,
- };
- populateFakeStats(0, 0, 0, OVERFLOW_COUNTERSET, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET1, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID2, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- std::vector<stats_line> lines;
- std::vector<std::string> ifaces;
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL, mFakeStatsMap,
- mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)4, lines.size());
- lines.clear();
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
- mFakeStatsMap, mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)3, lines.size());
- lines.clear();
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID2,
- mFakeStatsMap, mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)1, lines.size());
- expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID2, TEST_COUNTERSET0, 0, lines.front());
- lines.clear();
- ifaces.push_back(std::string(IFACE_NAME1));
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, TEST_UID1,
- mFakeStatsMap, mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)2, lines.size());
-}
-
-TEST_F(BpfNetworkStatsHelperTest, TestUnkownIfaceError) {
- updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
- StatsValue value1 = {
- .rxPackets = TEST_PACKET0,
- .rxBytes = TEST_BYTES0 * 20,
- .txPackets = TEST_PACKET1,
- .txBytes = TEST_BYTES1 * 20,
- };
- uint32_t ifaceIndex = UNKNOWN_IFACE;
- populateFakeStats(TEST_UID1, 0, ifaceIndex, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- StatsValue value2 = {
- .rxPackets = TEST_PACKET0,
- .rxBytes = TEST_BYTES0 * 40,
- .txPackets = TEST_PACKET1,
- .txBytes = TEST_BYTES1 * 40,
- };
- populateFakeStats(TEST_UID1, 0, IFACE_INDEX2, TEST_COUNTERSET0, value2, mFakeStatsMap);
- StatsKey curKey = {
- .uid = TEST_UID1,
- .tag = 0,
- .counterSet = TEST_COUNTERSET0,
- .ifaceIndex = ifaceIndex,
- };
- char ifname[IFNAMSIZ];
- int64_t unknownIfaceBytesTotal = 0;
- ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeStatsMap, ifaceIndex,
- ifname, curKey, &unknownIfaceBytesTotal));
- ASSERT_EQ(((int64_t)(TEST_BYTES0 * 20 + TEST_BYTES1 * 20)), unknownIfaceBytesTotal);
- curKey.ifaceIndex = IFACE_INDEX2;
- ASSERT_EQ(-ENODEV, getIfaceNameFromMap(mFakeIfaceIndexNameMap, mFakeStatsMap, ifaceIndex,
- ifname, curKey, &unknownIfaceBytesTotal));
- ASSERT_EQ(-1, unknownIfaceBytesTotal);
- std::vector<stats_line> lines;
- std::vector<std::string> ifaces;
- // TODO: find a way to test the total of unknown Iface Bytes go above limit.
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL, mFakeStatsMap,
- mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)1, lines.size());
- expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, 0, lines.front());
-}
-
-TEST_F(BpfNetworkStatsHelperTest, TestGetIfaceStatsDetail) {
- updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
- updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
- updateIfaceMap(IFACE_NAME3, IFACE_INDEX3);
- updateIfaceMap(LONG_IFACE_NAME, IFACE_INDEX4);
- StatsValue value1 = {
- .rxPackets = TEST_PACKET0,
- .rxBytes = TEST_BYTES0,
- .txPackets = TEST_PACKET1,
- .txBytes = TEST_BYTES1,
- };
- StatsValue value2 = {
- .rxPackets = TEST_PACKET1,
- .rxBytes = TEST_BYTES1,
- .txPackets = TEST_PACKET0,
- .txBytes = TEST_BYTES0,
- };
- uint32_t ifaceStatsKey = IFACE_INDEX1;
- EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY));
- ifaceStatsKey = IFACE_INDEX2;
- EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value2, BPF_ANY));
- ifaceStatsKey = IFACE_INDEX3;
- EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY));
- ifaceStatsKey = IFACE_INDEX4;
- EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value2, BPF_ANY));
- std::vector<stats_line> lines;
- ASSERT_EQ(0,
- parseBpfNetworkStatsDevInternal(&lines, mFakeIfaceStatsMap, mFakeIfaceIndexNameMap));
- ASSERT_EQ((unsigned long)4, lines.size());
-
- expectStatsLineEqual(value1, IFACE_NAME1, UID_ALL, SET_ALL, TAG_NONE, lines[0]);
- expectStatsLineEqual(value1, IFACE_NAME3, UID_ALL, SET_ALL, TAG_NONE, lines[1]);
- expectStatsLineEqual(value2, IFACE_NAME2, UID_ALL, SET_ALL, TAG_NONE, lines[2]);
- ASSERT_EQ(0, strcmp(TRUNCATED_IFACE_NAME, lines[3].iface));
- expectStatsLineEqual(value2, TRUNCATED_IFACE_NAME, UID_ALL, SET_ALL, TAG_NONE, lines[3]);
-}
-
-TEST_F(BpfNetworkStatsHelperTest, TestGetStatsSortedAndGrouped) {
- // Create iface indexes with duplicate iface name.
- updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
- updateIfaceMap(IFACE_NAME2, IFACE_INDEX2);
- updateIfaceMap(IFACE_NAME1, IFACE_INDEX3); // Duplicate!
-
- StatsValue value1 = {
- .rxPackets = TEST_PACKET0,
- .rxBytes = TEST_BYTES0,
- .txPackets = TEST_PACKET1,
- .txBytes = TEST_BYTES1,
- };
- StatsValue value2 = {
- .rxPackets = TEST_PACKET1,
- .rxBytes = TEST_BYTES1,
- .txPackets = TEST_PACKET0,
- .txBytes = TEST_BYTES0,
- };
- StatsValue value3 = {
- .rxPackets = TEST_PACKET0 * 2,
- .rxBytes = TEST_BYTES0 * 2,
- .txPackets = TEST_PACKET1 * 2,
- .txBytes = TEST_BYTES1 * 2,
- };
-
- std::vector<stats_line> lines;
- std::vector<std::string> ifaces;
-
- // Test empty stats.
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL, mFakeStatsMap,
- mFakeIfaceIndexNameMap));
- ASSERT_EQ((size_t) 0, lines.size());
- lines.clear();
-
- // Test 1 line stats.
- populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL, mFakeStatsMap,
- mFakeIfaceIndexNameMap));
- ASSERT_EQ((size_t) 1, lines.size());
- expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, TEST_TAG, lines[0]);
- lines.clear();
-
- // These items should not be grouped.
- populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX2, TEST_COUNTERSET0, value2, mFakeStatsMap);
- populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX3, TEST_COUNTERSET1, value2, mFakeStatsMap);
- populateFakeStats(TEST_UID1, TEST_TAG + 1, IFACE_INDEX1, TEST_COUNTERSET0, value2,
- mFakeStatsMap);
- populateFakeStats(TEST_UID2, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL, mFakeStatsMap,
- mFakeIfaceIndexNameMap));
- ASSERT_EQ((size_t) 5, lines.size());
- lines.clear();
-
- // These items should be grouped.
- populateFakeStats(TEST_UID1, TEST_TAG, IFACE_INDEX3, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID2, TEST_TAG, IFACE_INDEX3, TEST_COUNTERSET0, value1, mFakeStatsMap);
-
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL, mFakeStatsMap,
- mFakeIfaceIndexNameMap));
- ASSERT_EQ((size_t) 5, lines.size());
-
- // Verify Sorted & Grouped.
- expectStatsLineEqual(value3, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, TEST_TAG, lines[0]);
- expectStatsLineEqual(value2, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET1, TEST_TAG, lines[1]);
- expectStatsLineEqual(value2, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, TEST_TAG + 1, lines[2]);
- expectStatsLineEqual(value3, IFACE_NAME1, TEST_UID2, TEST_COUNTERSET0, TEST_TAG, lines[3]);
- expectStatsLineEqual(value2, IFACE_NAME2, TEST_UID1, TEST_COUNTERSET0, TEST_TAG, lines[4]);
- lines.clear();
-
- // Perform test on IfaceStats.
- uint32_t ifaceStatsKey = IFACE_INDEX2;
- EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value2, BPF_ANY));
- ifaceStatsKey = IFACE_INDEX1;
- EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY));
-
- // This should be grouped.
- ifaceStatsKey = IFACE_INDEX3;
- EXPECT_RESULT_OK(mFakeIfaceStatsMap.writeValue(ifaceStatsKey, value1, BPF_ANY));
-
- ASSERT_EQ(0,
- parseBpfNetworkStatsDevInternal(&lines, mFakeIfaceStatsMap, mFakeIfaceIndexNameMap));
- ASSERT_EQ((size_t) 2, lines.size());
-
- expectStatsLineEqual(value3, IFACE_NAME1, UID_ALL, SET_ALL, TAG_NONE, lines[0]);
- expectStatsLineEqual(value2, IFACE_NAME2, UID_ALL, SET_ALL, TAG_NONE, lines[1]);
- lines.clear();
-}
-
-// Test to verify that subtract overflow will not be triggered by the compare function invoked from
-// sorting. See http:/b/119193941.
-TEST_F(BpfNetworkStatsHelperTest, TestGetStatsSortAndOverflow) {
- updateIfaceMap(IFACE_NAME1, IFACE_INDEX1);
-
- StatsValue value1 = {
- .rxPackets = TEST_PACKET0,
- .rxBytes = TEST_BYTES0,
- .txPackets = TEST_PACKET1,
- .txBytes = TEST_BYTES1,
- };
-
- // Mutate uid, 0 < TEST_UID1 < INT_MAX < INT_MIN < UINT_MAX.
- populateFakeStats(0, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(UINT_MAX, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(INT_MIN, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(INT_MAX, TEST_TAG, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
-
- // Mutate tag, 0 < TEST_TAG < INT_MAX < INT_MIN < UINT_MAX.
- populateFakeStats(TEST_UID1, INT_MAX, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID1, INT_MIN, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID1, 0, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
- populateFakeStats(TEST_UID1, UINT_MAX, IFACE_INDEX1, TEST_COUNTERSET0, value1, mFakeStatsMap);
-
- // TODO: Mutate counterSet and enlarge TEST_MAP_SIZE if overflow on counterSet is possible.
-
- std::vector<stats_line> lines;
- std::vector<std::string> ifaces;
- ASSERT_EQ(0, parseBpfNetworkStatsDetailInternal(&lines, ifaces, TAG_ALL, UID_ALL, mFakeStatsMap,
- mFakeIfaceIndexNameMap));
- ASSERT_EQ((size_t) 8, lines.size());
-
- // Uid 0 first
- expectStatsLineEqual(value1, IFACE_NAME1, 0, TEST_COUNTERSET0, TEST_TAG, lines[0]);
-
- // Test uid, mutate tag.
- expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, 0, lines[1]);
- expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, INT_MAX, lines[2]);
- expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, INT_MIN, lines[3]);
- expectStatsLineEqual(value1, IFACE_NAME1, TEST_UID1, TEST_COUNTERSET0, UINT_MAX, lines[4]);
-
- // Mutate uid.
- expectStatsLineEqual(value1, IFACE_NAME1, INT_MAX, TEST_COUNTERSET0, TEST_TAG, lines[5]);
- expectStatsLineEqual(value1, IFACE_NAME1, INT_MIN, TEST_COUNTERSET0, TEST_TAG, lines[6]);
- expectStatsLineEqual(value1, IFACE_NAME1, UINT_MAX, TEST_COUNTERSET0, TEST_TAG, lines[7]);
- lines.clear();
-}
-} // namespace bpf
-} // namespace android
diff --git a/libnetdbpf/include/netdbpf/BpfNetworkStats.h b/libnetdbpf/include/netdbpf/BpfNetworkStats.h
deleted file mode 100644
index 8ab7e25..0000000
--- a/libnetdbpf/include/netdbpf/BpfNetworkStats.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#ifndef _BPF_NETWORKSTATS_H
-#define _BPF_NETWORKSTATS_H
-
-#include <bpf/BpfMap.h>
-#include "bpf_shared.h"
-
-namespace android {
-namespace bpf {
-
-// TODO: set this to a proper value based on the map size;
-constexpr int TAG_STATS_MAP_SOFT_LIMIT = 3;
-constexpr int UID_ALL = -1;
-constexpr int TAG_ALL = -1;
-constexpr int TAG_NONE = 0;
-constexpr int SET_ALL = -1;
-constexpr int SET_DEFAULT = 0;
-constexpr int SET_FOREGROUND = 1;
-
-// The limit for stats received by a unknown interface;
-constexpr const int64_t MAX_UNKNOWN_IFACE_BYTES = 100 * 1000;
-
-// This is used by
-// frameworks/base/core/jni/com_android_internal_net_NetworkStatsFactory.cpp
-// make sure it is consistent with the JNI code before changing this.
-struct stats_line {
- char iface[32];
- uint32_t uid;
- uint32_t set;
- uint32_t tag;
- int64_t rxBytes;
- int64_t rxPackets;
- int64_t txBytes;
- int64_t txPackets;
-
- stats_line& operator=(const stats_line& rhs);
- stats_line& operator+=(const stats_line& rhs);
-};
-
-bool operator==(const stats_line& lhs, const stats_line& rhs);
-bool operator<(const stats_line& lhs, const stats_line& rhs);
-
-// For test only
-int bpfGetUidStatsInternal(uid_t uid, Stats* stats,
- const BpfMap<uint32_t, StatsValue>& appUidStatsMap);
-// For test only
-int bpfGetIfaceStatsInternal(const char* iface, Stats* stats,
- const BpfMap<uint32_t, StatsValue>& ifaceStatsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceNameMap);
-// For test only
-int parseBpfNetworkStatsDetailInternal(std::vector<stats_line>* lines,
- const std::vector<std::string>& limitIfaces, int limitTag,
- int limitUid, const BpfMap<StatsKey, StatsValue>& statsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceMap);
-// For test only
-int cleanStatsMapInternal(const base::unique_fd& cookieTagMap, const base::unique_fd& tagStatsMap);
-// For test only
-template <class Key>
-int getIfaceNameFromMap(const BpfMap<uint32_t, IfaceValue>& ifaceMap,
- const BpfMap<Key, StatsValue>& statsMap, uint32_t ifaceIndex, char* ifname,
- const Key& curKey, int64_t* unknownIfaceBytesTotal) {
- auto iface = ifaceMap.readValue(ifaceIndex);
- if (!iface.ok()) {
- maybeLogUnknownIface(ifaceIndex, statsMap, curKey, unknownIfaceBytesTotal);
- return -ENODEV;
- }
- strlcpy(ifname, iface.value().name, sizeof(IfaceValue));
- return 0;
-}
-
-template <class Key>
-void maybeLogUnknownIface(int ifaceIndex, const BpfMap<Key, StatsValue>& statsMap,
- const Key& curKey, int64_t* unknownIfaceBytesTotal) {
- // Have we already logged an error?
- if (*unknownIfaceBytesTotal == -1) {
- return;
- }
-
- // Are we undercounting enough data to be worth logging?
- auto statsEntry = statsMap.readValue(curKey);
- if (!statsEntry.ok()) {
- // No data is being undercounted.
- return;
- }
-
- *unknownIfaceBytesTotal += (statsEntry.value().rxBytes + statsEntry.value().txBytes);
- if (*unknownIfaceBytesTotal >= MAX_UNKNOWN_IFACE_BYTES) {
- ALOGE("Unknown name for ifindex %d with more than %" PRId64 " bytes of traffic", ifaceIndex,
- *unknownIfaceBytesTotal);
- *unknownIfaceBytesTotal = -1;
- }
-}
-
-// For test only
-int parseBpfNetworkStatsDevInternal(std::vector<stats_line>* lines,
- const BpfMap<uint32_t, StatsValue>& statsMap,
- const BpfMap<uint32_t, IfaceValue>& ifaceMap);
-
-int bpfGetUidStats(uid_t uid, Stats* stats);
-int bpfGetIfaceStats(const char* iface, Stats* stats);
-int parseBpfNetworkStatsDetail(std::vector<stats_line>* lines,
- const std::vector<std::string>& limitIfaces, int limitTag,
- int limitUid);
-
-int parseBpfNetworkStatsDev(std::vector<stats_line>* lines);
-void groupNetworkStats(std::vector<stats_line>* lines);
-int cleanStatsMap();
-} // namespace bpf
-} // namespace android
-
-#endif // _BPF_NETWORKSTATS_H
diff --git a/libnetdbpf/include/netdbpf/bpf_shared.h b/libnetdbpf/include/netdbpf/bpf_shared.h
deleted file mode 100644
index 2fcb612..0000000
--- a/libnetdbpf/include/netdbpf/bpf_shared.h
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * Copyright (C) 2018 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
-
-#include <linux/if.h>
-#include <linux/if_ether.h>
-#include <linux/in.h>
-#include <linux/in6.h>
-#include <netdutils/UidConstants.h>
-
-// This header file is shared by eBPF kernel programs (C) and netd (C++) and
-// some of the maps are also accessed directly from Java mainline module code.
-//
-// Hence: explicitly pad all relevant structures and assert that their size
-// is the sum of the sizes of their fields.
-#define STRUCT_SIZE(name, size) _Static_assert(sizeof(name) == (size), "Incorrect struct size.")
-
-typedef struct {
- uint32_t uid;
- uint32_t tag;
-} UidTagValue;
-STRUCT_SIZE(UidTagValue, 2 * 4); // 8
-
-typedef struct {
- uint32_t uid;
- uint32_t tag;
- uint32_t counterSet;
- uint32_t ifaceIndex;
-} StatsKey;
-STRUCT_SIZE(StatsKey, 4 * 4); // 16
-
-typedef struct {
- uint64_t rxPackets;
- uint64_t rxBytes;
- uint64_t txPackets;
- uint64_t txBytes;
-} StatsValue;
-STRUCT_SIZE(StatsValue, 4 * 8); // 32
-
-typedef struct {
- char name[IFNAMSIZ];
-} IfaceValue;
-STRUCT_SIZE(IfaceValue, 16);
-
-typedef struct {
- uint64_t rxBytes;
- uint64_t rxPackets;
- uint64_t txBytes;
- uint64_t txPackets;
- uint64_t tcpRxPackets;
- uint64_t tcpTxPackets;
-} Stats;
-
-// Since we cannot garbage collect the stats map since device boot, we need to make these maps as
-// large as possible. The maximum size of number of map entries we can have is depend on the rlimit
-// of MEM_LOCK granted to netd. The memory space needed by each map can be calculated by the
-// following fomula:
-// elem_size = 40 + roundup(key_size, 8) + roundup(value_size, 8)
-// cost = roundup_pow_of_two(max_entries) * 16 + elem_size * max_entries +
-// elem_size * number_of_CPU
-// And the cost of each map currently used is(assume the device have 8 CPUs):
-// cookie_tag_map: key: 8 bytes, value: 8 bytes, cost: 822592 bytes = 823Kbytes
-// uid_counter_set_map: key: 4 bytes, value: 1 bytes, cost: 145216 bytes = 145Kbytes
-// app_uid_stats_map: key: 4 bytes, value: 32 bytes, cost: 1062784 bytes = 1063Kbytes
-// uid_stats_map: key: 16 bytes, value: 32 bytes, cost: 1142848 bytes = 1143Kbytes
-// tag_stats_map: key: 16 bytes, value: 32 bytes, cost: 1142848 bytes = 1143Kbytes
-// iface_index_name_map:key: 4 bytes, value: 16 bytes, cost: 80896 bytes = 81Kbytes
-// iface_stats_map: key: 4 bytes, value: 32 bytes, cost: 97024 bytes = 97Kbytes
-// dozable_uid_map: key: 4 bytes, value: 1 bytes, cost: 145216 bytes = 145Kbytes
-// standby_uid_map: key: 4 bytes, value: 1 bytes, cost: 145216 bytes = 145Kbytes
-// powersave_uid_map: key: 4 bytes, value: 1 bytes, cost: 145216 bytes = 145Kbytes
-// total: 4930Kbytes
-// It takes maximum 4.9MB kernel memory space if all maps are full, which requires any devices
-// running this module to have a memlock rlimit to be larger then 5MB. In the old qtaguid module,
-// we don't have a total limit for data entries but only have limitation of tags each uid can have.
-// (default is 1024 in kernel);
-
-const int COOKIE_UID_MAP_SIZE = 10000;
-const int UID_COUNTERSET_MAP_SIZE = 2000;
-const int APP_STATS_MAP_SIZE = 10000;
-const int STATS_MAP_SIZE = 5000;
-const int IFACE_INDEX_NAME_MAP_SIZE = 1000;
-const int IFACE_STATS_MAP_SIZE = 1000;
-const int CONFIGURATION_MAP_SIZE = 2;
-const int UID_OWNER_MAP_SIZE = 2000;
-
-#define BPF_PATH "/sys/fs/bpf/"
-
-#define BPF_EGRESS_PROG_PATH BPF_PATH "prog_netd_cgroupskb_egress_stats"
-#define BPF_INGRESS_PROG_PATH BPF_PATH "prog_netd_cgroupskb_ingress_stats"
-#define XT_BPF_INGRESS_PROG_PATH BPF_PATH "prog_netd_skfilter_ingress_xtbpf"
-#define XT_BPF_EGRESS_PROG_PATH BPF_PATH "prog_netd_skfilter_egress_xtbpf"
-#define XT_BPF_ALLOWLIST_PROG_PATH BPF_PATH "prog_netd_skfilter_allowlist_xtbpf"
-#define XT_BPF_DENYLIST_PROG_PATH BPF_PATH "prog_netd_skfilter_denylist_xtbpf"
-#define CGROUP_SOCKET_PROG_PATH BPF_PATH "prog_netd_cgroupsock_inet_create"
-
-#define COOKIE_TAG_MAP_PATH BPF_PATH "map_netd_cookie_tag_map"
-#define UID_COUNTERSET_MAP_PATH BPF_PATH "map_netd_uid_counterset_map"
-#define APP_UID_STATS_MAP_PATH BPF_PATH "map_netd_app_uid_stats_map"
-#define STATS_MAP_A_PATH BPF_PATH "map_netd_stats_map_A"
-#define STATS_MAP_B_PATH BPF_PATH "map_netd_stats_map_B"
-#define IFACE_INDEX_NAME_MAP_PATH BPF_PATH "map_netd_iface_index_name_map"
-#define IFACE_STATS_MAP_PATH BPF_PATH "map_netd_iface_stats_map"
-#define CONFIGURATION_MAP_PATH BPF_PATH "map_netd_configuration_map"
-#define UID_OWNER_MAP_PATH BPF_PATH "map_netd_uid_owner_map"
-#define UID_PERMISSION_MAP_PATH BPF_PATH "map_netd_uid_permission_map"
-
-enum UidOwnerMatchType {
- NO_MATCH = 0,
- HAPPY_BOX_MATCH = (1 << 0),
- PENALTY_BOX_MATCH = (1 << 1),
- DOZABLE_MATCH = (1 << 2),
- STANDBY_MATCH = (1 << 3),
- POWERSAVE_MATCH = (1 << 4),
- RESTRICTED_MATCH = (1 << 5),
- IIF_MATCH = (1 << 6),
-};
-
-enum BpfPermissionMatch {
- BPF_PERMISSION_INTERNET = 1 << 2,
- BPF_PERMISSION_UPDATE_DEVICE_STATS = 1 << 3,
-};
-// In production we use two identical stats maps to record per uid stats and
-// do swap and clean based on the configuration specified here. The statsMapType
-// value in configuration map specified which map is currently in use.
-enum StatsMapType {
- SELECT_MAP_A,
- SELECT_MAP_B,
-};
-
-// TODO: change the configuration object from an 8-bit bitmask to an object with clearer
-// semantics, like a struct.
-typedef uint8_t BpfConfig;
-const BpfConfig DEFAULT_CONFIG = 0;
-
-typedef struct {
- // Allowed interface index. Only applicable if IIF_MATCH is set in the rule bitmask above.
- uint32_t iif;
- // A bitmask of enum values in UidOwnerMatchType.
- uint32_t rule;
-} UidOwnerValue;
-STRUCT_SIZE(UidOwnerValue, 2 * 4); // 8
-
-#define UID_RULES_CONFIGURATION_KEY 1
-#define CURRENT_STATS_MAP_CONFIGURATION_KEY 2
-
-#define CLAT_INGRESS6_PROG_RAWIP_NAME "prog_clatd_schedcls_ingress6_clat_rawip"
-#define CLAT_INGRESS6_PROG_ETHER_NAME "prog_clatd_schedcls_ingress6_clat_ether"
-
-#define CLAT_INGRESS6_PROG_RAWIP_PATH BPF_PATH CLAT_INGRESS6_PROG_RAWIP_NAME
-#define CLAT_INGRESS6_PROG_ETHER_PATH BPF_PATH CLAT_INGRESS6_PROG_ETHER_NAME
-
-#define CLAT_INGRESS6_MAP_PATH BPF_PATH "map_clatd_clat_ingress6_map"
-
-typedef struct {
- uint32_t iif; // The input interface index
- struct in6_addr pfx96; // The source /96 nat64 prefix, bottom 32 bits must be 0
- struct in6_addr local6; // The full 128-bits of the destination IPv6 address
-} ClatIngress6Key;
-STRUCT_SIZE(ClatIngress6Key, 4 + 2 * 16); // 36
-
-typedef struct {
- uint32_t oif; // The output interface to redirect to (0 means don't redirect)
- struct in_addr local4; // The destination IPv4 address
-} ClatIngress6Value;
-STRUCT_SIZE(ClatIngress6Value, 4 + 4); // 8
-
-#define CLAT_EGRESS4_PROG_RAWIP_NAME "prog_clatd_schedcls_egress4_clat_rawip"
-#define CLAT_EGRESS4_PROG_ETHER_NAME "prog_clatd_schedcls_egress4_clat_ether"
-
-#define CLAT_EGRESS4_PROG_RAWIP_PATH BPF_PATH CLAT_EGRESS4_PROG_RAWIP_NAME
-#define CLAT_EGRESS4_PROG_ETHER_PATH BPF_PATH CLAT_EGRESS4_PROG_ETHER_NAME
-
-#define CLAT_EGRESS4_MAP_PATH BPF_PATH "map_clatd_clat_egress4_map"
-
-typedef struct {
- uint32_t iif; // The input interface index
- struct in_addr local4; // The source IPv4 address
-} ClatEgress4Key;
-STRUCT_SIZE(ClatEgress4Key, 4 + 4); // 8
-
-typedef struct {
- uint32_t oif; // The output interface to redirect to
- struct in6_addr local6; // The full 128-bits of the source IPv6 address
- struct in6_addr pfx96; // The destination /96 nat64 prefix, bottom 32 bits must be 0
- bool oifIsEthernet; // Whether the output interface requires ethernet header
- uint8_t pad[3];
-} ClatEgress4Value;
-STRUCT_SIZE(ClatEgress4Value, 4 + 2 * 16 + 1 + 3); // 40
-
-#undef STRUCT_SIZE
diff --git a/libnetdutils/Android.bp b/libnetdutils/Android.bp
deleted file mode 100644
index 31f2c53..0000000
--- a/libnetdutils/Android.bp
+++ /dev/null
@@ -1,70 +0,0 @@
-package {
- // See: http://go/android-license-faq
- // A large-scale-change added 'default_applicable_licenses' to import
- // all of the 'license_kinds' from "system_netd_license"
- // to get the below license kinds:
- // SPDX-license-identifier-Apache-2.0
- default_applicable_licenses: ["system_netd_license"],
-}
-
-cc_library {
- name: "libnetdutils",
- srcs: [
- "DumpWriter.cpp",
- "Fd.cpp",
- "InternetAddresses.cpp",
- "Log.cpp",
- "Netfilter.cpp",
- "Netlink.cpp",
- "Slice.cpp",
- "Socket.cpp",
- "SocketOption.cpp",
- "Status.cpp",
- "Syscalls.cpp",
- "UniqueFd.cpp",
- "UniqueFile.cpp",
- ],
- defaults: ["netd_defaults"],
- cflags: ["-Wall", "-Werror"],
- shared_libs: [
- "libbase",
- "liblog",
- ],
- export_shared_lib_headers: [
- "libbase",
- ],
- export_include_dirs: ["include"],
- sanitize: {
- cfi: true,
- },
-
- apex_available: [
- "//apex_available:platform",
- "com.android.resolv",
- ],
- min_sdk_version: "29",
-}
-
-cc_test {
- name: "netdutils_test",
- srcs: [
- "BackoffSequenceTest.cpp",
- "FdTest.cpp",
- "InternetAddressesTest.cpp",
- "LogTest.cpp",
- "MemBlockTest.cpp",
- "SliceTest.cpp",
- "StatusTest.cpp",
- "SyscallsTest.cpp",
- "ThreadUtilTest.cpp",
- ],
- defaults: ["netd_defaults"],
- test_suites: ["device-tests"],
- static_libs: [
- "libgmock",
- "libnetdutils",
- ],
- shared_libs: [
- "libbase",
- ],
-}
diff --git a/libnetdutils/BackoffSequenceTest.cpp b/libnetdutils/BackoffSequenceTest.cpp
deleted file mode 100644
index b6653fe..0000000
--- a/libnetdutils/BackoffSequenceTest.cpp
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include <gtest/gtest.h>
-
-#include "netdutils/BackoffSequence.h"
-
-namespace android {
-namespace netdutils {
-
-TEST(BackoffSequence, defaults) {
- BackoffSequence<uint32_t> backoff;
-
- EXPECT_TRUE(backoff.hasNextTimeout());
- EXPECT_EQ(0x00000001U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000002U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000004U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000008U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000010U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000020U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000040U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000080U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000100U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000200U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000400U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000800U, backoff.getNextTimeout());
- EXPECT_EQ(0x00001000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00002000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00004000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00008000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00010000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00020000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00040000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00080000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00100000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00200000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00400000U, backoff.getNextTimeout());
- EXPECT_EQ(0x00800000U, backoff.getNextTimeout());
- EXPECT_EQ(0x01000000U, backoff.getNextTimeout());
- EXPECT_EQ(0x02000000U, backoff.getNextTimeout());
- EXPECT_EQ(0x04000000U, backoff.getNextTimeout());
- EXPECT_EQ(0x08000000U, backoff.getNextTimeout());
- EXPECT_EQ(0x10000000U, backoff.getNextTimeout());
- EXPECT_EQ(0x20000000U, backoff.getNextTimeout());
- EXPECT_EQ(0x40000000U, backoff.getNextTimeout());
- EXPECT_EQ(0x80000000U, backoff.getNextTimeout());
- // Maxes out, and stays there, ad infinitum.
- for (int i = 0; i < 10; i++) {
- EXPECT_TRUE(backoff.hasNextTimeout());
- EXPECT_EQ(0xffffffffU, backoff.getNextTimeout());
- }
-}
-
-TEST(BackoffSequence, backoffToOncePerHour) {
- auto backoff = BackoffSequence<uint32_t>::Builder()
- .withInitialRetransmissionTime(1)
- .withMaximumRetransmissionTime(3600)
- .build();
-
- EXPECT_TRUE(backoff.hasNextTimeout());
- EXPECT_EQ(0x00000001U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000002U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000004U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000008U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000010U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000020U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000040U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000080U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000100U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000200U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000400U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000800U, backoff.getNextTimeout());
- // Maxes out, and stays there, ad infinitum.
- for (int i = 0; i < 10; i++) {
- EXPECT_TRUE(backoff.hasNextTimeout());
- EXPECT_EQ(3600U, backoff.getNextTimeout());
- }
-}
-
-TEST(BackoffSequence, simpleMaxRetransCount) {
- auto backoff = BackoffSequence<uint32_t>::Builder()
- .withInitialRetransmissionTime(3)
- .withMaximumRetransmissionCount(7)
- .build();
-
- EXPECT_TRUE(backoff.hasNextTimeout());
- EXPECT_EQ(0x00000003U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000006U, backoff.getNextTimeout());
- EXPECT_EQ(0x0000000cU, backoff.getNextTimeout());
- EXPECT_EQ(0x00000018U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000030U, backoff.getNextTimeout());
- EXPECT_EQ(0x00000060U, backoff.getNextTimeout());
- EXPECT_EQ(0x000000c0U, backoff.getNextTimeout());
-
- for (int i = 0; i < 10; i++) {
- EXPECT_FALSE(backoff.hasNextTimeout());
- EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout());
- }
-}
-
-TEST(BackoffSequence, simpleMaxDuration) {
- auto backoff = BackoffSequence<int>::Builder()
- .withInitialRetransmissionTime(3)
- .withMaximumRetransmissionDuration(7)
- .withEndOfSequenceIndicator(-1)
- .build();
-
- EXPECT_TRUE(backoff.hasNextTimeout());
- EXPECT_EQ(0x00000003, backoff.getNextTimeout());
- EXPECT_EQ(0x00000004, backoff.getNextTimeout());
-
- for (int i = 0; i < 10; i++) {
- EXPECT_FALSE(backoff.hasNextTimeout());
- EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout());
- EXPECT_EQ(-1, backoff.getNextTimeout());
- }
-}
-
-TEST(PathologicalBackoffSequence, ZeroInitialRetransTime) {
- auto backoff = BackoffSequence<std::chrono::seconds>::Builder()
- .withInitialRetransmissionTime(std::chrono::seconds(0))
- .build();
-
- for (int i = 0; i < 10; i++) {
- // TODO: Decide whether this needs fixing, and how.
- EXPECT_TRUE(backoff.hasNextTimeout());
- EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout());
- }
-}
-
-TEST(PathologicalBackoffSequence, MaxRetransDurationGreaterThanInitialRetransTime) {
- auto backoff = BackoffSequence<std::chrono::milliseconds>::Builder()
- .withInitialRetransmissionTime(std::chrono::milliseconds(5))
- .withMaximumRetransmissionDuration(std::chrono::milliseconds(3))
- .build();
-
- EXPECT_EQ(std::chrono::milliseconds(3), backoff.getNextTimeout());
- for (int i = 0; i < 10; i++) {
- EXPECT_FALSE(backoff.hasNextTimeout());
- EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout());
- }
-}
-
-TEST(PathologicalBackoffSequence, MaxRetransDurationEqualsInitialRetransTime) {
- auto backoff = BackoffSequence<std::chrono::hours>::Builder()
- .withInitialRetransmissionTime(std::chrono::hours(5))
- .withMaximumRetransmissionDuration(std::chrono::hours(5))
- .build();
-
- EXPECT_EQ(std::chrono::hours(5), backoff.getNextTimeout());
- for (int i = 0; i < 10; i++) {
- EXPECT_FALSE(backoff.hasNextTimeout());
- EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout());
- }
-}
-
-TEST(PathologicalBackoffSequence, MaxRetransTimeAndDurationGreaterThanInitialRetransTime) {
- auto backoff = BackoffSequence<std::chrono::nanoseconds>::Builder()
- .withInitialRetransmissionTime(std::chrono::nanoseconds(7))
- .withMaximumRetransmissionTime(std::chrono::nanoseconds(3))
- .withMaximumRetransmissionDuration(std::chrono::nanoseconds(5))
- .build();
-
- EXPECT_EQ(std::chrono::nanoseconds(3), backoff.getNextTimeout());
- EXPECT_EQ(std::chrono::nanoseconds(2), backoff.getNextTimeout());
- for (int i = 0; i < 10; i++) {
- EXPECT_FALSE(backoff.hasNextTimeout());
- EXPECT_EQ(backoff.getEndOfSequenceIndicator(), backoff.getNextTimeout());
- }
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/DumpWriter.cpp b/libnetdutils/DumpWriter.cpp
deleted file mode 100644
index 092ddba..0000000
--- a/libnetdutils/DumpWriter.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#include "netdutils/DumpWriter.h"
-
-#include <unistd.h>
-#include <limits>
-
-#include <android-base/stringprintf.h>
-#include <utils/String8.h>
-
-using android::base::StringAppendV;
-
-namespace android {
-namespace netdutils {
-
-namespace {
-
-const char kIndentString[] = " ";
-const size_t kIndentStringLen = strlen(kIndentString);
-
-} // namespace
-
-DumpWriter::DumpWriter(int fd) : mIndentLevel(0), mFd(fd) {}
-
-void DumpWriter::incIndent() {
- if (mIndentLevel < std::numeric_limits<decltype(mIndentLevel)>::max()) {
- mIndentLevel++;
- }
-}
-
-void DumpWriter::decIndent() {
- if (mIndentLevel > std::numeric_limits<decltype(mIndentLevel)>::min()) {
- mIndentLevel--;
- }
-}
-
-void DumpWriter::println(const std::string& line) {
- if (!line.empty()) {
- for (int i = 0; i < mIndentLevel; i++) {
- ::write(mFd, kIndentString, kIndentStringLen);
- }
- ::write(mFd, line.c_str(), line.size());
- }
- ::write(mFd, "\n", 1);
-}
-
-// NOLINTNEXTLINE(cert-dcl50-cpp): Grandfathered C-style variadic function.
-void DumpWriter::println(const char* fmt, ...) {
- std::string line;
- va_list ap;
- va_start(ap, fmt);
- StringAppendV(&line, fmt, ap);
- va_end(ap);
- println(line);
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/Fd.cpp b/libnetdutils/Fd.cpp
deleted file mode 100644
index 2651f90..0000000
--- a/libnetdutils/Fd.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "netdutils/Fd.h"
-
-namespace android {
-namespace netdutils {
-
-std::ostream& operator<<(std::ostream& os, const Fd& fd) {
- return os << "Fd[" << fd.get() << "]";
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/FdTest.cpp b/libnetdutils/FdTest.cpp
deleted file mode 100644
index 7080f83..0000000
--- a/libnetdutils/FdTest.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <cstdint>
-
-#include <gtest/gtest.h>
-
-#include "netdutils/MockSyscalls.h"
-#include "netdutils/Status.h"
-#include "netdutils/Syscalls.h"
-
-using testing::Mock;
-using testing::Return;
-using testing::StrictMock;
-
-namespace android {
-namespace netdutils {
-namespace {
-
-// Force implicit conversion from UniqueFd -> Fd
-inline Fd toFd(const UniqueFd& fd) {
- return fd;
-}
-
-} // namespace
-
-TEST(Fd, smoke) {
- // Expect the following lines to compile
- Fd fd1(1);
- Fd fd2(fd1);
- Fd fd3 = fd2;
- const Fd fd4(8);
- const Fd fd5(fd4);
- const Fd fd6 = fd5;
- EXPECT_TRUE(isWellFormed(fd3));
- EXPECT_TRUE(isWellFormed(fd6));
-
- // Corner case
- Fd zero(0);
- EXPECT_TRUE(isWellFormed(zero));
-
- // Invalid file descriptors
- Fd bad(-1);
- Fd weird(-9);
- EXPECT_FALSE(isWellFormed(bad));
- EXPECT_FALSE(isWellFormed(weird));
-
- // Default constructor
- EXPECT_EQ(Fd(-1), Fd());
- std::stringstream ss;
- ss << fd3 << " " << fd6 << " " << bad << " " << weird;
- EXPECT_EQ("Fd[1] Fd[8] Fd[-1] Fd[-9]", ss.str());
-}
-
-class UniqueFdTest : public testing::Test {
- protected:
- StrictMock<ScopedMockSyscalls> mSyscalls;
-};
-
-TEST_F(UniqueFdTest, operatorOstream) {
- UniqueFd u(97);
- EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok));
- std::stringstream ss;
- ss << u;
- EXPECT_EQ("UniqueFd[Fd[97]]", ss.str());
- u.reset();
-}
-
-TEST_F(UniqueFdTest, destructor) {
- {
- UniqueFd u(98);
- EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok));
- }
- // Expectation above should be upon leaving nested scope
- Mock::VerifyAndClearExpectations(&mSyscalls);
-}
-
-TEST_F(UniqueFdTest, reset) {
- UniqueFd u(99);
- EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok));
- u.reset();
-
- // Expectation above should be upon reset
- Mock::VerifyAndClearExpectations(&mSyscalls);
-}
-
-TEST_F(UniqueFdTest, moveConstructor) {
- constexpr Fd kFd(101);
- UniqueFd u1(kFd);
- {
- UniqueFd u2(std::move(u1));
- // NOLINTNEXTLINE bugprone-use-after-move
- EXPECT_FALSE(isWellFormed(u1));
- EXPECT_TRUE(isWellFormed(u2));
- EXPECT_CALL(mSyscalls, close(kFd)).WillOnce(Return(status::ok));
- }
- // Expectation above should be upon leaving nested scope
- Mock::VerifyAndClearExpectations(&mSyscalls);
-}
-
-TEST_F(UniqueFdTest, moveAssignment) {
- constexpr Fd kFd(102);
- UniqueFd u1(kFd);
- {
- UniqueFd u2 = std::move(u1);
- // NOLINTNEXTLINE bugprone-use-after-move
- EXPECT_FALSE(isWellFormed(u1));
- EXPECT_TRUE(isWellFormed(u2));
- UniqueFd u3;
- u3 = std::move(u2);
- // NOLINTNEXTLINE bugprone-use-after-move
- EXPECT_FALSE(isWellFormed(u2));
- EXPECT_TRUE(isWellFormed(u3));
- EXPECT_CALL(mSyscalls, close(kFd)).WillOnce(Return(status::ok));
- }
- // Expectation above should be upon leaving nested scope
- Mock::VerifyAndClearExpectations(&mSyscalls);
-}
-
-TEST_F(UniqueFdTest, constConstructor) {
- constexpr Fd kFd(103);
- const UniqueFd u(kFd);
- EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(status::ok));
-}
-
-TEST_F(UniqueFdTest, closeFailure) {
- constexpr Fd kFd(103);
- UniqueFd u(kFd);
- EXPECT_CALL(mSyscalls, close(toFd(u))).WillOnce(Return(statusFromErrno(EINTR, "test")));
- EXPECT_DEBUG_DEATH(u.reset(), "");
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/InternetAddresses.cpp b/libnetdutils/InternetAddresses.cpp
deleted file mode 100644
index 322f1b1..0000000
--- a/libnetdutils/InternetAddresses.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include "netdutils/InternetAddresses.h"
-
-#include <string>
-
-#include <android-base/stringprintf.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-namespace android {
-
-using base::StringPrintf;
-
-namespace netdutils {
-
-std::string IPAddress::toString() const noexcept {
- char repr[INET6_ADDRSTRLEN] = "\0";
-
- switch (mData.family) {
- case AF_UNSPEC:
- return "<unspecified>";
- case AF_INET: {
- const in_addr v4 = mData.ip.v4;
- inet_ntop(AF_INET, &v4, repr, sizeof(repr));
- break;
- }
- case AF_INET6: {
- const in6_addr v6 = mData.ip.v6;
- inet_ntop(AF_INET6, &v6, repr, sizeof(repr));
- break;
- }
- default:
- return "<unknown_family>";
- }
-
- if (mData.family == AF_INET6 && mData.scope_id > 0) {
- return StringPrintf("%s%%%u", repr, mData.scope_id);
- }
-
- return repr;
-}
-
-bool IPAddress::forString(const std::string& repr, IPAddress* ip) {
- const addrinfo hints = {
- .ai_flags = AI_NUMERICHOST | AI_NUMERICSERV,
- };
- addrinfo* res;
- const int ret = getaddrinfo(repr.c_str(), nullptr, &hints, &res);
- ScopedAddrinfo res_cleanup(res);
- if (ret != 0) {
- return false;
- }
-
- bool rval = true;
- switch (res[0].ai_family) {
- case AF_INET: {
- sockaddr_in* sin = (sockaddr_in*) res[0].ai_addr;
- if (ip) *ip = IPAddress(sin->sin_addr);
- break;
- }
- case AF_INET6: {
- sockaddr_in6* sin6 = (sockaddr_in6*) res[0].ai_addr;
- if (ip) *ip = IPAddress(sin6->sin6_addr, sin6->sin6_scope_id);
- break;
- }
- default:
- rval = false;
- break;
- }
-
- return rval;
-}
-
-IPPrefix::IPPrefix(const IPAddress& ip, int length) : IPPrefix(ip) {
- // Silently treat CIDR lengths like "-1" as meaning the full bit length
- // appropriate to the address family.
- if (length < 0) return;
- if (length >= mData.cidrlen) return;
-
- switch (mData.family) {
- case AF_UNSPEC:
- break;
- case AF_INET: {
- const in_addr_t mask = (length > 0) ? (~0U) << (IPV4_ADDR_BITS - length) : 0U;
- mData.ip.v4.s_addr &= htonl(mask);
- mData.cidrlen = static_cast<uint8_t>(length);
- break;
- }
- case AF_INET6: {
- // The byte in which this CIDR length falls.
- const int which = length / 8;
- const int mask = (length % 8 == 0) ? 0 : 0xff << (8 - length % 8);
- mData.ip.v6.s6_addr[which] &= mask;
- for (int i = which + 1; i < IPV6_ADDR_LEN; i++) {
- mData.ip.v6.s6_addr[i] = 0U;
- }
- mData.cidrlen = static_cast<uint8_t>(length);
- break;
- }
- default:
- // TODO: Complain bitterly about possible data corruption?
- return;
- }
-}
-
-bool IPPrefix::isUninitialized() const noexcept {
- static const internal_::compact_ipdata empty{};
- return mData == empty;
-}
-
-bool IPPrefix::forString(const std::string& repr, IPPrefix* prefix) {
- size_t index = repr.find('/');
- if (index == std::string::npos) return false;
-
- // Parse the IP address.
- IPAddress ip;
- if (!IPAddress::forString(repr.substr(0, index), &ip)) return false;
-
- // Parse the prefix length. Can't use base::ParseUint because it accepts non-base 10 input.
- const char* prefixString = repr.c_str() + index + 1;
- if (!isdigit(*prefixString)) return false;
- char* endptr;
- unsigned long prefixlen = strtoul(prefixString, &endptr, 10);
- if (*endptr != '\0') return false;
-
- uint8_t maxlen = (ip.family() == AF_INET) ? 32 : 128;
- if (prefixlen > maxlen) return false;
-
- *prefix = IPPrefix(ip, prefixlen);
- return true;
-}
-
-std::string IPPrefix::toString() const noexcept {
- return StringPrintf("%s/%d", ip().toString().c_str(), mData.cidrlen);
-}
-
-std::string IPSockAddr::toString() const noexcept {
- switch (mData.family) {
- case AF_INET6:
- return StringPrintf("[%s]:%u", ip().toString().c_str(), mData.port);
- default:
- return StringPrintf("%s:%u", ip().toString().c_str(), mData.port);
- }
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/InternetAddressesTest.cpp b/libnetdutils/InternetAddressesTest.cpp
deleted file mode 100644
index f75fa76..0000000
--- a/libnetdutils/InternetAddressesTest.cpp
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include <cstdint>
-#include <limits>
-#include <sstream>
-#include <string>
-#include <vector>
-
-#include <android-base/macros.h>
-#include <gtest/gtest.h>
-
-#include "netdutils/InternetAddresses.h"
-
-namespace android {
-namespace netdutils {
-namespace {
-
-enum Relation { EQ, LT };
-
-std::ostream& operator<<(std::ostream& os, Relation relation) {
- switch (relation) {
- case EQ: os << "eq"; break;
- case LT: os << "lt"; break;
- default: os << "?!"; break;
- }
- return os;
-}
-
-template <typename T>
-struct OperatorExpectation {
- const Relation relation;
- const T obj1;
- const T obj2;
-
- std::string toString() const {
- std::stringstream output;
- output << obj1 << " " << relation << " " << obj2;
- return output.str();
- }
-};
-
-template <typename T>
-void testGamutOfOperators(const OperatorExpectation<T>& expectation) {
- switch (expectation.relation) {
- case EQ:
- EXPECT_TRUE(expectation.obj1 == expectation.obj2);
- EXPECT_TRUE(expectation.obj1 <= expectation.obj2);
- EXPECT_TRUE(expectation.obj1 >= expectation.obj2);
- EXPECT_FALSE(expectation.obj1 != expectation.obj2);
- EXPECT_FALSE(expectation.obj1 < expectation.obj2);
- EXPECT_FALSE(expectation.obj1 > expectation.obj2);
- break;
-
- case LT:
- EXPECT_TRUE(expectation.obj1 < expectation.obj2);
- EXPECT_TRUE(expectation.obj1 <= expectation.obj2);
- EXPECT_TRUE(expectation.obj1 != expectation.obj2);
- EXPECT_FALSE(expectation.obj1 > expectation.obj2);
- EXPECT_FALSE(expectation.obj1 >= expectation.obj2);
- EXPECT_FALSE(expectation.obj1 == expectation.obj2);
- break;
-
- default:
- FAIL() << "Unknown relation given in test expectation";
- }
-}
-
-const in_addr IPV4_ANY{htonl(INADDR_ANY)};
-const in_addr IPV4_LOOPBACK{htonl(INADDR_LOOPBACK)};
-const in_addr IPV4_ONES{~0U};
-const in6_addr IPV6_ANY = IN6ADDR_ANY_INIT;
-const in6_addr IPV6_LOOPBACK = IN6ADDR_LOOPBACK_INIT;
-const in6_addr FE80{{{0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,0}}};
-const in6_addr FE80_1{{{0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,1}}};
-const in6_addr FE80_2{{{0xfe,0x80,0,0,0,0,0,0,0,0,0,0,0,0,0,2}}};
-const uint8_t ff = std::numeric_limits<uint8_t>::max();
-const in6_addr IPV6_ONES{{{ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff,ff}}};
-
-TEST(IPAddressTest, GamutOfOperators) {
- const std::vector<OperatorExpectation<IPAddress>> kExpectations{
- {EQ, IPAddress(), IPAddress()},
- {EQ, IPAddress(IPV4_ONES), IPAddress(IPV4_ONES)},
- {EQ, IPAddress(IPV6_ONES), IPAddress(IPV6_ONES)},
- {EQ, IPAddress(FE80_1), IPAddress(FE80_1)},
- {EQ, IPAddress(FE80_2), IPAddress(FE80_2)},
- {LT, IPAddress(), IPAddress(IPV4_ANY)},
- {LT, IPAddress(), IPAddress(IPV4_ONES)},
- {LT, IPAddress(), IPAddress(IPV6_ANY)},
- {LT, IPAddress(), IPAddress(IPV6_ONES)},
- {LT, IPAddress(IPV4_ANY), IPAddress(IPV4_ONES)},
- {LT, IPAddress(IPV4_ANY), IPAddress(IPV6_ANY)},
- {LT, IPAddress(IPV4_ONES), IPAddress(IPV6_ANY)},
- {LT, IPAddress(IPV4_ONES), IPAddress(IPV6_ONES)},
- {LT, IPAddress(IPV6_ANY), IPAddress(IPV6_LOOPBACK)},
- {LT, IPAddress(IPV6_ANY), IPAddress(IPV6_ONES)},
- {LT, IPAddress(IPV6_LOOPBACK), IPAddress(IPV6_ONES)},
- {LT, IPAddress(FE80_1), IPAddress(FE80_2)},
- {LT, IPAddress(FE80_1), IPAddress(IPV6_ONES)},
- {LT, IPAddress(FE80_2), IPAddress(IPV6_ONES)},
- // Sort by scoped_id within the same address.
- {LT, IPAddress(FE80_1), IPAddress(FE80_1, 1)},
- {LT, IPAddress(FE80_1, 1), IPAddress(FE80_1, 2)},
- // Sort by address first, scope_id second.
- {LT, IPAddress(FE80_1, 2), IPAddress(FE80_2, 1)},
- };
-
- size_t tests_run = 0;
- for (const auto& expectation : kExpectations) {
- SCOPED_TRACE(expectation.toString());
- EXPECT_NO_FATAL_FAILURE(testGamutOfOperators(expectation));
- tests_run++;
- }
- EXPECT_EQ(kExpectations.size(), tests_run);
-}
-
-TEST(IPAddressTest, ScopeIds) {
- // Scope IDs ignored for IPv4 addresses.
- const IPAddress ones(IPV4_ONES);
- EXPECT_EQ(0U, ones.scope_id());
- const IPAddress ones22(ones, 22);
- EXPECT_EQ(0U, ones22.scope_id());
- EXPECT_EQ(ones, ones22);
- const IPAddress ones23(ones, 23);
- EXPECT_EQ(0U, ones23.scope_id());
- EXPECT_EQ(ones22, ones23);
-
- EXPECT_EQ("fe80::1%22", IPAddress(FE80_1, 22).toString());
- EXPECT_EQ("fe80::2%23", IPAddress(FE80_2, 23).toString());
-
- // Verify that given an IPAddress with a scope_id an address without a
- // scope_id can be constructed (just in case it's useful).
- const IPAddress fe80_intf22(FE80_1, 22);
- EXPECT_EQ(22U, fe80_intf22.scope_id());
- EXPECT_EQ(fe80_intf22, IPAddress(fe80_intf22));
- EXPECT_EQ(IPAddress(FE80_1), IPAddress(fe80_intf22, 0));
-}
-
-TEST(IPAddressTest, forString) {
- IPAddress ip;
-
- EXPECT_FALSE(IPAddress::forString("not_an_ip", &ip));
- EXPECT_FALSE(IPAddress::forString("not_an_ip", nullptr));
- EXPECT_EQ(IPAddress(), IPAddress::forString("not_an_ip"));
-
- EXPECT_EQ(IPAddress(IPV4_ANY), IPAddress::forString("0.0.0.0"));
- EXPECT_EQ(IPAddress(IPV4_ONES), IPAddress::forString("255.255.255.255"));
- EXPECT_EQ(IPAddress(IPV4_LOOPBACK), IPAddress::forString("127.0.0.1"));
-
- EXPECT_EQ(IPAddress(IPV6_ANY), IPAddress::forString("::"));
- EXPECT_EQ(IPAddress(IPV6_ANY), IPAddress::forString("::0"));
- EXPECT_EQ(IPAddress(IPV6_ANY), IPAddress::forString("0::"));
- EXPECT_EQ(IPAddress(IPV6_LOOPBACK), IPAddress::forString("::1"));
- EXPECT_EQ(IPAddress(IPV6_LOOPBACK), IPAddress::forString("0::1"));
- EXPECT_EQ(IPAddress(FE80_1), IPAddress::forString("fe80::1"));
- EXPECT_EQ(IPAddress(FE80_1, 22), IPAddress::forString("fe80::1%22"));
- // This relies upon having a loopback interface named "lo" with ifindex 1.
- EXPECT_EQ(IPAddress(FE80_1, 1), IPAddress::forString("fe80::1%lo"));
-}
-
-TEST(IPPrefixTest, forString) {
- IPPrefix prefix;
-
- EXPECT_FALSE(IPPrefix::forString("", &prefix));
- EXPECT_FALSE(IPPrefix::forString("invalid", &prefix));
- EXPECT_FALSE(IPPrefix::forString("192.0.2.0", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001::db8::", &prefix));
-
- EXPECT_FALSE(IPPrefix::forString("2001:db8::/", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001:db8:://32", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001:db8::/32z", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001:db8::/32/", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001:db8::/0x20", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001:db8:: /32", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001:db8::/ 32", &prefix));
- EXPECT_FALSE(IPPrefix::forString(" 2001:db8::/32", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001:db8::/32 ", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001:db8::/+32", &prefix));
-
- EXPECT_FALSE(IPPrefix::forString("192.0.2.0/33", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001:db8::/129", &prefix));
- EXPECT_FALSE(IPPrefix::forString("192.0.2.0/-1", &prefix));
- EXPECT_FALSE(IPPrefix::forString("2001:db8::/-1", &prefix));
-
- EXPECT_TRUE(IPPrefix::forString("2001:db8::/32", &prefix));
- EXPECT_EQ("2001:db8::/32", prefix.toString());
- EXPECT_EQ(IPPrefix(IPAddress::forString("2001:db8::"), 32), prefix);
-
- EXPECT_EQ(IPPrefix(), IPPrefix::forString("invalid"));
-
- EXPECT_EQ("0.0.0.0/0", IPPrefix::forString("0.0.0.0/0").toString());
- EXPECT_EQ("::/0", IPPrefix::forString("::/0").toString());
- EXPECT_EQ("192.0.2.128/25", IPPrefix::forString("192.0.2.131/25").toString());
- EXPECT_EQ("2001:db8:1:2:3:4:5:4/126",
- IPPrefix::forString("2001:db8:1:2:3:4:5:6/126").toString());
-}
-
-TEST(IPPrefixTest, IPv4Truncation) {
- const auto prefixStr = [](int length) -> std::string {
- return IPPrefix(IPAddress(IPV4_ONES), length).toString();
- };
-
- EXPECT_EQ("0.0.0.0/0", prefixStr(0));
-
- EXPECT_EQ("128.0.0.0/1", prefixStr(1));
- EXPECT_EQ("192.0.0.0/2", prefixStr(2));
- EXPECT_EQ("224.0.0.0/3", prefixStr(3));
- EXPECT_EQ("240.0.0.0/4", prefixStr(4));
- EXPECT_EQ("248.0.0.0/5", prefixStr(5));
- EXPECT_EQ("252.0.0.0/6", prefixStr(6));
- EXPECT_EQ("254.0.0.0/7", prefixStr(7));
- EXPECT_EQ("255.0.0.0/8", prefixStr(8));
-
- EXPECT_EQ("255.128.0.0/9", prefixStr(9));
- EXPECT_EQ("255.192.0.0/10", prefixStr(10));
- EXPECT_EQ("255.224.0.0/11", prefixStr(11));
- EXPECT_EQ("255.240.0.0/12", prefixStr(12));
- EXPECT_EQ("255.248.0.0/13", prefixStr(13));
- EXPECT_EQ("255.252.0.0/14", prefixStr(14));
- EXPECT_EQ("255.254.0.0/15", prefixStr(15));
- EXPECT_EQ("255.255.0.0/16", prefixStr(16));
-
- EXPECT_EQ("255.255.128.0/17", prefixStr(17));
- EXPECT_EQ("255.255.192.0/18", prefixStr(18));
- EXPECT_EQ("255.255.224.0/19", prefixStr(19));
- EXPECT_EQ("255.255.240.0/20", prefixStr(20));
- EXPECT_EQ("255.255.248.0/21", prefixStr(21));
- EXPECT_EQ("255.255.252.0/22", prefixStr(22));
- EXPECT_EQ("255.255.254.0/23", prefixStr(23));
- EXPECT_EQ("255.255.255.0/24", prefixStr(24));
-
- EXPECT_EQ("255.255.255.128/25", prefixStr(25));
- EXPECT_EQ("255.255.255.192/26", prefixStr(26));
- EXPECT_EQ("255.255.255.224/27", prefixStr(27));
- EXPECT_EQ("255.255.255.240/28", prefixStr(28));
- EXPECT_EQ("255.255.255.248/29", prefixStr(29));
- EXPECT_EQ("255.255.255.252/30", prefixStr(30));
- EXPECT_EQ("255.255.255.254/31", prefixStr(31));
- EXPECT_EQ("255.255.255.255/32", prefixStr(32));
-}
-
-TEST(IPPrefixTest, IPv6Truncation) {
- const auto prefixStr = [](int length) -> std::string {
- return IPPrefix(IPAddress(IPV6_ONES), length).toString();
- };
-
- EXPECT_EQ("::/0", prefixStr(0));
-
- EXPECT_EQ("8000::/1", prefixStr(1));
- EXPECT_EQ("c000::/2", prefixStr(2));
- EXPECT_EQ("e000::/3", prefixStr(3));
- EXPECT_EQ("f000::/4", prefixStr(4));
- EXPECT_EQ("f800::/5", prefixStr(5));
- EXPECT_EQ("fc00::/6", prefixStr(6));
- EXPECT_EQ("fe00::/7", prefixStr(7));
- EXPECT_EQ("ff00::/8", prefixStr(8));
-
- EXPECT_EQ("ff80::/9", prefixStr(9));
- EXPECT_EQ("ffc0::/10", prefixStr(10));
- EXPECT_EQ("ffe0::/11", prefixStr(11));
- EXPECT_EQ("fff0::/12", prefixStr(12));
- EXPECT_EQ("fff8::/13", prefixStr(13));
- EXPECT_EQ("fffc::/14", prefixStr(14));
- EXPECT_EQ("fffe::/15", prefixStr(15));
- EXPECT_EQ("ffff::/16", prefixStr(16));
-
- EXPECT_EQ("ffff:8000::/17", prefixStr(17));
- EXPECT_EQ("ffff:c000::/18", prefixStr(18));
- EXPECT_EQ("ffff:e000::/19", prefixStr(19));
- EXPECT_EQ("ffff:f000::/20", prefixStr(20));
- EXPECT_EQ("ffff:f800::/21", prefixStr(21));
- EXPECT_EQ("ffff:fc00::/22", prefixStr(22));
- EXPECT_EQ("ffff:fe00::/23", prefixStr(23));
- EXPECT_EQ("ffff:ff00::/24", prefixStr(24));
-
- EXPECT_EQ("ffff:ff80::/25", prefixStr(25));
- EXPECT_EQ("ffff:ffc0::/26", prefixStr(26));
- EXPECT_EQ("ffff:ffe0::/27", prefixStr(27));
- EXPECT_EQ("ffff:fff0::/28", prefixStr(28));
- EXPECT_EQ("ffff:fff8::/29", prefixStr(29));
- EXPECT_EQ("ffff:fffc::/30", prefixStr(30));
- EXPECT_EQ("ffff:fffe::/31", prefixStr(31));
- EXPECT_EQ("ffff:ffff::/32", prefixStr(32));
-
- EXPECT_EQ("ffff:ffff:8000::/33", prefixStr(33));
- EXPECT_EQ("ffff:ffff:c000::/34", prefixStr(34));
- EXPECT_EQ("ffff:ffff:e000::/35", prefixStr(35));
- EXPECT_EQ("ffff:ffff:f000::/36", prefixStr(36));
- EXPECT_EQ("ffff:ffff:f800::/37", prefixStr(37));
- EXPECT_EQ("ffff:ffff:fc00::/38", prefixStr(38));
- EXPECT_EQ("ffff:ffff:fe00::/39", prefixStr(39));
- EXPECT_EQ("ffff:ffff:ff00::/40", prefixStr(40));
-
- EXPECT_EQ("ffff:ffff:ff80::/41", prefixStr(41));
- EXPECT_EQ("ffff:ffff:ffc0::/42", prefixStr(42));
- EXPECT_EQ("ffff:ffff:ffe0::/43", prefixStr(43));
- EXPECT_EQ("ffff:ffff:fff0::/44", prefixStr(44));
- EXPECT_EQ("ffff:ffff:fff8::/45", prefixStr(45));
- EXPECT_EQ("ffff:ffff:fffc::/46", prefixStr(46));
- EXPECT_EQ("ffff:ffff:fffe::/47", prefixStr(47));
- EXPECT_EQ("ffff:ffff:ffff::/48", prefixStr(48));
-
- EXPECT_EQ("ffff:ffff:ffff:8000::/49", prefixStr(49));
- EXPECT_EQ("ffff:ffff:ffff:c000::/50", prefixStr(50));
- EXPECT_EQ("ffff:ffff:ffff:e000::/51", prefixStr(51));
- EXPECT_EQ("ffff:ffff:ffff:f000::/52", prefixStr(52));
- EXPECT_EQ("ffff:ffff:ffff:f800::/53", prefixStr(53));
- EXPECT_EQ("ffff:ffff:ffff:fc00::/54", prefixStr(54));
- EXPECT_EQ("ffff:ffff:ffff:fe00::/55", prefixStr(55));
- EXPECT_EQ("ffff:ffff:ffff:ff00::/56", prefixStr(56));
-
- EXPECT_EQ("ffff:ffff:ffff:ff80::/57", prefixStr(57));
- EXPECT_EQ("ffff:ffff:ffff:ffc0::/58", prefixStr(58));
- EXPECT_EQ("ffff:ffff:ffff:ffe0::/59", prefixStr(59));
- EXPECT_EQ("ffff:ffff:ffff:fff0::/60", prefixStr(60));
- EXPECT_EQ("ffff:ffff:ffff:fff8::/61", prefixStr(61));
- EXPECT_EQ("ffff:ffff:ffff:fffc::/62", prefixStr(62));
- EXPECT_EQ("ffff:ffff:ffff:fffe::/63", prefixStr(63));
- EXPECT_EQ("ffff:ffff:ffff:ffff::/64", prefixStr(64));
-
- EXPECT_EQ("ffff:ffff:ffff:ffff:8000::/65", prefixStr(65));
- EXPECT_EQ("ffff:ffff:ffff:ffff:c000::/66", prefixStr(66));
- EXPECT_EQ("ffff:ffff:ffff:ffff:e000::/67", prefixStr(67));
- EXPECT_EQ("ffff:ffff:ffff:ffff:f000::/68", prefixStr(68));
- EXPECT_EQ("ffff:ffff:ffff:ffff:f800::/69", prefixStr(69));
- EXPECT_EQ("ffff:ffff:ffff:ffff:fc00::/70", prefixStr(70));
- EXPECT_EQ("ffff:ffff:ffff:ffff:fe00::/71", prefixStr(71));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ff00::/72", prefixStr(72));
-
- EXPECT_EQ("ffff:ffff:ffff:ffff:ff80::/73", prefixStr(73));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffc0::/74", prefixStr(74));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffe0::/75", prefixStr(75));
- EXPECT_EQ("ffff:ffff:ffff:ffff:fff0::/76", prefixStr(76));
- EXPECT_EQ("ffff:ffff:ffff:ffff:fff8::/77", prefixStr(77));
- EXPECT_EQ("ffff:ffff:ffff:ffff:fffc::/78", prefixStr(78));
- EXPECT_EQ("ffff:ffff:ffff:ffff:fffe::/79", prefixStr(79));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff::/80", prefixStr(80));
-
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:8000::/81", prefixStr(81));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:c000::/82", prefixStr(82));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:e000::/83", prefixStr(83));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:f000::/84", prefixStr(84));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:f800::/85", prefixStr(85));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fc00::/86", prefixStr(86));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fe00::/87", prefixStr(87));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ff00::/88", prefixStr(88));
-
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ff80::/89", prefixStr(89));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffc0::/90", prefixStr(90));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffe0::/91", prefixStr(91));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fff0::/92", prefixStr(92));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fff8::/93", prefixStr(93));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fffc::/94", prefixStr(94));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:fffe::/95", prefixStr(95));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff::/96", prefixStr(96));
-
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:8000:0/97", prefixStr(97));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:c000:0/98", prefixStr(98));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:e000:0/99", prefixStr(99));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:f000:0/100", prefixStr(100));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:f800:0/101", prefixStr(101));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fc00:0/102", prefixStr(102));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fe00:0/103", prefixStr(103));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ff00:0/104", prefixStr(104));
-
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ff80:0/105", prefixStr(105));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffc0:0/106", prefixStr(106));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffe0:0/107", prefixStr(107));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fff0:0/108", prefixStr(108));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fff8:0/109", prefixStr(109));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fffc:0/110", prefixStr(110));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:fffe:0/111", prefixStr(111));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:0/112", prefixStr(112));
-
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:8000/113", prefixStr(113));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:c000/114", prefixStr(114));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:e000/115", prefixStr(115));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:f000/116", prefixStr(116));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:f800/117", prefixStr(117));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fc00/118", prefixStr(118));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fe00/119", prefixStr(119));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff00/120", prefixStr(120));
-
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ff80/121", prefixStr(121));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffc0/122", prefixStr(122));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffe0/123", prefixStr(123));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff0/124", prefixStr(124));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fff8/125", prefixStr(125));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffc/126", prefixStr(126));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:fffe/127", prefixStr(127));
- EXPECT_EQ("ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128", prefixStr(128));
-}
-
-TEST(IPPrefixTest, TruncationOther) {
- const struct {
- const char* ip;
- const int cidrLen;
- const char* ipTruncated;
- } testExpectations[] = {
- {"192.0.2.0", 24, "192.0.2.0"},
- {"192.0.2.0", 23, "192.0.2.0"},
- {"192.0.2.0", 22, "192.0.0.0"},
- {"192.0.2.0", 1, "128.0.0.0"},
- {"2001:db8:cafe:d00d::", 56, "2001:db8:cafe:d000::"},
- {"2001:db8:cafe:d00d::", 48, "2001:db8:cafe::"},
- {"2001:db8:cafe:d00d::", 47, "2001:db8:cafe::"},
- {"2001:db8:cafe:d00d::", 46, "2001:db8:cafc::"},
- };
-
- for (const auto& expectation : testExpectations) {
- IPAddress ip;
- EXPECT_TRUE(IPAddress::forString(expectation.ip, &ip))
- << "Failed to parse IP address " << expectation.ip;
-
- IPAddress ipTruncated;
- EXPECT_TRUE(IPAddress::forString(expectation.ipTruncated, &ipTruncated))
- << "Failed to parse IP address " << expectation.ipTruncated;
-
- IPPrefix prefix(ip, expectation.cidrLen);
-
- EXPECT_EQ(expectation.cidrLen, prefix.length())
- << "Unexpected cidrLen " << expectation.cidrLen;
- EXPECT_EQ(ipTruncated, prefix.ip())
- << "Unexpected IP truncation: " << prefix.ip() << ", expected: " << ipTruncated;
- }
-}
-
-TEST(IPPrefixTest, GamutOfOperators) {
- const std::vector<OperatorExpectation<IPPrefix>> kExpectations{
- {EQ, IPPrefix(), IPPrefix()},
- {EQ, IPPrefix(IPAddress(IPV4_ANY), 0), IPPrefix(IPAddress(IPV4_ANY), 0)},
- {EQ, IPPrefix(IPAddress(IPV4_ANY), IPV4_ADDR_BITS), IPPrefix(IPAddress(IPV4_ANY))},
- {EQ, IPPrefix(IPAddress(IPV6_ANY), 0), IPPrefix(IPAddress(IPV6_ANY), 0)},
- {EQ, IPPrefix(IPAddress(IPV6_ANY), IPV6_ADDR_BITS), IPPrefix(IPAddress(IPV6_ANY))},
- // Needlessly fully-specified IPv6 link-local address.
- {EQ, IPPrefix(IPAddress(FE80_1)), IPPrefix(IPAddress(FE80_1, 0), IPV6_ADDR_BITS)},
- // Different IPv6 link-local addresses within the same /64, no scoped_id: same /64.
- {EQ, IPPrefix(IPAddress(FE80_1), 64), IPPrefix(IPAddress(FE80_2), 64)},
- // Different IPv6 link-local address within the same /64, same scoped_id: same /64.
- {EQ, IPPrefix(IPAddress(FE80_1, 17), 64), IPPrefix(IPAddress(FE80_2, 17), 64)},
- // Unspecified < IPv4.
- {LT, IPPrefix(), IPPrefix(IPAddress(IPV4_ANY), 0)},
- // Same IPv4 base address sorts by prefix length.
- {LT, IPPrefix(IPAddress(IPV4_ANY), 0), IPPrefix(IPAddress(IPV4_ANY), 1)},
- {LT, IPPrefix(IPAddress(IPV4_ANY), 1), IPPrefix(IPAddress(IPV4_ANY), IPV4_ADDR_BITS)},
- // Truncation means each base IPv4 address is different.
- {LT, IPPrefix(IPAddress(IPV4_ONES), 0), IPPrefix(IPAddress(IPV4_ONES), 1)},
- {LT, IPPrefix(IPAddress(IPV4_ONES), 1), IPPrefix(IPAddress(IPV4_ONES), IPV4_ADDR_BITS)},
- // Sort by base IPv4 addresses first.
- {LT, IPPrefix(IPAddress(IPV4_ANY), 0), IPPrefix(IPAddress::forString("0.0.0.1"))},
- {LT, IPPrefix(IPAddress(IPV4_ANY), 1), IPPrefix(IPAddress::forString("0.0.0.1"))},
- {LT, IPPrefix(IPAddress(IPV4_ANY), 24), IPPrefix(IPAddress::forString("0.0.0.1"))},
- // IPv4 < IPv6.
- {LT, IPPrefix(IPAddress(IPV4_ANY), 0), IPPrefix(IPAddress(IPV6_ANY), 0)},
- {LT, IPPrefix(IPAddress(IPV4_ONES)), IPPrefix(IPAddress(IPV6_ANY))},
- // Unspecified < IPv6.
- {LT, IPPrefix(), IPPrefix(IPAddress(IPV6_ANY), 0)},
- // Same IPv6 base address sorts by prefix length.
- {LT, IPPrefix(IPAddress(IPV6_ANY), 0), IPPrefix(IPAddress(IPV6_ANY), 1)},
- {LT, IPPrefix(IPAddress(IPV6_ANY), 1), IPPrefix(IPAddress(IPV6_ANY), IPV6_ADDR_BITS)},
- // Truncation means each base IPv6 address is different.
- {LT, IPPrefix(IPAddress(IPV6_ONES), 0), IPPrefix(IPAddress(IPV6_ONES), 1)},
- {LT, IPPrefix(IPAddress(IPV6_ONES), 1), IPPrefix(IPAddress(IPV6_ONES), IPV6_ADDR_BITS)},
- // Different IPv6 link-local address in same /64, different scoped_id: different /64.
- {LT, IPPrefix(IPAddress(FE80_1, 17), 64), IPPrefix(IPAddress(FE80_2, 22), 64)},
- {LT, IPPrefix(IPAddress(FE80_1, 17), 64), IPPrefix(IPAddress(FE80_1, 18), 64)},
- {LT, IPPrefix(IPAddress(FE80_1, 18), 64), IPPrefix(IPAddress(FE80_1, 19), 64)},
- };
-
- size_t tests_run = 0;
- for (const auto& expectation : kExpectations) {
- SCOPED_TRACE(expectation.toString());
- EXPECT_NO_FATAL_FAILURE(testGamutOfOperators(expectation));
- tests_run++;
- }
- EXPECT_EQ(kExpectations.size(), tests_run);
-}
-
-TEST(IPSockAddrTest, GamutOfOperators) {
- const std::vector<OperatorExpectation<IPSockAddr>> kExpectations{
- {EQ, IPSockAddr(), IPSockAddr()},
- {EQ, IPSockAddr(IPAddress(IPV4_ANY)), IPSockAddr(IPAddress(IPV4_ANY), 0)},
- {EQ, IPSockAddr(IPAddress(IPV6_ANY)), IPSockAddr(IPAddress(IPV6_ANY), 0)},
- {EQ, IPSockAddr(IPAddress(FE80_1), 80), IPSockAddr(IPAddress(FE80_1), 80)},
- {EQ, IPSockAddr(IPAddress(FE80_1, 17)), IPSockAddr(IPAddress(FE80_1, 17), 0)},
- {LT, IPSockAddr(IPAddress(IPV4_ANY), 0), IPSockAddr(IPAddress(IPV4_ANY), 1)},
- {LT, IPSockAddr(IPAddress(IPV4_ANY), 53), IPSockAddr(IPAddress(IPV4_ANY), 123)},
- {LT, IPSockAddr(IPAddress(IPV4_ONES), 123), IPSockAddr(IPAddress(IPV6_ANY), 53)},
- {LT, IPSockAddr(IPAddress(IPV6_ANY), 0), IPSockAddr(IPAddress(IPV6_ANY), 1)},
- {LT, IPSockAddr(IPAddress(IPV6_ANY), 53), IPSockAddr(IPAddress(IPV6_ANY), 123)},
- {LT, IPSockAddr(IPAddress(FE80_1), 80), IPSockAddr(IPAddress(FE80_1, 17), 80)},
- {LT, IPSockAddr(IPAddress(FE80_1, 17), 80), IPSockAddr(IPAddress(FE80_1, 22), 80)},
- };
-
- size_t tests_run = 0;
- for (const auto& expectation : kExpectations) {
- SCOPED_TRACE(expectation.toString());
- EXPECT_NO_FATAL_FAILURE(testGamutOfOperators(expectation));
- tests_run++;
- }
- EXPECT_EQ(kExpectations.size(), tests_run);
-}
-
-TEST(IPSockAddrTest, toString) {
- EXPECT_EQ("<unspecified>:0", IPSockAddr().toString());
- EXPECT_EQ("0.0.0.0:0", IPSockAddr(IPAddress(IPV4_ANY)).toString());
- EXPECT_EQ("255.255.255.255:67", IPSockAddr(IPAddress(IPV4_ONES), 67).toString());
- EXPECT_EQ("[::]:0", IPSockAddr(IPAddress(IPV6_ANY)).toString());
- EXPECT_EQ("[::1]:53", IPSockAddr(IPAddress(IPV6_LOOPBACK), 53).toString());
- EXPECT_EQ("[fe80::1]:0", IPSockAddr(IPAddress(FE80_1)).toString());
- EXPECT_EQ("[fe80::2%17]:123", IPSockAddr(IPAddress(FE80_2, 17), 123).toString());
-}
-
-TEST(CompatIPDataTest, ConversionsClearUnneededValues) {
- const uint32_t idx = 17;
- const IPSockAddr linkLocalNtpSockaddr(IPAddress(FE80_2, idx), 123);
- EXPECT_EQ(IPAddress(FE80_2, idx), linkLocalNtpSockaddr.ip());
- // IPSockAddr(IPSockaddr.ip()) see the port cleared.
- EXPECT_EQ(0, IPSockAddr(linkLocalNtpSockaddr.ip()).port());
- const IPPrefix linkLocalPrefix(linkLocalNtpSockaddr.ip(), 64);
- EXPECT_EQ(IPAddress(FE80, idx), linkLocalPrefix.ip());
- // IPPrefix(IPPrefix.ip()) see the CIDR length cleared.
- EXPECT_EQ(IPV6_ADDR_BITS, IPPrefix(linkLocalPrefix.ip()).length());
-}
-
-} // namespace
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/Log.cpp b/libnetdutils/Log.cpp
deleted file mode 100644
index d2ce98f..0000000
--- a/libnetdutils/Log.cpp
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include "netdutils/Log.h"
-#include "netdutils/Slice.h"
-
-#include <chrono>
-#include <ctime>
-#include <iomanip>
-#include <mutex>
-#include <sstream>
-
-#include <android-base/strings.h>
-#include <log/log.h>
-
-using ::android::base::Join;
-using ::android::base::StringPrintf;
-
-namespace android {
-namespace netdutils {
-
-namespace {
-
-std::string makeTimestampedEntry(const std::string& entry) {
- using ::std::chrono::duration_cast;
- using ::std::chrono::milliseconds;
- using ::std::chrono::system_clock;
-
- std::stringstream tsEntry;
- const auto now = system_clock::now();
- const auto time_sec = system_clock::to_time_t(now);
- tsEntry << std::put_time(std::localtime(&time_sec), "%m-%d %H:%M:%S.") << std::setw(3)
- << std::setfill('0')
- << duration_cast<milliseconds>(now - system_clock::from_time_t(time_sec)).count() << " "
- << entry;
-
- return tsEntry.str();
-}
-
-} // namespace
-
-std::string LogEntry::toString() const {
- std::vector<std::string> text;
-
- if (!mMsg.empty()) text.push_back(mMsg);
- if (!mFunc.empty()) {
- text.push_back(StringPrintf("%s(%s)", mFunc.c_str(), Join(mArgs, ", ").c_str()));
- }
- if (!mReturns.empty()) {
- text.push_back("->");
- text.push_back(StringPrintf("(%s)", Join(mReturns, ", ").c_str()));
- }
- if (!mUid.empty()) text.push_back(mUid);
- if (!mDuration.empty()) text.push_back(StringPrintf("(%s)", mDuration.c_str()));
-
- return Join(text, " ");
-}
-
-LogEntry& LogEntry::message(const std::string& message) {
- mMsg = message;
- return *this;
-}
-
-LogEntry& LogEntry::function(const std::string& function_name) {
- mFunc = function_name;
- return *this;
-}
-
-LogEntry& LogEntry::prettyFunction(const std::string& pretty_function) {
- // __PRETTY_FUNCTION__ generally seems to be of the form:
- //
- // qualifed::returnType qualified::function(args...)
- //
- // where the qualified forms include "(anonymous namespace)" in the
- // "::"-delimited list and keywords like "virtual" (where applicable).
- //
- // Here we try to convert strings like:
- //
- // virtual binder::Status android::net::NetdNativeService::isAlive(bool *)
- // netdutils::LogEntry android::netd::(anonymous namespace)::AAA::BBB::function()
- //
- // into just "NetdNativeService::isAlive" or "BBB::function". Note that
- // without imposing convention, how to easily identify any namespace/class
- // name boundary is not obvious.
- const size_t endFuncName = pretty_function.rfind('(');
- const size_t precedingSpace = pretty_function.rfind(' ', endFuncName);
- size_t substrStart = (precedingSpace != std::string::npos) ? precedingSpace + 1 : 0;
-
- const size_t beginFuncName = pretty_function.rfind("::", endFuncName);
- if (beginFuncName != std::string::npos && substrStart < beginFuncName) {
- const size_t previousNameBoundary = pretty_function.rfind("::", beginFuncName - 1);
- if (previousNameBoundary < beginFuncName && substrStart < previousNameBoundary) {
- substrStart = previousNameBoundary + 2;
- } else {
- substrStart = beginFuncName + 2;
- }
- }
-
- mFunc = pretty_function.substr(substrStart, endFuncName - substrStart);
- return *this;
-}
-
-LogEntry& LogEntry::arg(const std::string& val) {
- mArgs.push_back(val.empty() ? "\"\"" : val);
- return *this;
-}
-
-template <>
-LogEntry& LogEntry::arg<>(bool val) {
- mArgs.push_back(val ? "true" : "false");
- return *this;
-}
-
-LogEntry& LogEntry::arg(const std::vector<int32_t>& val) {
- mArgs.push_back(StringPrintf("[%s]", Join(val, ", ").c_str()));
- return *this;
-}
-
-LogEntry& LogEntry::arg(const std::vector<uint8_t>& val) {
- mArgs.push_back('{' + toHex(makeSlice(val)) + '}');
- return *this;
-}
-
-LogEntry& LogEntry::arg(const std::vector<std::string>& val) {
- mArgs.push_back(StringPrintf("[%s]", Join(val, ", ").c_str()));
- return *this;
-}
-
-LogEntry& LogEntry::returns(const std::string& rval) {
- mReturns.push_back(rval);
- return *this;
-}
-
-LogEntry& LogEntry::returns(bool rval) {
- mReturns.push_back(rval ? "true" : "false");
- return *this;
-}
-
-LogEntry& LogEntry::returns(const Status& status) {
- mReturns.push_back(status.msg());
- return *this;
-}
-
-LogEntry& LogEntry::withUid(uid_t uid) {
- mUid = StringPrintf("(uid=%d)", uid);
- return *this;
-}
-
-LogEntry& LogEntry::withAutomaticDuration() {
- using ms = std::chrono::duration<float, std::ratio<1, 1000>>;
-
- const std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
- std::stringstream duration;
- duration << std::setprecision(1) << std::chrono::duration_cast<ms>(end - mStart).count()
- << "ms";
- mDuration = duration.str();
- return *this;
-}
-
-LogEntry& LogEntry::withDuration(const std::string& duration) {
- mDuration = duration;
- return *this;
-}
-
-Log::~Log() {
- // TODO: dump the last N entries to the android log for possible posterity.
- info(LogEntry().function(__FUNCTION__));
-}
-
-void Log::forEachEntry(const std::function<void(const std::string&)>& perEntryFn) const {
- // We make a (potentially expensive) copy of the log buffer (including
- // all strings), in case the |perEntryFn| takes its sweet time.
- std::deque<std::string> entries;
- {
- std::shared_lock<std::shared_mutex> guard(mLock);
- entries.assign(mEntries.cbegin(), mEntries.cend());
- }
-
- for (const std::string& entry : entries) perEntryFn(entry);
-}
-
-void Log::record(Log::Level lvl, const std::string& entry) {
- switch (lvl) {
- case Level::LOG:
- break;
- case Level::INFO:
- ALOG(LOG_INFO, mTag.c_str(), "%s", entry.c_str());
- break;
- case Level::WARN:
- ALOG(LOG_WARN, mTag.c_str(), "%s", entry.c_str());
- break;
- case Level::ERROR:
- ALOG(LOG_ERROR, mTag.c_str(), "%s", entry.c_str());
- break;
- }
-
- std::lock_guard guard(mLock);
- mEntries.push_back(makeTimestampedEntry(entry));
- while (mEntries.size() > mMaxEntries) mEntries.pop_front();
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/LogTest.cpp b/libnetdutils/LogTest.cpp
deleted file mode 100644
index 1270560..0000000
--- a/libnetdutils/LogTest.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include <gtest/gtest.h>
-
-#include "netdutils/Log.h"
-
-android::netdutils::LogEntry globalFunctionName() {
- return android::netdutils::LogEntry().function(__FUNCTION__);
-}
-
-android::netdutils::LogEntry globalPrettyFunctionName() {
- return android::netdutils::LogEntry().prettyFunction(__PRETTY_FUNCTION__);
-}
-
-namespace android {
-namespace netdutils {
-
-namespace {
-
-LogEntry functionName() {
- return LogEntry().function(__FUNCTION__);
-}
-
-LogEntry prettyFunctionName() {
- return LogEntry().prettyFunction(__PRETTY_FUNCTION__);
-}
-
-} // namespace
-
-class AAA {
- public:
- AAA() = default;
-
- LogEntry functionName() {
- return LogEntry().function(__FUNCTION__);
- }
-
- LogEntry prettyFunctionName() {
- return LogEntry().prettyFunction(__PRETTY_FUNCTION__);
- }
-
- class BBB {
- public:
- BBB() = default;
-
- LogEntry functionName() {
- return LogEntry().function(__FUNCTION__);
- }
-
- LogEntry prettyFunctionName() {
- return LogEntry().prettyFunction(__PRETTY_FUNCTION__);
- }
- };
-};
-
-TEST(LogEntryTest, Empty) {
- LogEntry empty;
- EXPECT_EQ("", empty.toString());
-}
-
-TEST(LogEntryTest, GlobalFunction) {
- EXPECT_EQ("globalFunctionName()", ::globalFunctionName().toString());
-}
-
-TEST(LogEntryTest, GlobalPrettyFunction) {
- EXPECT_EQ("globalPrettyFunctionName()", ::globalPrettyFunctionName().toString());
-}
-
-TEST(LogEntryTest, UnnamedNamespaceFunction) {
- const LogEntry entry = functionName();
- EXPECT_EQ("functionName()", entry.toString());
-}
-
-TEST(LogEntryTest, UnnamedNamespacePrettyFunction) {
- const LogEntry entry = prettyFunctionName();
- EXPECT_EQ("prettyFunctionName()", entry.toString());
-}
-
-TEST(LogEntryTest, ClassFunction) {
- const LogEntry entry = AAA().functionName();
- EXPECT_EQ("functionName()", entry.toString());
-}
-
-TEST(LogEntryTest, ClassPrettyFunction) {
- const LogEntry entry = AAA().prettyFunctionName();
- EXPECT_EQ("AAA::prettyFunctionName()", entry.toString());
-}
-
-TEST(LogEntryTest, InnerClassFunction) {
- const LogEntry entry = AAA::BBB().functionName();
- EXPECT_EQ("functionName()", entry.toString());
-}
-
-TEST(LogEntryTest, InnerClassPrettyFunction) {
- const LogEntry entry = AAA::BBB().prettyFunctionName();
- EXPECT_EQ("BBB::prettyFunctionName()", entry.toString());
-}
-
-TEST(LogEntryTest, PrintChainedArguments) {
- const LogEntry entry = LogEntry()
- .function("testFunc")
- .arg("hello")
- .arg(42)
- .arg(true);
- EXPECT_EQ("testFunc(hello, 42, true)", entry.toString());
-}
-
-TEST(LogEntryTest, PrintIntegralTypes) {
- const LogEntry entry = LogEntry()
- .function("testFunc")
- .arg('A')
- .arg(100U)
- .arg(-1000LL);
- EXPECT_EQ("testFunc(65, 100, -1000)", entry.toString());
-}
-
-TEST(LogEntryTest, PrintHex) {
- const std::vector<uint8_t> buf{0xDE, 0xAD, 0xBE, 0xEF};
- const LogEntry entry = LogEntry().function("testFunc").arg(buf);
- EXPECT_EQ("testFunc({deadbeef})", entry.toString());
-}
-
-TEST(LogEntryTest, PrintArgumentPack) {
- const LogEntry entry = LogEntry().function("testFunc").args("hello", 42, false);
- EXPECT_EQ("testFunc(hello, 42, false)", entry.toString());
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/MemBlockTest.cpp b/libnetdutils/MemBlockTest.cpp
deleted file mode 100644
index 6455a7e..0000000
--- a/libnetdutils/MemBlockTest.cpp
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include <algorithm>
-#include <cstdint>
-#include <utility>
-
-#include <gtest/gtest.h>
-
-#include "netdutils/MemBlock.h"
-#include "netdutils/Slice.h"
-
-namespace android {
-namespace netdutils {
-
-namespace {
-
-constexpr unsigned DNS_PACKET_SIZE = 512;
-constexpr int ARBITRARY_VALUE = 0x55;
-
-MemBlock makeArbitraryMemBlock(size_t len) {
- MemBlock result(len);
- // Do some fictional work before returning.
- for (Slice slice = result.get(); !slice.empty(); slice = drop(slice, 1)) {
- slice.base()[0] = ARBITRARY_VALUE;
- }
- return result;
-}
-
-void checkAllZeros(Slice slice) {
- for (; !slice.empty(); slice = drop(slice, 1)) {
- EXPECT_EQ(0U, slice.base()[0]);
- }
-}
-
-void checkArbitraryMemBlock(const MemBlock& block, size_t expectedSize) {
- Slice slice = block.get();
- EXPECT_EQ(expectedSize, slice.size());
- EXPECT_NE(nullptr, slice.base());
- for (; !slice.empty(); slice = drop(slice, 1)) {
- EXPECT_EQ(ARBITRARY_VALUE, slice.base()[0]);
- }
-}
-
-void checkHelloMello(Slice dest, Slice src) {
- EXPECT_EQ('h', dest.base()[0]);
- EXPECT_EQ('e', dest.base()[1]);
- EXPECT_EQ('l', dest.base()[2]);
- EXPECT_EQ('l', dest.base()[3]);
- EXPECT_EQ('o', dest.base()[4]);
-
- src.base()[0] = 'm';
- EXPECT_EQ('h', dest.base()[0]);
-}
-
-} // namespace
-
-TEST(MemBlockTest, Empty) {
- MemBlock empty;
- EXPECT_TRUE(empty.get().empty());
- EXPECT_EQ(nullptr, empty.get().base());
-}
-
-TEST(MemBlockTest, ExplicitZero) {
- MemBlock zero(0);
- EXPECT_TRUE(zero.get().empty());
- EXPECT_EQ(nullptr, zero.get().base());
-}
-
-TEST(MemBlockTest, BasicAllocation) {
- MemBlock dnsPacket(DNS_PACKET_SIZE);
- Slice slice = dnsPacket.get();
- EXPECT_EQ(DNS_PACKET_SIZE, slice.size());
- // Verify the space is '\0'-initialized.
- ASSERT_NO_FATAL_FAILURE(checkAllZeros(slice));
- EXPECT_NE(nullptr, slice.base());
-}
-
-TEST(MemBlockTest, MoveConstruction) {
- MemBlock block(makeArbitraryMemBlock(DNS_PACKET_SIZE));
- ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE));
-}
-
-TEST(MemBlockTest, MoveAssignmentOrConstruction) {
- MemBlock block = makeArbitraryMemBlock(DNS_PACKET_SIZE);
- ASSERT_NO_FATAL_FAILURE(checkArbitraryMemBlock(block, DNS_PACKET_SIZE));
-}
-
-TEST(MemBlockTest, StdMoveAssignment) {
- constexpr unsigned SIZE = 10;
-
- MemBlock block;
- EXPECT_TRUE(block.get().empty());
- EXPECT_EQ(nullptr, block.get().base());
-
- {
- MemBlock block2 = makeArbitraryMemBlock(SIZE);
- EXPECT_EQ(SIZE, block2.get().size());
- // More fictional work.
- for (unsigned i = 0; i < SIZE; i++) {
- block2.get().base()[i] = i;
- }
- block = std::move(block2);
- }
-
- EXPECT_EQ(SIZE, block.get().size());
- for (unsigned i = 0; i < SIZE; i++) {
- EXPECT_EQ(i, block.get().base()[i]);
- }
-}
-
-TEST(MemBlockTest, ConstructionFromSlice) {
- uint8_t data[] = {'h', 'e', 'l', 'l', 'o'};
- Slice dataSlice(Slice(data, sizeof(data) / sizeof(data[0])));
-
- MemBlock dataCopy(dataSlice);
- ASSERT_NO_FATAL_FAILURE(checkHelloMello(dataCopy.get(), dataSlice));
-}
-
-TEST(MemBlockTest, ImplicitCastToSlice) {
- uint8_t data[] = {'h', 'e', 'l', 'l', 'o'};
- Slice dataSlice(Slice(data, sizeof(data) / sizeof(data[0])));
-
- MemBlock dataCopy(dataSlice.size());
- // NOTE: no explicit MemBlock::get().
- // Verify the space is '\0'-initialized.
- ASSERT_NO_FATAL_FAILURE(checkAllZeros(dataCopy));
- copy(dataCopy, dataSlice);
- ASSERT_NO_FATAL_FAILURE(checkHelloMello(dataCopy, dataSlice));
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/Netfilter.cpp b/libnetdutils/Netfilter.cpp
deleted file mode 100644
index bb43de0..0000000
--- a/libnetdutils/Netfilter.cpp
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <arpa/inet.h>
-#include <linux/netfilter.h>
-#include <linux/netfilter/nfnetlink.h>
-#include <linux/netlink.h>
-#include <ios>
-
-#include "netdutils/Netfilter.h"
-
-std::ostream& operator<<(std::ostream& os, const nfgenmsg& msg) {
- return os << std::hex << "nfgenmsg["
- << "family: 0x" << static_cast<int>(msg.nfgen_family) << ", version: 0x"
- << static_cast<int>(msg.version) << ", res_id: 0x" << ntohs(msg.res_id) << "]"
- << std::dec;
-}
diff --git a/libnetdutils/Netlink.cpp b/libnetdutils/Netlink.cpp
deleted file mode 100644
index 824c0f2..0000000
--- a/libnetdutils/Netlink.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <ios>
-#include <linux/netlink.h>
-
-#include "netdutils/Math.h"
-#include "netdutils/Netlink.h"
-
-namespace android {
-namespace netdutils {
-
-void forEachNetlinkMessage(const Slice buf,
- const std::function<void(const nlmsghdr&, const Slice)>& onMsg) {
- Slice tail = buf;
- while (tail.size() >= sizeof(nlmsghdr)) {
- nlmsghdr hdr = {};
- extract(tail, hdr);
- const auto len = std::max<size_t>(hdr.nlmsg_len, sizeof(hdr));
- onMsg(hdr, drop(take(tail, len), sizeof(hdr)));
- tail = drop(tail, align(len, 2));
- }
-}
-
-void forEachNetlinkAttribute(const Slice buf,
- const std::function<void(const nlattr&, const Slice)>& onAttr) {
- Slice tail = buf;
- while (tail.size() >= sizeof(nlattr)) {
- nlattr hdr = {};
- extract(tail, hdr);
- const auto len = std::max<size_t>(hdr.nla_len, sizeof(hdr));
- onAttr(hdr, drop(take(tail, len), sizeof(hdr)));
- tail = drop(tail, align(len, 2));
- }
-}
-
-} // namespace netdutils
-} // namespace android
-
-bool operator==(const sockaddr_nl& lhs, const sockaddr_nl& rhs) {
- return (lhs.nl_family == rhs.nl_family) && (lhs.nl_pid == rhs.nl_pid) &&
- (lhs.nl_groups == rhs.nl_groups);
-}
-
-bool operator!=(const sockaddr_nl& lhs, const sockaddr_nl& rhs) {
- return !(lhs == rhs);
-}
-
-std::ostream& operator<<(std::ostream& os, const nlmsghdr& hdr) {
- return os << std::hex << "nlmsghdr["
- << "len: 0x" << hdr.nlmsg_len << ", type: 0x" << hdr.nlmsg_type << ", flags: 0x"
- << hdr.nlmsg_flags << ", seq: 0x" << hdr.nlmsg_seq << ", pid: 0x" << hdr.nlmsg_pid
- << "]" << std::dec;
-}
-
-std::ostream& operator<<(std::ostream& os, const nlattr& attr) {
- return os << std::hex << "nlattr["
- << "len: 0x" << attr.nla_len << ", type: 0x" << attr.nla_type << "]" << std::dec;
-}
-
-std::ostream& operator<<(std::ostream& os, const sockaddr_nl& addr) {
- return os << std::hex << "sockaddr_nl["
- << "family: " << addr.nl_family << ", pid: " << addr.nl_pid
- << ", groups: " << addr.nl_groups << "]" << std::dec;
-}
diff --git a/libnetdutils/Slice.cpp b/libnetdutils/Slice.cpp
deleted file mode 100644
index 7a07d47..0000000
--- a/libnetdutils/Slice.cpp
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <sstream>
-
-#include "netdutils/Slice.h"
-
-namespace android {
-namespace netdutils {
-namespace {
-
-// Convert one byte to a two character hexadecimal string
-const std::string toHex(uint8_t byte) {
- const std::array<char, 16> kLookup = {
- {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}};
- return {kLookup[byte >> 4], kLookup[byte & 0xf]};
-}
-
-} // namespace
-
-std::string toString(const Slice s) {
- return std::string(reinterpret_cast<char*>(s.base()), s.size());
-}
-
-std::string toHex(const Slice s, int wrap) {
- Slice tail = s;
- int count = 0;
- std::stringstream ss;
- while (!tail.empty()) {
- uint8_t byte = 0;
- extract(tail, byte);
- ss << toHex(byte);
- if ((++count % wrap) == 0) {
- ss << "\n";
- }
- tail = drop(tail, 1);
- }
- return ss.str();
-}
-
-std::ostream& operator<<(std::ostream& os, const Slice& slice) {
- return os << std::hex << "Slice[base: " << reinterpret_cast<void*>(slice.base())
- << ", limit: " << reinterpret_cast<void*>(slice.limit()) << ", size: 0x"
- << slice.size() << "]" << std::dec;
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/SliceTest.cpp b/libnetdutils/SliceTest.cpp
deleted file mode 100644
index a496933..0000000
--- a/libnetdutils/SliceTest.cpp
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <array>
-#include <cstdint>
-
-#include <gtest/gtest.h>
-
-#include "netdutils/Slice.h"
-#include "netdutils/Status.h"
-#include "netdutils/StatusOr.h"
-
-namespace android {
-namespace netdutils {
-
-class SliceTest : public testing::Test {
- protected:
- std::array<char, 256> mRaw = {};
-};
-
-TEST_F(SliceTest, smoke) {
- Slice s1 = makeSlice(mRaw);
- Slice s2 = makeSlice(mRaw);
- auto p = split(s1, 14);
- s2 = p.first; // avoid warn-unused error
- std::stringstream ss;
- ss << Slice();
- EXPECT_EQ("Slice[base: 0x0, limit: 0x0, size: 0x0]", ss.str());
- constexpr size_t kBytes = 14;
- EXPECT_EQ(s1.base(), take(s1, kBytes).base());
- EXPECT_EQ(kBytes, take(s1, kBytes).size());
- EXPECT_EQ(s1.base() + kBytes, drop(s1, kBytes).base());
- EXPECT_EQ(s1.size() - kBytes, drop(s1, kBytes).size());
- double a = 0;
- double b = 0;
- int c = 0;
- EXPECT_EQ(sizeof(a), extract(s1, a));
- EXPECT_EQ(sizeof(a) + sizeof(b), extract(s1, a, b));
- EXPECT_EQ(sizeof(a) + sizeof(b) + sizeof(c), extract(s1, a, b, c));
-}
-
-TEST_F(SliceTest, constructor) {
- // Expect the following lines to compile
- Slice s1 = makeSlice(mRaw);
- Slice s2(s1);
- Slice s3 = s2;
- const Slice s4(s3);
- const Slice s5 = s4;
- s3 = s5;
- Slice s6(mRaw.data(), mRaw.size());
- Slice s7(mRaw.data(), mRaw.data() + mRaw.size());
- struct {
- int a;
- double b;
- float c;
- } anon;
- makeSlice(anon);
- EXPECT_EQ(reinterpret_cast<uint8_t*>(mRaw.data()), s1.base());
- EXPECT_EQ(reinterpret_cast<uint8_t*>(mRaw.data()) + mRaw.size(), s1.limit());
- EXPECT_EQ(mRaw.size(), s1.size());
- EXPECT_FALSE(mRaw.empty());
- EXPECT_TRUE(Slice().empty());
- EXPECT_TRUE(Slice(nullptr, static_cast<size_t>(0)).empty());
- EXPECT_TRUE(Slice(nullptr, nullptr).empty());
-}
-
-TEST_F(SliceTest, extract) {
- struct A {
- int a, b;
- bool operator==(const A& other) const { return a == other.a && b == other.b; }
- };
- struct B {
- char str[12];
- bool b;
- int i;
- bool operator==(const B& other) const {
- return b == other.b && i == other.i && 0 == strncmp(str, other.str, 12);
- }
- };
-
- A origA1 = {1, 2};
- A origA2 = {3, 4};
- B origB = {"hello world", true, 1234};
-
- // Populate buffer for extracting.
- Slice buffer = makeSlice(mRaw);
- copy(buffer, makeSlice(origA1));
- copy(drop(buffer, sizeof(origA1)), makeSlice(origB));
- copy(drop(buffer, sizeof(origA1) + sizeof(origB)), makeSlice(origA2));
-
- {
- // Non-variadic extract
- A a1{};
- size_t len = extract(buffer, a1);
- EXPECT_EQ(sizeof(A), len);
- EXPECT_EQ(origA1, a1);
- }
-
- {
- // Variadic extract, 2 destinations
- A a1{};
- B b{};
- size_t len = extract(buffer, a1, b);
- EXPECT_EQ(sizeof(A) + sizeof(B), len);
- EXPECT_EQ(origA1, a1);
- EXPECT_EQ(origB, b);
- }
-
- {
- // Variadic extract, 3 destinations
- A a1{}, a2{};
- B b{};
- size_t len = extract(buffer, a1, b, a2);
- EXPECT_EQ(2 * sizeof(A) + sizeof(B), len);
- EXPECT_EQ(origA1, a1);
- EXPECT_EQ(origB, b);
- EXPECT_EQ(origA2, a2);
- }
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/Socket.cpp b/libnetdutils/Socket.cpp
deleted file mode 100644
index e962b6e..0000000
--- a/libnetdutils/Socket.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <arpa/inet.h>
-
-#include "netdutils/Slice.h"
-#include "netdutils/Socket.h"
-
-namespace android {
-namespace netdutils {
-
-StatusOr<std::string> toString(const in6_addr& addr) {
- std::array<char, INET6_ADDRSTRLEN> out = {};
- auto* rv = inet_ntop(AF_INET6, &addr, out.data(), out.size());
- if (rv == nullptr) {
- return statusFromErrno(errno, "inet_ntop() failed");
- }
- return std::string(out.data());
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/SocketOption.cpp b/libnetdutils/SocketOption.cpp
deleted file mode 100644
index 023df6e..0000000
--- a/libnetdutils/SocketOption.cpp
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#include "netdutils/SocketOption.h"
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <sys/socket.h>
-#include <utility>
-
-#include "netdutils/Syscalls.h"
-
-namespace android {
-namespace netdutils {
-
-Status enableSockopt(Fd sock, int level, int optname) {
- auto& sys = sSyscalls.get();
- const int on = 1;
- return sys.setsockopt(sock, level, optname, &on, sizeof(on));
-}
-
-Status enableTcpKeepAlives(Fd sock, unsigned idleTime, unsigned numProbes, unsigned probeInterval) {
- RETURN_IF_NOT_OK(enableSockopt(sock, SOL_SOCKET, SO_KEEPALIVE));
-
- auto& sys = sSyscalls.get();
- if (idleTime != 0) {
- RETURN_IF_NOT_OK(sys.setsockopt(sock, SOL_TCP, TCP_KEEPIDLE, &idleTime, sizeof(idleTime)));
- }
- if (numProbes != 0) {
- RETURN_IF_NOT_OK(sys.setsockopt(sock, SOL_TCP, TCP_KEEPCNT, &numProbes, sizeof(numProbes)));
- }
- if (probeInterval != 0) {
- RETURN_IF_NOT_OK(sys.setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &probeInterval,
- sizeof(probeInterval)));
- }
-
- return status::ok;
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/Status.cpp b/libnetdutils/Status.cpp
deleted file mode 100644
index acd8f11..0000000
--- a/libnetdutils/Status.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "netdutils/Status.h"
-
-#include <sstream>
-
-#include "android-base/stringprintf.h"
-
-namespace android {
-namespace netdutils {
-
-Status statusFromErrno(int err, const std::string& msg) {
- return Status(err, base::StringPrintf("[%s] : %s", strerror(err), msg.c_str()));
-}
-
-bool equalToErrno(const Status& status, int err) {
- return status.code() == err;
-}
-
-std::string toString(const Status& status) {
- std::stringstream ss;
- ss << status;
- return ss.str();
-}
-
-std::ostream& operator<<(std::ostream& os, const Status& s) {
- return os << "Status[code: " << s.code() << ", msg: \"" << s.msg() << "\"]";
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/StatusTest.cpp b/libnetdutils/StatusTest.cpp
deleted file mode 100644
index 4cfc3bb..0000000
--- a/libnetdutils/StatusTest.cpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "netdutils/Status.h"
-#include "netdutils/StatusOr.h"
-
-#include <sstream>
-
-#include <gtest/gtest.h>
-
-namespace android {
-namespace netdutils {
-namespace {
-
-TEST(StatusTest, valueSemantics) {
- // Default constructor
- EXPECT_EQ(status::ok, Status());
-
- // Copy constructor
- Status status1(1);
- Status status2(status1); // NOLINT(performance-unnecessary-copy-initialization)
- EXPECT_EQ(1, status2.code());
-
- // Copy assignment
- Status status3;
- status3 = status2;
- EXPECT_EQ(1, status3.code());
-
- // Same with const objects
- const Status status4(4);
- const Status status5(status4); // NOLINT(performance-unnecessary-copy-initialization)
- Status status6;
- status6 = status5;
- EXPECT_EQ(4, status6.code());
-}
-
-TEST(StatusTest, errorMessages) {
- Status s(42, "for tea too");
- EXPECT_EQ(42, s.code());
- EXPECT_FALSE(s.ok());
- EXPECT_EQ(s.msg(), "for tea too");
-}
-
-TEST(StatusOrTest, moveSemantics) {
- // Status objects should be cheaply movable.
- EXPECT_TRUE(std::is_nothrow_move_constructible<Status>::value);
- EXPECT_TRUE(std::is_nothrow_move_assignable<Status>::value);
-
- // Should move from a temporary Status (twice)
- Status s(Status(Status(42, "move me")));
- EXPECT_EQ(42, s.code());
- EXPECT_EQ(s.msg(), "move me");
-
- Status s2(666, "EDAEMON");
- EXPECT_NE(s, s2);
- s = s2; // Invokes the move-assignment operator.
- EXPECT_EQ(666, s.code());
- EXPECT_EQ(s.msg(), "EDAEMON");
- EXPECT_EQ(s, s2);
-
- // A moved-from Status can be re-used.
- s2 = s;
-
- // Now both objects are valid.
- EXPECT_EQ(666, s.code());
- EXPECT_EQ(s.msg(), "EDAEMON");
- EXPECT_EQ(s, s2);
-}
-
-TEST(StatusTest, ignoredStatus) {
- statusFromErrno(ENOTTY, "Not a typewriter, what did you expect?").ignoreError();
-}
-
-TEST(StatusOrTest, ostream) {
- {
- StatusOr<int> so(11);
- std::stringstream ss;
- ss << so;
- // TODO: Fix StatusOr to optionally output "value:".
- EXPECT_EQ("StatusOr[status: Status[code: 0, msg: \"\"]]", ss.str());
- }
- {
- StatusOr<int> err(status::undefined);
- std::stringstream ss;
- ss << err;
- EXPECT_EQ("StatusOr[status: Status[code: 2147483647, msg: \"undefined\"]]", ss.str());
- }
-}
-
-} // namespace
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/Syscalls.cpp b/libnetdutils/Syscalls.cpp
deleted file mode 100644
index 9f653f7..0000000
--- a/libnetdutils/Syscalls.cpp
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include "netdutils/Syscalls.h"
-
-#include <atomic>
-#include <type_traits>
-#include <utility>
-
-namespace android {
-namespace netdutils {
-namespace {
-
-// Retry syscall fn as long as it returns -1 with errno == EINTR
-template <typename FnT, typename... Params>
-typename std::result_of<FnT(Params...)>::type syscallRetry(FnT fn, Params&&... params) {
- auto rv = fn(std::forward<Params>(params)...);
- while ((rv == -1) && (errno == EINTR)) {
- rv = fn(std::forward<Params>(params)...);
- }
- return rv;
-}
-
-} // namespace
-
-// Production implementation of Syscalls that forwards to libc syscalls.
-class RealSyscalls final : public Syscalls {
- public:
- ~RealSyscalls() override = default;
-
- StatusOr<UniqueFd> open(const std::string& pathname, int flags, mode_t mode) const override {
- UniqueFd fd(::open(pathname.c_str(), flags, mode));
- if (!isWellFormed(fd)) {
- return statusFromErrno(errno, "open(\"" + pathname + "\"...) failed");
- }
- return fd;
- }
-
- StatusOr<UniqueFd> socket(int domain, int type, int protocol) const override {
- UniqueFd sock(::socket(domain, type, protocol));
- if (!isWellFormed(sock)) {
- return statusFromErrno(errno, "socket() failed");
- }
- return sock;
- }
-
- Status getsockname(Fd sock, sockaddr* addr, socklen_t* addrlen) const override {
- auto rv = ::getsockname(sock.get(), addr, addrlen);
- if (rv == -1) {
- return statusFromErrno(errno, "getsockname() failed");
- }
- return status::ok;
- }
-
- Status getsockopt(Fd sock, int level, int optname, void* optval,
- socklen_t* optlen) const override {
- auto rv = ::getsockopt(sock.get(), level, optname, optval, optlen);
- if (rv == -1) {
- return statusFromErrno(errno, "getsockopt() failed");
- }
- return status::ok;
- }
-
- Status setsockopt(Fd sock, int level, int optname, const void* optval,
- socklen_t optlen) const override {
- auto rv = ::setsockopt(sock.get(), level, optname, optval, optlen);
- if (rv == -1) {
- return statusFromErrno(errno, "setsockopt() failed");
- }
- return status::ok;
- }
-
- Status bind(Fd sock, const sockaddr* addr, socklen_t addrlen) const override {
- auto rv = ::bind(sock.get(), addr, addrlen);
- if (rv == -1) {
- return statusFromErrno(errno, "bind() failed");
- }
- return status::ok;
- }
-
- Status connect(Fd sock, const sockaddr* addr, socklen_t addrlen) const override {
- auto rv = syscallRetry(::connect, sock.get(), addr, addrlen);
- if (rv == -1) {
- return statusFromErrno(errno, "connect() failed");
- }
- return status::ok;
- }
-
- StatusOr<ifreq> ioctl(Fd sock, unsigned long request, ifreq* ifr) const override {
- auto rv = ::ioctl(sock.get(), request, ifr);
- if (rv == -1) {
- return statusFromErrno(errno, "ioctl() failed");
- }
- return *ifr;
- }
-
- StatusOr<UniqueFd> eventfd(unsigned int initval, int flags) const override {
- UniqueFd fd(::eventfd(initval, flags));
- if (!isWellFormed(fd)) {
- return statusFromErrno(errno, "eventfd() failed");
- }
- return fd;
- }
-
- StatusOr<int> ppoll(pollfd* fds, nfds_t nfds, double timeout) const override {
- timespec ts = {};
- ts.tv_sec = timeout;
- ts.tv_nsec = (timeout - ts.tv_sec) * 1e9;
- auto rv = syscallRetry(::ppoll, fds, nfds, &ts, nullptr);
- if (rv == -1) {
- return statusFromErrno(errno, "ppoll() failed");
- }
- return rv;
- }
-
- StatusOr<size_t> writev(Fd fd, const std::vector<iovec>& iov) const override {
- auto rv = syscallRetry(::writev, fd.get(), iov.data(), iov.size());
- if (rv == -1) {
- return statusFromErrno(errno, "writev() failed");
- }
- return rv;
- }
-
- StatusOr<size_t> write(Fd fd, const Slice buf) const override {
- auto rv = syscallRetry(::write, fd.get(), buf.base(), buf.size());
- if (rv == -1) {
- return statusFromErrno(errno, "write() failed");
- }
- return static_cast<size_t>(rv);
- }
-
- StatusOr<Slice> read(Fd fd, const Slice buf) const override {
- auto rv = syscallRetry(::read, fd.get(), buf.base(), buf.size());
- if (rv == -1) {
- return statusFromErrno(errno, "read() failed");
- }
- return Slice(buf.base(), rv);
- }
-
- StatusOr<size_t> sendto(Fd sock, const Slice buf, int flags, const sockaddr* dst,
- socklen_t dstlen) const override {
- auto rv = syscallRetry(::sendto, sock.get(), buf.base(), buf.size(), flags, dst, dstlen);
- if (rv == -1) {
- return statusFromErrno(errno, "sendto() failed");
- }
- return static_cast<size_t>(rv);
- }
-
- StatusOr<Slice> recvfrom(Fd sock, const Slice dst, int flags, sockaddr* src,
- socklen_t* srclen) const override {
- auto rv = syscallRetry(::recvfrom, sock.get(), dst.base(), dst.size(), flags, src, srclen);
- if (rv == -1) {
- return statusFromErrno(errno, "recvfrom() failed");
- }
- if (rv == 0) {
- return status::eof;
- }
- return take(dst, rv);
- }
-
- Status shutdown(Fd fd, int how) const override {
- auto rv = ::shutdown(fd.get(), how);
- if (rv == -1) {
- return statusFromErrno(errno, "shutdown() failed");
- }
- return status::ok;
- }
-
- Status close(Fd fd) const override {
- auto rv = ::close(fd.get());
- if (rv == -1) {
- return statusFromErrno(errno, "close() failed");
- }
- return status::ok;
- }
-
- StatusOr<UniqueFile> fopen(const std::string& path, const std::string& mode) const override {
- UniqueFile file(::fopen(path.c_str(), mode.c_str()));
- if (file == nullptr) {
- return statusFromErrno(errno, "fopen(\"" + path + "\", \"" + mode + "\") failed");
- }
- return file;
- }
-
- StatusOr<pid_t> fork() const override {
- pid_t rv = ::fork();
- if (rv == -1) {
- return statusFromErrno(errno, "fork() failed");
- }
- return rv;
- }
-
- StatusOr<int> vfprintf(FILE* file, const char* format, va_list ap) const override {
- auto rv = ::vfprintf(file, format, ap);
- if (rv == -1) {
- return statusFromErrno(errno, "vfprintf() failed");
- }
- return rv;
- }
-
- StatusOr<int> vfscanf(FILE* file, const char* format, va_list ap) const override {
- auto rv = ::vfscanf(file, format, ap);
- if (rv == -1) {
- return statusFromErrno(errno, "vfscanf() failed");
- }
- return rv;
- }
-
- Status fclose(FILE* file) const override {
- auto rv = ::fclose(file);
- if (rv == -1) {
- return statusFromErrno(errno, "fclose() failed");
- }
- return status::ok;
- }
-};
-
-SyscallsHolder::~SyscallsHolder() {
- delete &get();
-}
-
-Syscalls& SyscallsHolder::get() {
- while (true) {
- // memory_order_relaxed gives the compiler and hardware more
- // freedom. If we get a stale value (this should only happen
- // early in the execution of a program) the exchange code below
- // will loop until we get the most current value.
- auto* syscalls = mSyscalls.load(std::memory_order_relaxed);
- // Common case returns existing syscalls
- if (syscalls) {
- return *syscalls;
- }
-
- // This code will execute on first get()
- std::unique_ptr<Syscalls> tmp(new RealSyscalls());
- Syscalls* expected = nullptr;
- bool success = mSyscalls.compare_exchange_strong(expected, tmp.get());
- if (success) {
- // Ownership was transferred to mSyscalls already, must release()
- return *tmp.release();
- }
- }
-}
-
-Syscalls& SyscallsHolder::swap(Syscalls& syscalls) {
- return *mSyscalls.exchange(&syscalls);
-}
-
-SyscallsHolder sSyscalls;
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/SyscallsTest.cpp b/libnetdutils/SyscallsTest.cpp
deleted file mode 100644
index 78ffab5..0000000
--- a/libnetdutils/SyscallsTest.cpp
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <array>
-#include <cstdint>
-#include <memory>
-
-#include <gtest/gtest.h>
-
-#include "netdutils/Handle.h"
-#include "netdutils/Math.h"
-#include "netdutils/MockSyscalls.h"
-#include "netdutils/Netfilter.h"
-#include "netdutils/Netlink.h"
-#include "netdutils/Slice.h"
-#include "netdutils/Status.h"
-#include "netdutils/StatusOr.h"
-#include "netdutils/Syscalls.h"
-
-using testing::_;
-using testing::ByMove;
-using testing::Invoke;
-using testing::Return;
-using testing::StrictMock;
-
-namespace android {
-namespace netdutils {
-
-class SyscallsTest : public testing::Test {
- protected:
- StrictMock<ScopedMockSyscalls> mSyscalls;
-};
-
-TEST(syscalls, scopedMock) {
- auto& old = sSyscalls.get();
- {
- StrictMock<ScopedMockSyscalls> s;
- EXPECT_EQ(&s, &sSyscalls.get());
- }
- EXPECT_EQ(&old, &sSyscalls.get());
-}
-
-TEST_F(SyscallsTest, open) {
- const char kPath[] = "/test/path/please/ignore";
- constexpr Fd kFd(40);
- constexpr int kFlags = 883;
- constexpr mode_t kMode = 37373;
- const auto& sys = sSyscalls.get();
- EXPECT_CALL(mSyscalls, open(kPath, kFlags, kMode)).WillOnce(Return(ByMove(UniqueFd(kFd))));
- EXPECT_CALL(mSyscalls, close(kFd)).WillOnce(Return(status::ok));
- auto result = sys.open(kPath, kFlags, kMode);
- EXPECT_EQ(status::ok, result.status());
- EXPECT_EQ(kFd, result.value());
-}
-
-TEST_F(SyscallsTest, getsockname) {
- constexpr Fd kFd(40);
- sockaddr_nl expected = {};
- auto& sys = sSyscalls.get();
-
- // Success
- EXPECT_CALL(mSyscalls, getsockname(kFd, _, _))
- .WillOnce(Invoke([expected](Fd, sockaddr* addr, socklen_t* addrlen) {
- memcpy(addr, &expected, sizeof(expected));
- EXPECT_EQ(*addrlen, static_cast<socklen_t>(sizeof(expected)));
- return status::ok;
- }));
- const auto result = sys.getsockname<sockaddr_nl>(kFd);
- EXPECT_TRUE(isOk(result));
- EXPECT_EQ(expected, result.value());
-
- // Failure
- const Status kError = statusFromErrno(EINVAL, "test");
- EXPECT_CALL(mSyscalls, getsockname(kFd, _, _)).WillOnce(Return(kError));
- EXPECT_EQ(kError, sys.getsockname<sockaddr_nl>(kFd).status());
-}
-
-TEST_F(SyscallsTest, setsockopt) {
- constexpr Fd kFd(40);
- constexpr int kLevel = 50;
- constexpr int kOptname = 70;
- sockaddr_nl expected = {};
- auto& sys = sSyscalls.get();
-
- // Success
- EXPECT_CALL(mSyscalls, setsockopt(kFd, kLevel, kOptname, &expected, sizeof(expected)))
- .WillOnce(Return(status::ok));
- EXPECT_EQ(status::ok, sys.setsockopt(kFd, kLevel, kOptname, expected));
-
- // Failure
- const Status kError = statusFromErrno(EINVAL, "test");
- EXPECT_CALL(mSyscalls, setsockopt(kFd, kLevel, kOptname, &expected, sizeof(expected)))
- .WillOnce(Return(kError));
- EXPECT_EQ(kError, sys.setsockopt(kFd, kLevel, kOptname, expected));
-}
-
-TEST_F(SyscallsTest, getsockopt) {
- constexpr Fd kFd(40);
- constexpr int kLevel = 50;
- constexpr int kOptname = 70;
- sockaddr_nl expected = {};
- socklen_t optLen = 0;
- auto& sys = sSyscalls.get();
-
- // Success
- EXPECT_CALL(mSyscalls, getsockopt(kFd, kLevel, kOptname, &expected, &optLen))
- .WillOnce(Return(status::ok));
- EXPECT_EQ(status::ok, sys.getsockopt(kFd, kLevel, kOptname, &expected, &optLen));
-
- // Failure
- const Status kError = statusFromErrno(EINVAL, "test");
- EXPECT_CALL(mSyscalls, getsockopt(kFd, kLevel, kOptname, &expected, &optLen))
- .WillOnce(Return(kError));
- EXPECT_EQ(kError, sys.getsockopt(kFd, kLevel, kOptname, &expected, &optLen));
-}
-
-TEST_F(SyscallsTest, bind) {
- constexpr Fd kFd(40);
- sockaddr_nl expected = {};
- auto& sys = sSyscalls.get();
-
- // Success
- EXPECT_CALL(mSyscalls, bind(kFd, asSockaddrPtr(&expected), sizeof(expected)))
- .WillOnce(Return(status::ok));
- EXPECT_EQ(status::ok, sys.bind(kFd, expected));
-
- // Failure
- const Status kError = statusFromErrno(EINVAL, "test");
- EXPECT_CALL(mSyscalls, bind(kFd, asSockaddrPtr(&expected), sizeof(expected)))
- .WillOnce(Return(kError));
- EXPECT_EQ(kError, sys.bind(kFd, expected));
-}
-
-TEST_F(SyscallsTest, connect) {
- constexpr Fd kFd(40);
- sockaddr_nl expected = {};
- auto& sys = sSyscalls.get();
-
- // Success
- EXPECT_CALL(mSyscalls, connect(kFd, asSockaddrPtr(&expected), sizeof(expected)))
- .WillOnce(Return(status::ok));
- EXPECT_EQ(status::ok, sys.connect(kFd, expected));
-
- // Failure
- const Status kError = statusFromErrno(EINVAL, "test");
- EXPECT_CALL(mSyscalls, connect(kFd, asSockaddrPtr(&expected), sizeof(expected)))
- .WillOnce(Return(kError));
- EXPECT_EQ(kError, sys.connect(kFd, expected));
-}
-
-TEST_F(SyscallsTest, sendto) {
- constexpr Fd kFd(40);
- constexpr int kFlags = 0;
- std::array<char, 10> payload;
- const auto slice = makeSlice(payload);
- sockaddr_nl expected = {};
- auto& sys = sSyscalls.get();
-
- // Success
- EXPECT_CALL(mSyscalls, sendto(kFd, slice, kFlags, asSockaddrPtr(&expected), sizeof(expected)))
- .WillOnce(Return(slice.size()));
- EXPECT_EQ(status::ok, sys.sendto(kFd, slice, kFlags, expected));
-}
-
-TEST_F(SyscallsTest, recvfrom) {
- constexpr Fd kFd(40);
- constexpr int kFlags = 0;
- std::array<char, 10> payload;
- const auto dst = makeSlice(payload);
- const auto used = take(dst, 8);
- sockaddr_nl expected = {};
- auto& sys = sSyscalls.get();
-
- // Success
- EXPECT_CALL(mSyscalls, recvfrom(kFd, dst, kFlags, _, _))
- .WillOnce(Invoke(
- [expected, used](Fd, const Slice, int, sockaddr* src, socklen_t* srclen) {
- *srclen = sizeof(expected);
- memcpy(src, &expected, *srclen);
- return used;
- }));
- auto result = sys.recvfrom<sockaddr_nl>(kFd, dst, kFlags);
- EXPECT_EQ(status::ok, result.status());
- EXPECT_EQ(used, result.value().first);
- EXPECT_EQ(expected, result.value().second);
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/ThreadUtilTest.cpp b/libnetdutils/ThreadUtilTest.cpp
deleted file mode 100644
index 8fad8b8..0000000
--- a/libnetdutils/ThreadUtilTest.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#include <string>
-
-#include <android-base/expected.h>
-#include <gtest/gtest.h>
-#include <netdutils/ThreadUtil.h>
-
-namespace android::netdutils {
-
-namespace {
-
-android::base::expected<std::string, int> getThreadName() {
- char name[16] = {};
- if (const int ret = pthread_getname_np(pthread_self(), name, sizeof(name)); ret != 0) {
- return android::base::unexpected(ret);
- }
- return std::string(name);
-}
-
-class NoopRun {
- public:
- explicit NoopRun(const std::string& name = "") : mName(name) { instanceNum++; }
-
- // Destructor happens in the thread.
- ~NoopRun() {
- if (checkName) {
- auto expected = getThreadName();
- EXPECT_TRUE(expected.has_value());
- EXPECT_EQ(mExpectedName, expected.value());
- }
- instanceNum--;
- }
-
- void run() {}
-
- std::string threadName() { return mName; }
-
- // Set the expected thread name which will be used to check if it matches the actual thread
- // name which is returned from the system call. The check will happen in the destructor.
- void setExpectedName(const std::string& expectedName) {
- checkName = true;
- mExpectedName = expectedName;
- }
-
- static bool waitForAllReleased(int timeoutMs) {
- constexpr int intervalMs = 20;
- int limit = timeoutMs / intervalMs;
- for (int i = 1; i < limit; i++) {
- if (instanceNum == 0) {
- return true;
- }
- usleep(intervalMs * 1000);
- }
- return false;
- }
-
- // To track how many instances are alive.
- static std::atomic<int> instanceNum;
-
- private:
- std::string mName;
- std::string mExpectedName;
- bool checkName = false;
-};
-
-std::atomic<int> NoopRun::instanceNum;
-
-} // namespace
-
-TEST(ThreadUtilTest, objectReleased) {
- NoopRun::instanceNum = 0;
- NoopRun* obj = new NoopRun();
- EXPECT_EQ(1, NoopRun::instanceNum);
- threadLaunch(obj);
-
- // Wait for the object released along with the thread exited.
- EXPECT_TRUE(NoopRun::waitForAllReleased(1000));
- EXPECT_EQ(0, NoopRun::instanceNum);
-}
-
-TEST(ThreadUtilTest, SetThreadName) {
- NoopRun::instanceNum = 0;
-
- // Test thread name empty.
- NoopRun* obj1 = new NoopRun();
- obj1->setExpectedName("");
-
- // Test normal case.
- NoopRun* obj2 = new NoopRun("TestName");
- obj2->setExpectedName("TestName");
-
- // Test thread name too long.
- std::string name("TestNameTooooLong");
- NoopRun* obj3 = new NoopRun(name);
- obj3->setExpectedName(name.substr(0, 15));
-
- // Thread names are examined in their destructors.
- EXPECT_EQ(3, NoopRun::instanceNum);
- threadLaunch(obj1);
- threadLaunch(obj2);
- threadLaunch(obj3);
-
- EXPECT_TRUE(NoopRun::waitForAllReleased(1000));
- EXPECT_EQ(0, NoopRun::instanceNum);
-}
-
-} // namespace android::netdutils
diff --git a/libnetdutils/UniqueFd.cpp b/libnetdutils/UniqueFd.cpp
deleted file mode 100644
index 1cb30ed..0000000
--- a/libnetdutils/UniqueFd.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <algorithm>
-
-#include "netdutils/UniqueFd.h"
-#include "netdutils/Syscalls.h"
-
-namespace android {
-namespace netdutils {
-
-void UniqueFd::reset(Fd fd) {
- auto& sys = sSyscalls.get();
- std::swap(fd, mFd);
- if (isWellFormed(fd)) {
- expectOk(sys.close(fd));
- }
-}
-
-std::ostream& operator<<(std::ostream& os, const UniqueFd& fd) {
- return os << "UniqueFd[" << static_cast<Fd>(fd) << "]";
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/UniqueFile.cpp b/libnetdutils/UniqueFile.cpp
deleted file mode 100644
index 21e8779..0000000
--- a/libnetdutils/UniqueFile.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#include <algorithm>
-
-#include "netdutils/Syscalls.h"
-#include "netdutils/UniqueFile.h"
-
-namespace android {
-namespace netdutils {
-
-void UniqueFileDtor::operator()(FILE* file) const {
- const auto& sys = sSyscalls.get();
- sys.fclose(file).ignoreError();
-}
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/include/netdutils/BackoffSequence.h b/libnetdutils/include/netdutils/BackoffSequence.h
deleted file mode 100644
index a52e72d..0000000
--- a/libnetdutils/include/netdutils/BackoffSequence.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#ifndef NETDUTILS_BACKOFFSEQUENCE_H
-#define NETDUTILS_BACKOFFSEQUENCE_H
-
-#include <stdint.h>
-#include <algorithm>
-#include <chrono>
-#include <limits>
-
-namespace android {
-namespace netdutils {
-
-// Encapsulate some RFC 3315 section 14 -style backoff mechanics.
-//
-// https://tools.ietf.org/html/rfc3315#section-14
-template<typename time_type = std::chrono::seconds, typename counter_type = uint32_t>
-class BackoffSequence {
- public:
- struct Parameters {
- time_type initialRetransTime{TIME_UNITY};
- counter_type maxRetransCount{0U};
- time_type maxRetransTime{TIME_ZERO};
- time_type maxRetransDuration{TIME_ZERO};
- time_type endOfSequenceIndicator{TIME_ZERO};
- };
-
- BackoffSequence() : BackoffSequence(Parameters{}) {}
- BackoffSequence(const BackoffSequence &) = default;
- BackoffSequence(BackoffSequence &&) = default;
- BackoffSequence& operator=(const BackoffSequence &) = default;
- BackoffSequence& operator=(BackoffSequence &&) = default;
-
- bool hasNextTimeout() const noexcept {
- return !maxRetransCountExceed() && !maxRetransDurationExceeded();
- }
-
- // Returns 0 when the sequence is exhausted.
- time_type getNextTimeout() {
- if (!hasNextTimeout()) return getEndOfSequenceIndicator();
-
- mRetransTime = getNextTimeoutAfter(mRetransTime);
-
- mRetransCount++;
- mTotalRetransDuration += mRetransTime;
- return mRetransTime;
- }
-
- time_type getEndOfSequenceIndicator() const noexcept {
- return mParams.endOfSequenceIndicator;
- }
-
- class Builder {
- public:
- Builder() {}
-
- constexpr Builder& withInitialRetransmissionTime(time_type irt) {
- mParams.initialRetransTime = irt;
- return *this;
- }
- constexpr Builder& withMaximumRetransmissionCount(counter_type mrc) {
- mParams.maxRetransCount = mrc;
- return *this;
- }
- constexpr Builder& withMaximumRetransmissionTime(time_type mrt) {
- mParams.maxRetransTime = mrt;
- return *this;
- }
- constexpr Builder& withMaximumRetransmissionDuration(time_type mrd) {
- mParams.maxRetransDuration = mrd;
- return *this;
- }
- constexpr Builder& withEndOfSequenceIndicator(time_type eos) {
- mParams.endOfSequenceIndicator = eos;
- return *this;
- }
-
- constexpr BackoffSequence build() const {
- return BackoffSequence(mParams);
- }
-
- private:
- Parameters mParams;
- };
-
- private:
- static constexpr int PER_ITERATION_SCALING_FACTOR = 2;
- static constexpr time_type TIME_ZERO = time_type();
- static constexpr time_type TIME_UNITY = time_type(1);
-
- constexpr BackoffSequence(const struct Parameters ¶ms)
- : mParams(params),
- mRetransCount(0),
- mRetransTime(TIME_ZERO),
- mTotalRetransDuration(TIME_ZERO) {}
-
- constexpr bool maxRetransCountExceed() const {
- return (mParams.maxRetransCount > 0) && (mRetransCount >= mParams.maxRetransCount);
- }
-
- constexpr bool maxRetransDurationExceeded() const {
- return (mParams.maxRetransDuration > TIME_ZERO) &&
- (mTotalRetransDuration >= mParams.maxRetransDuration);
- }
-
- time_type getNextTimeoutAfter(time_type lastTimeout) const {
- // TODO: Support proper random jitter. Also, consider supporting some
- // per-iteration scaling factor other than doubling.
- time_type nextTimeout = (lastTimeout > TIME_ZERO)
- ? PER_ITERATION_SCALING_FACTOR * lastTimeout
- : mParams.initialRetransTime;
-
- // Check if overflow occurred.
- if (nextTimeout < lastTimeout) {
- nextTimeout = std::numeric_limits<time_type>::max();
- }
-
- // Cap to maximum allowed, if necessary.
- if (mParams.maxRetransTime > TIME_ZERO) {
- nextTimeout = std::min(nextTimeout, mParams.maxRetransTime);
- }
-
- // Don't overflow the maximum total duration.
- if (mParams.maxRetransDuration > TIME_ZERO) {
- nextTimeout = std::min(nextTimeout, mParams.maxRetransDuration - lastTimeout);
- }
- return nextTimeout;
- }
-
- const Parameters mParams;
- counter_type mRetransCount;
- time_type mRetransTime;
- time_type mTotalRetransDuration;
-};
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETDUTILS_BACKOFFSEQUENCE_H */
diff --git a/libnetdutils/include/netdutils/DumpWriter.h b/libnetdutils/include/netdutils/DumpWriter.h
deleted file mode 100644
index a50b5e6..0000000
--- a/libnetdutils/include/netdutils/DumpWriter.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#ifndef NETDUTILS_DUMPWRITER_H_
-#define NETDUTILS_DUMPWRITER_H_
-
-#include <string>
-
-namespace android {
-namespace netdutils {
-
-class DumpWriter {
- public:
- DumpWriter(int fd);
-
- void incIndent();
- void decIndent();
-
- void println(const std::string& line);
- template <size_t n>
- void println(const char line[n]) {
- println(std::string(line));
- }
- // Hint to the compiler that it should apply printf validation of
- // arguments (beginning at position 3) of the format (specified in
- // position 2). Note that position 1 is the implicit "this" argument.
- void println(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3)));
- void blankline() { println(""); }
-
- private:
- uint8_t mIndentLevel;
- int mFd;
-};
-
-class ScopedIndent {
- public:
- ScopedIndent() = delete;
- ScopedIndent(const ScopedIndent&) = delete;
- ScopedIndent(ScopedIndent&&) = delete;
- explicit ScopedIndent(DumpWriter& dw) : mDw(dw) { mDw.incIndent(); }
- ~ScopedIndent() { mDw.decIndent(); }
- ScopedIndent& operator=(const ScopedIndent&) = delete;
- ScopedIndent& operator=(ScopedIndent&&) = delete;
-
- // TODO: consider additional {inc,dec}Indent methods and a counter that
- // can be used to unwind all pending increments on exit.
-
- private:
- DumpWriter& mDw;
-};
-
-} // namespace netdutils
-} // namespace android
-
-#endif // NETDUTILS_DUMPWRITER_H_
diff --git a/libnetdutils/include/netdutils/Fd.h b/libnetdutils/include/netdutils/Fd.h
deleted file mode 100644
index 7db4087..0000000
--- a/libnetdutils/include/netdutils/Fd.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_FD_H
-#define NETUTILS_FD_H
-
-#include <ostream>
-
-#include "netdutils/Status.h"
-
-namespace android {
-namespace netdutils {
-
-// Strongly typed wrapper for file descriptors with value semantics.
-// This class should typically hold unowned file descriptors.
-class Fd {
- public:
- constexpr Fd() = default;
-
- constexpr Fd(int fd) : mFd(fd) {}
-
- int get() const { return mFd; }
-
- bool operator==(const Fd& other) const { return get() == other.get(); }
- bool operator!=(const Fd& other) const { return get() != other.get(); }
-
- private:
- int mFd = -1;
-};
-
-// Return true if fd appears valid (non-negative)
-inline bool isWellFormed(const Fd fd) {
- return fd.get() >= 0;
-}
-
-std::ostream& operator<<(std::ostream& os, const Fd& fd);
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_FD_H */
diff --git a/libnetdutils/include/netdutils/Handle.h b/libnetdutils/include/netdutils/Handle.h
deleted file mode 100644
index 82083d4..0000000
--- a/libnetdutils/include/netdutils/Handle.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_HANDLE_H
-#define NETUTILS_HANDLE_H
-
-#include <ostream>
-
-namespace android {
-namespace netdutils {
-
-// Opaque, strongly typed wrapper for integer-like handles.
-// Explicitly avoids implementing arithmetic operations.
-//
-// This class is intended to avoid common errors when reordering
-// arguments to functions, typos and other cases where plain integer
-// types would silently cover up the mistake.
-//
-// usage:
-// DEFINE_HANDLE(ProductId, uint64_t);
-// DEFINE_HANDLE(ThumbnailHash, uint64_t);
-// void foo(ProductId p, ThumbnailHash th) {...}
-//
-// void test() {
-// ProductId p(88);
-// ThumbnailHash th1(100), th2(200);
-//
-// foo(p, th1); <- ok!
-// foo(th1, p); <- disallowed!
-// th1 += 10; <- disallowed!
-// p = th2; <- disallowed!
-// assert(th1 != th2); <- ok!
-// }
-template <typename T, typename TagT>
-class Handle {
- public:
- constexpr Handle() = default;
- constexpr Handle(const T& value) : mValue(value) {}
-
- const T get() const { return mValue; }
-
- bool operator==(const Handle& that) const { return get() == that.get(); }
- bool operator!=(const Handle& that) const { return get() != that.get(); }
-
- private:
- T mValue;
-};
-
-#define DEFINE_HANDLE(name, type) \
- struct _##name##Tag {}; \
- using name = ::android::netdutils::Handle<type, _##name##Tag>;
-
-template <typename T, typename TagT>
-inline std::ostream& operator<<(std::ostream& os, const Handle<T, TagT>& handle) {
- return os << handle.get();
-}
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_HANDLE_H */
diff --git a/libnetdutils/include/netdutils/InternetAddresses.h b/libnetdutils/include/netdutils/InternetAddresses.h
deleted file mode 100644
index d5cbe2b..0000000
--- a/libnetdutils/include/netdutils/InternetAddresses.h
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * Copyright (C) 2018 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
-
-#include <netdb.h>
-#include <netinet/in.h>
-#include <stdint.h>
-#include <cstring>
-#include <limits>
-#include <string>
-
-#include "netdutils/NetworkConstants.h"
-
-namespace android {
-namespace netdutils {
-
-namespace internal_ {
-
-// A structure to hold data for dealing with Internet addresses (IPAddress) and
-// related types such as IPSockAddr and IPPrefix.
-struct compact_ipdata {
- uint8_t family{AF_UNSPEC};
- uint8_t cidrlen{0U}; // written and read in host-byte order
- in_port_t port{0U}; // written and read in host-byte order
- uint32_t scope_id{0U};
- union {
- in_addr v4;
- in6_addr v6;
- } ip{.v6 = IN6ADDR_ANY_INIT}; // written and read in network-byte order
-
- // Classes that use compact_ipdata and this method should be sure to clear
- // (i.e. zero or make uniform) any fields not relevant to the class.
- friend bool operator==(const compact_ipdata& a, const compact_ipdata& b) {
- if ((a.family != b.family) || (a.cidrlen != b.cidrlen) || (a.port != b.port) ||
- (a.scope_id != b.scope_id)) {
- return false;
- }
- switch (a.family) {
- case AF_UNSPEC:
- // After the above checks, two AF_UNSPEC objects can be
- // considered equal, for convenience.
- return true;
- case AF_INET: {
- const in_addr v4a = a.ip.v4;
- const in_addr v4b = b.ip.v4;
- return (v4a.s_addr == v4b.s_addr);
- }
- case AF_INET6: {
- const in6_addr v6a = a.ip.v6;
- const in6_addr v6b = b.ip.v6;
- return IN6_ARE_ADDR_EQUAL(&v6a, &v6b);
- }
- }
- return false;
- }
-
- // Classes that use compact_ipdata and this method should be sure to clear
- // (i.e. zero or make uniform) any fields not relevant to the class.
- friend bool operator!=(const compact_ipdata& a, const compact_ipdata& b) { return !(a == b); }
-
- // Classes that use compact_ipdata and this method should be sure to clear
- // (i.e. zero or make uniform) any fields not relevant to the class.
- friend bool operator<(const compact_ipdata& a, const compact_ipdata& b) {
- if (a.family != b.family) return (a.family < b.family);
- switch (a.family) {
- case AF_INET: {
- const in_addr v4a = a.ip.v4;
- const in_addr v4b = b.ip.v4;
- if (v4a.s_addr != v4b.s_addr) return (ntohl(v4a.s_addr) < ntohl(v4b.s_addr));
- break;
- }
- case AF_INET6: {
- const in6_addr v6a = a.ip.v6;
- const in6_addr v6b = b.ip.v6;
- const int cmp = std::memcmp(v6a.s6_addr, v6b.s6_addr, IPV6_ADDR_LEN);
- if (cmp != 0) return cmp < 0;
- break;
- }
- }
- if (a.cidrlen != b.cidrlen) return (a.cidrlen < b.cidrlen);
- if (a.port != b.port) return (a.port < b.port);
- return (a.scope_id < b.scope_id);
- }
-};
-
-static_assert(AF_UNSPEC <= std::numeric_limits<uint8_t>::max(), "AF_UNSPEC value too large");
-static_assert(AF_INET <= std::numeric_limits<uint8_t>::max(), "AF_INET value too large");
-static_assert(AF_INET6 <= std::numeric_limits<uint8_t>::max(), "AF_INET6 value too large");
-static_assert(sizeof(compact_ipdata) == 24U, "compact_ipdata unexpectedly large");
-
-} // namespace internal_
-
-struct AddrinfoDeleter {
- void operator()(struct addrinfo* p) const {
- if (p != nullptr) {
- freeaddrinfo(p);
- }
- }
-};
-
-typedef std::unique_ptr<struct addrinfo, struct AddrinfoDeleter> ScopedAddrinfo;
-
-inline bool usesScopedIds(const in6_addr& ipv6) {
- return (IN6_IS_ADDR_LINKLOCAL(&ipv6) || IN6_IS_ADDR_MC_LINKLOCAL(&ipv6));
-}
-
-class IPPrefix;
-class IPSockAddr;
-
-class IPAddress {
- public:
- static bool forString(const std::string& repr, IPAddress* ip);
- static IPAddress forString(const std::string& repr) {
- IPAddress ip;
- if (!forString(repr, &ip)) return IPAddress();
- return ip;
- }
-
- IPAddress() = default;
- IPAddress(const IPAddress&) = default;
- IPAddress(IPAddress&&) = default;
-
- explicit IPAddress(const in_addr& ipv4)
- : mData({AF_INET, IPV4_ADDR_BITS, 0U, 0U, {.v4 = ipv4}}) {}
- explicit IPAddress(const in6_addr& ipv6)
- : mData({AF_INET6, IPV6_ADDR_BITS, 0U, 0U, {.v6 = ipv6}}) {}
- IPAddress(const in6_addr& ipv6, uint32_t scope_id)
- : mData({AF_INET6,
- IPV6_ADDR_BITS,
- 0U,
- // Sanity check: scoped_ids only for link-local addresses.
- usesScopedIds(ipv6) ? scope_id : 0U,
- {.v6 = ipv6}}) {}
- IPAddress(const IPAddress& ip, uint32_t scope_id) : IPAddress(ip) {
- mData.scope_id = (family() == AF_INET6 && usesScopedIds(mData.ip.v6)) ? scope_id : 0U;
- }
-
- IPAddress& operator=(const IPAddress&) = default;
- IPAddress& operator=(IPAddress&&) = default;
-
- constexpr sa_family_t family() const noexcept { return mData.family; }
- constexpr uint32_t scope_id() const noexcept { return mData.scope_id; }
-
- std::string toString() const noexcept;
-
- friend std::ostream& operator<<(std::ostream& os, const IPAddress& ip) {
- os << ip.toString();
- return os;
- }
- friend bool operator==(const IPAddress& a, const IPAddress& b) { return (a.mData == b.mData); }
- friend bool operator!=(const IPAddress& a, const IPAddress& b) { return (a.mData != b.mData); }
- friend bool operator<(const IPAddress& a, const IPAddress& b) { return (a.mData < b.mData); }
- friend bool operator>(const IPAddress& a, const IPAddress& b) { return (b.mData < a.mData); }
- friend bool operator<=(const IPAddress& a, const IPAddress& b) { return (a < b) || (a == b); }
- friend bool operator>=(const IPAddress& a, const IPAddress& b) { return (b < a) || (a == b); }
-
- private:
- friend class IPPrefix;
- friend class IPSockAddr;
-
- explicit IPAddress(const internal_::compact_ipdata& ipdata) : mData(ipdata) {
- mData.port = 0U;
- switch (mData.family) {
- case AF_INET:
- mData.cidrlen = IPV4_ADDR_BITS;
- mData.scope_id = 0U;
- break;
- case AF_INET6:
- mData.cidrlen = IPV6_ADDR_BITS;
- if (usesScopedIds(ipdata.ip.v6)) mData.scope_id = ipdata.scope_id;
- break;
- default:
- mData.cidrlen = 0U;
- mData.scope_id = 0U;
- break;
- }
- }
-
- internal_::compact_ipdata mData{};
-};
-
-class IPPrefix {
- public:
- static bool forString(const std::string& repr, IPPrefix* prefix);
- static IPPrefix forString(const std::string& repr) {
- IPPrefix prefix;
- if (!forString(repr, &prefix)) return IPPrefix();
- return prefix;
- }
-
- IPPrefix() = default;
- IPPrefix(const IPPrefix&) = default;
- IPPrefix(IPPrefix&&) = default;
-
- explicit IPPrefix(const IPAddress& ip) : mData(ip.mData) {}
-
- // Truncate the IP address |ip| at length |length|. Lengths greater than
- // the address-family-relevant maximum, along with negative values, are
- // interpreted as if the address-family-relevant maximum had been given.
- IPPrefix(const IPAddress& ip, int length);
-
- IPPrefix& operator=(const IPPrefix&) = default;
- IPPrefix& operator=(IPPrefix&&) = default;
-
- constexpr sa_family_t family() const noexcept { return mData.family; }
- IPAddress ip() const noexcept { return IPAddress(mData); }
- in_addr addr4() const noexcept { return mData.ip.v4; }
- in6_addr addr6() const noexcept { return mData.ip.v6; }
- constexpr int length() const noexcept { return mData.cidrlen; }
-
- bool isUninitialized() const noexcept;
- std::string toString() const noexcept;
-
- friend std::ostream& operator<<(std::ostream& os, const IPPrefix& prefix) {
- os << prefix.toString();
- return os;
- }
- friend bool operator==(const IPPrefix& a, const IPPrefix& b) { return (a.mData == b.mData); }
- friend bool operator!=(const IPPrefix& a, const IPPrefix& b) { return (a.mData != b.mData); }
- friend bool operator<(const IPPrefix& a, const IPPrefix& b) { return (a.mData < b.mData); }
- friend bool operator>(const IPPrefix& a, const IPPrefix& b) { return (b.mData < a.mData); }
- friend bool operator<=(const IPPrefix& a, const IPPrefix& b) { return (a < b) || (a == b); }
- friend bool operator>=(const IPPrefix& a, const IPPrefix& b) { return (b < a) || (a == b); }
-
- private:
- internal_::compact_ipdata mData{};
-};
-
-// An Internet socket address.
-//
-// Cannot represent other types of socket addresses (e.g. UNIX socket address, et cetera).
-class IPSockAddr {
- public:
- // TODO: static forString
-
- static IPSockAddr toIPSockAddr(const std::string& repr, in_port_t port) {
- return IPSockAddr(IPAddress::forString(repr), port);
- }
- static IPSockAddr toIPSockAddr(const sockaddr& sa) {
- switch (sa.sa_family) {
- case AF_INET:
- return IPSockAddr(*reinterpret_cast<const sockaddr_in*>(&sa));
- case AF_INET6:
- return IPSockAddr(*reinterpret_cast<const sockaddr_in6*>(&sa));
- default:
- return IPSockAddr();
- }
- }
- static IPSockAddr toIPSockAddr(const sockaddr_storage& ss) {
- return toIPSockAddr(*reinterpret_cast<const sockaddr*>(&ss));
- }
-
- IPSockAddr() = default;
- IPSockAddr(const IPSockAddr&) = default;
- IPSockAddr(IPSockAddr&&) = default;
-
- explicit IPSockAddr(const IPAddress& ip) : mData(ip.mData) {}
- IPSockAddr(const IPAddress& ip, in_port_t port) : mData(ip.mData) { mData.port = port; }
- explicit IPSockAddr(const sockaddr_in& ipv4sa)
- : IPSockAddr(IPAddress(ipv4sa.sin_addr), ntohs(ipv4sa.sin_port)) {}
- explicit IPSockAddr(const sockaddr_in6& ipv6sa)
- : IPSockAddr(IPAddress(ipv6sa.sin6_addr, ipv6sa.sin6_scope_id), ntohs(ipv6sa.sin6_port)) {}
-
- IPSockAddr& operator=(const IPSockAddr&) = default;
- IPSockAddr& operator=(IPSockAddr&&) = default;
-
- constexpr sa_family_t family() const noexcept { return mData.family; }
- IPAddress ip() const noexcept { return IPAddress(mData); }
- constexpr in_port_t port() const noexcept { return mData.port; }
-
- // Implicit conversion to sockaddr_storage.
- operator sockaddr_storage() const noexcept {
- sockaddr_storage ss;
- ss.ss_family = mData.family;
- switch (mData.family) {
- case AF_INET:
- reinterpret_cast<sockaddr_in*>(&ss)->sin_addr = mData.ip.v4;
- reinterpret_cast<sockaddr_in*>(&ss)->sin_port = htons(mData.port);
- break;
- case AF_INET6:
- reinterpret_cast<sockaddr_in6*>(&ss)->sin6_addr = mData.ip.v6;
- reinterpret_cast<sockaddr_in6*>(&ss)->sin6_port = htons(mData.port);
- reinterpret_cast<sockaddr_in6*>(&ss)->sin6_scope_id = mData.scope_id;
- break;
- }
- return ss;
- }
-
- std::string toString() const noexcept;
-
- friend std::ostream& operator<<(std::ostream& os, const IPSockAddr& prefix) {
- os << prefix.toString();
- return os;
- }
- friend bool operator==(const IPSockAddr& a, const IPSockAddr& b) {
- return (a.mData == b.mData);
- }
- friend bool operator!=(const IPSockAddr& a, const IPSockAddr& b) {
- return (a.mData != b.mData);
- }
- friend bool operator<(const IPSockAddr& a, const IPSockAddr& b) { return (a.mData < b.mData); }
- friend bool operator>(const IPSockAddr& a, const IPSockAddr& b) { return (b.mData < a.mData); }
- friend bool operator<=(const IPSockAddr& a, const IPSockAddr& b) { return (a < b) || (a == b); }
- friend bool operator>=(const IPSockAddr& a, const IPSockAddr& b) { return (b < a) || (a == b); }
-
- private:
- internal_::compact_ipdata mData{};
-};
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/include/netdutils/Log.h b/libnetdutils/include/netdutils/Log.h
deleted file mode 100644
index 77ae649..0000000
--- a/libnetdutils/include/netdutils/Log.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#ifndef NETUTILS_LOG_H
-#define NETUTILS_LOG_H
-
-#include <chrono>
-#include <deque>
-#include <shared_mutex>
-#include <string>
-#include <type_traits>
-#include <vector>
-
-#include <android-base/stringprintf.h>
-#include <android-base/thread_annotations.h>
-
-#include <netdutils/Status.h>
-
-namespace android {
-namespace netdutils {
-
-class LogEntry {
- public:
- LogEntry() = default;
- LogEntry(const LogEntry&) = default;
- LogEntry(LogEntry&&) = default;
- ~LogEntry() = default;
- LogEntry& operator=(const LogEntry&) = default;
- LogEntry& operator=(LogEntry&&) = default;
-
- std::string toString() const;
-
- ///
- // Helper methods that make it easy to build up a LogEntry message.
- // If performance becomes a factor the implementations could be inlined.
- ///
- LogEntry& message(const std::string& message);
-
- // For calling with __FUNCTION__.
- LogEntry& function(const std::string& function_name);
- // For calling with __PRETTY_FUNCTION__.
- LogEntry& prettyFunction(const std::string& pretty_function);
-
- // Convenience methods for each of the common types of function arguments.
- LogEntry& arg(const std::string& val);
- // Intended for binary buffers, formats as hex
- LogEntry& arg(const std::vector<uint8_t>& val);
- LogEntry& arg(const std::vector<int32_t>& val);
- LogEntry& arg(const std::vector<std::string>& val);
- template <typename IntT, typename = std::enable_if_t<std::is_arithmetic_v<IntT>>>
- LogEntry& arg(IntT val) {
- mArgs.push_back(std::to_string(val));
- return *this;
- }
- // Not using a plain overload here to avoid the implicit conversion from
- // any pointer to bool, which causes string literals to print as 'true'.
- template <>
- LogEntry& arg<>(bool val);
-
- template <typename... Args>
- LogEntry& args(const Args&... a) {
- // Cleverness ahead: we throw away the initializer_list filled with
- // zeroes, all we care about is calling arg() for each argument.
- (void) std::initializer_list<int>{(arg(a), 0)...};
- return *this;
- }
-
- // Some things can return more than one value, or have multiple output
- // parameters, so each of these adds to the mReturns vector.
- LogEntry& returns(const std::string& rval);
- LogEntry& returns(const Status& status);
- LogEntry& returns(bool rval);
- template <class T>
- LogEntry& returns(T val) {
- mReturns.push_back(std::to_string(val));
- return *this;
- }
-
- LogEntry& withUid(uid_t uid);
-
- // Append the duration computed since the creation of this instance.
- LogEntry& withAutomaticDuration();
- // Append the string-ified duration computed by some other means.
- LogEntry& withDuration(const std::string& duration);
-
- private:
- std::chrono::steady_clock::time_point mStart = std::chrono::steady_clock::now();
- std::string mMsg{};
- std::string mFunc{};
- std::vector<std::string> mArgs{};
- std::vector<std::string> mReturns{};
- std::string mUid{};
- std::string mDuration{};
-};
-
-class Log {
- public:
- Log() = delete;
- Log(const std::string& tag) : Log(tag, MAX_ENTRIES) {}
- Log(const std::string& tag, size_t maxEntries) : mTag(tag), mMaxEntries(maxEntries) {}
- Log(const Log&) = delete;
- Log(Log&&) = delete;
- ~Log();
- Log& operator=(const Log&) = delete;
- Log& operator=(Log&&) = delete;
-
- LogEntry newEntry() const { return LogEntry(); }
-
- // Record a log entry in internal storage only.
- void log(const std::string& entry) { record(Level::LOG, entry); }
- template <size_t n>
- void log(const char entry[n]) { log(std::string(entry)); }
- void log(const LogEntry& entry) { log(entry.toString()); }
- void log(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
- using ::android::base::StringAppendV;
- std::string result;
- va_list ap;
- va_start(ap, fmt);
- StringAppendV(&result, fmt, ap);
- va_end(ap);
- log(result);
- }
-
- // Record a log entry in internal storage and to ALOGI as well.
- void info(const std::string& entry) { record(Level::INFO, entry); }
- template <size_t n>
- void info(const char entry[n]) { info(std::string(entry)); }
- void info(const LogEntry& entry) { info(entry.toString()); }
- void info(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
- using ::android::base::StringAppendV;
- std::string result;
- va_list ap;
- va_start(ap, fmt);
- StringAppendV(&result, fmt, ap);
- va_end(ap);
- info(result);
- }
-
- // Record a log entry in internal storage and to ALOGW as well.
- void warn(const std::string& entry) { record(Level::WARN, entry); }
- template <size_t n>
- void warn(const char entry[n]) { warn(std::string(entry)); }
- void warn(const LogEntry& entry) { warn(entry.toString()); }
- void warn(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
- using ::android::base::StringAppendV;
- std::string result;
- va_list ap;
- va_start(ap, fmt);
- StringAppendV(&result, fmt, ap);
- va_end(ap);
- warn(result);
- }
-
- // Record a log entry in internal storage and to ALOGE as well.
- void error(const std::string& entry) { record(Level::ERROR, entry); }
- template <size_t n>
- void error(const char entry[n]) { error(std::string(entry)); }
- void error(const LogEntry& entry) { error(entry.toString()); }
- void error(const char* fmt, ...) __attribute__((__format__(__printf__, 2, 3))) {
- using ::android::base::StringAppendV;
- std::string result;
- va_list ap;
- va_start(ap, fmt);
- StringAppendV(&result, fmt, ap);
- va_end(ap);
- error(result);
- }
-
- // Iterates over every entry in the log in chronological order. Operates
- // on a copy of the log entries, and so perEntryFn may itself call one of
- // the logging functions if needed.
- void forEachEntry(const std::function<void(const std::string&)>& perEntryFn) const;
-
- private:
- static constexpr const size_t MAX_ENTRIES = 750U;
- const std::string mTag;
- const size_t mMaxEntries;
-
- // The LOG level adds an entry to mEntries but does not output the message
- // to the system log. All other levels append to mEntries and output to the
- // the system log.
- enum class Level {
- LOG,
- INFO,
- WARN,
- ERROR,
- };
-
- void record(Level lvl, const std::string& entry);
-
- mutable std::shared_mutex mLock;
- std::deque<const std::string> mEntries; // GUARDED_BY(mLock), when supported
-};
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_LOG_H */
diff --git a/libnetdutils/include/netdutils/Math.h b/libnetdutils/include/netdutils/Math.h
deleted file mode 100644
index c41fbf5..0000000
--- a/libnetdutils/include/netdutils/Math.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_MATH_H
-#define NETUTILS_MATH_H
-
-#include <algorithm>
-#include <cstdint>
-
-namespace android {
-namespace netdutils {
-
-template <class T>
-inline constexpr const T mask(const int shift) {
- return (1 << shift) - 1;
-}
-
-// Align x up to the nearest integer multiple of 2^shift
-template <class T>
-inline constexpr const T align(const T& x, const int shift) {
- return (x + mask<T>(shift)) & ~mask<T>(shift);
-}
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_MATH_H */
diff --git a/libnetdutils/include/netdutils/MemBlock.h b/libnetdutils/include/netdutils/MemBlock.h
deleted file mode 100644
index fd4d612..0000000
--- a/libnetdutils/include/netdutils/MemBlock.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#ifndef NETUTILS_MEMBLOCK_H
-#define NETUTILS_MEMBLOCK_H
-
-#include <memory>
-#include "netdutils/Slice.h"
-
-namespace android {
-namespace netdutils {
-
-// A class to encapsulate self-deleting byte arrays while preserving access
-// to the underlying length (without the length being part of the type, e.g.
-// std::array<>). By design, the only interface to the underlying bytes is
-// via Slice, to encourage safer memory access usage.
-//
-// No thread-safety guarantees whatsoever.
-class MemBlock {
- public:
- MemBlock() : MemBlock(0U) {}
- explicit MemBlock(size_t len)
- : mData((len > 0U) ? new uint8_t[len]{} : nullptr),
- mLen(len) {}
- // Allocate memory of size src.size() and copy src into this MemBlock.
- explicit MemBlock(Slice src) : MemBlock(src.size()) {
- copy(get(), src);
- }
-
- // No copy construction or assignment.
- MemBlock(const MemBlock&) = delete;
- MemBlock& operator=(const MemBlock&) = delete;
-
- // Move construction and assignment are okay.
- MemBlock(MemBlock&&) = default;
- MemBlock& operator=(MemBlock&&) = default;
-
- // Even though this method is const, the memory wrapped by the
- // returned Slice is mutable.
- Slice get() const noexcept { return Slice(mData.get(), mLen); }
-
- // Implicit cast to Slice.
- // NOLINTNEXTLINE(google-explicit-constructor)
- operator const Slice() const noexcept { return get(); }
-
- private:
- std::unique_ptr<uint8_t[]> mData;
- size_t mLen;
-};
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_MEMBLOCK_H */
diff --git a/libnetdutils/include/netdutils/Misc.h b/libnetdutils/include/netdutils/Misc.h
deleted file mode 100644
index d344f81..0000000
--- a/libnetdutils/include/netdutils/Misc.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_MISC_H
-#define NETUTILS_MISC_H
-
-#include <map>
-
-namespace android {
-namespace netdutils {
-
-// Lookup key in map, returing a default value if key is not found
-template <typename U, typename V>
-inline const V& findWithDefault(const std::map<U, V>& map, const U& key, const V& dflt) {
- auto it = map.find(key);
- return (it == map.end()) ? dflt : it->second;
-}
-
-// Movable, copiable, scoped lambda (or std::function) runner. Useful
-// for running arbitrary cleanup or logging code when exiting a scope.
-//
-// Compare to defer in golang.
-template <typename FnT>
-class Cleanup {
- public:
- Cleanup() = delete;
- explicit Cleanup(FnT fn) : mFn(fn) {}
- ~Cleanup() { if (!mReleased) mFn(); }
-
- void release() { mReleased = true; }
-
- private:
- bool mReleased{false};
- FnT mFn;
-};
-
-// Helper to make a new Cleanup. Avoids complex or impossible syntax
-// when wrapping lambdas.
-//
-// Usage:
-// auto cleanup = makeCleanup([](){ your_code_here; });
-template <typename FnT>
-Cleanup<FnT> makeCleanup(FnT fn) {
- return Cleanup<FnT>(fn);
-}
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_MISC_H */
diff --git a/libnetdutils/include/netdutils/MockSyscalls.h b/libnetdutils/include/netdutils/MockSyscalls.h
deleted file mode 100644
index f57b55c..0000000
--- a/libnetdutils/include/netdutils/MockSyscalls.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_MOCK_SYSCALLS_H
-#define NETUTILS_MOCK_SYSCALLS_H
-
-#include <atomic>
-#include <cassert>
-#include <memory>
-
-#include <gmock/gmock.h>
-#include <gtest/gtest.h>
-
-#include "netdutils/Syscalls.h"
-
-namespace android {
-namespace netdutils {
-
-class MockSyscalls : public Syscalls {
- public:
- virtual ~MockSyscalls() = default;
- // Use Return(ByMove(...)) to deal with movable return types.
- MOCK_CONST_METHOD3(open,
- StatusOr<UniqueFd>(const std::string& pathname, int flags, mode_t mode));
- MOCK_CONST_METHOD3(socket, StatusOr<UniqueFd>(int domain, int type, int protocol));
- MOCK_CONST_METHOD3(getsockname, Status(Fd sock, sockaddr* addr, socklen_t* addrlen));
- MOCK_CONST_METHOD5(getsockopt, Status(Fd sock, int level, int optname, void* optval,
- socklen_t *optlen));
- MOCK_CONST_METHOD5(setsockopt, Status(Fd sock, int level, int optname, const void* optval,
- socklen_t optlen));
-
- MOCK_CONST_METHOD3(bind, Status(Fd sock, const sockaddr* addr, socklen_t addrlen));
- MOCK_CONST_METHOD3(connect, Status(Fd sock, const sockaddr* addr, socklen_t addrlen));
- MOCK_CONST_METHOD3(ioctl, StatusOr<ifreq>(Fd sock, unsigned long request, ifreq* ifr));
-
- // Use Return(ByMove(...)) to deal with movable return types.
- MOCK_CONST_METHOD2(eventfd, StatusOr<UniqueFd>(unsigned int initval, int flags));
- MOCK_CONST_METHOD3(ppoll, StatusOr<int>(pollfd* fds, nfds_t nfds, double timeout));
-
- MOCK_CONST_METHOD2(writev, StatusOr<size_t>(Fd fd, const std::vector<iovec>& iov));
- MOCK_CONST_METHOD2(write, StatusOr<size_t>(Fd fd, const Slice buf));
- MOCK_CONST_METHOD2(read, StatusOr<Slice>(Fd fd, const Slice buf));
- MOCK_CONST_METHOD5(sendto, StatusOr<size_t>(Fd sock, const Slice buf, int flags,
- const sockaddr* dst, socklen_t dstlen));
- MOCK_CONST_METHOD5(recvfrom, StatusOr<Slice>(Fd sock, const Slice dst, int flags, sockaddr* src,
- socklen_t* srclen));
- MOCK_CONST_METHOD2(shutdown, Status(Fd fd, int how));
- MOCK_CONST_METHOD1(close, Status(Fd fd));
-
- MOCK_CONST_METHOD2(fopen,
- StatusOr<UniqueFile>(const std::string& path, const std::string& mode));
- MOCK_CONST_METHOD3(vfprintf, StatusOr<int>(FILE* file, const char* format, va_list ap));
- MOCK_CONST_METHOD3(vfscanf, StatusOr<int>(FILE* file, const char* format, va_list ap));
- MOCK_CONST_METHOD1(fclose, Status(FILE* file));
- MOCK_CONST_METHOD0(fork, StatusOr<pid_t>());
-};
-
-// For the lifetime of this mock, replace the contents of sSyscalls
-// with a pointer to this mock. Behavior is undefined if multiple
-// ScopedMockSyscalls instances exist concurrently.
-class ScopedMockSyscalls : public MockSyscalls {
- public:
- ScopedMockSyscalls() : mOld(sSyscalls.swap(*this)) { assert((mRefcount++) == 1); }
- virtual ~ScopedMockSyscalls() {
- sSyscalls.swap(mOld);
- assert((mRefcount--) == 0);
- }
-
- private:
- std::atomic<int> mRefcount{0};
- Syscalls& mOld;
-};
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_MOCK_SYSCALLS_H */
diff --git a/libnetdutils/include/netdutils/Netfilter.h b/libnetdutils/include/netdutils/Netfilter.h
deleted file mode 100644
index 22736f1..0000000
--- a/libnetdutils/include/netdutils/Netfilter.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_NETFILTER_H
-#define NETUTILS_NETFILTER_H
-
-#include <ostream>
-
-#include <linux/netfilter.h>
-#include <linux/netfilter/nfnetlink.h>
-#include <linux/netlink.h>
-
-std::ostream& operator<<(std::ostream& os, const nfgenmsg& msg);
-
-#endif /* NETUTILS_NETFILTER_H */
diff --git a/libnetdutils/include/netdutils/Netlink.h b/libnetdutils/include/netdutils/Netlink.h
deleted file mode 100644
index ee5183a..0000000
--- a/libnetdutils/include/netdutils/Netlink.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_NETLINK_H
-#define NETUTILS_NETLINK_H
-
-#include <functional>
-#include <ostream>
-#include <linux/netlink.h>
-
-#include "netdutils/Slice.h"
-
-namespace android {
-namespace netdutils {
-
-// Invoke onMsg once for each netlink message in buf. onMsg will be
-// invoked with an aligned and deserialized header along with a Slice
-// containing the message payload.
-//
-// Assume that the first message begins at offset zero within buf.
-void forEachNetlinkMessage(const Slice buf,
- const std::function<void(const nlmsghdr&, const Slice)>& onMsg);
-
-// Invoke onAttr once for each netlink attribute in buf. onAttr will be
-// invoked with an aligned and deserialized header along with a Slice
-// containing the attribute payload.
-//
-// Assume that the first attribute begins at offset zero within buf.
-void forEachNetlinkAttribute(const Slice buf,
- const std::function<void(const nlattr&, const Slice)>& onAttr);
-
-} // namespace netdutils
-} // namespace android
-
-bool operator==(const sockaddr_nl& lhs, const sockaddr_nl& rhs);
-bool operator!=(const sockaddr_nl& lhs, const sockaddr_nl& rhs);
-
-std::ostream& operator<<(std::ostream& os, const nlmsghdr& hdr);
-std::ostream& operator<<(std::ostream& os, const nlattr& attr);
-std::ostream& operator<<(std::ostream& os, const sockaddr_nl& addr);
-
-#endif /* NETUTILS_NETLINK_H */
diff --git a/libnetdutils/include/netdutils/NetworkConstants.h b/libnetdutils/include/netdutils/NetworkConstants.h
deleted file mode 100644
index dead9a1..0000000
--- a/libnetdutils/include/netdutils/NetworkConstants.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 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
-
-namespace android {
-namespace netdutils {
-
-// See also NetworkConstants.java in frameworks/base.
-constexpr int IPV4_ADDR_LEN = 4;
-constexpr int IPV4_ADDR_BITS = 32;
-constexpr int IPV6_ADDR_LEN = 16;
-constexpr int IPV6_ADDR_BITS = 128;
-
-// Referred from SHA256_DIGEST_LENGTH in boringssl
-constexpr size_t SHA256_SIZE = 32;
-
-} // namespace netdutils
-} // namespace android
diff --git a/libnetdutils/include/netdutils/ResponseCode.h b/libnetdutils/include/netdutils/ResponseCode.h
deleted file mode 100644
index c170684..0000000
--- a/libnetdutils/include/netdutils/ResponseCode.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-#ifndef NETDUTILS_RESPONSECODE_H
-#define NETDUTILS_RESPONSECODE_H
-
-namespace android {
-namespace netdutils {
-
-class ResponseCode {
- // Keep in sync with
- // frameworks/base/services/java/com/android/server/NetworkManagementService.java
- public:
- // 100 series - Requestion action was initiated; expect another reply
- // before proceeding with a new command.
- // clang-format off
- static constexpr int ActionInitiated = 100;
- static constexpr int InterfaceListResult = 110;
- static constexpr int TetherInterfaceListResult = 111;
- static constexpr int TetherDnsFwdTgtListResult = 112;
- static constexpr int TtyListResult = 113;
- static constexpr int TetheringStatsListResult = 114;
- static constexpr int TetherDnsFwdNetIdResult = 115;
-
- // 200 series - Requested action has been successfully completed
- static constexpr int CommandOkay = 200;
- static constexpr int TetherStatusResult = 210;
- static constexpr int IpFwdStatusResult = 211;
- static constexpr int InterfaceGetCfgResult = 213;
- // Formerly: int SoftapStatusResult = 214;
- static constexpr int UsbRNDISStatusResult = 215;
- static constexpr int InterfaceRxCounterResult = 216;
- static constexpr int InterfaceTxCounterResult = 217;
- static constexpr int InterfaceRxThrottleResult = 218;
- static constexpr int InterfaceTxThrottleResult = 219;
- static constexpr int QuotaCounterResult = 220;
- static constexpr int TetheringStatsResult = 221;
- // NOTE: keep synced with bionic/libc/dns/net/gethnamaddr.c
- static constexpr int DnsProxyQueryResult = 222;
- static constexpr int ClatdStatusResult = 223;
-
- // 400 series - The command was accepted but the requested action
- // did not take place.
- static constexpr int OperationFailed = 400;
- static constexpr int DnsProxyOperationFailed = 401;
- static constexpr int ServiceStartFailed = 402;
- static constexpr int ServiceStopFailed = 403;
-
- // 500 series - The command was not accepted and the requested
- // action did not take place.
- static constexpr int CommandSyntaxError = 500;
- static constexpr int CommandParameterError = 501;
-
- // 600 series - Unsolicited broadcasts
- static constexpr int InterfaceChange = 600;
- static constexpr int BandwidthControl = 601;
- static constexpr int ServiceDiscoveryFailed = 602;
- static constexpr int ServiceDiscoveryServiceAdded = 603;
- static constexpr int ServiceDiscoveryServiceRemoved = 604;
- static constexpr int ServiceRegistrationFailed = 605;
- static constexpr int ServiceRegistrationSucceeded = 606;
- static constexpr int ServiceResolveFailed = 607;
- static constexpr int ServiceResolveSuccess = 608;
- static constexpr int ServiceSetHostnameFailed = 609;
- static constexpr int ServiceSetHostnameSuccess = 610;
- static constexpr int ServiceGetAddrInfoFailed = 611;
- static constexpr int ServiceGetAddrInfoSuccess = 612;
- static constexpr int InterfaceClassActivity = 613;
- static constexpr int InterfaceAddressChange = 614;
- static constexpr int InterfaceDnsInfo = 615;
- static constexpr int RouteChange = 616;
- static constexpr int StrictCleartext = 617;
- // clang-format on
-};
-
-} // namespace netdutils
-} // namespace android
-
-#endif // NETDUTILS_RESPONSECODE_H
diff --git a/libnetdutils/include/netdutils/Slice.h b/libnetdutils/include/netdutils/Slice.h
deleted file mode 100644
index 717fbd1..0000000
--- a/libnetdutils/include/netdutils/Slice.h
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_SLICE_H
-#define NETUTILS_SLICE_H
-
-#include <algorithm>
-#include <array>
-#include <cstring>
-#include <ostream>
-#include <tuple>
-#include <vector>
-
-namespace android {
-namespace netdutils {
-
-// Immutable wrapper for a linear region of unowned bytes.
-// Slice represents memory as a half-closed interval [base, limit).
-//
-// Note that without manually invoking the Slice() constructor, it is
-// impossible to increase the size of a slice. This guarantees that
-// applications that properly use the slice API will never access
-// memory outside of a slice.
-//
-// Note that const Slice still wraps mutable memory, however copy
-// assignment and move assignment to slice are disabled.
-class Slice {
- public:
- Slice() = default;
-
- // Create a slice beginning at base and continuing to but not including limit
- Slice(void* base, void* limit) : mBase(toUint8(base)), mLimit(toUint8(limit)) {}
-
- // Create a slice beginning at base and continuing for size bytes
- Slice(void* base, size_t size) : Slice(base, toUint8(base) + size) {}
-
- // Return the address of the first byte in this slice
- uint8_t* base() const { return mBase; }
-
- // Return the address of the first byte following this slice
- uint8_t* limit() const { return mLimit; }
-
- // Return the size of this slice in bytes
- size_t size() const { return limit() - base(); }
-
- // Return true if size() == 0
- bool empty() const { return base() == limit(); }
-
- private:
- static uint8_t* toUint8(void* ptr) { return reinterpret_cast<uint8_t*>(ptr); }
-
- uint8_t* mBase = nullptr;
- uint8_t* mLimit = nullptr;
-};
-
-// Return slice representation of ref which must be a POD type
-template <typename T>
-inline const Slice makeSlice(const T& ref) {
- static_assert(std::is_pod<T>::value, "value must be a POD type");
- static_assert(!std::is_pointer<T>::value, "value must not be a pointer type");
- return {const_cast<T*>(&ref), sizeof(ref)};
-}
-
-// Return slice representation of string data()
-inline const Slice makeSlice(const std::string& s) {
- using ValueT = std::string::value_type;
- return {const_cast<ValueT*>(s.data()), s.size() * sizeof(ValueT)};
-}
-
-// Return slice representation of vector data()
-template <typename T>
-inline const Slice makeSlice(const std::vector<T>& v) {
- return {const_cast<T*>(v.data()), v.size() * sizeof(T)};
-}
-
-// Return slice representation of array data()
-template <typename U, size_t V>
-inline const Slice makeSlice(const std::array<U, V>& a) {
- return {const_cast<U*>(a.data()), a.size() * sizeof(U)};
-}
-
-// Return prefix and suffix of Slice s ending and starting at position cut
-inline std::pair<const Slice, const Slice> split(const Slice s, size_t cut) {
- const size_t tmp = std::min(cut, s.size());
- return {{s.base(), s.base() + tmp}, {s.base() + tmp, s.limit()}};
-}
-
-// Return prefix of Slice s ending at position cut
-inline const Slice take(const Slice s, size_t cut) {
- return std::get<0>(split(s, cut));
-}
-
-// Return suffix of Slice s starting at position cut
-inline const Slice drop(const Slice s, size_t cut) {
- return std::get<1>(split(s, cut));
-}
-
-// Copy from src into dst. Bytes copied is the lesser of dst.size() and src.size()
-inline size_t copy(const Slice dst, const Slice src) {
- const auto min = std::min(dst.size(), src.size());
- memcpy(dst.base(), src.base(), min);
- return min;
-}
-
-// Base case for variadic extract below
-template <typename Head>
-inline size_t extract(const Slice src, Head& head) {
- return copy(makeSlice(head), src);
-}
-
-// Copy from src into one or more pointers to POD data. If src.size()
-// is less than the sum of all data pointers a suffix of data will be
-// left unmodified. Return the number of bytes copied.
-template <typename Head, typename... Tail>
-inline size_t extract(const Slice src, Head& head, Tail&... tail) {
- const auto extracted = extract(src, head);
- return extracted + extract(drop(src, extracted), tail...);
-}
-
-// Return a string containing a copy of the contents of s
-std::string toString(const Slice s);
-
-// Return a string containing a hexadecimal representation of the contents of s.
-// This function inserts a newline into its output every wrap bytes.
-std::string toHex(const Slice s, int wrap = INT_MAX);
-
-inline bool operator==(const Slice& lhs, const Slice& rhs) {
- return (lhs.base() == rhs.base()) && (lhs.limit() == rhs.limit());
-}
-
-inline bool operator!=(const Slice& lhs, const Slice& rhs) {
- return !(lhs == rhs);
-}
-
-std::ostream& operator<<(std::ostream& os, const Slice& slice);
-
-// Return suffix of Slice s starting at the first match of byte c. If no matched
-// byte, return an empty Slice.
-inline const Slice findFirstMatching(const Slice s, uint8_t c) {
- uint8_t* match = (uint8_t*)memchr(s.base(), c, s.size());
- if (!match) return Slice();
- return drop(s, match - s.base());
-}
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_SLICE_H */
diff --git a/libnetdutils/include/netdutils/Socket.h b/libnetdutils/include/netdutils/Socket.h
deleted file mode 100644
index e5aaab9..0000000
--- a/libnetdutils/include/netdutils/Socket.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETDUTILS_SOCKET_H
-#define NETDUTILS_SOCKET_H
-
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <string>
-
-#include "netdutils/StatusOr.h"
-
-namespace android {
-namespace netdutils {
-
-inline sockaddr* asSockaddrPtr(void* addr) {
- return reinterpret_cast<sockaddr*>(addr);
-}
-
-inline const sockaddr* asSockaddrPtr(const void* addr) {
- return reinterpret_cast<const sockaddr*>(addr);
-}
-
-// Return a string representation of addr or Status if there was a
-// failure during conversion.
-StatusOr<std::string> toString(const in6_addr& addr);
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETDUTILS_SOCKET_H */
diff --git a/libnetdutils/include/netdutils/SocketOption.h b/libnetdutils/include/netdutils/SocketOption.h
deleted file mode 100644
index 3b0aab7..0000000
--- a/libnetdutils/include/netdutils/SocketOption.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-#ifndef NETDUTILS_SOCKETOPTION_H
-#define NETDUTILS_SOCKETOPTION_H
-
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <string>
-
-#include "netdutils/Fd.h"
-#include "netdutils/Status.h"
-
-namespace android {
-namespace netdutils {
-
-// Turn on simple "boolean" socket options.
-//
-// This is simple wrapper for options that are enabled via code of the form:
-//
-// int on = 1;
-// setsockopt(..., &on, sizeof(on));
-Status enableSockopt(Fd sock, int level, int optname);
-
-// Turn on TCP keepalives, and set keepalive parameters for this socket.
-//
-// A parameter value of zero does not set that parameter.
-//
-// Typical system defaults are:
-//
-// idleTime (in seconds)
-// $ cat /proc/sys/net/ipv4/tcp_keepalive_time
-// 7200
-//
-// numProbes
-// $ cat /proc/sys/net/ipv4/tcp_keepalive_probes
-// 9
-//
-// probeInterval (in seconds)
-// $ cat /proc/sys/net/ipv4/tcp_keepalive_intvl
-// 75
-Status enableTcpKeepAlives(Fd sock, unsigned idleTime, unsigned numProbes, unsigned probeInterval);
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETDUTILS_SOCKETOPTION_H */
diff --git a/libnetdutils/include/netdutils/Status.h b/libnetdutils/include/netdutils/Status.h
deleted file mode 100644
index bc347d5..0000000
--- a/libnetdutils/include/netdutils/Status.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_STATUS_H
-#define NETUTILS_STATUS_H
-
-#include <cassert>
-#include <limits>
-#include <ostream>
-
-#include <android-base/result.h>
-
-namespace android {
-namespace netdutils {
-
-// Simple status implementation suitable for use on the stack in low
-// or moderate performance code. This can definitely be improved but
-// for now short string optimization is expected to keep the common
-// success case fast.
-//
-// Status is implicitly movable via the default noexcept move constructor
-// and noexcept move-assignment operator.
-class [[nodiscard]] Status {
- public:
- Status() = default;
- explicit Status(int code) : mCode(code) {}
-
- // Constructs an error Status, |code| must be non-zero.
- Status(int code, std::string msg) : mCode(code), mMsg(std::move(msg)) { assert(!ok()); }
-
- Status(android::base::Result<void> result)
- : mCode(result.ok() ? 0 : result.error().code()),
- mMsg(result.ok() ? "" : result.error().message()) {}
-
- int code() const { return mCode; }
-
- bool ok() const { return code() == 0; }
-
- const std::string& msg() const { return mMsg; }
-
- // Explicitly ignores the Status without triggering [[nodiscard]] errors.
- void ignoreError() const {}
-
- bool operator==(const Status& other) const { return code() == other.code(); }
- bool operator!=(const Status& other) const { return !(*this == other); }
-
- private:
- int mCode = 0;
- std::string mMsg;
-};
-
-namespace status {
-
-const Status ok{0};
-// EOF is not part of errno space, we'll place it far above the
-// highest existing value.
-const Status eof{0x10001, "end of file"};
-const Status undefined{std::numeric_limits<int>::max(), "undefined"};
-
-} // namespace status
-
-// Return true if status is "OK". This is sometimes preferable to
-// status.ok() when we want to check the state of Status-like objects
-// that implicitly cast to Status.
-inline bool isOk(const Status& status) {
- return status.ok();
-}
-
-// For use only in tests. Used for both Status and Status-like objects. See also isOk().
-#define EXPECT_OK(status) EXPECT_TRUE(isOk(status))
-#define ASSERT_OK(status) ASSERT_TRUE(isOk(status))
-
-// Documents that status is expected to be ok. This function may log
-// (or assert when running in debug mode) if status has an unexpected value.
-inline void expectOk(const Status& /*status*/) {
- // TODO: put something here, for now this function serves solely as documentation.
-}
-
-// Convert POSIX errno to a Status object.
-// If Status is extended to have more features, this mapping may
-// become more complex.
-Status statusFromErrno(int err, const std::string& msg);
-
-// Helper that checks Status-like object (notably StatusOr) against a
-// value in the errno space.
-bool equalToErrno(const Status& status, int err);
-
-// Helper that converts Status-like object (notably StatusOr) to a
-// message.
-std::string toString(const Status& status);
-
-std::ostream& operator<<(std::ostream& os, const Status& s);
-
-// Evaluate 'stmt' to a Status object and if it results in an error, return that
-// error. Use 'tmp' as a variable name to avoid shadowing any variables named
-// tmp.
-#define RETURN_IF_NOT_OK_IMPL(tmp, stmt) \
- do { \
- ::android::netdutils::Status tmp = (stmt); \
- if (!isOk(tmp)) { \
- return tmp; \
- } \
- } while (false)
-
-// Create a unique variable name to avoid shadowing local variables.
-#define RETURN_IF_NOT_OK_CONCAT(line, stmt) RETURN_IF_NOT_OK_IMPL(__CONCAT(_status_, line), stmt)
-
-// Macro to allow exception-like handling of error return values.
-//
-// If the evaluation of stmt results in an error, return that error
-// from current function.
-//
-// Example usage:
-// Status bar() { ... }
-//
-// RETURN_IF_NOT_OK(status);
-// RETURN_IF_NOT_OK(bar());
-#define RETURN_IF_NOT_OK(stmt) RETURN_IF_NOT_OK_CONCAT(__LINE__, stmt)
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_STATUS_H */
diff --git a/libnetdutils/include/netdutils/StatusOr.h b/libnetdutils/include/netdutils/StatusOr.h
deleted file mode 100644
index c7aa4e4..0000000
--- a/libnetdutils/include/netdutils/StatusOr.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_STATUSOR_H
-#define NETUTILS_STATUSOR_H
-
-#include <cassert>
-#include "netdutils/Status.h"
-
-namespace android {
-namespace netdutils {
-
-// Wrapper around a combination of Status and application value type.
-// T may be any copyable or movable type.
-template <typename T>
-class [[nodiscard]] StatusOr {
- public:
- // Constructs a new StatusOr with status::undefined status.
- // This is marked 'explicit' to try to catch cases like 'return {};',
- // where people think StatusOr<std::vector<int>> will be initialized
- // with an empty vector, instead of a status::undefined.
- explicit StatusOr() = default;
-
- // Implicit copy constructor and construction from T.
- // NOLINTNEXTLINE(google-explicit-constructor)
- StatusOr(Status status) : mStatus(std::move(status)) { assert(!isOk(mStatus)); }
-
- // Implicit construction from T. It is convenient and sensible to be able
- // to do 'return T()' when the return type is StatusOr<T>.
- // NOLINTNEXTLINE(google-explicit-constructor)
- StatusOr(const T& value) : mStatus(status::ok), mValue(value) {}
- // NOLINTNEXTLINE(google-explicit-constructor)
- StatusOr(T&& value) : mStatus(status::ok), mValue(std::move(value)) {}
-
- // Move constructor ok (if T supports move)
- StatusOr(StatusOr&&) noexcept = default;
- // Move assignment ok (if T supports move)
- StatusOr& operator=(StatusOr&&) noexcept = default;
- // Copy constructor ok (if T supports copy)
- StatusOr(const StatusOr&) = default;
- // Copy assignment ok (if T supports copy)
- StatusOr& operator=(const StatusOr&) = default;
-
- // Returns a const reference to wrapped type.
- // It is an error to call value() when !isOk(status())
- const T& value() const & { return mValue; }
- const T&& value() const && { return mValue; }
-
- // Returns an rvalue reference to wrapped type
- // It is an error to call value() when !isOk(status())
- //
- // If T is expensive to copy but supports efficient move, it can be moved
- // out of a StatusOr as follows:
- // T value = std::move(statusor).value();
- T& value() & { return mValue; }
- T&& value() && { return mValue; }
-
- // Returns the Status object assigned at construction time.
- const Status status() const { return mStatus; }
-
- // Explicitly ignores the Status without triggering [[nodiscard]] errors.
- void ignoreError() const {}
-
- // Implicit cast to Status.
- // NOLINTNEXTLINE(google-explicit-constructor)
- operator Status() const { return status(); }
-
- private:
- Status mStatus = status::undefined;
- T mValue;
-};
-
-template <typename T>
-inline std::ostream& operator<<(std::ostream& os, const StatusOr<T>& s) {
- return os << "StatusOr[status: " << s.status() << "]";
-}
-
-#define ASSIGN_OR_RETURN_IMPL(tmp, lhs, stmt) \
- auto tmp = (stmt); \
- RETURN_IF_NOT_OK(tmp); \
- lhs = std::move(tmp.value());
-
-#define ASSIGN_OR_RETURN_CONCAT(line, lhs, stmt) \
- ASSIGN_OR_RETURN_IMPL(__CONCAT(_status_or_, line), lhs, stmt)
-
-// Macro to allow exception-like handling of error return values.
-//
-// If the evaluation of stmt results in an error, return that error
-// from the current function. Otherwise, assign the result to lhs.
-//
-// This macro supports both move and copy assignment operators. lhs
-// may be either a new local variable or an existing non-const
-// variable accessible in the current scope.
-//
-// Example usage:
-// StatusOr<MyType> foo() { ... }
-//
-// ASSIGN_OR_RETURN(auto myVar, foo());
-// ASSIGN_OR_RETURN(myExistingVar, foo());
-// ASSIGN_OR_RETURN(myMemberVar, foo());
-#define ASSIGN_OR_RETURN(lhs, stmt) ASSIGN_OR_RETURN_CONCAT(__LINE__, lhs, stmt)
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_STATUSOR_H */
diff --git a/libnetdutils/include/netdutils/Stopwatch.h b/libnetdutils/include/netdutils/Stopwatch.h
deleted file mode 100644
index e7b4326..0000000
--- a/libnetdutils/include/netdutils/Stopwatch.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2016 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.
- */
-
-#ifndef NETDUTILS_STOPWATCH_H
-#define NETDUTILS_STOPWATCH_H
-
-#include <chrono>
-
-namespace android {
-namespace netdutils {
-
-class Stopwatch {
- private:
- using clock = std::chrono::steady_clock;
- using time_point = std::chrono::time_point<clock>;
-
- public:
- Stopwatch() : mStart(clock::now()) {}
- virtual ~Stopwatch() = default;
-
- int64_t timeTakenUs() const { return getElapsedUs(clock::now()); }
- int64_t getTimeAndResetUs() {
- const auto& now = clock::now();
- int64_t elapsed = getElapsedUs(now);
- mStart = now;
- return elapsed;
- }
-
- private:
- time_point mStart;
-
- int64_t getElapsedUs(const time_point& now) const {
- return (std::chrono::duration_cast<std::chrono::microseconds>(now - mStart)).count();
- }
-};
-
-} // namespace netdutils
-} // namespace android
-
-#endif // NETDUTILS_STOPWATCH_H
diff --git a/libnetdutils/include/netdutils/Syscalls.h b/libnetdutils/include/netdutils/Syscalls.h
deleted file mode 100644
index 36fcd85..0000000
--- a/libnetdutils/include/netdutils/Syscalls.h
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETDUTILS_SYSCALLS_H
-#define NETDUTILS_SYSCALLS_H
-
-#include <memory>
-
-#include <net/if.h>
-#include <poll.h>
-#include <sys/eventfd.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <unistd.h>
-
-#include "netdutils/Fd.h"
-#include "netdutils/Slice.h"
-#include "netdutils/Socket.h"
-#include "netdutils/Status.h"
-#include "netdutils/StatusOr.h"
-#include "netdutils/UniqueFd.h"
-#include "netdutils/UniqueFile.h"
-
-namespace android {
-namespace netdutils {
-
-class Syscalls {
- public:
- virtual ~Syscalls() = default;
-
- virtual StatusOr<UniqueFd> open(const std::string& pathname, int flags,
- mode_t mode = 0) const = 0;
-
- virtual StatusOr<UniqueFd> socket(int domain, int type, int protocol) const = 0;
-
- virtual Status getsockname(Fd sock, sockaddr* addr, socklen_t* addrlen) const = 0;
-
- virtual Status getsockopt(Fd sock, int level, int optname, void *optval,
- socklen_t *optlen) const = 0;
-
- virtual Status setsockopt(Fd sock, int level, int optname, const void* optval,
- socklen_t optlen) const = 0;
-
- virtual Status bind(Fd sock, const sockaddr* addr, socklen_t addrlen) const = 0;
-
- virtual Status connect(Fd sock, const sockaddr* addr, socklen_t addrlen) const = 0;
-
- virtual StatusOr<ifreq> ioctl(Fd sock, unsigned long request, ifreq* ifr) const = 0;
-
- virtual StatusOr<UniqueFd> eventfd(unsigned int initval, int flags) const = 0;
-
- virtual StatusOr<int> ppoll(pollfd* fds, nfds_t nfds, double timeout) const = 0;
-
- virtual StatusOr<size_t> writev(Fd fd, const std::vector<iovec>& iov) const = 0;
-
- virtual StatusOr<size_t> write(Fd fd, const Slice buf) const = 0;
-
- virtual StatusOr<Slice> read(Fd fd, const Slice buf) const = 0;
-
- virtual StatusOr<size_t> sendto(Fd sock, const Slice buf, int flags, const sockaddr* dst,
- socklen_t dstlen) const = 0;
-
- virtual StatusOr<Slice> recvfrom(Fd sock, const Slice dst, int flags, sockaddr* src,
- socklen_t* srclen) const = 0;
-
- virtual Status shutdown(Fd fd, int how) const = 0;
-
- virtual Status close(Fd fd) const = 0;
-
- virtual StatusOr<UniqueFile> fopen(const std::string& path, const std::string& mode) const = 0;
-
- virtual StatusOr<int> vfprintf(FILE* file, const char* format, va_list ap) const = 0;
-
- virtual StatusOr<int> vfscanf(FILE* file, const char* format, va_list ap) const = 0;
-
- virtual Status fclose(FILE* file) const = 0;
-
- virtual StatusOr<pid_t> fork() const = 0;
-
- // va_args helpers
- // va_start doesn't work when the preceding argument is a reference
- // type so we're forced to use const char*.
- StatusOr<int> fprintf(FILE* file, const char* format, ...) const {
- va_list ap;
- va_start(ap, format);
- auto result = vfprintf(file, format, ap);
- va_end(ap);
- return result;
- }
-
- // va_start doesn't work when the preceding argument is a reference
- // type so we're forced to use const char*.
- StatusOr<int> fscanf(FILE* file, const char* format, ...) const {
- va_list ap;
- va_start(ap, format);
- auto result = vfscanf(file, format, ap);
- va_end(ap);
- return result;
- }
-
- // Templated helpers that forward directly to methods declared above
- template <typename SockaddrT>
- StatusOr<SockaddrT> getsockname(Fd sock) const {
- SockaddrT addr = {};
- socklen_t addrlen = sizeof(addr);
- RETURN_IF_NOT_OK(getsockname(sock, asSockaddrPtr(&addr), &addrlen));
- return addr;
- }
-
- template <typename SockoptT>
- Status getsockopt(Fd sock, int level, int optname, void* optval, socklen_t* optlen) const {
- return getsockopt(sock, level, optname, optval, optlen);
- }
-
- template <typename SockoptT>
- Status setsockopt(Fd sock, int level, int optname, const SockoptT& opt) const {
- return setsockopt(sock, level, optname, &opt, sizeof(opt));
- }
-
- template <typename SockaddrT>
- Status bind(Fd sock, const SockaddrT& addr) const {
- return bind(sock, asSockaddrPtr(&addr), sizeof(addr));
- }
-
- template <typename SockaddrT>
- Status connect(Fd sock, const SockaddrT& addr) const {
- return connect(sock, asSockaddrPtr(&addr), sizeof(addr));
- }
-
- template <size_t size>
- StatusOr<std::array<uint16_t, size>> ppoll(const std::array<Fd, size>& fds, uint16_t events,
- double timeout) const {
- std::array<pollfd, size> tmp;
- for (size_t i = 0; i < size; ++i) {
- tmp[i].fd = fds[i].get();
- tmp[i].events = events;
- tmp[i].revents = 0;
- }
- RETURN_IF_NOT_OK(ppoll(tmp.data(), tmp.size(), timeout).status());
- std::array<uint16_t, size> out;
- for (size_t i = 0; i < size; ++i) {
- out[i] = tmp[i].revents;
- }
- return out;
- }
-
- template <typename SockaddrT>
- StatusOr<size_t> sendto(Fd sock, const Slice buf, int flags, const SockaddrT& dst) const {
- return sendto(sock, buf, flags, asSockaddrPtr(&dst), sizeof(dst));
- }
-
- // Ignore src sockaddr
- StatusOr<Slice> recvfrom(Fd sock, const Slice dst, int flags) const {
- return recvfrom(sock, dst, flags, nullptr, nullptr);
- }
-
- template <typename SockaddrT>
- StatusOr<std::pair<Slice, SockaddrT>> recvfrom(Fd sock, const Slice dst, int flags) const {
- SockaddrT addr = {};
- socklen_t addrlen = sizeof(addr);
- ASSIGN_OR_RETURN(auto used, recvfrom(sock, dst, flags, asSockaddrPtr(&addr), &addrlen));
- return std::make_pair(used, addr);
- }
-};
-
-// Specialized singleton that supports zero initialization and runtime
-// override of contained pointer.
-class SyscallsHolder {
- public:
- ~SyscallsHolder();
-
- // Return a pointer to an unowned instance of Syscalls.
- Syscalls& get();
-
- // Testing only: set the value returned by getSyscalls. Return the old value.
- // Callers are responsible for restoring the previous value returned
- // by getSyscalls to avoid leaks.
- Syscalls& swap(Syscalls& syscalls);
-
- private:
- std::atomic<Syscalls*> mSyscalls{nullptr};
-};
-
-// Syscalls instance used throughout netdutils
-extern SyscallsHolder sSyscalls;
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETDUTILS_SYSCALLS_H */
diff --git a/libnetdutils/include/netdutils/ThreadUtil.h b/libnetdutils/include/netdutils/ThreadUtil.h
deleted file mode 100644
index 62e6f70..0000000
--- a/libnetdutils/include/netdutils/ThreadUtil.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETDUTILS_THREADUTIL_H
-#define NETDUTILS_THREADUTIL_H
-
-#include <pthread.h>
-#include <memory>
-
-#include <android-base/logging.h>
-
-namespace android {
-namespace netdutils {
-
-struct scoped_pthread_attr {
- scoped_pthread_attr() { pthread_attr_init(&attr); }
- ~scoped_pthread_attr() { pthread_attr_destroy(&attr); }
-
- int detach() { return -pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); }
-
- pthread_attr_t attr;
-};
-
-inline void setThreadName(std::string name) {
- // MAX_TASK_COMM_LEN=16 is not exported by bionic.
- const size_t MAX_TASK_COMM_LEN = 16;
-
- // Crop name to 16 bytes including the NUL byte, as required by pthread_setname_np()
- if (name.size() >= MAX_TASK_COMM_LEN) name.resize(MAX_TASK_COMM_LEN - 1);
-
- if (int ret = pthread_setname_np(pthread_self(), name.c_str()); ret != 0) {
- LOG(WARNING) << "Unable to set thread name to " << name << ": " << strerror(ret);
- }
-}
-
-template <typename T>
-inline void* runAndDelete(void* obj) {
- std::unique_ptr<T> handler(reinterpret_cast<T*>(obj));
- setThreadName(handler->threadName().c_str());
- handler->run();
- return nullptr;
-}
-
-template <typename T>
-inline int threadLaunch(T* obj) {
- if (obj == nullptr) {
- return -EINVAL;
- }
-
- scoped_pthread_attr scoped_attr;
-
- int rval = scoped_attr.detach();
- if (rval != 0) {
- return rval;
- }
-
- pthread_t thread;
- rval = pthread_create(&thread, &scoped_attr.attr, &runAndDelete<T>, obj);
- if (rval != 0) {
- LOG(WARNING) << __func__ << ": pthread_create failed: " << rval;
- return -rval;
- }
-
- return rval;
-}
-
-} // namespace netdutils
-} // namespace android
-
-#endif // NETDUTILS_THREADUTIL_H
diff --git a/libnetdutils/include/netdutils/UidConstants.h b/libnetdutils/include/netdutils/UidConstants.h
deleted file mode 100644
index 42c1090..0000000
--- a/libnetdutils/include/netdutils/UidConstants.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#ifndef NETDUTILS_UID_CONSTANTS_H
-#define NETDUTILS_UID_CONSTANTS_H
-
-// These are used by both eBPF kernel programs and netd, we cannot put them in NetdConstant.h since
-// we have to minimize the number of headers included by the BPF kernel program.
-#define MIN_SYSTEM_UID 0
-#define MAX_SYSTEM_UID 9999
-
-#define PER_USER_RANGE 100000
-
-#endif // NETDUTILS_UID_CONSTANTS_H
diff --git a/libnetdutils/include/netdutils/UniqueFd.h b/libnetdutils/include/netdutils/UniqueFd.h
deleted file mode 100644
index 61101f9..0000000
--- a/libnetdutils/include/netdutils/UniqueFd.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETUTILS_UNIQUEFD_H
-#define NETUTILS_UNIQUEFD_H
-
-#include <unistd.h>
-#include <ostream>
-
-#include "netdutils/Fd.h"
-
-namespace android {
-namespace netdutils {
-
-// Stricter unique_fd implementation that:
-// *) Does not implement release()
-// *) Does not implicitly cast to int
-// *) Uses a strongly typed wrapper (Fd) for the underlying file descriptor
-//
-// Users of UniqueFd should endeavor to treat this as a completely
-// opaque object. The only code that should interpret the wrapped
-// value is in Syscalls.h
-class UniqueFd {
- public:
- UniqueFd() = default;
-
- UniqueFd(Fd fd) : mFd(fd) {}
-
- ~UniqueFd() { reset(); }
-
- // Disallow copy
- UniqueFd(const UniqueFd&) = delete;
- UniqueFd& operator=(const UniqueFd&) = delete;
-
- // Allow move
- UniqueFd(UniqueFd&& other) { std::swap(mFd, other.mFd); }
- UniqueFd& operator=(UniqueFd&& other) {
- std::swap(mFd, other.mFd);
- return *this;
- }
-
- // Cleanup any currently owned Fd, replacing it with the optional
- // parameter fd
- void reset(Fd fd = Fd());
-
- // Implict cast to Fd
- operator const Fd &() const { return mFd; }
-
- private:
- Fd mFd;
-};
-
-std::ostream& operator<<(std::ostream& os, const UniqueFd& fd);
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETUTILS_UNIQUEFD_H */
diff --git a/libnetdutils/include/netdutils/UniqueFile.h b/libnetdutils/include/netdutils/UniqueFile.h
deleted file mode 100644
index 6dd6d67..0000000
--- a/libnetdutils/include/netdutils/UniqueFile.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETDUTILS_UNIQUEFILE_H
-#define NETDUTILS_UNIQUEFILE_H
-
-#include <stdio.h>
-#include <memory>
-
-namespace android {
-namespace netdutils {
-
-struct UniqueFileDtor {
- void operator()(FILE* file) const;
-};
-
-using UniqueFile = std::unique_ptr<FILE, UniqueFileDtor>;
-
-} // namespace netdutils
-} // namespace android
-
-#endif /* NETDUTILS_UNIQUEFILE_H */
diff --git a/server/Android.bp b/server/Android.bp
index 9c89041..d008919 100644
--- a/server/Android.bp
+++ b/server/Android.bp
@@ -7,148 +7,6 @@
default_applicable_licenses: ["system_netd_license"],
}
-java_library {
- name: "netd_aidl_interface-lateststable-java",
- sdk_version: "system_current",
- min_sdk_version: "29",
- static_libs: [
- "netd_aidl_interface-V7-java",
- ],
- apex_available: [
- "//apex_available:platform", // used from services.net
- "com.android.bluetooth.updatable",
- "com.android.tethering",
- "com.android.wifi",
- ],
-}
-
-cc_library_static {
- name: "netd_event_listener_interface-lateststable-ndk_platform",
- whole_static_libs: [
- "netd_event_listener_interface-V1-ndk_platform",
- ],
- apex_available: [
- "com.android.resolv",
- ],
- min_sdk_version: "29",
-}
-
-cc_library_static {
- name: "netd_aidl_interface-lateststable-ndk_platform",
- whole_static_libs: [
- "netd_aidl_interface-V7-ndk_platform",
- ],
- apex_available: [
- "com.android.resolv",
- ],
- min_sdk_version: "29",
-}
-
-cc_library_static {
- name: "netd_aidl_interface-lateststable-cpp",
- whole_static_libs: [
- "netd_aidl_interface-V7-cpp",
- ],
-}
-
-aidl_interface {
- name: "netd_aidl_interface",
- local_include_dir: "binder",
- srcs: [
- "binder/android/net/INetd.aidl",
- // AIDL interface that callers can implement to receive networking events from netd.
- "binder/android/net/INetdUnsolicitedEventListener.aidl",
- "binder/android/net/InterfaceConfigurationParcel.aidl",
- "binder/android/net/MarkMaskParcel.aidl",
- "binder/android/net/NativeNetworkConfig.aidl",
- "binder/android/net/NativeNetworkType.aidl",
- "binder/android/net/NativeVpnType.aidl",
- "binder/android/net/RouteInfoParcel.aidl",
- "binder/android/net/TetherConfigParcel.aidl",
- "binder/android/net/TetherOffloadRuleParcel.aidl",
- "binder/android/net/TetherStatsParcel.aidl",
- "binder/android/net/UidRangeParcel.aidl",
- // Add new AIDL classes in android.net.netd.aidl to consist with other network modules.
- "binder/android/net/netd/aidl/**/*.aidl",
- ],
- backend: {
- cpp: {
- gen_log: true,
- },
- java: {
- // TODO: Remove apex_available and restrict visibility to only mainline modules that are
- // either outside the system server or use jarjar to rename the generated AIDL classes.
- apex_available: [
- "//apex_available:platform", // used from services.net
- "com.android.bluetooth.updatable",
- "com.android.tethering",
- "com.android.wifi",
- ],
- // this is part of updatable modules(NetworkStack) which targets 29(Q)
- min_sdk_version: "29",
- },
- ndk: {
- apex_available: [
- "//apex_available:platform",
- ],
- // This is necessary for the DnsResovler tests to run in Android Q.
- // Soong would recognize this value and produce the Q compatible aidl library.
- min_sdk_version: "29",
- },
- },
- versions: [
- "1",
- "2",
- "3",
- "4",
- "5",
- "6",
- "7",
- ],
-}
-
-java_library {
- name: "netd_event_listener_interface-lateststable-java",
- sdk_version: "system_current",
- min_sdk_version: "29",
- static_libs: [
- "netd_event_listener_interface-V1-java",
- ],
- apex_available: [
- "//apex_available:platform",
- "com.android.bluetooth.updatable",
- "com.android.wifi",
- "com.android.tethering",
- ],
-}
-
-aidl_interface {
- name: "netd_event_listener_interface",
- local_include_dir: "binder",
- srcs: [
- "binder/android/net/metrics/INetdEventListener.aidl",
- ],
- versions: ["1"],
- backend: {
- ndk: {
- apex_available: [
- "//apex_available:platform",
- "com.android.resolv",
- ],
- min_sdk_version: "29",
- },
- java: {
- apex_available: [
- "//apex_available:platform",
- "com.android.bluetooth.updatable",
- "com.android.wifi",
- "com.android.tethering",
- ],
- min_sdk_version: "29",
- },
- },
-}
-
aidl_interface {
// This interface is for OEM calls to netd and vice versa that do not exist in AOSP.
// Those calls cannot be part of INetd.aidl and INetdUnsolicitedEventListener.aidl
@@ -171,25 +29,25 @@
"NetdConstants.cpp",
"InterfaceController.cpp",
"NetlinkCommands.cpp",
- "NetlinkListener.cpp",
- "OffloadUtils.cpp",
"SockDiag.cpp",
"XfrmController.cpp",
- "TrafficController.cpp",
],
}
// Modules common to both netd and netd_unit_test
cc_library_static {
name: "libnetd_server",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_shared",
+ "netd_defaults",
+ ],
include_dirs: [
"system/netd/include",
"system/netd/server/binder",
],
+ header_libs: ["bpf_connectivity_headers"],
srcs: [
"BandwidthController.cpp",
- "ClatdController.cpp",
"Controllers.cpp",
"NetdConstants.cpp",
"FirewallController.cpp",
@@ -198,33 +56,30 @@
"IptablesRestoreController.cpp",
"NFLogListener.cpp",
"NetlinkCommands.cpp",
- "NetlinkListener.cpp",
"NetlinkManager.cpp",
- "OffloadUtils.cpp",
"RouteController.cpp",
"SockDiag.cpp",
"StrictController.cpp",
"TcpSocketMonitor.cpp",
"TetherController.cpp",
- "TrafficController.cpp",
"UidRanges.cpp",
"WakeupController.cpp",
"XfrmController.cpp",
],
shared_libs: [
- "libbpf_android",
"libbase",
"libbinder",
- "libnetdbpf",
"libnetutils",
"libnetdutils",
"libpcap",
- "libqtaguid",
"libssl",
"libsysutils",
- "netd_aidl_interface-V7-cpp",
"netd_event_listener_interface-V1-cpp",
],
+ static_libs: [
+ "libip_checksum",
+ "libtcutils",
+ ],
aidl: {
export_aidl_headers: true,
local_include_dirs: ["binder"],
@@ -233,7 +88,10 @@
cc_binary {
name: "netd",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_shared",
+ "netd_defaults",
+ ],
include_dirs: [
"external/mdnsresponder/mDNSShared",
"system/netd/include",
@@ -241,43 +99,44 @@
init_rc: ["netd.rc"],
required: [
"bpfloader",
- "clatd.o",
- "netd.o",
],
+ header_libs: ["bpf_connectivity_headers"],
shared_libs: [
"android.system.net.netd@1.0",
"android.system.net.netd@1.1",
"libbase",
"libbinder",
- "libbpf_android",
"libcutils",
"libdl",
"libhidlbase",
"liblog",
"libmdnssd",
+ "libnetd_updatable",
"libnetd_resolv",
- "libnetdbpf",
"libnetdutils",
"libnetutils",
"libpcap",
"libprocessgroup",
- "libqtaguid",
"libselinux",
"libsysutils",
"libutils",
- "netd_aidl_interface-V7-cpp",
+ "mdns_aidl_interface-V1-cpp",
"netd_event_listener_interface-V1-cpp",
"oemnetd_aidl_interface-cpp",
],
static_libs: [
+ "libip_checksum",
"libnetd_server",
+ "libtcutils",
],
srcs: [
"DummyNetwork.cpp",
"EventReporter.cpp",
"FwmarkServer.cpp",
"LocalNetwork.cpp",
+ "MDnsEventReporter.cpp",
"MDnsSdListener.cpp",
+ "MDnsService.cpp",
"NetdCommand.cpp",
"NetdHwService.cpp",
"NetdNativeService.cpp",
@@ -295,12 +154,16 @@
],
sanitize: {
cfi: true,
+ memtag_heap: true,
},
}
cc_binary {
name: "ndc",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_shared",
+ "netd_defaults",
+ ],
include_dirs: [
"system/netd/include",
],
@@ -316,7 +179,6 @@
"libutils",
"libbinder",
"dnsresolver_aidl_interface-V7-cpp",
- "netd_aidl_interface-V6-cpp",
],
srcs: [
"ndc.cpp",
@@ -331,7 +193,10 @@
cc_test {
name: "netd_unit_test",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_static",
+ "netd_defaults",
+ ],
test_suites: ["device-tests"],
require_root: true,
include_dirs: [
@@ -339,9 +204,14 @@
"system/netd/server/binder",
"system/netd/tests",
],
+ header_libs: ["bpf_connectivity_headers"],
+ tidy_timeout_srcs: [
+ "BandwidthControllerTest.cpp",
+ "InterfaceControllerTest.cpp",
+ "XfrmControllerTest.cpp",
+ ],
srcs: [
"BandwidthControllerTest.cpp",
- "ClatdControllerTest.cpp",
"ControllersTest.cpp",
"FirewallControllerTest.cpp",
"IdletimerControllerTest.cpp",
@@ -349,31 +219,27 @@
"IptablesBaseTest.cpp",
"IptablesRestoreControllerTest.cpp",
"NFLogListenerTest.cpp",
- "OffloadUtilsTest.cpp",
"RouteControllerTest.cpp",
"SockDiagTest.cpp",
"StrictControllerTest.cpp",
"TetherControllerTest.cpp",
- "TrafficControllerTest.cpp",
"XfrmControllerTest.cpp",
"WakeupControllerTest.cpp",
],
static_libs: [
"libgmock",
+ "libip_checksum",
"libnetd_server",
"libnetd_test_tun_interface",
- "libqtaguid",
- "netd_aidl_interface-V7-cpp",
+ "libtcutils",
"netd_event_listener_interface-V1-cpp",
],
shared_libs: [
"libbase",
"libbinder",
- "libbpf_android",
"libcrypto",
"libcutils",
"liblog",
- "libnetdbpf",
"libnetdutils",
"libnetutils",
"libsysutils",
diff --git a/server/BandwidthController.cpp b/server/BandwidthController.cpp
index 1b46234..96a82e2 100644
--- a/server/BandwidthController.cpp
+++ b/server/BandwidthController.cpp
@@ -55,7 +55,6 @@
#include "FirewallController.h" /* For makeCriticalCommands */
#include "Fwmark.h"
#include "NetdConstants.h"
-#include "TrafficController.h"
#include "bpf/BpfUtils.h"
/* Alphabetical */
@@ -67,6 +66,9 @@
const char BandwidthController::LOCAL_MANGLE_POSTROUTING[] = "bw_mangle_POSTROUTING";
const char BandwidthController::LOCAL_GLOBAL_ALERT[] = "bw_global_alert";
+// Sync from packages/modules/Connectivity/bpf_progs/clatd.c
+#define CLAT_MARK 0xdeadc1a7
+
auto BandwidthController::iptablesRestoreFunction = execIptablesRestoreWithOutput;
using android::base::Join;
@@ -74,8 +76,6 @@
using android::base::StringAppendF;
using android::base::StringPrintf;
using android::net::FirewallController;
-using android::net::gCtls;
-using android::netdutils::Status;
using android::netdutils::StatusOr;
using android::netdutils::UniqueFile;
@@ -227,6 +227,8 @@
"COMMIT",
"*raw",
+ // Drop duplicate ingress clat packets
+ StringPrintf("-A bw_raw_PREROUTING -m mark --mark 0x%x -j DROP", CLAT_MARK),
// Prevents IPSec double counting (Tunnel mode and Transport mode,
// respectively)
("-A bw_raw_PREROUTING -i " IPSEC_IFACE_PREFIX "+ -j RETURN"),
@@ -236,9 +238,7 @@
// interface and later correct for overhead (+20 bytes/packet).
//
// Note: eBPF offloaded packets never hit base interface's ip6tables, and non
- // offloaded packets (which when using xt_qtaguid means all packets, because
- // clat eBPF offload does not work on xt_qtaguid devices) are dropped in
- // clat_raw_PREROUTING.
+ // offloaded packets are dropped up above due to being marked with CLAT_MARK
//
// Hence we will never double count and additional corrections are not needed.
// We can simply take the sum of base and stacked (+20B/pkt) interface counts.
@@ -252,9 +252,6 @@
"-A bw_mangle_POSTROUTING -m policy --pol ipsec --dir out -j RETURN",
// Clear the uid billing done (egress) mark before sending this packet
StringPrintf("-A bw_mangle_POSTROUTING -j MARK --set-mark 0x0/0x%x", uidBillingMask),
- // Packets from the clat daemon have already been counted on egress through the
- // stacked v4-* interface.
- "-A bw_mangle_POSTROUTING -m owner --uid-owner clat -j RETURN",
// This is egress interface accounting: we account 464xlat traffic only on
// the clat interface (as offloaded packets never hit base interface's ip6tables)
// and later sum base and stacked with overhead (+20B/pkt) in higher layers
@@ -323,31 +320,6 @@
return ret;
}
-int BandwidthController::addNaughtyApps(const std::vector<uint32_t>& appUids) {
- return manipulateSpecialApps(appUids, PENALTY_BOX_MATCH, IptOpInsert);
-}
-
-int BandwidthController::removeNaughtyApps(const std::vector<uint32_t>& appUids) {
- return manipulateSpecialApps(appUids, PENALTY_BOX_MATCH, IptOpDelete);
-}
-
-int BandwidthController::addNiceApps(const std::vector<uint32_t>& appUids) {
- return manipulateSpecialApps(appUids, HAPPY_BOX_MATCH, IptOpInsert);
-}
-
-int BandwidthController::removeNiceApps(const std::vector<uint32_t>& appUids) {
- return manipulateSpecialApps(appUids, HAPPY_BOX_MATCH, IptOpDelete);
-}
-
-int BandwidthController::manipulateSpecialApps(const std::vector<uint32_t>& appUids,
- UidOwnerMatchType matchType, IptOp op) {
- Status status = gCtls->trafficCtrl.updateUidOwnerMap(appUids, matchType, op);
- if (!isOk(status)) {
- ALOGE("unable to update the Bandwidth Uid Map: %s", toString(status).c_str());
- }
- return status.code();
-}
-
int BandwidthController::setInterfaceSharedQuota(const std::string& iface, int64_t maxBytes) {
int res = 0;
std::string quotaCmd;
diff --git a/server/BandwidthController.h b/server/BandwidthController.h
index 414e91b..2a3b4bd 100644
--- a/server/BandwidthController.h
+++ b/server/BandwidthController.h
@@ -24,7 +24,6 @@
#include <mutex>
#include "NetdConstants.h"
-#include "netdbpf/bpf_shared.h"
class BandwidthController {
public:
@@ -90,9 +89,6 @@
std::string makeDataSaverCommand(IptablesTarget target, bool enable);
- int manipulateSpecialApps(const std::vector<uint32_t>& appStrUids, UidOwnerMatchType matchType,
- IptOp appOp);
-
int runIptablesAlertCmd(IptOp op, const std::string& alertName, int64_t bytes);
int runIptablesAlertFwdCmd(IptOp op, const std::string& alertName, int64_t bytes);
diff --git a/server/BandwidthControllerTest.cpp b/server/BandwidthControllerTest.cpp
index d635daf..e7d29d2 100644
--- a/server/BandwidthControllerTest.cpp
+++ b/server/BandwidthControllerTest.cpp
@@ -34,8 +34,7 @@
#include "BandwidthController.h"
#include "Fwmark.h"
#include "IptablesBaseTest.h"
-#include "bpf/BpfUtils.h"
-#include "netdbpf/bpf_shared.h"
+#include "bpf_shared.h"
#include "tun_interface.h"
using ::testing::_;
@@ -188,6 +187,7 @@
"-I bw_happy_box -m bpf --object-pinned " XT_BPF_ALLOWLIST_PROG_PATH " -j RETURN\n"
"COMMIT\n"
"*raw\n"
+ "-A bw_raw_PREROUTING -m mark --mark 0xdeadc1a7 -j DROP\n"
"-A bw_raw_PREROUTING -i ipsec+ -j RETURN\n"
"-A bw_raw_PREROUTING -m policy --pol ipsec --dir in -j RETURN\n"
"-A bw_raw_PREROUTING -m bpf --object-pinned " XT_BPF_INGRESS_PROG_PATH "\n"
@@ -196,7 +196,6 @@
"-A bw_mangle_POSTROUTING -o ipsec+ -j RETURN\n"
"-A bw_mangle_POSTROUTING -m policy --pol ipsec --dir out -j RETURN\n"
"-A bw_mangle_POSTROUTING -j MARK --set-mark 0x0/0x100000\n"
- "-A bw_mangle_POSTROUTING -m owner --uid-owner clat -j RETURN\n"
"-A bw_mangle_POSTROUTING -m bpf --object-pinned " XT_BPF_EGRESS_PROG_PATH "\n"
"COMMIT\n";
// clang-format on
diff --git a/server/ClatdController.cpp b/server/ClatdController.cpp
deleted file mode 100644
index 847a6db..0000000
--- a/server/ClatdController.cpp
+++ /dev/null
@@ -1,669 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-#include <map>
-#include <string>
-
-#include <arpa/inet.h>
-#include <errno.h>
-#include <linux/if_tun.h>
-#include <linux/ioctl.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <spawn.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-
-#define LOG_TAG "ClatdController"
-#include <log/log.h>
-
-#include "ClatdController.h"
-#include "InterfaceController.h"
-
-#include "android-base/properties.h"
-#include "android-base/scopeguard.h"
-#include "android-base/stringprintf.h"
-#include "android-base/unique_fd.h"
-#include "bpf/BpfMap.h"
-#include "netdbpf/bpf_shared.h"
-#include "netdutils/DumpWriter.h"
-
-extern "C" {
-#include "netutils/checksum.h"
-}
-
-#include "Fwmark.h"
-#include "NetdConstants.h"
-#include "NetworkController.h"
-#include "OffloadUtils.h"
-#include "netid_client.h"
-
-static const char* kClatdPath = "/system/bin/clatd";
-
-// For historical reasons, start with 192.0.0.4, and after that, use all subsequent addresses in
-// 192.0.0.0/29 (RFC 7335).
-static const char* kV4AddrString = "192.0.0.4";
-static const in_addr kV4Addr = {inet_addr(kV4AddrString)};
-static const int kV4AddrLen = 29;
-
-using android::base::Result;
-using android::base::StringPrintf;
-using android::base::unique_fd;
-using android::bpf::BpfMap;
-using android::netdutils::DumpWriter;
-using android::netdutils::ScopedIndent;
-
-namespace android {
-namespace net {
-
-void ClatdController::init(void) {
- std::lock_guard guard(mutex);
-
- int rv = getClatEgress4MapFd();
- if (rv < 0) {
- ALOGE("getClatEgress4MapFd() failure: %s", strerror(-rv));
- return;
- }
- mClatEgress4Map.reset(rv);
-
- rv = getClatIngress6MapFd();
- if (rv < 0) {
- ALOGE("getClatIngress6MapFd() failure: %s", strerror(-rv));
- mClatEgress4Map.reset(-1);
- return;
- }
- mClatIngress6Map.reset(rv);
-
- mClatEgress4Map.clear();
- mClatIngress6Map.clear();
-}
-
-bool ClatdController::isIpv4AddressFree(in_addr_t addr) {
- 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.
- struct sockaddr_in sin = {
- .sin_family = AF_INET,
- .sin_port = htons(53),
- .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;
-
- close(s);
- return !inuse;
-}
-
-// Picks a free IPv4 address, starting from ip and trying all addresses in the prefix in order.
-// 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 ClatdController::selectIpv4Address(const in_addr ip, int16_t prefixlen) {
- // Don't accept prefixes that are too large because we scan addresses one by one.
- 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;
-
- // 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);
- }
- ipv4 = prefix | ((ipv4 + 1) & ~mask);
- } while (ipv4 != first_ipv4);
-
- return INADDR_NONE;
-}
-
-// Alters the bits in the IPv6 address to make them checksum neutral with v4 and nat64Prefix.
-void ClatdController::makeChecksumNeutral(in6_addr* 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);
-
- // Make the IID checksum-neutral. That is, make it so that:
- // checksum(Local IPv4 | Remote IPv4) = checksum(Local IPv6 | Remote IPv6)
- // in other words (because remote IPv6 = NAT64 prefix | Remote IPv4):
- // checksum(Local IPv4) = checksum(Local IPv6 | NAT64 prefix)
- // Do this by adjusting the two bytes in the middle of the IID.
-
- uint16_t middlebytes = (v6->s6_addr[11] << 8) + v6->s6_addr[12];
-
- uint32_t c1 = ip_checksum_add(0, &v4, sizeof(v4));
- uint32_t c2 = ip_checksum_add(0, &nat64Prefix, sizeof(nat64Prefix)) +
- ip_checksum_add(0, v6, sizeof(*v6));
-
- uint16_t delta = ip_checksum_adjust(middlebytes, c1, c2);
- v6->s6_addr[11] = delta >> 8;
- v6->s6_addr[12] = delta & 0xff;
-}
-
-// Picks a random interface ID that is checksum neutral with the IPv4 address and the NAT64 prefix.
-int ClatdController::generateIpv6Address(const char* iface, const in_addr v4,
- const in6_addr& nat64Prefix, in6_addr* v6) {
- unique_fd s(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
- if (s == -1) return -errno;
-
- if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, iface, strlen(iface) + 1) == -1) {
- return -errno;
- }
-
- sockaddr_in6 sin6 = {.sin6_family = AF_INET6, .sin6_addr = nat64Prefix};
- if (connect(s, reinterpret_cast<struct sockaddr*>(&sin6), sizeof(sin6)) == -1) {
- return -errno;
- }
-
- socklen_t len = sizeof(sin6);
- if (getsockname(s, reinterpret_cast<struct sockaddr*>(&sin6), &len) == -1) {
- return -errno;
- }
-
- *v6 = sin6.sin6_addr;
-
- if (IN6_IS_ADDR_UNSPECIFIED(v6) || IN6_IS_ADDR_LOOPBACK(v6) || IN6_IS_ADDR_LINKLOCAL(v6) ||
- IN6_IS_ADDR_SITELOCAL(v6) || IN6_IS_ADDR_ULA(v6)) {
- return -ENETUNREACH;
- }
-
- makeChecksumNeutral(v6, v4, nat64Prefix);
-
- return 0;
-}
-
-void ClatdController::maybeStartBpf(const ClatdTracker& tracker) {
- auto isEthernet = android::net::isEthernet(tracker.iface);
- if (!isEthernet.ok()) {
- ALOGE("isEthernet(%s[%d]) failure: %s", tracker.iface, tracker.ifIndex,
- isEthernet.error().message().c_str());
- return;
- }
-
- // This program will be attached to the v4-* interface which is a TUN and thus always rawip.
- int rv = getClatEgress4ProgFd(RAWIP);
- if (rv < 0) {
- ALOGE("getClatEgress4ProgFd(RAWIP) failure: %s", strerror(-rv));
- return;
- }
- unique_fd txRawIpProgFd(rv);
-
- rv = getClatIngress6ProgFd(isEthernet.value());
- if (rv < 0) {
- ALOGE("getClatIngress6ProgFd(%d) failure: %s", isEthernet.value(), strerror(-rv));
- return;
- }
- unique_fd rxProgFd(rv);
-
- ClatEgress4Key txKey = {
- .iif = tracker.v4ifIndex,
- .local4 = tracker.v4,
- };
- ClatEgress4Value txValue = {
- .oif = tracker.ifIndex,
- .local6 = tracker.v6,
- .pfx96 = tracker.pfx96,
- .oifIsEthernet = isEthernet.value(),
- };
-
- auto ret = mClatEgress4Map.writeValue(txKey, txValue, BPF_ANY);
- if (!ret.ok()) {
- ALOGE("mClatEgress4Map.writeValue failure: %s", strerror(ret.error().code()));
- return;
- }
-
- ClatIngress6Key rxKey = {
- .iif = tracker.ifIndex,
- .pfx96 = tracker.pfx96,
- .local6 = tracker.v6,
- };
- ClatIngress6Value rxValue = {
- // TODO: move all the clat code to eBPF and remove the tun interface entirely.
- .oif = tracker.v4ifIndex,
- .local4 = tracker.v4,
- };
-
- ret = mClatIngress6Map.writeValue(rxKey, rxValue, BPF_ANY);
- if (!ret.ok()) {
- ALOGE("mClatIngress6Map.writeValue failure: %s", strerror(ret.error().code()));
- ret = mClatEgress4Map.deleteValue(txKey);
- if (!ret.ok())
- ALOGE("mClatEgress4Map.deleteValue failure: %s", strerror(ret.error().code()));
- return;
- }
-
- // We do tc setup *after* populating the maps, so scanning through them
- // can always be used to tell us what needs cleanup.
-
- // Usually the clsact will be added in RouteController::addInterfaceToPhysicalNetwork.
- // But clat is started before the v4- interface is added to the network. The clat startup have
- // to add clsact of v4- tun interface first for adding bpf filter in maybeStartBpf.
- // TODO: move "qdisc add clsact" of v4- tun interface out from ClatdController.
- rv = tcQdiscAddDevClsact(tracker.v4ifIndex);
- if (rv) {
- ALOGE("tcQdiscAddDevClsact(%d[%s]) failure: %s", tracker.v4ifIndex, tracker.v4iface,
- strerror(-rv));
- ret = mClatEgress4Map.deleteValue(txKey);
- if (!ret.ok())
- ALOGE("mClatEgress4Map.deleteValue failure: %s", strerror(ret.error().code()));
- ret = mClatIngress6Map.deleteValue(rxKey);
- if (!ret.ok())
- ALOGE("mClatIngress6Map.deleteValue failure: %s", strerror(ret.error().code()));
- return;
- }
-
- rv = tcFilterAddDevEgressClatIpv4(tracker.v4ifIndex, txRawIpProgFd, RAWIP);
- if (rv) {
- ALOGE("tcFilterAddDevEgressClatIpv4(%d[%s], RAWIP) failure: %s", tracker.v4ifIndex,
- tracker.v4iface, strerror(-rv));
-
- // The v4- interface clsact is not deleted for unwinding error because once it is created
- // with interface addition, the lifetime is till interface deletion. Moreover, the clsact
- // has no clat filter now. It should not break anything.
-
- ret = mClatEgress4Map.deleteValue(txKey);
- if (!ret.ok())
- ALOGE("mClatEgress4Map.deleteValue failure: %s", strerror(ret.error().code()));
- ret = mClatIngress6Map.deleteValue(rxKey);
- if (!ret.ok())
- ALOGE("mClatIngress6Map.deleteValue failure: %s", strerror(ret.error().code()));
- return;
- }
-
- rv = tcFilterAddDevIngressClatIpv6(tracker.ifIndex, rxProgFd, isEthernet.value());
- if (rv) {
- ALOGE("tcFilterAddDevIngressClatIpv6(%d[%s], %d) failure: %s", tracker.ifIndex,
- tracker.iface, isEthernet.value(), strerror(-rv));
- rv = tcFilterDelDevEgressClatIpv4(tracker.v4ifIndex);
- if (rv) {
- ALOGE("tcFilterDelDevEgressClatIpv4(%d[%s]) failure: %s", tracker.v4ifIndex,
- tracker.v4iface, strerror(-rv));
- }
-
- // The v4- interface clsact is not deleted. See the reason in the error unwinding code of
- // the egress filter attaching of v4- tun interface.
-
- ret = mClatEgress4Map.deleteValue(txKey);
- if (!ret.ok())
- ALOGE("mClatEgress4Map.deleteValue failure: %s", strerror(ret.error().code()));
- ret = mClatIngress6Map.deleteValue(rxKey);
- if (!ret.ok())
- ALOGE("mClatIngress6Map.deleteValue failure: %s", strerror(ret.error().code()));
- return;
- }
-
- // success
-}
-
-void ClatdController::setIptablesDropRule(bool add, const char* iface, const char* pfx96Str,
- const char* v6Str) {
- std::string cmd = StringPrintf(
- "*raw\n"
- "%s %s -i %s -s %s/96 -d %s -j DROP\n"
- "COMMIT\n",
- (add ? "-A" : "-D"), LOCAL_RAW_PREROUTING, iface, pfx96Str, v6Str);
-
- iptablesRestoreFunction(V6, cmd);
-}
-
-void ClatdController::maybeStopBpf(const ClatdTracker& tracker) {
- int rv = tcFilterDelDevIngressClatIpv6(tracker.ifIndex);
- if (rv < 0) {
- ALOGE("tcFilterDelDevIngressClatIpv6(%d[%s]) failure: %s", tracker.ifIndex, tracker.iface,
- strerror(-rv));
- }
-
- rv = tcFilterDelDevEgressClatIpv4(tracker.v4ifIndex);
- if (rv < 0) {
- ALOGE("tcFilterDelDevEgressClatIpv4(%d[%s]) failure: %s", tracker.v4ifIndex,
- tracker.v4iface, strerror(-rv));
- }
-
- // We cleanup the maps last, so scanning through them can be used to
- // determine what still needs cleanup.
-
- ClatEgress4Key txKey = {
- .iif = tracker.v4ifIndex,
- .local4 = tracker.v4,
- };
-
- auto ret = mClatEgress4Map.deleteValue(txKey);
- if (!ret.ok()) ALOGE("mClatEgress4Map.deleteValue failure: %s", strerror(ret.error().code()));
-
- ClatIngress6Key rxKey = {
- .iif = tracker.ifIndex,
- .pfx96 = tracker.pfx96,
- .local6 = tracker.v6,
- };
-
- ret = mClatIngress6Map.deleteValue(rxKey);
- if (!ret.ok()) ALOGE("mClatIngress6Map.deleteValue failure: %s", strerror(ret.error().code()));
-}
-
-// Finds the tracker of the clatd running on interface |interface|, or nullptr if clatd has not been
-// started on |interface|.
-ClatdController::ClatdTracker* ClatdController::getClatdTracker(const std::string& interface) {
- auto it = mClatdTrackers.find(interface);
- return (it == mClatdTrackers.end() ? nullptr : &it->second);
-}
-
-// Initializes a ClatdTracker for the specified interface.
-int ClatdController::ClatdTracker::init(unsigned networkId, const std::string& interface,
- const std::string& v4interface,
- const std::string& nat64Prefix) {
- fwmark.netId = networkId;
- fwmark.explicitlySelected = true;
- fwmark.protectedFromVpn = true;
- fwmark.permission = PERMISSION_SYSTEM;
-
- snprintf(fwmarkString, sizeof(fwmarkString), "0x%x", fwmark.intValue);
- strlcpy(iface, interface.c_str(), sizeof(iface));
- ifIndex = if_nametoindex(iface);
- strlcpy(v4iface, v4interface.c_str(), sizeof(v4iface));
- v4ifIndex = if_nametoindex(v4iface);
-
- // Pass in everything that clatd needs: interface, a fwmark for outgoing packets, the NAT64
- // prefix, and the IPv4 and IPv6 addresses.
- // Validate the prefix and strip off the prefix length.
- uint8_t family;
- uint8_t prefixLen;
- int res = parsePrefix(nat64Prefix.c_str(), &family, &pfx96, sizeof(pfx96), &prefixLen);
- // clatd only supports /96 prefixes.
- if (res != sizeof(pfx96)) return res;
- if (family != AF_INET6) return -EAFNOSUPPORT;
- if (prefixLen != 96) return -EINVAL;
- if (!inet_ntop(AF_INET6, &pfx96, pfx96String, sizeof(pfx96String))) return -errno;
-
- // Pick an IPv4 address.
- // TODO: this picks the address based on other addresses that are assigned to interfaces, but
- // the address is only actually assigned to an interface once clatd starts up. So we could end
- // up with two clatd instances with the same IPv4 address.
- // Stop doing this and instead pick a free one from the kV4Addr pool.
- v4 = {selectIpv4Address(kV4Addr, kV4AddrLen)};
- if (v4.s_addr == INADDR_NONE) {
- ALOGE("No free IPv4 address in %s/%d", kV4AddrString, kV4AddrLen);
- return -EADDRNOTAVAIL;
- }
- if (!inet_ntop(AF_INET, &v4, v4Str, sizeof(v4Str))) return -errno;
-
- // Generate a checksum-neutral IID.
- if (generateIpv6Address(iface, v4, pfx96, &v6)) {
- ALOGE("Unable to find global source address on %s for %s", iface, pfx96String);
- return -EADDRNOTAVAIL;
- }
- if (!inet_ntop(AF_INET6, &v6, v6Str, sizeof(v6Str))) return -errno;
-
- ALOGD("starting clatd on %s v4=%s v6=%s pfx96=%s", iface, v4Str, v6Str, pfx96String);
- return 0;
-}
-
-int ClatdController::startClatd(const std::string& interface, const std::string& nat64Prefix,
- std::string* v6Str) {
- std::lock_guard guard(mutex);
-
- // 1. fail if pre-existing tracker already exists
- ClatdTracker* existing = getClatdTracker(interface);
- if (existing != nullptr) {
- ALOGE("clatd pid=%d already started on %s", existing->pid, interface.c_str());
- return -EBUSY;
- }
-
- // 2. get network id associated with this external interface
- unsigned networkId = mNetCtrl->getNetworkForInterface(interface.c_str());
- if (networkId == NETID_UNSET) {
- ALOGE("Interface %s not assigned to any netId", interface.c_str());
- return -ENODEV;
- }
-
- // 3. open the tun device in non blocking mode as required by clatd
- int res = open("/dev/net/tun", O_RDWR | O_NONBLOCK | O_CLOEXEC);
- if (res == -1) {
- res = errno;
- ALOGE("open of tun device failed (%s)", strerror(res));
- return -res;
- }
- unique_fd tmpTunFd(res);
-
- // 4. create the v4-... tun interface
- std::string v4interface("v4-");
- v4interface += interface;
-
- struct ifreq ifr = {
- .ifr_flags = IFF_TUN,
- };
- strlcpy(ifr.ifr_name, v4interface.c_str(), sizeof(ifr.ifr_name));
-
- res = ioctl(tmpTunFd, TUNSETIFF, &ifr, sizeof(ifr));
- if (res == -1) {
- res = errno;
- ALOGE("ioctl(TUNSETIFF) failed (%s)", strerror(res));
- return -res;
- }
-
- // disable IPv6 on it - failing to do so is not a critical error
- res = InterfaceController::setEnableIPv6(v4interface.c_str(), 0);
- if (res) ALOGE("setEnableIPv6 %s failed (%s)", v4interface.c_str(), strerror(res));
-
- // 5. initialize tracker object
- ClatdTracker tracker;
- int ret = tracker.init(networkId, interface, v4interface, nat64Prefix);
- if (ret) return ret;
-
- // 6. create a throwaway socket to reserve a file descriptor number
- res = socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0);
- if (res == -1) {
- res = errno;
- ALOGE("socket(ipv6/udp) failed (%s)", strerror(res));
- return -res;
- }
- unique_fd passedTunFd(res);
-
- // 7. this is the FD we'll pass to clatd on the cli, so need it as a string
- char passedTunFdStr[INT32_STRLEN];
- snprintf(passedTunFdStr, sizeof(passedTunFdStr), "%d", passedTunFd.get());
-
- // 8. we're going to use this as argv[0] to clatd to make ps output more useful
- std::string progname("clatd-");
- progname += tracker.iface;
-
- // clang-format off
- const char* args[] = {progname.c_str(),
- "-i", tracker.iface,
- "-m", tracker.fwmarkString,
- "-p", tracker.pfx96String,
- "-4", tracker.v4Str,
- "-6", tracker.v6Str,
- "-t", passedTunFdStr,
- nullptr};
- // clang-format on
-
- // 9. register vfork requirement
- posix_spawnattr_t attr;
- res = posix_spawnattr_init(&attr);
- if (res) {
- ALOGE("posix_spawnattr_init failed (%s)", strerror(res));
- return -res;
- }
- const android::base::ScopeGuard attrGuard = [&] { posix_spawnattr_destroy(&attr); };
- res = posix_spawnattr_setflags(&attr, POSIX_SPAWN_USEVFORK);
- if (res) {
- ALOGE("posix_spawnattr_setflags failed (%s)", strerror(res));
- return -res;
- }
-
- // 10. register dup2() action: this is what 'clears' the CLOEXEC flag
- // on the tun fd that we want the child clatd process to inherit
- // (this will happen after the vfork, and before the execve)
- posix_spawn_file_actions_t fa;
- res = posix_spawn_file_actions_init(&fa);
- if (res) {
- ALOGE("posix_spawn_file_actions_init failed (%s)", strerror(res));
- return -res;
- }
- const android::base::ScopeGuard faGuard = [&] { posix_spawn_file_actions_destroy(&fa); };
- res = posix_spawn_file_actions_adddup2(&fa, tmpTunFd, passedTunFd);
- if (res) {
- ALOGE("posix_spawn_file_actions_adddup2 failed (%s)", strerror(res));
- return -res;
- }
-
- // 11. add the drop rule for iptables.
- setIptablesDropRule(true, tracker.iface, tracker.pfx96String, tracker.v6Str);
-
- // 12. actually perform vfork/dup2/execve
- res = posix_spawn(&tracker.pid, kClatdPath, &fa, &attr, (char* const*)args, nullptr);
- if (res) {
- ALOGE("posix_spawn failed (%s)", strerror(res));
- return -res;
- }
-
- // 13. configure eBPF offload - if possible
- maybeStartBpf(tracker);
-
- mClatdTrackers[interface] = tracker;
- ALOGD("clatd started on %s", interface.c_str());
-
- *v6Str = tracker.v6Str;
- return 0;
-}
-
-int ClatdController::stopClatd(const std::string& interface) {
- std::lock_guard guard(mutex);
- ClatdTracker* tracker = getClatdTracker(interface);
-
- if (tracker == nullptr) {
- ALOGE("clatd already stopped");
- return -ENODEV;
- }
-
- ALOGD("Stopping clatd pid=%d on %s", tracker->pid, interface.c_str());
-
- maybeStopBpf(*tracker);
-
- kill(tracker->pid, SIGTERM);
- waitpid(tracker->pid, nullptr, 0);
-
- setIptablesDropRule(false, tracker->iface, tracker->pfx96String, tracker->v6Str);
- mClatdTrackers.erase(interface);
-
- ALOGD("clatd on %s stopped", interface.c_str());
-
- return 0;
-}
-
-void ClatdController::dumpEgress(DumpWriter& dw) {
- if (!mClatEgress4Map.isValid()) return; // if unsupported just don't dump anything
-
- ScopedIndent bpfIndent(dw);
- dw.println("BPF egress map: iif(iface) v4Addr -> v6Addr nat64Prefix oif(iface)");
-
- ScopedIndent bpfDetailIndent(dw);
- const auto printClatMap = [&dw](const ClatEgress4Key& key, const ClatEgress4Value& value,
- const BpfMap<ClatEgress4Key, ClatEgress4Value>&) {
- char iifStr[IFNAMSIZ] = "?";
- char local4Str[INET_ADDRSTRLEN] = "?";
- char local6Str[INET6_ADDRSTRLEN] = "?";
- char pfx96Str[INET6_ADDRSTRLEN] = "?";
- char oifStr[IFNAMSIZ] = "?";
-
- if_indextoname(key.iif, iifStr);
- inet_ntop(AF_INET, &key.local4, local4Str, sizeof(local4Str));
- inet_ntop(AF_INET6, &value.local6, local6Str, sizeof(local6Str));
- inet_ntop(AF_INET6, &value.pfx96, pfx96Str, sizeof(pfx96Str));
- if_indextoname(value.oif, oifStr);
-
- dw.println("%u(%s) %s -> %s %s/96 %u(%s) %s", key.iif, iifStr, local4Str, local6Str,
- pfx96Str, value.oif, oifStr, value.oifIsEthernet ? "ether" : "rawip");
- return Result<void>();
- };
- auto res = mClatEgress4Map.iterateWithValue(printClatMap);
- if (!res.ok()) {
- dw.println("Error printing BPF map: %s", res.error().message().c_str());
- }
-}
-
-void ClatdController::dumpIngress(DumpWriter& dw) {
- if (!mClatIngress6Map.isValid()) return; // if unsupported just don't dump anything
-
- ScopedIndent bpfIndent(dw);
- dw.println("BPF ingress map: iif(iface) nat64Prefix v6Addr -> v4Addr oif(iface)");
-
- ScopedIndent bpfDetailIndent(dw);
- const auto printClatMap = [&dw](const ClatIngress6Key& key, const ClatIngress6Value& value,
- const BpfMap<ClatIngress6Key, ClatIngress6Value>&) {
- char iifStr[IFNAMSIZ] = "?";
- char pfx96Str[INET6_ADDRSTRLEN] = "?";
- char local6Str[INET6_ADDRSTRLEN] = "?";
- char local4Str[INET_ADDRSTRLEN] = "?";
- char oifStr[IFNAMSIZ] = "?";
-
- if_indextoname(key.iif, iifStr);
- inet_ntop(AF_INET6, &key.pfx96, pfx96Str, sizeof(pfx96Str));
- inet_ntop(AF_INET6, &key.local6, local6Str, sizeof(local6Str));
- inet_ntop(AF_INET, &value.local4, local4Str, sizeof(local4Str));
- if_indextoname(value.oif, oifStr);
-
- dw.println("%u(%s) %s/96 %s -> %s %u(%s)", key.iif, iifStr, pfx96Str, local6Str, local4Str,
- value.oif, oifStr);
- return Result<void>();
- };
- auto res = mClatIngress6Map.iterateWithValue(printClatMap);
- if (!res.ok()) {
- dw.println("Error printing BPF map: %s", res.error().message().c_str());
- }
-}
-
-void ClatdController::dumpTrackers(DumpWriter& dw) {
- ScopedIndent trackerIndent(dw);
- dw.println("Trackers: iif[iface] nat64Prefix v6Addr -> v4Addr v4iif[v4iface] [fwmark]");
-
- ScopedIndent trackerDetailIndent(dw);
- for (const auto& pair : mClatdTrackers) {
- const ClatdTracker& tracker = pair.second;
- dw.println("%u[%s] %s/96 %s -> %s %u[%s] [%s]", tracker.ifIndex, tracker.iface,
- tracker.pfx96String, tracker.v6Str, tracker.v4Str, tracker.v4ifIndex,
- tracker.v4iface, tracker.fwmarkString);
- }
-}
-
-void ClatdController::dump(DumpWriter& dw) {
- std::lock_guard guard(mutex);
-
- ScopedIndent clatdIndent(dw);
- dw.println("ClatdController");
-
- dumpTrackers(dw);
- dumpIngress(dw);
- dumpEgress(dw);
-}
-
-auto ClatdController::isIpv4AddressFreeFunc = isIpv4AddressFree;
-auto ClatdController::iptablesRestoreFunction = execIptablesRestore;
-
-} // namespace net
-} // namespace android
diff --git a/server/ClatdController.h b/server/ClatdController.h
deleted file mode 100644
index 4b7c60b..0000000
--- a/server/ClatdController.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2008 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.
- */
-
-#ifndef _CLATD_CONTROLLER_H
-#define _CLATD_CONTROLLER_H
-
-#include <map>
-#include <mutex>
-#include <string>
-
-#include <linux/if.h>
-#include <netinet/in.h>
-
-#include <android-base/thread_annotations.h>
-
-#include "Fwmark.h"
-#include "NetdConstants.h"
-#include "bpf/BpfMap.h"
-#include "netdbpf/bpf_shared.h"
-#include "netdutils/DumpWriter.h"
-
-namespace android {
-namespace net {
-
-class NetworkController;
-
-class ClatdController {
- public:
- explicit ClatdController(NetworkController* controller) EXCLUDES(mutex)
- : mNetCtrl(controller){};
- virtual ~ClatdController() EXCLUDES(mutex){};
-
- /* First thing init/startClatd/stopClatd/dump do is grab the mutex. */
- void init(void) EXCLUDES(mutex);
-
- int startClatd(const std::string& interface, const std::string& nat64Prefix,
- std::string* v6Addr) EXCLUDES(mutex);
- int stopClatd(const std::string& interface) EXCLUDES(mutex);
-
- void dump(netdutils::DumpWriter& dw) EXCLUDES(mutex);
-
- static constexpr const char LOCAL_RAW_PREROUTING[] = "clat_raw_PREROUTING";
-
- private:
- struct ClatdTracker {
- pid_t pid = -1;
- unsigned ifIndex;
- char iface[IFNAMSIZ];
- unsigned v4ifIndex;
- char v4iface[IFNAMSIZ];
- Fwmark fwmark;
- char fwmarkString[UINT32_STRLEN];
- in_addr v4;
- char v4Str[INET_ADDRSTRLEN];
- in6_addr v6;
- char v6Str[INET6_ADDRSTRLEN];
- in6_addr pfx96;
- char pfx96String[INET6_ADDRSTRLEN];
-
- int init(unsigned networkId, const std::string& interface, const std::string& v4interface,
- const std::string& nat64Prefix);
- };
-
- std::mutex mutex;
-
- const NetworkController* mNetCtrl GUARDED_BY(mutex);
- std::map<std::string, ClatdTracker> mClatdTrackers GUARDED_BY(mutex);
- ClatdTracker* getClatdTracker(const std::string& interface) REQUIRES(mutex);
-
- void dumpEgress(netdutils::DumpWriter& dw) REQUIRES(mutex);
- void dumpIngress(netdutils::DumpWriter& dw) REQUIRES(mutex);
- void dumpTrackers(netdutils::DumpWriter& dw) REQUIRES(mutex);
-
- static in_addr_t selectIpv4Address(const in_addr ip, int16_t prefixlen);
- static int generateIpv6Address(const char* iface, const in_addr v4, const in6_addr& nat64Prefix,
- in6_addr* v6);
- static void makeChecksumNeutral(in6_addr* v6, const in_addr v4, const in6_addr& nat64Prefix);
-
- bpf::BpfMap<ClatEgress4Key, ClatEgress4Value> mClatEgress4Map GUARDED_BY(mutex);
- bpf::BpfMap<ClatIngress6Key, ClatIngress6Value> mClatIngress6Map GUARDED_BY(mutex);
-
- void maybeStartBpf(const ClatdTracker& tracker) REQUIRES(mutex);
- void maybeStopBpf(const ClatdTracker& tracker) REQUIRES(mutex);
- void setIptablesDropRule(bool add, const char* iface, const char* pfx96Str, const char* v6Str)
- REQUIRES(mutex);
-
- // For testing.
- friend class ClatdControllerTest;
-
- static bool (*isIpv4AddressFreeFunc)(in_addr_t);
- static bool isIpv4AddressFree(in_addr_t addr);
- static int (*iptablesRestoreFunction)(IptablesTarget target, const std::string& commands);
-};
-
-} // namespace net
-} // namespace android
-
-#endif
diff --git a/server/ClatdControllerTest.cpp b/server/ClatdControllerTest.cpp
deleted file mode 100644
index d3a2aa7..0000000
--- a/server/ClatdControllerTest.cpp
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * Copyright 2018 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.
- *
- * ClatdControllerTest.cpp - unit tests for ClatdController.cpp
- */
-
-#include <arpa/inet.h>
-#include <netinet/in.h>
-#include <string>
-
-#include <gtest/gtest.h>
-
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <netutils/ifc.h>
-
-extern "C" {
-#include <netutils/checksum.h>
-}
-
-#include "ClatdController.h"
-#include "IptablesBaseTest.h"
-#include "NetworkController.h"
-#include "tun_interface.h"
-
-static const char kIPv4LocalAddr[] = "192.0.0.4";
-
-namespace android {
-namespace net {
-
-using android::base::StringPrintf;
-
-// Mock functions for isIpv4AddressFree.
-bool neverFree(in_addr_t /* addr */) {
- return 0;
-}
-bool alwaysFree(in_addr_t /* addr */) {
- return 1;
-}
-bool only2Free(in_addr_t addr) {
- return (ntohl(addr) & 0xff) == 2;
-}
-bool over6Free(in_addr_t addr) {
- return (ntohl(addr) & 0xff) >= 6;
-}
-bool only10Free(in_addr_t addr) {
- return (ntohl(addr) & 0xff) == 10;
-}
-
-class ClatdControllerTest : public IptablesBaseTest {
- public:
- ClatdControllerTest() : mClatdCtrl(nullptr) {
- ClatdController::iptablesRestoreFunction = fakeExecIptablesRestore;
- }
-
- void SetUp() { resetIpv4AddressFreeFunc(); }
-
- protected:
- ClatdController mClatdCtrl;
- void setIptablesDropRule(bool a, const char* b, const char* c, const char* d) {
- std::lock_guard guard(mClatdCtrl.mutex);
- return mClatdCtrl.setIptablesDropRule(a, b, c, d);
- }
- void setIpv4AddressFreeFunc(bool (*func)(in_addr_t)) {
- ClatdController::isIpv4AddressFreeFunc = func;
- }
- void resetIpv4AddressFreeFunc() {
- ClatdController::isIpv4AddressFreeFunc = ClatdController::isIpv4AddressFree;
- }
- in_addr_t selectIpv4Address(const in_addr a, int16_t b) {
- return ClatdController::selectIpv4Address(a, b);
- }
- void makeChecksumNeutral(in6_addr* a, const in_addr b, const in6_addr& c) {
- ClatdController::makeChecksumNeutral(a, b, c);
- }
-};
-
-TEST_F(ClatdControllerTest, SelectIpv4Address) {
- struct in_addr addr;
-
- inet_pton(AF_INET, kIPv4LocalAddr, &addr);
-
- // If no addresses are free, return INADDR_NONE.
- setIpv4AddressFreeFunc(neverFree);
- EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 29));
- EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 16));
-
- // If the configured address is free, pick that. But a prefix that's too big is invalid.
- setIpv4AddressFreeFunc(alwaysFree);
- EXPECT_EQ(inet_addr(kIPv4LocalAddr), selectIpv4Address(addr, 29));
- EXPECT_EQ(inet_addr(kIPv4LocalAddr), selectIpv4Address(addr, 20));
- EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 15));
-
- // A prefix length of 32 works, but anything above it is invalid.
- EXPECT_EQ(inet_addr(kIPv4LocalAddr), selectIpv4Address(addr, 32));
- EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 33));
-
- // If another address is free, pick it.
- setIpv4AddressFreeFunc(over6Free);
- EXPECT_EQ(inet_addr("192.0.0.6"), selectIpv4Address(addr, 29));
-
- // Check that we wrap around to addresses that are lower than the first address.
- setIpv4AddressFreeFunc(only2Free);
- EXPECT_EQ(inet_addr("192.0.0.2"), selectIpv4Address(addr, 29));
- EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 30));
-
- // If a free address exists outside the prefix, we don't pick it.
- setIpv4AddressFreeFunc(only10Free);
- EXPECT_EQ(INADDR_NONE, selectIpv4Address(addr, 29));
- EXPECT_EQ(inet_addr("192.0.0.10"), selectIpv4Address(addr, 24));
-
- // Now try using the real function which sees if IP addresses are free using bind().
- // Assume that the machine running the test has the address 127.0.0.1, but not 8.8.8.8.
- resetIpv4AddressFreeFunc();
- addr.s_addr = inet_addr("8.8.8.8");
- EXPECT_EQ(inet_addr("8.8.8.8"), selectIpv4Address(addr, 29));
-
- addr.s_addr = inet_addr("127.0.0.1");
- EXPECT_EQ(inet_addr("127.0.0.2"), selectIpv4Address(addr, 29));
-}
-
-TEST_F(ClatdControllerTest, MakeChecksumNeutral) {
- // We can't test generateIPv6Address here since it requires manipulating routing, which we can't
- // do without talking to the real netd on the system.
- uint32_t rand = arc4random_uniform(0xffffffff);
- uint16_t rand1 = rand & 0xffff;
- uint16_t rand2 = (rand >> 16) & 0xffff;
- std::string v6PrefixStr = StringPrintf("2001:db8:%x:%x", rand1, rand2);
- std::string v6InterfaceAddrStr = StringPrintf("%s::%x:%x", v6PrefixStr.c_str(), rand2, rand1);
- std::string nat64PrefixStr = StringPrintf("2001:db8:%x:%x::", rand2, rand1);
-
- in_addr v4 = {inet_addr(kIPv4LocalAddr)};
- in6_addr v6InterfaceAddr;
- ASSERT_TRUE(inet_pton(AF_INET6, v6InterfaceAddrStr.c_str(), &v6InterfaceAddr));
- in6_addr nat64Prefix;
- ASSERT_TRUE(inet_pton(AF_INET6, nat64PrefixStr.c_str(), &nat64Prefix));
-
- // Generate a boatload of random IIDs.
- int onebits = 0;
- uint64_t prev_iid = 0;
- for (int i = 0; i < 100000; i++) {
- in6_addr v6 = v6InterfaceAddr;
- makeChecksumNeutral(&v6, v4, nat64Prefix);
-
- // Check the generated IP address is in the same prefix as the interface IPv6 address.
- EXPECT_EQ(0, memcmp(&v6, &v6InterfaceAddr, 8));
-
- // Check that consecutive IIDs are not the same.
- uint64_t iid = *(uint64_t*)(&v6.s6_addr[8]);
- ASSERT_TRUE(iid != prev_iid)
- << "Two consecutive random IIDs are the same: " << std::showbase << std::hex << iid
- << "\n";
- prev_iid = iid;
-
- // Check that the IID is checksum-neutral with the NAT64 prefix and the
- // local prefix.
- uint16_t c1 = ip_checksum_finish(ip_checksum_add(0, &v4, sizeof(v4)));
- uint16_t c2 = ip_checksum_finish(ip_checksum_add(0, &nat64Prefix, sizeof(nat64Prefix)) +
- ip_checksum_add(0, &v6, sizeof(v6)));
-
- if (c1 != c2) {
- char v6Str[INET6_ADDRSTRLEN];
- inet_ntop(AF_INET6, &v6, v6Str, sizeof(v6Str));
- FAIL() << "Bad IID: " << v6Str << " not checksum-neutral with " << kIPv4LocalAddr
- << " and " << nat64PrefixStr.c_str() << std::showbase << std::hex
- << "\n IPv4 checksum: " << c1 << "\n IPv6 checksum: " << c2 << "\n";
- }
-
- // Check that IIDs are roughly random and use all the bits by counting the
- // total number of bits set to 1 in a random sample of 100000 generated IIDs.
- onebits += __builtin_popcountll(*(uint64_t*)&iid);
- }
- EXPECT_LE(3190000, onebits);
- EXPECT_GE(3210000, onebits);
-}
-
-TEST_F(ClatdControllerTest, AddIptablesRule) {
- setIptablesDropRule(true, "wlan0", "64:ff9b::", "2001:db8::1:2:3:4");
- expectIptablesRestoreCommands((ExpectedIptablesCommands){
- {V6,
- "*raw\n"
- "-A clat_raw_PREROUTING -i wlan0 -s 64:ff9b::/96 -d 2001:db8::1:2:3:4 -j DROP\n"
- "COMMIT\n"}});
-}
-
-TEST_F(ClatdControllerTest, RemoveIptablesRule) {
- setIptablesDropRule(false, "wlan0", "64:ff9b::", "2001:db8::a:b:c:d");
- expectIptablesRestoreCommands((ExpectedIptablesCommands){
- {V6,
- "*raw\n"
- "-D clat_raw_PREROUTING -i wlan0 -s 64:ff9b::/96 -d 2001:db8::a:b:c:d -j DROP\n"
- "COMMIT\n"}});
-}
-
-} // namespace net
-} // namespace android
diff --git a/server/Controllers.cpp b/server/Controllers.cpp
index 1f2bac2..0df6b0e 100644
--- a/server/Controllers.cpp
+++ b/server/Controllers.cpp
@@ -74,9 +74,8 @@
};
static const std::vector<const char*> RAW_PREROUTING = {
- ClatdController::LOCAL_RAW_PREROUTING,
- BandwidthController::LOCAL_RAW_PREROUTING,
IdletimerController::LOCAL_RAW_PREROUTING,
+ BandwidthController::LOCAL_RAW_PREROUTING,
TetherController::LOCAL_RAW_PREROUTING,
};
@@ -192,8 +191,7 @@
}
Controllers::Controllers()
- : clatdCtrl(&netCtrl),
- wakeupCtrl(
+ : wakeupCtrl(
[this](const WakeupController::ReportArgs& args) {
const auto listener = eventReporter.getNetdEventListener();
if (listener == nullptr) {
@@ -279,21 +277,6 @@
initIptablesRules();
Stopwatch s;
- clatdCtrl.init();
- gLog.info("Initializing ClatdController: %" PRId64 "us", s.getTimeAndResetUs());
-
- netdutils::Status tcStatus = trafficCtrl.start();
- if (!isOk(tcStatus)) {
- gLog.error("Failed to start trafficcontroller: (%s)", toString(tcStatus).c_str());
- gLog.error("CRITICAL: sleeping 60 seconds, netd exiting with failure, crash loop likely!");
- // The expected reason we get here is a major kernel or other code bug, as such
- // the probability that things will succeed on restart of netd is pretty small.
- // So, let's wait a minute to at least try to limit the log spam a little bit.
- sleep(60);
- exit(1);
- }
- gLog.info("Initializing traffic control: %" PRId64 "us", s.getTimeAndResetUs());
-
bandwidthCtrl.enableBandwidthControl();
gLog.info("Enabling bandwidth control: %" PRId64 "us", s.getTimeAndResetUs());
diff --git a/server/Controllers.h b/server/Controllers.h
index fbd9bf1..8b51ddf 100644
--- a/server/Controllers.h
+++ b/server/Controllers.h
@@ -18,7 +18,6 @@
#define _CONTROLLERS_H__
#include "BandwidthController.h"
-#include "ClatdController.h"
#include "EventReporter.h"
#include "FirewallController.h"
#include "IdletimerController.h"
@@ -29,7 +28,6 @@
#include "StrictController.h"
#include "TcpSocketMonitor.h"
#include "TetherController.h"
-#include "TrafficController.h"
#include "WakeupController.h"
#include "XfrmController.h"
#include "netdutils/Log.h"
@@ -47,13 +45,11 @@
BandwidthController bandwidthCtrl;
IdletimerController idletimerCtrl;
FirewallController firewallCtrl;
- ClatdController clatdCtrl;
StrictController strictCtrl;
EventReporter eventReporter;
IptablesRestoreController iptablesRestoreCtrl;
WakeupController wakeupCtrl;
XfrmController xfrmCtrl;
- TrafficController trafficCtrl;
TcpSocketMonitor tcpSocketMonitor;
void init();
diff --git a/server/ControllersTest.cpp b/server/ControllersTest.cpp
index ebaa38f..9033a1d 100644
--- a/server/ControllersTest.cpp
+++ b/server/ControllersTest.cpp
@@ -96,12 +96,10 @@
"*raw\n"
":PREROUTING -\n"
"-F PREROUTING\n"
- ":clat_raw_PREROUTING -\n"
- "-A PREROUTING -j clat_raw_PREROUTING\n"
- ":bw_raw_PREROUTING -\n"
- "-A PREROUTING -j bw_raw_PREROUTING\n"
":idletimer_raw_PREROUTING -\n"
"-A PREROUTING -j idletimer_raw_PREROUTING\n"
+ ":bw_raw_PREROUTING -\n"
+ "-A PREROUTING -j bw_raw_PREROUTING\n"
":tetherctrl_raw_PREROUTING -\n"
"-A PREROUTING -j tetherctrl_raw_PREROUTING\n"
"COMMIT\n"},
diff --git a/server/FirewallController.cpp b/server/FirewallController.cpp
index 35fd1e2..b3c6b02 100644
--- a/server/FirewallController.cpp
+++ b/server/FirewallController.cpp
@@ -37,23 +37,8 @@
#include "bpf/BpfUtils.h"
using android::base::Join;
-using android::base::ReadFileToString;
-using android::base::Split;
using android::base::StringAppendF;
using android::base::StringPrintf;
-using android::net::gCtls;
-
-namespace {
-
-// Default maximum valid uid in a normal root user namespace. The maximum valid uid is used in
-// rules that exclude all possible UIDs in the namespace in order to match packets that have
-// no socket associated with them.
-constexpr const uid_t kDefaultMaximumUid = UID_MAX - 1; // UID_MAX defined as UINT_MAX
-
-// Proc file containing the uid mapping for the user namespace of the current process.
-const char kUidMapProcFile[] = "/proc/self/uid_map";
-
-} // namespace
namespace android {
namespace net {
@@ -66,11 +51,6 @@
const char* FirewallController::LOCAL_OUTPUT = "fw_OUTPUT";
const char* FirewallController::LOCAL_FORWARD = "fw_FORWARD";
-const char* FirewallController::LOCAL_DOZABLE = "fw_dozable";
-const char* FirewallController::LOCAL_STANDBY = "fw_standby";
-const char* FirewallController::LOCAL_POWERSAVE = "fw_powersave";
-const char* FirewallController::LOCAL_RESTRICTED = "fw_restricted";
-
// ICMPv6 types that are required for any form of IPv6 connectivity to work. Note that because the
// fw_dozable chain is called from both INPUT and OUTPUT, this includes both packets that we need
// to be able to send (e.g., RS, NS), and packets that we need to receive (e.g., RA, NA).
@@ -83,25 +63,14 @@
"redirect",
};
-FirewallController::FirewallController(void) : mMaxUid(discoverMaximumValidUid(kUidMapProcFile)) {
+FirewallController::FirewallController(void) {
// If no rules are set, it's in DENYLIST mode
mFirewallType = DENYLIST;
mIfaceRules = {};
}
int FirewallController::setupIptablesHooks(void) {
- int res = flushRules();
-
- // mUseBpfOwnerMatch should be removed, but it is still depended upon by test code.
- mUseBpfOwnerMatch = true;
- if (mUseBpfOwnerMatch) {
- return res;
- }
- res |= createChain(LOCAL_DOZABLE, getFirewallType(DOZABLE));
- res |= createChain(LOCAL_STANDBY, getFirewallType(STANDBY));
- res |= createChain(LOCAL_POWERSAVE, getFirewallType(POWERSAVE));
- res |= createChain(LOCAL_RESTRICTED, getFirewallType(RESTRICTED));
- return res;
+ return flushRules();
}
int FirewallController::setFirewallType(FirewallType ftype) {
@@ -145,39 +114,6 @@
return flushRules();
}
-int FirewallController::enableChildChains(ChildChain chain, bool enable) {
- int res = 0;
- const char* name;
- switch(chain) {
- case DOZABLE:
- name = LOCAL_DOZABLE;
- break;
- case STANDBY:
- name = LOCAL_STANDBY;
- break;
- case POWERSAVE:
- name = LOCAL_POWERSAVE;
- break;
- case RESTRICTED:
- name = LOCAL_RESTRICTED;
- break;
- default:
- return res;
- }
-
- if (mUseBpfOwnerMatch) {
- return gCtls->trafficCtrl.toggleUidOwnerMap(chain, enable);
- }
-
- std::string command = "*filter\n";
- for (const char *parent : { LOCAL_INPUT, LOCAL_OUTPUT }) {
- StringAppendF(&command, "%s %s -j %s\n", (enable ? "-A" : "-D"), parent, name);
- }
- StringAppendF(&command, "COMMIT\n");
-
- return execIptablesRestore(V4V6, command);
-}
-
int FirewallController::isFirewallEnabled(void) {
// TODO: verify that rules are still in place near top
return -1;
@@ -217,77 +153,6 @@
return (execIptablesRestore(V4V6, command) == 0) ? 0 : -EREMOTEIO;
}
-FirewallType FirewallController::getFirewallType(ChildChain chain) {
- switch(chain) {
- case DOZABLE:
- return ALLOWLIST;
- case STANDBY:
- return DENYLIST;
- case POWERSAVE:
- return ALLOWLIST;
- case RESTRICTED:
- return ALLOWLIST;
- case NONE:
- return mFirewallType;
- default:
- return DENYLIST;
- }
-}
-
-int FirewallController::setUidRule(ChildChain chain, int uid, FirewallRule rule) {
- const char* op;
- const char* target;
- FirewallType firewallType = getFirewallType(chain);
- if (firewallType == ALLOWLIST) {
- target = "RETURN";
- // When adding, insert RETURN rules at the front, before the catch-all DROP at the end.
- op = (rule == ALLOW)? "-I" : "-D";
- } else { // DENYLIST mode
- target = "DROP";
- // When adding, append DROP rules at the end, after the RETURN rule that matches TCP RSTs.
- op = (rule == DENY)? "-A" : "-D";
- }
-
- std::vector<std::string> chainNames;
- switch(chain) {
- case DOZABLE:
- chainNames = {LOCAL_DOZABLE};
- break;
- case STANDBY:
- chainNames = {LOCAL_STANDBY};
- break;
- case POWERSAVE:
- chainNames = {LOCAL_POWERSAVE};
- break;
- case RESTRICTED:
- chainNames = {LOCAL_RESTRICTED};
- break;
- case NONE:
- chainNames = {LOCAL_INPUT, LOCAL_OUTPUT};
- break;
- default:
- ALOGW("Unknown child chain: %d", chain);
- return -EINVAL;
- }
- if (mUseBpfOwnerMatch) {
- return gCtls->trafficCtrl.changeUidOwnerRule(chain, uid, rule, firewallType);
- }
-
- std::string command = "*filter\n";
- for (const std::string& chainName : chainNames) {
- StringAppendF(&command, "%s %s -m owner --uid-owner %d -j %s\n",
- op, chainName.c_str(), uid, target);
- }
- StringAppendF(&command, "COMMIT\n");
-
- return (execIptablesRestore(V4V6, command) == 0) ? 0 : -EREMOTEIO;
-}
-
-int FirewallController::createChain(const char* chain, FirewallType type) {
- static const std::vector<int32_t> NO_UIDS;
- return replaceUidChain(chain, type == ALLOWLIST, NO_UIDS);
-}
-
/* static */
std::string FirewallController::makeCriticalCommands(IptablesTarget target, const char* chainName) {
// Allow ICMPv6 packets necessary to make IPv6 connectivity work. http://b/23158230 .
@@ -301,112 +166,5 @@
return commands;
}
-std::string FirewallController::makeUidRules(IptablesTarget target, const char* name,
- bool isAllowlist, const std::vector<int32_t>& uids) {
- std::string commands;
- StringAppendF(&commands, "*filter\n:%s -\n", name);
-
- // Allowlist chains have UIDs at the beginning, and new UIDs are added with '-I'.
- if (isAllowlist) {
- for (auto uid : uids) {
- StringAppendF(&commands, "-A %s -m owner --uid-owner %d -j RETURN\n", name, uid);
- }
-
- // Always allowlist system UIDs.
- StringAppendF(&commands,
- "-A %s -m owner --uid-owner %d-%d -j RETURN\n", name, 0, MAX_SYSTEM_UID);
-
- // This rule inverts the match for all UIDs; ie, if there is no UID match here,
- // there is no socket to be found
- StringAppendF(&commands,
- "-A %s -m owner ! --uid-owner %d-%u -j RETURN\n", name, 0, mMaxUid);
-
- // Always allowlist traffic with protocol ESP, or no known socket - required for IPSec
- StringAppendF(&commands, "-A %s -p esp -j RETURN\n", name);
- }
-
- // Always allow networking on loopback.
- StringAppendF(&commands, "-A %s -i lo -j RETURN\n", name);
- StringAppendF(&commands, "-A %s -o lo -j RETURN\n", name);
-
- // Allow TCP RSTs so we can cleanly close TCP connections of apps that no longer have network
- // access. Both incoming and outgoing RSTs are allowed.
- StringAppendF(&commands, "-A %s -p tcp --tcp-flags RST RST -j RETURN\n", name);
-
- if (isAllowlist) {
- commands.append(makeCriticalCommands(target, name));
- }
-
- // Denylist chains have UIDs at the end, and new UIDs are added with '-A'.
- if (!isAllowlist) {
- for (auto uid : uids) {
- StringAppendF(&commands, "-A %s -m owner --uid-owner %d -j DROP\n", name, uid);
- }
- }
-
- // If it's an allowlist chain, add a default DROP at the end. This is not necessary for a
- // denylist chain, because all user-defined chains implicitly RETURN at the end.
- if (isAllowlist) {
- StringAppendF(&commands, "-A %s -j DROP\n", name);
- }
-
- StringAppendF(&commands, "COMMIT\n");
-
- return commands;
-}
-
-int FirewallController::replaceUidChain(const std::string& name, bool isAllowlist,
- const std::vector<int32_t>& uids) {
- if (mUseBpfOwnerMatch) {
- return gCtls->trafficCtrl.replaceUidOwnerMap(name, isAllowlist, uids);
- }
- std::string commands4 = makeUidRules(V4, name.c_str(), isAllowlist, uids);
- std::string commands6 = makeUidRules(V6, name.c_str(), isAllowlist, uids);
- return execIptablesRestore(V4, commands4.c_str()) | execIptablesRestore(V6, commands6.c_str());
-}
-
-/* static */
-uid_t FirewallController::discoverMaximumValidUid(const std::string& fileName) {
- std::string content;
- if (!ReadFileToString(fileName, &content, false)) {
- // /proc/self/uid_map only exists if a uid mapping has been set.
- ALOGD("Could not read %s, max uid defaulting to %u", fileName.c_str(), kDefaultMaximumUid);
- return kDefaultMaximumUid;
- }
-
- std::vector<std::string> lines = Split(content, "\n");
- if (lines.empty()) {
- ALOGD("%s was empty, max uid defaulting to %u", fileName.c_str(), kDefaultMaximumUid);
- return kDefaultMaximumUid;
- }
-
- uint32_t maxUid = 0;
- for (const auto& line : lines) {
- if (line.empty()) {
- continue;
- }
-
- // Choose the end of the largest range found in the file.
- uint32_t start;
- uint32_t ignored;
- uint32_t rangeLength;
- int items = sscanf(line.c_str(), "%u %u %u", &start, &ignored, &rangeLength);
- if (items != 3) {
- // uid_map lines must have 3 items, see the man page of 'user_namespaces' for details.
- ALOGD("Format of %s unrecognized, max uid defaulting to %u", fileName.c_str(),
- kDefaultMaximumUid);
- return kDefaultMaximumUid;
- }
- maxUid = std::max(maxUid, start + rangeLength - 1);
- }
-
- if (maxUid == 0) {
- ALOGD("No max uid found, max uid defaulting to %u", kDefaultMaximumUid);
- return kDefaultMaximumUid;
- }
-
- return maxUid;
-}
-
} // namespace net
} // namespace android
diff --git a/server/FirewallController.h b/server/FirewallController.h
index 6de1b45..6d6f48f 100644
--- a/server/FirewallController.h
+++ b/server/FirewallController.h
@@ -23,30 +23,12 @@
#include <string>
#include <vector>
-#include "android/net/INetd.h"
-
#include "NetdConstants.h"
#include "bpf/BpfUtils.h"
namespace android {
namespace net {
-enum FirewallRule { ALLOW = INetd::FIREWALL_RULE_ALLOW, DENY = INetd::FIREWALL_RULE_DENY };
-
-// 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
-
-enum FirewallType { ALLOWLIST = INetd::FIREWALL_ALLOWLIST, DENYLIST = INetd::FIREWALL_DENYLIST };
-
-enum ChildChain {
- NONE = INetd::FIREWALL_CHAIN_NONE,
- DOZABLE = INetd::FIREWALL_CHAIN_DOZABLE,
- STANDBY = INetd::FIREWALL_CHAIN_STANDBY,
- POWERSAVE = INetd::FIREWALL_CHAIN_POWERSAVE,
- RESTRICTED = INetd::FIREWALL_CHAIN_RESTRICTED,
- INVALID_CHAIN
-};
-
/*
* Simple firewall that drops all packets except those matching explicitly
* defined ALLOW rules.
@@ -72,10 +54,7 @@
int enableChildChains(ChildChain, bool);
- int replaceUidChain(const std::string&, bool, const std::vector<int32_t>&);
-
static std::string makeCriticalCommands(IptablesTarget target, const char* chainName);
- static uid_t discoverMaximumValidUid(const std::string& fileName);
static const char* TABLE;
@@ -83,36 +62,18 @@
static const char* LOCAL_OUTPUT;
static const char* LOCAL_FORWARD;
- static const char* LOCAL_DOZABLE;
- static const char* LOCAL_STANDBY;
- static const char* LOCAL_POWERSAVE;
- static const char* LOCAL_RESTRICTED;
-
static const char* ICMPV6_TYPES[];
std::mutex lock;
protected:
friend class FirewallControllerTest;
- std::string makeUidRules(IptablesTarget target, const char* name, bool isAllowlist,
- const std::vector<int32_t>& uids);
static int (*execIptablesRestore)(IptablesTarget target, const std::string& commands);
private:
- // Netd supports two cases, in both of which mMaxUid that derives from the uid mapping is const:
- // - netd runs in a root namespace which contains all UIDs.
- // - netd runs in a user namespace where the uid mapping is written once before netd starts.
- // In that case, an attempt to write more than once to a uid_map file in a user namespace
- // fails with EPERM. Netd can therefore assumes the max valid uid to be const.
- const uid_t mMaxUid;
FirewallType mFirewallType;
- bool mUseBpfOwnerMatch;
std::set<std::string> mIfaceRules;
int flushRules(void);
- int attachChain(const char*, const char*);
- int detachChain(const char*, const char*);
- int createChain(const char*, FirewallType);
- FirewallType getFirewallType(ChildChain);
};
} // namespace net
diff --git a/server/FirewallControllerTest.cpp b/server/FirewallControllerTest.cpp
index 1f199af..a7aee47 100644
--- a/server/FirewallControllerTest.cpp
+++ b/server/FirewallControllerTest.cpp
@@ -22,16 +22,9 @@
#include <gtest/gtest.h>
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
#include "FirewallController.h"
#include "IptablesBaseTest.h"
-using android::base::Join;
-using android::base::WriteStringToFile;
-
namespace android {
namespace net {
@@ -39,192 +32,10 @@
protected:
FirewallControllerTest() {
FirewallController::execIptablesRestore = fakeExecIptablesRestore;
- // This unit test currently doesn't cover the eBPF owner match case so
- // we have to manually turn eBPF support off.
- // TODO: find a way to unit test the eBPF code path.
- mFw.mUseBpfOwnerMatch = false;
}
FirewallController mFw;
-
- std::string makeUidRules(IptablesTarget a, const char* b, bool c,
- const std::vector<int32_t>& d) {
- return mFw.makeUidRules(a, b, c, d);
- }
-
- int createChain(const char* a, FirewallType b) {
- return mFw.createChain(a, b);
- }
};
-TEST_F(FirewallControllerTest, TestCreateAllowlistChain) {
- std::vector<std::string> expectedRestore4 = {
- "*filter",
- ":fw_allowlist -",
- "-A fw_allowlist -m owner --uid-owner 0-9999 -j RETURN",
- "-A fw_allowlist -m owner ! --uid-owner 0-4294967294 -j RETURN",
- "-A fw_allowlist -p esp -j RETURN",
- "-A fw_allowlist -i lo -j RETURN",
- "-A fw_allowlist -o lo -j RETURN",
- "-A fw_allowlist -p tcp --tcp-flags RST RST -j RETURN",
- "-A fw_allowlist -j DROP",
- "COMMIT\n"};
- std::vector<std::string> expectedRestore6 = {
- "*filter",
- ":fw_allowlist -",
- "-A fw_allowlist -m owner --uid-owner 0-9999 -j RETURN",
- "-A fw_allowlist -m owner ! --uid-owner 0-4294967294 -j RETURN",
- "-A fw_allowlist -p esp -j RETURN",
- "-A fw_allowlist -i lo -j RETURN",
- "-A fw_allowlist -o lo -j RETURN",
- "-A fw_allowlist -p tcp --tcp-flags RST RST -j RETURN",
- "-A fw_allowlist -p icmpv6 --icmpv6-type packet-too-big -j RETURN",
- "-A fw_allowlist -p icmpv6 --icmpv6-type router-solicitation -j RETURN",
- "-A fw_allowlist -p icmpv6 --icmpv6-type router-advertisement -j RETURN",
- "-A fw_allowlist -p icmpv6 --icmpv6-type neighbour-solicitation -j RETURN",
- "-A fw_allowlist -p icmpv6 --icmpv6-type neighbour-advertisement -j RETURN",
- "-A fw_allowlist -p icmpv6 --icmpv6-type redirect -j RETURN",
- "-A fw_allowlist -j DROP",
- "COMMIT\n"};
- std::vector<std::pair<IptablesTarget, std::string>> expectedRestoreCommands = {
- {V4, Join(expectedRestore4, '\n')},
- {V6, Join(expectedRestore6, '\n')},
- };
-
- createChain("fw_allowlist", ALLOWLIST);
- expectIptablesRestoreCommands(expectedRestoreCommands);
-}
-
-TEST_F(FirewallControllerTest, TestCreateDenylistChain) {
- std::vector<std::string> expectedRestore = {
- "*filter",
- ":fw_denylist -",
- "-A fw_denylist -i lo -j RETURN",
- "-A fw_denylist -o lo -j RETURN",
- "-A fw_denylist -p tcp --tcp-flags RST RST -j RETURN",
- "COMMIT\n"};
- std::vector<std::pair<IptablesTarget, std::string>> expectedRestoreCommands = {
- {V4, Join(expectedRestore, '\n')},
- {V6, Join(expectedRestore, '\n')},
- };
-
- createChain("fw_denylist", DENYLIST);
- expectIptablesRestoreCommands(expectedRestoreCommands);
-}
-
-TEST_F(FirewallControllerTest, TestSetStandbyRule) {
- ExpectedIptablesCommands expected = {
- { V4V6, "*filter\n-D fw_standby -m owner --uid-owner 12345 -j DROP\nCOMMIT\n" }
- };
- mFw.setUidRule(STANDBY, 12345, ALLOW);
- expectIptablesRestoreCommands(expected);
-
- expected = {
- { V4V6, "*filter\n-A fw_standby -m owner --uid-owner 12345 -j DROP\nCOMMIT\n" }
- };
- mFw.setUidRule(STANDBY, 12345, DENY);
- expectIptablesRestoreCommands(expected);
-}
-
-TEST_F(FirewallControllerTest, TestSetDozeRule) {
- ExpectedIptablesCommands expected = {
- { V4V6, "*filter\n-I fw_dozable -m owner --uid-owner 54321 -j RETURN\nCOMMIT\n" }
- };
- mFw.setUidRule(DOZABLE, 54321, ALLOW);
- expectIptablesRestoreCommands(expected);
-
- expected = {
- { V4V6, "*filter\n-D fw_dozable -m owner --uid-owner 54321 -j RETURN\nCOMMIT\n" }
- };
- mFw.setUidRule(DOZABLE, 54321, DENY);
- expectIptablesRestoreCommands(expected);
-}
-
-TEST_F(FirewallControllerTest, TestSetFirewallRule) {
- ExpectedIptablesCommands expected = {
- { V4V6, "*filter\n"
- "-A fw_INPUT -m owner --uid-owner 54321 -j DROP\n"
- "-A fw_OUTPUT -m owner --uid-owner 54321 -j DROP\n"
- "COMMIT\n" }
- };
- mFw.setUidRule(NONE, 54321, DENY);
- expectIptablesRestoreCommands(expected);
-
- expected = {
- { V4V6, "*filter\n"
- "-D fw_INPUT -m owner --uid-owner 54321 -j DROP\n"
- "-D fw_OUTPUT -m owner --uid-owner 54321 -j DROP\n"
- "COMMIT\n" }
- };
- mFw.setUidRule(NONE, 54321, ALLOW);
- expectIptablesRestoreCommands(expected);
-}
-
-TEST_F(FirewallControllerTest, TestReplaceAllowlistUidRule) {
- std::string expected =
- "*filter\n"
- ":FW_allowchain -\n"
- "-A FW_allowchain -m owner --uid-owner 10023 -j RETURN\n"
- "-A FW_allowchain -m owner --uid-owner 10059 -j RETURN\n"
- "-A FW_allowchain -m owner --uid-owner 10124 -j RETURN\n"
- "-A FW_allowchain -m owner --uid-owner 10111 -j RETURN\n"
- "-A FW_allowchain -m owner --uid-owner 110122 -j RETURN\n"
- "-A FW_allowchain -m owner --uid-owner 210153 -j RETURN\n"
- "-A FW_allowchain -m owner --uid-owner 210024 -j RETURN\n"
- "-A FW_allowchain -m owner --uid-owner 0-9999 -j RETURN\n"
- "-A FW_allowchain -m owner ! --uid-owner 0-4294967294 -j RETURN\n"
- "-A FW_allowchain -p esp -j RETURN\n"
- "-A FW_allowchain -i lo -j RETURN\n"
- "-A FW_allowchain -o lo -j RETURN\n"
- "-A FW_allowchain -p tcp --tcp-flags RST RST -j RETURN\n"
- "-A FW_allowchain -p icmpv6 --icmpv6-type packet-too-big -j RETURN\n"
- "-A FW_allowchain -p icmpv6 --icmpv6-type router-solicitation -j RETURN\n"
- "-A FW_allowchain -p icmpv6 --icmpv6-type router-advertisement -j RETURN\n"
- "-A FW_allowchain -p icmpv6 --icmpv6-type neighbour-solicitation -j RETURN\n"
- "-A FW_allowchain -p icmpv6 --icmpv6-type neighbour-advertisement -j RETURN\n"
- "-A FW_allowchain -p icmpv6 --icmpv6-type redirect -j RETURN\n"
- "-A FW_allowchain -j DROP\n"
- "COMMIT\n";
-
- std::vector<int32_t> uids = { 10023, 10059, 10124, 10111, 110122, 210153, 210024 };
- EXPECT_EQ(expected, makeUidRules(V6, "FW_allowchain", true, uids));
-}
-
-TEST_F(FirewallControllerTest, TestReplaceDenylistUidRule) {
- std::string expected =
- "*filter\n"
- ":FW_denychain -\n"
- "-A FW_denychain -i lo -j RETURN\n"
- "-A FW_denychain -o lo -j RETURN\n"
- "-A FW_denychain -p tcp --tcp-flags RST RST -j RETURN\n"
- "-A FW_denychain -m owner --uid-owner 10023 -j DROP\n"
- "-A FW_denychain -m owner --uid-owner 10059 -j DROP\n"
- "-A FW_denychain -m owner --uid-owner 10124 -j DROP\n"
- "COMMIT\n";
-
- std::vector<int32_t> uids = { 10023, 10059, 10124 };
- EXPECT_EQ(expected, makeUidRules(V4, "FW_denychain", false, uids));
-}
-
-TEST_F(FirewallControllerTest, TestEnableChildChains) {
- std::vector<std::string> expected = {
- "*filter\n"
- "-A fw_INPUT -j fw_dozable\n"
- "-A fw_OUTPUT -j fw_dozable\n"
- "COMMIT\n"
- };
- EXPECT_EQ(0, mFw.enableChildChains(DOZABLE, true));
- expectIptablesRestoreCommands(expected);
-
- expected = {
- "*filter\n"
- "-D fw_INPUT -j fw_powersave\n"
- "-D fw_OUTPUT -j fw_powersave\n"
- "COMMIT\n"
- };
- EXPECT_EQ(0, mFw.enableChildChains(POWERSAVE, false));
- expectIptablesRestoreCommands(expected);
-}
-
TEST_F(FirewallControllerTest, TestFirewall) {
std::vector<std::string> enableCommands = {
"*filter\n"
@@ -298,52 +109,5 @@
expectIptablesRestoreCommands(noCommands);
}
-TEST_F(FirewallControllerTest, TestDiscoverMaximumValidUid) {
- struct {
- const std::string description;
- const std::string content;
- const uint32_t expected;
- } testCases[] = {
- {
- .description = "root namespace case",
- .content = " 0 0 4294967295",
- .expected = 4294967294,
- },
- {
- .description = "container namespace case",
- .content = " 0 655360 5000\n"
- " 5000 600 50\n"
- " 5050 660410 1994950\n",
- .expected = 1999999,
- },
- {
- .description = "garbage content case",
- .content = "garbage",
- .expected = 4294967294,
- },
- {
- .description = "no content case",
- .content = "",
- .expected = 4294967294,
- },
- };
-
- const std::string tempFile = "/data/local/tmp/fake_uid_mapping";
-
- for (const auto& test : testCases) {
- EXPECT_TRUE(WriteStringToFile(test.content, tempFile, false));
- uint32_t got = FirewallController::discoverMaximumValidUid(tempFile);
- EXPECT_EQ(0, remove(tempFile.c_str()));
- if (got != test.expected) {
- FAIL() << test.description << ":\n"
- << test.content << "\ngot " << got << ", but expected " << test.expected;
- }
- }
-
- // Also check when the file is not defined
- EXPECT_NE(0, access(tempFile.c_str(), F_OK));
- EXPECT_EQ(4294967294, FirewallController::discoverMaximumValidUid(tempFile));
-}
-
} // namespace net
} // namespace android
diff --git a/server/FwmarkServer.cpp b/server/FwmarkServer.cpp
index 60981e5..1ae8ed3 100644
--- a/server/FwmarkServer.cpp
+++ b/server/FwmarkServer.cpp
@@ -32,9 +32,9 @@
#include "FwmarkCommand.h"
#include "NetdConstants.h"
#include "NetworkController.h"
-#include "TrafficController.h"
-using android::String16;
+#include "NetdUpdatablePublic.h"
+
using android::base::ReceiveFileDescriptorVector;
using android::base::unique_fd;
using android::net::metrics::INetdEventListener;
@@ -62,12 +62,10 @@
return ret;
}
-FwmarkServer::FwmarkServer(NetworkController* networkController, EventReporter* eventReporter,
- TrafficController* trafficCtrl)
+FwmarkServer::FwmarkServer(NetworkController* networkController, EventReporter* eventReporter)
: SocketListener(SOCKET_NAME, true),
mNetworkController(networkController),
mEventReporter(eventReporter),
- mTrafficCtrl(trafficCtrl),
mRedirectSocketCalls(
android::base::GetBoolProperty("ro.vendor.redirect_socket_calls", false)) {}
@@ -134,14 +132,6 @@
return mNetworkController->checkUserNetworkAccess(command.uid, command.netId);
}
- if (command.cmdId == FwmarkCommand::SET_COUNTERSET) {
- return mTrafficCtrl->setCounterSet(command.trafficCtrlInfo, command.uid, client->getUid());
- }
-
- if (command.cmdId == FwmarkCommand::DELETE_TAGDATA) {
- return mTrafficCtrl->deleteTagData(command.trafficCtrlInfo, command.uid, client->getUid());
- }
-
if (received_fds.size() != 1) {
LOG(ERROR) << "FwmarkServer received " << received_fds.size() << " fds from client?";
return -EBADF;
@@ -309,13 +299,13 @@
if (static_cast<int>(command.uid) == -1) {
command.uid = client->getUid();
}
- return mTrafficCtrl->tagSocket(*socketFd, command.trafficCtrlInfo, command.uid,
- client->getUid());
+ return libnetd_updatable_tagSocket(*socketFd, command.trafficCtrlInfo, command.uid,
+ client->getUid());
}
case FwmarkCommand::UNTAG_SOCKET: {
// Any process can untag a socket it has an fd for.
- return mTrafficCtrl->untagSocket(*socketFd);
+ return libnetd_updatable_untagSocket(*socketFd);
}
default: {
diff --git a/server/FwmarkServer.h b/server/FwmarkServer.h
index 32d5791..b013582 100644
--- a/server/FwmarkServer.h
+++ b/server/FwmarkServer.h
@@ -24,12 +24,10 @@
namespace net {
class NetworkController;
-class TrafficController;
class FwmarkServer : public SocketListener {
public:
- explicit FwmarkServer(NetworkController* networkController, EventReporter* eventReporter,
- TrafficController* trafficCtrl);
+ explicit FwmarkServer(NetworkController* networkController, EventReporter* eventReporter);
static constexpr const char* SOCKET_NAME = "fwmarkd";
@@ -42,7 +40,6 @@
NetworkController* const mNetworkController;
EventReporter* mEventReporter;
- TrafficController* mTrafficCtrl;
bool mRedirectSocketCalls;
};
diff --git a/server/InterfaceController.cpp b/server/InterfaceController.cpp
index 7504fb9..99d85fa 100644
--- a/server/InterfaceController.cpp
+++ b/server/InterfaceController.cpp
@@ -44,8 +44,6 @@
using android::base::StringPrintf;
using android::base::Trim;
using android::base::WriteStringToFile;
-using android::net::INetd;
-using android::net::RouteController;
using android::netdutils::isOk;
using android::netdutils::makeSlice;
using android::netdutils::sSyscalls;
@@ -416,37 +414,6 @@
setOnAllInterfaces(ipv6_proc_path, "use_optimistic", value);
}
-StatusOr<std::vector<std::string>> InterfaceController::getIfaceNames() {
- std::vector<std::string> ifaceNames;
- DIR* d;
- struct dirent* de;
-
- if (!(d = opendir("/sys/class/net"))) {
- return statusFromErrno(errno, "Cannot open iface directory");
- }
- while ((de = readdir(d))) {
- if ((de->d_type != DT_DIR) && (de->d_type != DT_LNK)) continue;
- if (de->d_name[0] == '.') continue;
- ifaceNames.push_back(std::string(de->d_name));
- }
- closedir(d);
- return ifaceNames;
-}
-
-StatusOr<std::map<std::string, uint32_t>> InterfaceController::getIfaceList() {
- std::map<std::string, uint32_t> ifacePairs;
-
- ASSIGN_OR_RETURN(auto ifaceNames, getIfaceNames());
-
- for (const auto& name : ifaceNames) {
- uint32_t ifaceIndex = if_nametoindex(name.c_str());
- if (ifaceIndex) {
- ifacePairs.insert(std::pair<std::string, uint32_t>(name, ifaceIndex));
- }
- }
- return ifacePairs;
-}
-
namespace {
std::string hwAddrToStr(unsigned char* hwaddr) {
diff --git a/server/InterfaceController.h b/server/InterfaceController.h
index e21c75d..e9dce01 100644
--- a/server/InterfaceController.h
+++ b/server/InterfaceController.h
@@ -59,9 +59,6 @@
static int setParameter(const char* family, const char* which, const char* ifName,
const char* parameter, const char* value);
- static android::netdutils::StatusOr<std::vector<std::string>> getIfaceNames();
- static android::netdutils::StatusOr<std::map<std::string, uint32_t>> getIfaceList();
-
static std::mutex mutex;
private:
diff --git a/server/InterfaceControllerTest.cpp b/server/InterfaceControllerTest.cpp
index 78d507f..006018d 100644
--- a/server/InterfaceControllerTest.cpp
+++ b/server/InterfaceControllerTest.cpp
@@ -22,6 +22,7 @@
#include <gtest/gtest.h>
#include <netdutils/MockSyscalls.h>
+#include <netdutils/Utils.h>
#include "InterfaceController.h"
@@ -36,14 +37,16 @@
namespace {
using netdutils::Fd;
+using netdutils::getIfaceList;
+using netdutils::getIfaceNames;
+using netdutils::makeSlice;
using netdutils::ScopedMockSyscalls;
using netdutils::Slice;
using netdutils::Status;
+using netdutils::statusFromErrno;
using netdutils::StatusOr;
using netdutils::UniqueFd;
-using netdutils::makeSlice;
using netdutils::status::ok;
-using netdutils::statusFromErrno;
constexpr Fd kDevRandomFd(777);
constexpr Fd kStableSecretFd(9999);
@@ -179,7 +182,7 @@
class GetIfaceListTest : public testing::Test {};
TEST_F(GetIfaceListTest, IfaceNames) {
- StatusOr<std::vector<std::string>> ifaceNames = InterfaceController::getIfaceNames();
+ StatusOr<std::vector<std::string>> ifaceNames = getIfaceNames();
EXPECT_EQ(ok, ifaceNames.status());
struct ifaddrs *ifaddr, *ifa;
EXPECT_EQ(0, getifaddrs(&ifaddr));
@@ -192,7 +195,7 @@
}
TEST_F(GetIfaceListTest, IfaceExist) {
- StatusOr<std::map<std::string, uint32_t>> ifaceMap = InterfaceController::getIfaceList();
+ StatusOr<std::map<std::string, uint32_t>> ifaceMap = getIfaceList();
EXPECT_EQ(ok, ifaceMap.status());
struct ifaddrs *ifaddr, *ifa;
EXPECT_EQ(0, getifaddrs(&ifaddr));
diff --git a/server/IptablesBaseTest.cpp b/server/IptablesBaseTest.cpp
index b3748cd..ef4d743 100644
--- a/server/IptablesBaseTest.cpp
+++ b/server/IptablesBaseTest.cpp
@@ -24,10 +24,10 @@
#include <android-base/stringprintf.h>
+#define LOG_TAG "IptablesBaseTest"
#include "IptablesBaseTest.h"
#include "NetdConstants.h"
-#define LOG_TAG "IptablesBaseTest"
#include <log/log.h>
using android::base::StringPrintf;
diff --git a/server/IptablesRestoreController.cpp b/server/IptablesRestoreController.cpp
index 10cedfa..f7ba200 100644
--- a/server/IptablesRestoreController.cpp
+++ b/server/IptablesRestoreController.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#define LOG_TAG "IptablesRestoreController"
#include "IptablesRestoreController.h"
#include <poll.h>
@@ -21,12 +22,12 @@
#include <sys/wait.h>
#include <unistd.h>
-#define LOG_TAG "IptablesRestoreController"
#include <android-base/logging.h>
#include <android-base/file.h>
#include <netdutils/Syscalls.h>
#include "Controllers.h"
+#include "NetdConstants.h"
using android::netdutils::StatusOr;
using android::netdutils::sSyscalls;
@@ -44,7 +45,9 @@
class IptablesProcess {
public:
- IptablesProcess(pid_t pid, int stdIn, int stdOut, int stdErr) :
+ IptablesProcess(const IptablesRestoreController::IptablesProcessType type,
+ pid_t pid, int stdIn, int stdOut, int stdErr) :
+ type(type),
pid(pid),
stdIn(stdIn),
processTerminated(false) {
@@ -76,34 +79,13 @@
// process was killed by something else on the system). In both cases, it's safe to send the
// PID a SIGTERM, because the PID continues to exist until its parent (i.e., us) calls
// waitpid on it, so there's no risk that the PID is reused.
- int err = kill(pid, SIGTERM);
- if (err) {
- err = errno;
- }
-
- if (err == ESRCH) {
- // This means that someone else inside netd but outside this class called waitpid(),
- // which is a programming error. There's no point in calling waitpid() here since we
- // know that the process is gone.
- ALOGE("iptables child process %d unexpectedly disappeared", pid);
- processTerminated = true;
- return;
- }
-
- if (err) {
- ALOGE("Error killing iptables child process %d: %s", pid, strerror(err));
- }
-
- int status;
- if (waitpid(pid, &status, 0) == -1) {
- ALOGE("Error waiting for iptables child process %d: %s", pid, strerror(errno));
- } else {
- ALOGW("iptables-restore process %d terminated status=%d", pid, status);
- }
+ ::stopProcess(pid, (type == IptablesRestoreController::IPTABLES_PROCESS) ?
+ "iptables-restore" : "ip6tables-restore");
processTerminated = true;
}
+ const IptablesRestoreController::IptablesProcessType type;
const pid_t pid; // NOLINT(misc-non-private-member-variables-in-classes)
const int stdIn; // NOLINT(misc-non-private-member-variables-in-classes)
@@ -197,7 +179,8 @@
ALOGW("close() failed: %s", strerror(errno));
}
- return new IptablesProcess(child_pid.value(), stdin_pipe[1], stdout_pipe[0], stderr_pipe[0]);
+ return new IptablesProcess(type,
+ child_pid.value(), stdin_pipe[1], stdout_pipe[0], stderr_pipe[0]);
}
// TODO: Return -errno on failure instead of -1.
diff --git a/server/IptablesRestoreControllerTest.cpp b/server/IptablesRestoreControllerTest.cpp
index 3881124..a05c76d 100644
--- a/server/IptablesRestoreControllerTest.cpp
+++ b/server/IptablesRestoreControllerTest.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#define LOG_TAG "IptablesRestoreControllerTest"
+#include "IptablesRestoreController.h"
+
#include <fcntl.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
@@ -25,14 +28,12 @@
#include <iostream>
#include <string>
-#define LOG_TAG "IptablesRestoreControllerTest"
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <log/log.h>
#include <netdutils/MockSyscalls.h>
#include <netdutils/Stopwatch.h>
-#include "IptablesRestoreController.h"
#include "NetdConstants.h"
#include "bpf/BpfUtils.h"
diff --git a/server/MDnsEventReporter.cpp b/server/MDnsEventReporter.cpp
new file mode 100644
index 0000000..db9021a
--- /dev/null
+++ b/server/MDnsEventReporter.cpp
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#define LOG_TAG "MDnsEventReporter"
+
+#include "MDnsEventReporter.h"
+
+using android::net::mdns::aidl::IMDnsEventListener;
+
+MDnsEventReporter& MDnsEventReporter::getInstance() {
+ // It should be initialized only once.
+ static MDnsEventReporter instance;
+ return instance;
+}
+
+const MDnsEventReporter::EventListenerSet& MDnsEventReporter::getEventListeners() const {
+ return getEventListenersImpl();
+}
+
+int MDnsEventReporter::addEventListener(const android::sp<IMDnsEventListener>& listener) {
+ return addEventListenerImpl(listener);
+}
+
+int MDnsEventReporter::removeEventListener(const android::sp<IMDnsEventListener>& listener) {
+ return removeEventListenerImpl(listener);
+}
+
+const MDnsEventReporter::EventListenerSet& MDnsEventReporter::getEventListenersImpl() const {
+ std::lock_guard lock(mMutex);
+ return mEventListeners;
+}
+
+int MDnsEventReporter::addEventListenerImpl(const android::sp<IMDnsEventListener>& listener) {
+ if (listener == nullptr) {
+ ALOGE("The event listener should not be null");
+ return -EINVAL;
+ }
+
+ std::lock_guard lock(mMutex);
+
+ for (const auto& it : mEventListeners) {
+ if (android::IInterface::asBinder(it).get() ==
+ android::IInterface::asBinder(listener).get()) {
+ ALOGW("The event listener was already subscribed");
+ return -EEXIST;
+ }
+ }
+
+ // Create the death listener.
+ class DeathRecipient : public android::IBinder::DeathRecipient {
+ public:
+ DeathRecipient(MDnsEventReporter* eventReporter,
+ const android::sp<IMDnsEventListener>& listener)
+ : mEventReporter(eventReporter), mListener(listener) {}
+ ~DeathRecipient() override = default;
+ void binderDied(const android::wp<android::IBinder>& /* who */) override {
+ mEventReporter->removeEventListenerImpl(mListener);
+ }
+
+ private:
+ MDnsEventReporter* mEventReporter;
+ android::sp<IMDnsEventListener> mListener;
+ };
+
+ android::sp<android::IBinder::DeathRecipient> deathRecipient =
+ new DeathRecipient(this, listener);
+
+ android::IInterface::asBinder(listener)->linkToDeath(deathRecipient);
+
+ mEventListeners.insert(listener);
+ return 0;
+}
+
+int MDnsEventReporter::removeEventListenerImpl(const android::sp<IMDnsEventListener>& listener) {
+ if (listener == nullptr) {
+ ALOGE("The event listener should not be null");
+ return -EINVAL;
+ }
+
+ std::lock_guard lock(mMutex);
+
+ mEventListeners.erase(listener);
+ return 0;
+}
diff --git a/server/MDnsEventReporter.h b/server/MDnsEventReporter.h
new file mode 100644
index 0000000..e49c3e3
--- /dev/null
+++ b/server/MDnsEventReporter.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 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
+
+#include <android-base/thread_annotations.h>
+#include <android/net/mdns/aidl/IMDnsEventListener.h>
+
+#include <set>
+
+class MDnsEventReporter final {
+ public:
+ MDnsEventReporter(const MDnsEventReporter&) = delete;
+ MDnsEventReporter& operator=(const MDnsEventReporter&) = delete;
+
+ using EventListenerSet = std::set<android::sp<android::net::mdns::aidl::IMDnsEventListener>>;
+
+ // Get the instance of the singleton MDnsEventReporter.
+ static MDnsEventReporter& getInstance();
+
+ // Return registered binder services from the singleton MDnsEventReporter. This method is
+ // threadsafe.
+ const EventListenerSet& getEventListeners() const;
+
+ // Add the binder to the singleton MDnsEventReporter. This method is threadsafe.
+ int addEventListener(const android::sp<android::net::mdns::aidl::IMDnsEventListener>& listener);
+
+ // Remove the binder from the singleton MDnsEventReporter. This method is threadsafe.
+ int removeEventListener(
+ const android::sp<android::net::mdns::aidl::IMDnsEventListener>& listener);
+
+ private:
+ MDnsEventReporter() = default;
+ ~MDnsEventReporter() = default;
+
+ mutable std::mutex mMutex;
+ EventListenerSet mEventListeners GUARDED_BY(mMutex);
+
+ int addEventListenerImpl(
+ const android::sp<android::net::mdns::aidl::IMDnsEventListener>& listener)
+ EXCLUDES(mMutex);
+ int removeEventListenerImpl(
+ const android::sp<android::net::mdns::aidl::IMDnsEventListener>& listener)
+ EXCLUDES(mMutex);
+ const EventListenerSet& getEventListenersImpl() const EXCLUDES(mMutex);
+ void handleEventBinderDied(const void* who) EXCLUDES(mMutex);
+};
diff --git a/server/MDnsSdListener.cpp b/server/MDnsSdListener.cpp
index 42dcddf..1636400 100644
--- a/server/MDnsSdListener.cpp
+++ b/server/MDnsSdListener.cpp
@@ -19,6 +19,7 @@
#include <arpa/inet.h>
#include <dirent.h>
#include <errno.h>
+#include <inttypes.h>
#include <linux/if.h>
#include <netdb.h>
#include <netinet/in.h>
@@ -36,10 +37,15 @@
#include <cutils/properties.h>
#include <log/log.h>
-#include <netdutils/ResponseCode.h>
#include <netdutils/ThreadUtil.h>
#include <sysutils/SocketClient.h>
+#include "Controllers.h"
+#include "MDnsEventReporter.h"
+#include "netid_client.h"
+
+using android::net::gCtls;
+
#define MDNS_SERVICE_NAME "mdnsd"
#define MDNS_SERVICE_STATUS "init.svc.mdnsd"
@@ -47,474 +53,312 @@
constexpr char RESCAN[] = "1";
-using android::netdutils::ResponseCode;
+using android::net::mdns::aidl::DiscoveryInfo;
+using android::net::mdns::aidl::GetAddressInfo;
+using android::net::mdns::aidl::IMDnsEventListener;
+using android::net::mdns::aidl::RegistrationInfo;
+using android::net::mdns::aidl::ResolutionInfo;
-MDnsSdListener::MDnsSdListener() : FrameworkListener(SOCKET_NAME, true) {
- Monitor *m = new Monitor();
- registerCmd(new Handler(m, this));
-}
-
-MDnsSdListener::Handler::Handler(Monitor *m, MDnsSdListener *listener) :
- NetdCommand("mdnssd") {
- if (DBG) ALOGD("MDnsSdListener::Hander starting up");
- mMonitor = m;
- mListener = listener;
-}
-
-MDnsSdListener::Handler::~Handler() {}
-
-void MDnsSdListener::Handler::discover(SocketClient *cli,
- const char *iface,
- const char *regType,
- const char *domain,
- const int requestId,
- const int requestFlags) {
- if (VDBG) {
- ALOGD("discover(%s, %s, %s, %d, %d)", iface, regType, domain, requestId,
- requestFlags);
+static unsigned ifaceIndexToNetId(uint32_t interfaceIndex) {
+ char interfaceName[IFNAMSIZ] = {};
+ unsigned netId;
+ if (if_indextoname(interfaceIndex, interfaceName) == nullptr) {
+ ALOGE("Interface %d was not found", interfaceIndex);
+ return NETID_UNSET;
+ } else if ((netId = gCtls->netCtrl.getNetworkForInterface(interfaceName)) == NETID_UNSET) {
+ ALOGE("Network was not found for interface %s", interfaceName);
+ return NETID_UNSET;
}
- Context *context = new Context(requestId, mListener);
- DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
+ return netId;
+}
+
+int MDnsSdListener::discover(uint32_t ifIndex, const char* regType, const char* domain,
+ const int requestId, const int requestFlags) {
+ if (VDBG) {
+ ALOGD("discover(%d, %s, %s, %d, %d)", ifIndex, regType, domain ? domain : "null", requestId,
+ requestFlags);
+ }
+ Context* context = new Context(requestId);
+ DNSServiceRef* ref = mMonitor.allocateServiceRef(requestId, context);
if (ref == nullptr) {
ALOGE("requestId %d already in use during discover call", requestId);
- cli->sendMsg(ResponseCode::CommandParameterError,
- "RequestId already in use during discover call", false);
- return;
+ return -EBUSY;
}
if (VDBG) ALOGD("using ref %p", ref);
- DNSServiceFlags nativeFlags = iToFlags(requestFlags);
- int interfaceInt = ifaceNameToI(iface);
- DNSServiceErrorType result = DNSServiceBrowse(ref, nativeFlags, interfaceInt, regType,
- domain, &MDnsSdListenerDiscoverCallback, context);
+ DNSServiceErrorType result = DNSServiceBrowse(ref, requestFlags, ifIndex, regType, domain,
+ &MDnsSdListenerDiscoverCallback, context);
if (result != kDNSServiceErr_NoError) {
ALOGE("Discover request %d got an error from DNSServiceBrowse %d", requestId, result);
- mMonitor->freeServiceRef(requestId);
- cli->sendMsg(ResponseCode::CommandParameterError,
- "Discover request got an error from DNSServiceBrowse", false);
- return;
+ mMonitor.freeServiceRef(requestId);
+ // Return kDNSServiceErr_* directly instead of transferring to an UNIX error.
+ // This can help caller to know what going wrong from mdnsresponder side.
+ return -result;
}
- mMonitor->startMonitoring(requestId);
+ mMonitor.startMonitoring(requestId);
if (VDBG) ALOGD("discover successful");
- cli->sendMsg(ResponseCode::CommandOkay, "Discover operation started", false);
- return;
+ return 0;
}
void MDnsSdListenerDiscoverCallback(DNSServiceRef /* sdRef */, DNSServiceFlags flags,
- uint32_t /* interfaceIndex */, DNSServiceErrorType errorCode, const char *serviceName,
- const char *regType, const char *replyDomain, void *inContext) {
+ uint32_t ifIndex, DNSServiceErrorType errorCode,
+ const char* serviceName, const char* regType,
+ const char* replyDomain, void* inContext) {
MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
- char *msg;
int refNumber = context->mRefNumber;
+ const auto& listeners = MDnsEventReporter::getInstance().getEventListeners();
+ if (listeners.empty()) {
+ ALOGI("Discover callback not sent since no IMDnsEventListener receiver is available.");
+ return;
+ }
- if (errorCode != kDNSServiceErr_NoError) {
- asprintf(&msg, "%d %d", refNumber, errorCode);
- context->mListener->sendBroadcast(ResponseCode::ServiceDiscoveryFailed, msg, false);
- if (DBG) ALOGE("discover failure for %d, error= %d", refNumber, errorCode);
- } else {
- int respCode;
- char *quotedServiceName = SocketClient::quoteArg(serviceName);
+ DiscoveryInfo info;
+ info.id = refNumber;
+ info.serviceName = serviceName;
+ info.registrationType = regType;
+ info.interfaceIdx = ifIndex;
+ // If the network is not found, still send the event and let
+ // the service decide what to do with a callback with an empty network
+ info.netId = ifaceIndexToNetId(ifIndex);
+ if (errorCode == kDNSServiceErr_NoError) {
if (flags & kDNSServiceFlagsAdd) {
if (VDBG) {
ALOGD("Discover found new serviceName %s, regType %s and domain %s for %d",
- serviceName, regType, replyDomain, refNumber);
+ serviceName, regType, replyDomain, refNumber);
}
- respCode = ResponseCode::ServiceDiscoveryServiceAdded;
+ info.result = IMDnsEventListener::SERVICE_FOUND;
} else {
if (VDBG) {
- ALOGD("Discover lost serviceName %s, regType %s and domain %s for %d",
- serviceName, regType, replyDomain, refNumber);
+ ALOGD("Discover lost serviceName %s, regType %s and domain %s for %d", serviceName,
+ regType, replyDomain, refNumber);
}
- respCode = ResponseCode::ServiceDiscoveryServiceRemoved;
+ info.result = IMDnsEventListener::SERVICE_LOST;
}
- asprintf(&msg, "%d %s %s %s", refNumber, quotedServiceName, regType, replyDomain);
- free(quotedServiceName);
- context->mListener->sendBroadcast(respCode, msg, false);
+ } else {
+ if (DBG) ALOGE("discover failure for %d, error= %d", refNumber, errorCode);
+ info.result = IMDnsEventListener::SERVICE_DISCOVERY_FAILED;
}
- free(msg);
+
+ for (const auto& it : listeners) {
+ it->onServiceDiscoveryStatus(info);
+ }
}
-void MDnsSdListener::Handler::stop(SocketClient *cli, int argc, char **argv, const char *str) {
- if (argc != 3) {
- char *msg;
- asprintf(&msg, "Invalid number of arguments to %s", str);
- cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
- free(msg);
- return;
- }
- int requestId = strtol(argv[2], nullptr, 10);
- DNSServiceRef *ref = mMonitor->lookupServiceRef(requestId);
+int MDnsSdListener::stop(int requestId) {
+ DNSServiceRef* ref = mMonitor.lookupServiceRef(requestId);
if (ref == nullptr) {
- if (DBG) ALOGE("%s stop used unknown requestId %d", str, requestId);
- cli->sendMsg(ResponseCode::CommandParameterError, "Unknown requestId", false);
- return;
+ if (DBG) ALOGE("Stop used unknown requestId %d", requestId);
+ return -ESRCH;
}
- if (VDBG) ALOGD("Stopping %s with ref %p", str, ref);
- mMonitor->deallocateServiceRef(ref);
- mMonitor->freeServiceRef(requestId);
- char *msg;
- asprintf(&msg, "%s stopped", str);
- cli->sendMsg(ResponseCode::CommandOkay, msg, false);
- free(msg);
+ if (VDBG) ALOGD("Stopping operation with ref %p", ref);
+ mMonitor.deallocateServiceRef(ref);
+ mMonitor.freeServiceRef(requestId);
+ return 0;
}
-void MDnsSdListener::Handler::serviceRegister(SocketClient *cli, int requestId,
- const char *interfaceName, const char *serviceName, const char *serviceType,
- const char *domain, const char *host, int port, int txtLen, void *txtRecord) {
+int MDnsSdListener::serviceRegister(int requestId, const char* serviceName, const char* serviceType,
+ const char* domain, const char* host, int port,
+ const std::vector<unsigned char>& txtRecord, uint32_t ifIndex) {
if (VDBG) {
- ALOGD("serviceRegister(%d, %s, %s, %s, %s, %s, %d, %d, <binary>)", requestId,
- interfaceName, serviceName, serviceType, domain, host, port, txtLen);
+ ALOGD("serviceRegister(%d, %d, %s, %s, %s, %s, %d, <binary>)", requestId, ifIndex,
+ serviceName, serviceType, domain ? domain : "null", host ? host : "null", port);
}
- Context *context = new Context(requestId, mListener);
- DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
- port = htons(port);
+ Context* context = new Context(requestId);
+ DNSServiceRef* ref = mMonitor.allocateServiceRef(requestId, context);
if (ref == nullptr) {
ALOGE("requestId %d already in use during register call", requestId);
- cli->sendMsg(ResponseCode::CommandParameterError,
- "RequestId already in use during register call", false);
- return;
+ return -EBUSY;
}
+ port = htons(port);
DNSServiceFlags nativeFlags = 0;
- int interfaceInt = ifaceNameToI(interfaceName);
- DNSServiceErrorType result = DNSServiceRegister(ref, interfaceInt, nativeFlags, serviceName,
- serviceType, domain, host, port, txtLen, txtRecord, &MDnsSdListenerRegisterCallback,
- context);
+ DNSServiceErrorType result = DNSServiceRegister(
+ ref, nativeFlags, ifIndex, serviceName, serviceType, domain, host, port,
+ txtRecord.size(), &txtRecord.front(), &MDnsSdListenerRegisterCallback, context);
if (result != kDNSServiceErr_NoError) {
ALOGE("service register request %d got an error from DNSServiceRegister %d", requestId,
result);
- mMonitor->freeServiceRef(requestId);
- cli->sendMsg(ResponseCode::CommandParameterError,
- "serviceRegister request got an error from DNSServiceRegister", false);
- return;
+ mMonitor.freeServiceRef(requestId);
+ // Return kDNSServiceErr_* directly instead of transferring to an UNIX error.
+ // This can help caller to know what going wrong from mdnsresponder side.
+ return -result;
}
- mMonitor->startMonitoring(requestId);
+ mMonitor.startMonitoring(requestId);
if (VDBG) ALOGD("serviceRegister successful");
- cli->sendMsg(ResponseCode::CommandOkay, "serviceRegister started", false);
- return;
+ return 0;
}
void MDnsSdListenerRegisterCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
- DNSServiceErrorType errorCode, const char *serviceName, const char * /* regType */,
- const char * /* domain */, void *inContext) {
- MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
- char *msg;
+ DNSServiceErrorType errorCode, const char* serviceName,
+ const char* regType, const char* /* domain */,
+ void* inContext) {
+ MDnsSdListener::Context* context = reinterpret_cast<MDnsSdListener::Context*>(inContext);
int refNumber = context->mRefNumber;
- if (errorCode != kDNSServiceErr_NoError) {
- asprintf(&msg, "%d %d", refNumber, errorCode);
- context->mListener->sendBroadcast(ResponseCode::ServiceRegistrationFailed, msg, false);
- if (DBG) ALOGE("register failure for %d, error= %d", refNumber, errorCode);
- } else {
- char *quotedServiceName = SocketClient::quoteArg(serviceName);
- asprintf(&msg, "%d %s", refNumber, quotedServiceName);
- free(quotedServiceName);
- context->mListener->sendBroadcast(ResponseCode::ServiceRegistrationSucceeded, msg, false);
- if (VDBG) ALOGD("register succeeded for %d as %s", refNumber, serviceName);
+ const auto& listeners = MDnsEventReporter::getInstance().getEventListeners();
+ if (listeners.empty()) {
+ ALOGI("Register callback not sent since no IMDnsEventListener receiver is available.");
+ return;
}
- free(msg);
+
+ RegistrationInfo info;
+ info.id = refNumber;
+ info.serviceName = serviceName;
+ info.registrationType = regType;
+ if (errorCode == kDNSServiceErr_NoError) {
+ if (VDBG) ALOGD("register succeeded for %d as %s", refNumber, serviceName);
+ info.result = IMDnsEventListener::SERVICE_REGISTERED;
+ } else {
+ if (DBG) ALOGE("register failure for %d, error= %d", refNumber, errorCode);
+ info.result = IMDnsEventListener::SERVICE_REGISTRATION_FAILED;
+ }
+
+ for (const auto& it : listeners) {
+ it->onServiceRegistrationStatus(info);
+ }
}
-
-void MDnsSdListener::Handler::resolveService(SocketClient *cli, int requestId,
- const char *interfaceName, const char *serviceName, const char *regType,
- const char *domain) {
+int MDnsSdListener::resolveService(int requestId, uint32_t ifIndex, const char* serviceName,
+ const char* regType, const char* domain) {
if (VDBG) {
- ALOGD("resolveService(%d, %s, %s, %s, %s)", requestId, interfaceName,
- serviceName, regType, domain);
+ ALOGD("resolveService(%d, %d, %s, %s, %s)", requestId, ifIndex, serviceName, regType,
+ domain);
}
- Context *context = new Context(requestId, mListener);
- DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
+ Context* context = new Context(requestId);
+ DNSServiceRef* ref = mMonitor.allocateServiceRef(requestId, context);
if (ref == nullptr) {
ALOGE("request Id %d already in use during resolve call", requestId);
- cli->sendMsg(ResponseCode::CommandParameterError,
- "RequestId already in use during resolve call", false);
- return;
+ return -EBUSY;
}
DNSServiceFlags nativeFlags = 0;
- int interfaceInt = ifaceNameToI(interfaceName);
- DNSServiceErrorType result = DNSServiceResolve(ref, nativeFlags, interfaceInt, serviceName,
- regType, domain, &MDnsSdListenerResolveCallback, context);
+ DNSServiceErrorType result = DNSServiceResolve(ref, nativeFlags, ifIndex, serviceName, regType,
+ domain, &MDnsSdListenerResolveCallback, context);
if (result != kDNSServiceErr_NoError) {
- ALOGE("service resolve request %d got an error from DNSServiceResolve %d", requestId,
- result);
- mMonitor->freeServiceRef(requestId);
- cli->sendMsg(ResponseCode::CommandParameterError,
- "resolveService got an error from DNSServiceResolve", false);
- return;
+ ALOGE("service resolve request %d on iface %d: got an error from DNSServiceResolve %d",
+ requestId, ifIndex, result);
+ mMonitor.freeServiceRef(requestId);
+ // Return kDNSServiceErr_* directly instead of transferring to an UNIX error.
+ // This can help caller to know what going wrong from mdnsresponder side.
+ return -result;
}
- mMonitor->startMonitoring(requestId);
+ mMonitor.startMonitoring(requestId);
if (VDBG) ALOGD("resolveService successful");
- cli->sendMsg(ResponseCode::CommandOkay, "resolveService started", false);
- return;
+ return 0;
}
void MDnsSdListenerResolveCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
- uint32_t /* interface */, DNSServiceErrorType errorCode, const char *fullname,
- const char *hosttarget, uint16_t port, uint16_t txtLen,
- const unsigned char *txtRecord , void *inContext) {
- MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
- char *msg;
+ uint32_t ifIndex, DNSServiceErrorType errorCode,
+ const char* fullname, const char* hosttarget, uint16_t port,
+ uint16_t txtLen, const unsigned char* txtRecord,
+ void* inContext) {
+ MDnsSdListener::Context* context = reinterpret_cast<MDnsSdListener::Context*>(inContext);
int refNumber = context->mRefNumber;
- port = ntohs(port);
- if (errorCode != kDNSServiceErr_NoError) {
- asprintf(&msg, "%d %d", refNumber, errorCode);
- context->mListener->sendBroadcast(ResponseCode::ServiceResolveFailed, msg, false);
- if (DBG) ALOGE("resolve failure for %d, error= %d", refNumber, errorCode);
- } else {
- char *quotedFullName = SocketClient::quoteArg(fullname);
- char *quotedHostTarget = SocketClient::quoteArg(hosttarget);
-
- // Base 64 encodes every 3 bytes into 4 characters, but then adds padding to the next
- // multiple of 4 and a \0
- size_t dstLength = CEIL(CEIL(txtLen * 4, 3), 4) * 4 + 1;
-
- char *dst = (char *)malloc(dstLength);
- b64_ntop(txtRecord, txtLen, dst, dstLength);
-
- asprintf(&msg, "%d %s %s %d %d \"%s\"", refNumber, quotedFullName, quotedHostTarget, port,
- txtLen, dst);
- free(quotedFullName);
- free(quotedHostTarget);
- free(dst);
- context->mListener->sendBroadcast(ResponseCode::ServiceResolveSuccess, msg, false);
- if (VDBG) {
- ALOGD("resolve succeeded for %d finding %s at %s:%d with txtLen %d",
- refNumber, fullname, hosttarget, port, txtLen);
- }
- }
- free(msg);
-}
-
-void MDnsSdListener::Handler::getAddrInfo(SocketClient *cli, int requestId,
- const char *interfaceName, uint32_t protocol, const char *hostname) {
- if (VDBG) ALOGD("getAddrInfo(%d, %s %d, %s)", requestId, interfaceName, protocol, hostname);
- Context *context = new Context(requestId, mListener);
- DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
- if (ref == nullptr) {
- ALOGE("request ID %d already in use during getAddrInfo call", requestId);
- cli->sendMsg(ResponseCode::CommandParameterError,
- "RequestId already in use during getAddrInfo call", false);
+ const auto& listeners = MDnsEventReporter::getInstance().getEventListeners();
+ if (listeners.empty()) {
+ ALOGI("Resolve callback not sent since no IMDnsEventListener receiver is available.");
return;
}
+ port = ntohs(port);
+
+ ResolutionInfo info;
+ info.id = refNumber;
+ info.port = port;
+ info.serviceFullName = fullname;
+ info.hostname = hosttarget;
+ info.txtRecord = std::vector<unsigned char>(txtRecord, txtRecord + txtLen);
+ info.interfaceIdx = ifIndex;
+ if (errorCode == kDNSServiceErr_NoError) {
+ if (VDBG) {
+ ALOGD("resolve succeeded for %d finding %s at %s:%d with txtLen %d", refNumber,
+ fullname, hosttarget, port, txtLen);
+ }
+ info.result = IMDnsEventListener::SERVICE_RESOLVED;
+ } else {
+ if (DBG) ALOGE("resolve failure for %d, error= %d", refNumber, errorCode);
+ info.result = IMDnsEventListener::SERVICE_RESOLUTION_FAILED;
+ }
+
+ for (const auto& it : listeners) {
+ it->onServiceResolutionStatus(info);
+ }
+}
+
+int MDnsSdListener::getAddrInfo(int requestId, uint32_t ifIndex, uint32_t protocol,
+ const char* hostname) {
+ if (VDBG) ALOGD("getAddrInfo(%d, %u %d, %s)", requestId, ifIndex, protocol, hostname);
+ Context* context = new Context(requestId);
+ DNSServiceRef* ref = mMonitor.allocateServiceRef(requestId, context);
+ if (ref == nullptr) {
+ ALOGE("request ID %d already in use during getAddrInfo call", requestId);
+ return -EBUSY;
+ }
DNSServiceFlags nativeFlags = 0;
- int interfaceInt = ifaceNameToI(interfaceName);
- DNSServiceErrorType result = DNSServiceGetAddrInfo(ref, nativeFlags, interfaceInt, protocol,
- hostname, &MDnsSdListenerGetAddrInfoCallback, context);
+ DNSServiceErrorType result =
+ DNSServiceGetAddrInfo(ref, nativeFlags, ifIndex, protocol, hostname,
+ &MDnsSdListenerGetAddrInfoCallback, context);
if (result != kDNSServiceErr_NoError) {
ALOGE("getAddrInfo request %d got an error from DNSServiceGetAddrInfo %d", requestId,
result);
- mMonitor->freeServiceRef(requestId);
- cli->sendMsg(ResponseCode::CommandParameterError,
- "getAddrInfo request got an error from DNSServiceGetAddrInfo", false);
- return;
+ mMonitor.freeServiceRef(requestId);
+ // Return kDNSServiceErr_* directly instead of transferring to an UNIX error.
+ // This can help caller to know what going wrong from mdnsresponder side.
+ return -result;
}
- mMonitor->startMonitoring(requestId);
+ mMonitor.startMonitoring(requestId);
if (VDBG) ALOGD("getAddrInfo successful");
- cli->sendMsg(ResponseCode::CommandOkay, "getAddrInfo started", false);
- return;
+ return 0;
}
void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
- uint32_t /* interface */, DNSServiceErrorType errorCode, const char *hostname,
- const struct sockaddr *const sa, uint32_t ttl, void *inContext) {
+ uint32_t ifIndex, DNSServiceErrorType errorCode,
+ const char* hostname, const struct sockaddr* const sa,
+ uint32_t /* ttl */, void* inContext) {
MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
int refNumber = context->mRefNumber;
+ const auto& listeners = MDnsEventReporter::getInstance().getEventListeners();
+ if (listeners.empty()) {
+ ALOGI("Get address callback not sent since no IMDnsEventListener receiver is available.");
+ return;
+ }
- if (errorCode != kDNSServiceErr_NoError) {
- char *msg;
- asprintf(&msg, "%d %d", refNumber, errorCode);
- context->mListener->sendBroadcast(ResponseCode::ServiceGetAddrInfoFailed, msg, false);
- if (DBG) ALOGE("getAddrInfo failure for %d, error= %d", refNumber, errorCode);
- free(msg);
- } else {
+ GetAddressInfo info;
+ info.id = refNumber;
+ info.hostname = hostname;
+ info.interfaceIdx = ifIndex;
+ // If the network is not found, still send the event with an empty network
+ // and let the service decide what to do with it
+ info.netId = ifaceIndexToNetId(ifIndex);
+ if (errorCode == kDNSServiceErr_NoError) {
char addr[INET6_ADDRSTRLEN];
- char *msg;
- char *quotedHostname = SocketClient::quoteArg(hostname);
if (sa->sa_family == AF_INET) {
inet_ntop(sa->sa_family, &(((struct sockaddr_in *)sa)->sin_addr), addr, sizeof(addr));
} else {
inet_ntop(sa->sa_family, &(((struct sockaddr_in6 *)sa)->sin6_addr), addr, sizeof(addr));
}
- asprintf(&msg, "%d %s %d %s", refNumber, quotedHostname, ttl, addr);
- free(quotedHostname);
- context->mListener->sendBroadcast(ResponseCode::ServiceGetAddrInfoSuccess, msg, false);
+ info.address = addr;
if (VDBG) {
- ALOGD("getAddrInfo succeeded for %d: %s", refNumber, msg);
+ ALOGD("getAddrInfo succeeded for %d:", refNumber);
}
- free(msg);
- }
-}
-
-void MDnsSdListener::Handler::setHostname(SocketClient *cli, int requestId,
- const char *hostname) {
- if (VDBG) ALOGD("setHostname(%d, %s)", requestId, hostname);
- Context *context = new Context(requestId, mListener);
- DNSServiceRef *ref = mMonitor->allocateServiceRef(requestId, context);
- if (ref == nullptr) {
- ALOGE("request Id %d already in use during setHostname call", requestId);
- cli->sendMsg(ResponseCode::CommandParameterError,
- "RequestId already in use during setHostname call", false);
- return;
- }
- DNSServiceFlags nativeFlags = 0;
- DNSServiceErrorType result = DNSSetHostname(ref, nativeFlags, hostname,
- &MDnsSdListenerSetHostnameCallback, context);
- if (result != kDNSServiceErr_NoError) {
- ALOGE("setHostname request %d got an error from DNSSetHostname %d", requestId, result);
- mMonitor->freeServiceRef(requestId);
- cli->sendMsg(ResponseCode::CommandParameterError,
- "setHostname got an error from DNSSetHostname", false);
- return;
- }
- mMonitor->startMonitoring(requestId);
- if (VDBG) ALOGD("setHostname successful");
- cli->sendMsg(ResponseCode::CommandOkay, "setHostname started", false);
- return;
-}
-
-void MDnsSdListenerSetHostnameCallback(DNSServiceRef /* sdRef */, DNSServiceFlags /* flags */,
- DNSServiceErrorType errorCode, const char *hostname, void *inContext) {
- MDnsSdListener::Context *context = reinterpret_cast<MDnsSdListener::Context *>(inContext);
- char *msg;
- int refNumber = context->mRefNumber;
- if (errorCode != kDNSServiceErr_NoError) {
- asprintf(&msg, "%d %d", refNumber, errorCode);
- context->mListener->sendBroadcast(ResponseCode::ServiceSetHostnameFailed, msg, false);
- if (DBG) ALOGE("setHostname failure for %d, error= %d", refNumber, errorCode);
+ info.result = IMDnsEventListener::SERVICE_GET_ADDR_SUCCESS;
} else {
- char *quotedHostname = SocketClient::quoteArg(hostname);
- asprintf(&msg, "%d %s", refNumber, quotedHostname);
- free(quotedHostname);
- context->mListener->sendBroadcast(ResponseCode::ServiceSetHostnameSuccess, msg, false);
- if (VDBG) ALOGD("setHostname succeeded for %d. Set to %s", refNumber, hostname);
+ if (DBG) ALOGE("getAddrInfo failure for %d, error= %d", refNumber, errorCode);
+ info.result = IMDnsEventListener::SERVICE_GET_ADDR_FAILED;
}
- free(msg);
-}
-
-
-int MDnsSdListener::Handler::ifaceNameToI(const char * /* iface */) {
- return 0;
-}
-
-const char *MDnsSdListener::Handler::iToIfaceName(int /* i */) {
- return nullptr;
-}
-
-DNSServiceFlags MDnsSdListener::Handler::iToFlags(int /* i */) {
- return 0;
-}
-
-int MDnsSdListener::Handler::flagsToI(DNSServiceFlags /* flags */) {
- return 0;
-}
-
-int MDnsSdListener::Handler::runCommand(SocketClient *cli,
- int argc, char **argv) {
- if (argc < 2) {
- char* msg = nullptr;
- asprintf( &msg, "Invalid number of arguments to mdnssd: %i", argc);
- ALOGW("%s", msg);
- cli->sendMsg(ResponseCode::CommandParameterError, msg, false);
- free(msg);
- return -1;
+ for (const auto& it : listeners) {
+ it->onGettingServiceAddressStatus(info);
}
+}
- char* cmd = argv[1];
+int MDnsSdListener::startDaemon() {
+ if (!mMonitor.startService()) {
+ ALOGE("Failed to start: Service already running");
+ return -EBUSY;
+ }
+ return 0;
+}
- if (strcmp(cmd, "discover") == 0) {
- if (argc != 4) {
- cli->sendMsg(ResponseCode::CommandParameterError,
- "Invalid number of arguments to mdnssd discover", false);
- return 0;
- }
- int requestId = strtol(argv[2], nullptr, 10);
- char *serviceType = argv[3];
-
- discover(cli, nullptr, serviceType, nullptr, requestId, 0);
- } else if (strcmp(cmd, "stop-discover") == 0) {
- stop(cli, argc, argv, "discover");
- } else if (strcmp(cmd, "register") == 0) {
- if (argc != 7) {
- cli->sendMsg(ResponseCode::CommandParameterError,
- "Invalid number of arguments to mdnssd register", false);
- return 0;
- }
- int requestId = atoi(argv[2]);
- char *serviceName = argv[3];
- char *serviceType = argv[4];
- int port = strtol(argv[5], nullptr, 10);
- char *interfaceName = nullptr; // will use all
- char *domain = nullptr; // will use default
- char *host = nullptr; // will use default hostname
-
- // TXT record length is <= 1300, see NsdServiceInfo.setAttribute
- char dst[1300];
-
- int length = b64_pton(argv[6], (u_char *)dst, 1300);
-
- if (length < 0) {
- cli->sendMsg(ResponseCode::CommandParameterError,
- "Could not decode txtRecord", false);
- return 0;
- }
-
- serviceRegister(cli, requestId, interfaceName, serviceName,
- serviceType, domain, host, port, length, dst);
- } else if (strcmp(cmd, "stop-register") == 0) {
- stop(cli, argc, argv, "register");
- } else if (strcmp(cmd, "resolve") == 0) {
- if (argc != 6) {
- cli->sendMsg(ResponseCode::CommandParameterError,
- "Invalid number of arguments to mdnssd resolve", false);
- return 0;
- }
- int requestId = atoi(argv[2]);
- char *interfaceName = nullptr; // will use all
- char *serviceName = argv[3];
- char *regType = argv[4];
- char *domain = argv[5];
- resolveService(cli, requestId, interfaceName, serviceName, regType, domain);
- } else if (strcmp(cmd, "stop-resolve") == 0) {
- stop(cli, argc, argv, "resolve");
- } else if (strcmp(cmd, "start-service") == 0) {
- if (mMonitor->startService()) {
- cli->sendMsg(ResponseCode::CommandOkay, "Service Started", false);
- } else {
- cli->sendMsg(ResponseCode::ServiceStartFailed, "Service already running", false);
- }
- } else if (strcmp(cmd, "stop-service") == 0) {
- if (mMonitor->stopService()) {
- cli->sendMsg(ResponseCode::CommandOkay, "Service Stopped", false);
- } else {
- cli->sendMsg(ResponseCode::ServiceStopFailed, "Service still in use", false);
- }
- } else if (strcmp(cmd, "sethostname") == 0) {
- if (argc != 4) {
- cli->sendMsg(ResponseCode::CommandParameterError,
- "Invalid number of arguments to mdnssd sethostname", false);
- return 0;
- }
- int requestId = strtol(argv[2], nullptr, 10);
- char *hostname = argv[3];
- setHostname(cli, requestId, hostname);
- } else if (strcmp(cmd, "stop-sethostname") == 0) {
- stop(cli, argc, argv, "sethostname");
- } else if (strcmp(cmd, "getaddrinfo") == 0) {
- if (argc != 4) {
- cli->sendMsg(ResponseCode::CommandParameterError,
- "Invalid number of arguments to mdnssd getaddrinfo", false);
- return 0;
- }
- int requestId = atoi(argv[2]);
- char *hostname = argv[3];
- char *interfaceName = nullptr; // default
- int protocol = 0; // intelligient heuristic (both v4 + v6)
- getAddrInfo(cli, requestId, interfaceName, protocol, hostname);
- } else if (strcmp(cmd, "stop-getaddrinfo") == 0) {
- stop(cli, argc, argv, "getaddrinfo");
- } else {
- if (VDBG) ALOGE("Unknown cmd %s", cmd);
- cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown mdnssd cmd", false);
- return 0;
+int MDnsSdListener::stopDaemon() {
+ if (!mMonitor.stopService()) {
+ ALOGE("Failed to stop: Service still in use");
+ return -EBUSY;
}
return 0;
}
@@ -595,6 +439,7 @@
while (1) {
if (VDBG) ALOGD("Going to poll with pollCount %d", pollCount);
int pollResults = poll(mPollFds, pollCount, 10000000);
+ if (VDBG) ALOGD("pollResults=%d", pollResults);
if (pollResults < 0) {
ALOGE("Error in poll - got %d", errno);
} else if (pollResults > 0) {
diff --git a/server/MDnsSdListener.h b/server/MDnsSdListener.h
index 83cf23e..f9c2e87 100644
--- a/server/MDnsSdListener.h
+++ b/server/MDnsSdListener.h
@@ -26,48 +26,60 @@
#include "NetdCommand.h"
// callbacks
-void MDnsSdListenerDiscoverCallback(DNSServiceRef sdRef, DNSServiceFlags flags,
- uint32_t interfaceIndex, DNSServiceErrorType errorCode,
- const char *serviceName, const char *regType, const char *replyDomain,
- void *inContext);
+void MDnsSdListenerDiscoverCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex,
+ DNSServiceErrorType errorCode, const char* serviceName,
+ const char* regType, const char* replyDomain, void* inContext);
void MDnsSdListenerRegisterCallback(DNSServiceRef sdRef, DNSServiceFlags flags,
DNSServiceErrorType errorCode, const char *serviceName, const char *regType,
const char *domain, void *inContext);
-void MDnsSdListenerResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interface,
- DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, uint16_t port,
- uint16_t txtLen, const unsigned char *txtRecord, void *inContext);
+void MDnsSdListenerResolveCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex,
+ DNSServiceErrorType errorCode, const char* fullname,
+ const char* hosttarget, uint16_t port, uint16_t txtLen,
+ const unsigned char* txtRecord, void* inContext);
void MDnsSdListenerSetHostnameCallback(DNSServiceRef, DNSServiceFlags flags,
DNSServiceErrorType errorCode, const char *hostname, void *inContext);
-void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef sdRef, DNSServiceFlags flags,
- uint32_t interface, DNSServiceErrorType errorCode, const char *hostname,
- const struct sockaddr *const sa, uint32_t ttl, void *inContext);
+void MDnsSdListenerGetAddrInfoCallback(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t ifIndex,
+ DNSServiceErrorType errorCode, const char* hostname,
+ const struct sockaddr* const sa, uint32_t ttl,
+ void* inContext);
-class MDnsSdListener : public FrameworkListener {
+class MDnsSdListener {
public:
- MDnsSdListener();
- virtual ~MDnsSdListener() {}
-
static constexpr const char* SOCKET_NAME = "mdns";
class Context {
public:
- MDnsSdListener *mListener;
int mRefNumber;
- Context(int refNumber, MDnsSdListener *m) {
- mRefNumber = refNumber;
- mListener = m;
- }
+ Context(int refNumber) { mRefNumber = refNumber; }
~Context() {
}
};
-private:
+ int stop(int requestId);
+
+ int discover(uint32_t ifIndex, const char* regType, const char* domain, const int requestId,
+ const int requestFlags);
+
+ int serviceRegister(int requestId, const char* serviceName, const char* serviceType,
+ const char* domain, const char* host, int port,
+ const std::vector<unsigned char>& txtRecord, uint32_t ifIndex);
+
+ int resolveService(int requestId, uint32_t ifIndex, const char* serviceName,
+ const char* regType, const char* domain);
+
+ int getAddrInfo(int requestId, uint32_t ifIndex, uint32_t protocol, const char* hostname);
+
+ int startDaemon();
+
+ int stopDaemon();
+
+ private:
class Monitor {
public:
Monitor();
@@ -103,40 +115,7 @@
int mCtrlSocketPair[2];
std::mutex mMutex;
};
-
- class Handler : public NetdCommand {
- public:
- Handler(Monitor *m, MDnsSdListener *listener);
- virtual ~Handler();
- int runCommand(SocketClient *c, int argc, char** argv);
-
- MDnsSdListener *mListener; // needed for broadcast purposes
- private:
- void stop(SocketClient *cli, int argc, char **argv, const char *str);
-
- void discover(SocketClient *cli, const char *iface, const char *regType,
- const char *domain, const int requestNumber,
- const int requestFlags);
-
- void serviceRegister(SocketClient *cli, int requestId, const char *interfaceName,
- const char *serviceName, const char *serviceType, const char *domain,
- const char *host, int port, int textLen, void *txtRecord);
-
- void resolveService(SocketClient *cli, int requestId,
- const char *interfaceName, const char *serviceName, const char *regType,
- const char *domain);
-
- void setHostname(SocketClient *cli, int requestId, const char *hostname);
-
- void getAddrInfo(SocketClient *cli, int requestId, const char *interfaceName,
- uint32_t protocol, const char *hostname);
-
- int ifaceNameToI(const char *iface);
- const char *iToIfaceName(int i);
- DNSServiceFlags iToFlags(int i);
- int flagsToI(DNSServiceFlags flags);
- Monitor *mMonitor;
- };
+ Monitor mMonitor;
};
#endif
diff --git a/server/MDnsService.cpp b/server/MDnsService.cpp
new file mode 100644
index 0000000..1c1dfca
--- /dev/null
+++ b/server/MDnsService.cpp
@@ -0,0 +1,120 @@
+/**
+ * Copyright (c) 2022, 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.
+ */
+
+#define LOG_TAG "MDnsService"
+
+#include "MDnsService.h"
+
+#include "binder_utils/BinderUtil.h"
+#include "binder_utils/NetdPermissions.h"
+
+#include <android-base/strings.h>
+#include <binder/Status.h>
+
+#include <string>
+#include <vector>
+
+using android::net::mdns::aidl::DiscoveryInfo;
+using android::net::mdns::aidl::GetAddressInfo;
+using android::net::mdns::aidl::IMDnsEventListener;
+using android::net::mdns::aidl::RegistrationInfo;
+using android::net::mdns::aidl::ResolutionInfo;
+
+namespace android::net {
+
+// TODO: DnsResolver has same macro definition but returns ScopedAStatus. Move these macros to
+// BinderUtil.h to do the same permission check.
+#define ENFORCE_ANY_PERMISSION(...) \
+ do { \
+ binder::Status status = checkAnyPermission({__VA_ARGS__}); \
+ if (!status.isOk()) { \
+ return status; \
+ } \
+ } while (0)
+
+#define ENFORCE_NETWORK_STACK_PERMISSIONS() \
+ ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK)
+
+status_t MDnsService::start() {
+ IPCThreadState::self()->disableBackgroundScheduling(true);
+ const status_t ret = BinderService<MDnsService>::publish();
+ if (ret != android::OK) {
+ return ret;
+ }
+ return android::OK;
+}
+
+binder::Status MDnsService::startDaemon() {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int res = mListener.startDaemon();
+ return statusFromErrcode(res);
+}
+
+binder::Status MDnsService::stopDaemon() {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int res = mListener.stopDaemon();
+ return statusFromErrcode(res);
+}
+
+binder::Status MDnsService::registerService(const RegistrationInfo& info) {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int res = mListener.serviceRegister(
+ info.id, info.serviceName.c_str(), info.registrationType.c_str(), nullptr /* domain */,
+ nullptr /* host */, info.port, info.txtRecord, info.interfaceIdx);
+ return statusFromErrcode(res);
+}
+
+binder::Status MDnsService::discover(const DiscoveryInfo& info) {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int res = mListener.discover(info.interfaceIdx, info.registrationType.c_str(),
+ nullptr /* domain */, info.id, 0 /* requestFlags */);
+ return statusFromErrcode(res);
+}
+
+binder::Status MDnsService::resolve(const ResolutionInfo& info) {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int res = mListener.resolveService(info.id, info.interfaceIdx, info.serviceName.c_str(),
+ info.registrationType.c_str(), info.domain.c_str());
+ return statusFromErrcode(res);
+}
+
+binder::Status MDnsService::getServiceAddress(const GetAddressInfo& info) {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int res = mListener.getAddrInfo(info.id, info.interfaceIdx, 0 /* protocol */,
+ info.hostname.c_str());
+ return statusFromErrcode(res);
+}
+
+binder::Status MDnsService::stopOperation(int32_t id) {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int res = mListener.stop(id);
+ return statusFromErrcode(res);
+}
+
+binder::Status MDnsService::registerEventListener(const android::sp<IMDnsEventListener>& listener) {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int res = MDnsEventReporter::getInstance().addEventListener(listener);
+ return statusFromErrcode(res);
+}
+
+binder::Status MDnsService::unregisterEventListener(
+ const android::sp<IMDnsEventListener>& listener) {
+ ENFORCE_NETWORK_STACK_PERMISSIONS();
+ int res = MDnsEventReporter::getInstance().removeEventListener(listener);
+ return statusFromErrcode(res);
+}
+
+} // namespace android::net
diff --git a/server/MDnsService.h b/server/MDnsService.h
new file mode 100644
index 0000000..fc3eca6
--- /dev/null
+++ b/server/MDnsService.h
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2022, 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
+
+#include "MDnsEventReporter.h"
+#include "MDnsSdListener.h"
+
+#include <android/net/mdns/aidl/BnMDns.h>
+#include <binder/BinderService.h>
+
+namespace android::net {
+
+class MDnsService : public BinderService<MDnsService>, public android::net::mdns::aidl::BnMDns {
+ public:
+ static status_t start();
+ static char const* getServiceName() { return "mdns"; }
+
+ binder::Status startDaemon() override;
+ binder::Status stopDaemon() override;
+ binder::Status registerService(
+ const ::android::net::mdns::aidl::RegistrationInfo& info) override;
+ binder::Status discover(const ::android::net::mdns::aidl::DiscoveryInfo& info) override;
+ binder::Status resolve(const ::android::net::mdns::aidl::ResolutionInfo& info) override;
+ binder::Status getServiceAddress(
+ const ::android::net::mdns::aidl::GetAddressInfo& info) override;
+ binder::Status stopOperation(int32_t id) override;
+ binder::Status registerEventListener(
+ const android::sp<android::net::mdns::aidl::IMDnsEventListener>& listener) override;
+ binder::Status unregisterEventListener(
+ const android::sp<android::net::mdns::aidl::IMDnsEventListener>& listener) override;
+
+ private:
+ MDnsSdListener mListener;
+};
+
+} // namespace android::net
diff --git a/server/NFLogListener.cpp b/server/NFLogListener.cpp
index 76972b6..62ac19d 100644
--- a/server/NFLogListener.cpp
+++ b/server/NFLogListener.cpp
@@ -35,6 +35,8 @@
using netdutils::extract;
using netdutils::findWithDefault;
using netdutils::makeSlice;
+using netdutils::NetlinkListener;
+using netdutils::NetlinkListenerInterface;
using netdutils::Slice;
using netdutils::sSyscalls;
using netdutils::Status;
diff --git a/server/NFLogListener.h b/server/NFLogListener.h
index 459b5cf..722fdd0 100644
--- a/server/NFLogListener.h
+++ b/server/NFLogListener.h
@@ -19,7 +19,7 @@
#include <netdutils/Netfilter.h>
-#include "NetlinkListener.h"
+#include "netdutils/NetlinkListener.h"
#include "netdutils/StatusOr.h"
namespace android {
@@ -64,7 +64,7 @@
// Do not invoke this constructor directly outside of tests. Use
// makeNFLogListener() instead.
- NFLogListener(std::shared_ptr<NetlinkListenerInterface> listener);
+ NFLogListener(std::shared_ptr<netdutils::NetlinkListenerInterface> listener);
~NFLogListener() override;
@@ -76,7 +76,7 @@
netdutils::Status unsubscribe(uint16_t nfLogGroup) override;
private:
- std::shared_ptr<NetlinkListenerInterface> mListener;
+ std::shared_ptr<netdutils::NetlinkListenerInterface> mListener;
std::mutex mMutex;
std::map<uint16_t, DispatchFn> mDispatchMap; // guarded by mMutex
};
diff --git a/server/NFLogListenerTest.cpp b/server/NFLogListenerTest.cpp
index f3bd810..88ab2c6 100644
--- a/server/NFLogListenerTest.cpp
+++ b/server/NFLogListenerTest.cpp
@@ -38,9 +38,10 @@
namespace android {
namespace net {
+using netdutils::makeSlice;
+using netdutils::NetlinkListenerInterface;
using netdutils::Slice;
using netdutils::StatusOr;
-using netdutils::makeSlice;
using netdutils::status::ok;
constexpr int kNFLogPacketMsgType = (NFNL_SUBSYS_ULOG << 8) | NFULNL_MSG_PACKET;
diff --git a/server/NdcDispatcher.cpp b/server/NdcDispatcher.cpp
index 80ad7fb..303d0dd 100644
--- a/server/NdcDispatcher.cpp
+++ b/server/NdcDispatcher.cpp
@@ -136,7 +136,6 @@
registerCmd(new BandwidthControlCmd());
registerCmd(new IdletimerControlCmd());
registerCmd(new FirewallCmd());
- registerCmd(new ClatdCmd());
registerCmd(new NetworkCommand());
registerCmd(new StrictCmd());
}
@@ -844,40 +843,6 @@
return 0;
}
-NdcDispatcher::ClatdCmd::ClatdCmd() : NdcNetdCommand("clatd") {}
-
-int NdcDispatcher::ClatdCmd::runCommand(NdcClient* cli, int argc, char** argv) const {
- int rc = 0;
- if (argc < 3) {
- cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
- return 0;
- }
-
- std::string v6Addr;
-
- if (!strcmp(argv[1], "stop")) {
- rc = !mNetd->clatdStop(argv[2]).isOk();
- } else if (!strcmp(argv[1], "start")) {
- if (argc < 4) {
- cli->sendMsg(ResponseCode::CommandSyntaxError, "Missing argument", false);
- return 0;
- }
- rc = !mNetd->clatdStart(argv[2], argv[3], &v6Addr).isOk();
- } else {
- cli->sendMsg(ResponseCode::CommandSyntaxError, "Unknown clatd cmd", false);
- return 0;
- }
-
- if (!rc) {
- cli->sendMsg(ResponseCode::CommandOkay,
- std::string(("Clatd operation succeeded ") + v6Addr).c_str(), false);
- } else {
- cli->sendMsg(ResponseCode::OperationFailed, "Clatd operation failed", false);
- }
-
- return 0;
-}
-
NdcDispatcher::StrictCmd::StrictCmd() : NdcNetdCommand("strict") {}
int NdcDispatcher::StrictCmd::sendGenericOkFail(NdcClient* cli, int cond) const {
diff --git a/server/NdcDispatcher.h b/server/NdcDispatcher.h
index 5732e22..2b01116 100644
--- a/server/NdcDispatcher.h
+++ b/server/NdcDispatcher.h
@@ -137,13 +137,6 @@
static int parseChildChain(const char* arg);
};
- class ClatdCmd : public NdcNetdCommand {
- public:
- ClatdCmd();
- virtual ~ClatdCmd() {}
- int runCommand(NdcClient* cli, int argc, char** argv) const;
- };
-
class StrictCmd : public NdcNetdCommand {
public:
StrictCmd();
diff --git a/server/NetdConstants.cpp b/server/NetdConstants.cpp
index f3898f5..6de164f 100644
--- a/server/NetdConstants.cpp
+++ b/server/NetdConstants.cpp
@@ -171,3 +171,37 @@
ALOGE("Can't set control socket %s to FD_CLOEXEC", sock);
}
}
+
+// SIGTERM with timeout first, if fail, SIGKILL
+void stopProcess(int pid, const char* processName) {
+ int err = kill(pid, SIGTERM);
+ if (err) {
+ err = errno;
+ }
+ if (err == ESRCH) {
+ // This means that someone else inside netd called this helper function,
+ // which is a programming error. There's no point in calling waitpid() here since we
+ // know that the process is gone.
+ ALOGE("%s child process %d unexpectedly disappeared", processName, pid);
+ return;
+ }
+ if (err) {
+ ALOGE("Error killing %s child process %d: %s", processName, pid, strerror(err));
+ }
+ int status = 0;
+ int ret = 0;
+ for (int count = 0; ret == 0 && count < 50; count++) {
+ usleep(100000); // sleep 0.1s to wait for process stop.
+ ret = waitpid(pid, &status, WNOHANG);
+ }
+ if (ret == 0) {
+ ALOGE("Failed to SIGTERM %s pid=%d, try SIGKILL", processName, pid);
+ kill(pid, SIGKILL);
+ ret = waitpid(pid, &status, 0);
+ }
+ if (ret == -1) {
+ ALOGE("Error waiting for %s child process %d: %s", processName, pid, strerror(errno));
+ } else {
+ ALOGD("%s process %d terminated status=%d", processName, pid, status);
+ }
+}
diff --git a/server/NetdConstants.h b/server/NetdConstants.h
index c273e1b..6951239 100644
--- a/server/NetdConstants.h
+++ b/server/NetdConstants.h
@@ -24,6 +24,8 @@
#include <mutex>
#include <string>
+#include "android/net/INetd.h"
+
#include <netdutils/UidConstants.h>
#include <private/android_filesystem_config.h>
@@ -39,6 +41,8 @@
void blockSigpipe();
void setCloseOnExec(const char *sock);
+void stopProcess(int pid, const char* processName);
+
// TODO: use std::size() instead.
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(*(a)))
@@ -74,4 +78,20 @@
*/
extern std::mutex gBigNetdLock;
+enum FirewallRule { ALLOW = INetd::FIREWALL_RULE_ALLOW, DENY = INetd::FIREWALL_RULE_DENY };
+
+// 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
+
+enum FirewallType { ALLOWLIST = INetd::FIREWALL_ALLOWLIST, DENYLIST = INetd::FIREWALL_DENYLIST };
+
+enum ChildChain {
+ NONE = INetd::FIREWALL_CHAIN_NONE,
+ DOZABLE = INetd::FIREWALL_CHAIN_DOZABLE,
+ STANDBY = INetd::FIREWALL_CHAIN_STANDBY,
+ POWERSAVE = INetd::FIREWALL_CHAIN_POWERSAVE,
+ RESTRICTED = INetd::FIREWALL_CHAIN_RESTRICTED,
+ INVALID_CHAIN
+};
+
} // namespace android::net
diff --git a/server/NetdNativeService.cpp b/server/NetdNativeService.cpp
index 1f5dc97..466d8ba 100644
--- a/server/NetdNativeService.cpp
+++ b/server/NetdNativeService.cpp
@@ -32,6 +32,7 @@
#include <cutils/properties.h>
#include <log/log.h>
#include <netdutils/DumpWriter.h>
+#include <netdutils/Utils.h>
#include <utils/Errors.h>
#include <utils/String16.h>
@@ -52,12 +53,11 @@
using android::base::StringPrintf;
using android::base::WriteStringToFile;
-using android::net::NativeNetworkType;
-using android::net::TetherOffloadRuleParcel;
using android::net::TetherStatsParcel;
using android::net::UidRangeParcel;
using android::net::netd::aidl::NativeUidRangeConfig;
using android::netdutils::DumpWriter;
+using android::netdutils::getIfaceNames;
using android::netdutils::ScopedIndent;
using android::os::ParcelFileDescriptor;
@@ -67,48 +67,6 @@
namespace {
const char OPT_SHORT[] = "--short";
-// The input permissions should be equivalent that this function would return ok if any of them is
-// granted.
-binder::Status checkAnyPermission(const std::vector<const char*>& permissions) {
- pid_t pid = IPCThreadState::self()->getCallingPid();
- uid_t uid = IPCThreadState::self()->getCallingUid();
-
- // TODO: Do the pure permission check in this function. Have another method
- // (e.g. checkNetworkStackPermission) to wrap AID_SYSTEM and
- // AID_NETWORK_STACK uid check.
- // If the caller is the system UID, don't check permissions.
- // Otherwise, if the system server's binder thread pool is full, and all the threads are
- // blocked on a thread that's waiting for us to complete, we deadlock. http://b/69389492
- //
- // From a security perspective, there is currently no difference, because:
- // 1. The system server has the NETWORK_STACK permission, which grants access to all the
- // IPCs in this file.
- // 2. AID_SYSTEM always has all permissions. See ActivityManager#checkComponentPermission.
- if (uid == AID_SYSTEM) {
- return binder::Status::ok();
- }
- // AID_NETWORK_STACK own MAINLINE_NETWORK_STACK permission, don't IPC to system server to check
- // MAINLINE_NETWORK_STACK permission. Cross-process(netd, networkstack and system server)
- // deadlock: http://b/149766727
- if (uid == AID_NETWORK_STACK) {
- for (const char* permission : permissions) {
- if (std::strcmp(permission, PERM_MAINLINE_NETWORK_STACK) == 0) {
- return binder::Status::ok();
- }
- }
- }
-
- for (const char* permission : permissions) {
- if (checkPermission(String16(permission), pid, uid)) {
- return binder::Status::ok();
- }
- }
-
- auto err = StringPrintf("UID %d / PID %d does not have any of the following permissions: %s",
- uid, pid, android::base::Join(permissions, ',').c_str());
- return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY, err.c_str());
-}
-
#define ENFORCE_ANY_PERMISSION(...) \
do { \
binder::Status status = checkAnyPermission({__VA_ARGS__}); \
@@ -153,13 +111,6 @@
result.error().message().c_str());
}
-inline binder::Status statusFromErrcode(int ret) {
- if (ret) {
- return binder::Status::fromServiceSpecificError(-ret, strerror(-ret));
- }
- return binder::Status::ok();
-}
-
bool contains(const Vector<String16>& words, const String16& word) {
for (const auto& w : words) {
if (w == word) return true;
@@ -210,27 +161,14 @@
return NO_ERROR;
}
- if (!args.isEmpty() && args[0] == TrafficController::DUMP_KEYWORD) {
- dw.blankline();
- gCtls->trafficCtrl.dump(dw, true);
- dw.blankline();
- return NO_ERROR;
- }
-
process::dump(dw);
dw.blankline();
gCtls->netCtrl.dump(dw);
dw.blankline();
- gCtls->trafficCtrl.dump(dw, false);
- dw.blankline();
-
gCtls->xfrmCtrl.dump(dw);
dw.blankline();
- gCtls->clatdCtrl.dump(dw);
- dw.blankline();
-
gCtls->tetherCtrl.dump(dw);
dw.blankline();
@@ -270,14 +208,9 @@
return binder::Status::ok();
}
-binder::Status NetdNativeService::firewallReplaceUidChain(const std::string& chainName,
- bool isAllowlist,
- const std::vector<int32_t>& uids,
- bool* ret) {
- NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
- int err = gCtls->firewallCtrl.replaceUidChain(chainName, isAllowlist, uids);
- *ret = (err == 0);
- return binder::Status::ok();
+binder::Status NetdNativeService::firewallReplaceUidChain(const std::string&, bool,
+ const std::vector<int32_t>&, bool*) {
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
binder::Status NetdNativeService::bandwidthEnableDataSaver(bool enable, bool *ret) {
@@ -319,32 +252,20 @@
return statusFromErrcode(res);
}
-binder::Status NetdNativeService::bandwidthAddNaughtyApp(int32_t uid) {
- NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
- std::vector<uint32_t> appUids = {static_cast<uint32_t>(abs(uid))};
- int res = gCtls->bandwidthCtrl.addNaughtyApps(appUids);
- return statusFromErrcode(res);
+binder::Status NetdNativeService::bandwidthAddNaughtyApp(int32_t) {
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
-binder::Status NetdNativeService::bandwidthRemoveNaughtyApp(int32_t uid) {
- NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
- std::vector<uint32_t> appUids = {static_cast<uint32_t>(abs(uid))};
- int res = gCtls->bandwidthCtrl.removeNaughtyApps(appUids);
- return statusFromErrcode(res);
+binder::Status NetdNativeService::bandwidthRemoveNaughtyApp(int32_t) {
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
-binder::Status NetdNativeService::bandwidthAddNiceApp(int32_t uid) {
- NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
- std::vector<uint32_t> appUids = {static_cast<uint32_t>(abs(uid))};
- int res = gCtls->bandwidthCtrl.addNiceApps(appUids);
- return statusFromErrcode(res);
+binder::Status NetdNativeService::bandwidthAddNiceApp(int32_t) {
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
-binder::Status NetdNativeService::bandwidthRemoveNiceApp(int32_t uid) {
- NETD_LOCKING_RPC(gCtls->bandwidthCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
- std::vector<uint32_t> appUids = {static_cast<uint32_t>(abs(uid))};
- int res = gCtls->bandwidthCtrl.removeNiceApps(appUids);
- return statusFromErrcode(res);
+binder::Status NetdNativeService::bandwidthRemoveNiceApp(int32_t) {
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
// TODO: Remove this function when there are no users. Currently, it is still used by DNS resolver
@@ -362,7 +283,8 @@
// The value of vpnType does not matter here, because it is not used in AOSP and is only
// implemented by OEMs. Also, the RPC is going to deprecate. Just pick a value defined in INetd
// as default.
- int ret = gCtls->netCtrl.createVirtualNetwork(netId, secure, NativeVpnType::LEGACY);
+ int ret = gCtls->netCtrl.createVirtualNetwork(netId, secure, NativeVpnType::LEGACY,
+ false /* excludeLocalRoutes */);
return statusFromErrcode(ret);
}
@@ -373,7 +295,8 @@
ret = gCtls->netCtrl.createPhysicalNetwork(config.netId,
convertPermission(config.permission));
} else if (config.networkType == NativeNetworkType::VIRTUAL) {
- ret = gCtls->netCtrl.createVirtualNetwork(config.netId, config.secure, config.vpnType);
+ ret = gCtls->netCtrl.createVirtualNetwork(config.netId, config.secure, config.vpnType,
+ config.excludeLocalRoutes);
}
return statusFromErrcode(ret);
}
@@ -402,7 +325,7 @@
// NetworkController::addUsersToNetwork is thread-safe.
ENFORCE_NETWORK_STACK_PERMISSIONS();
int ret = gCtls->netCtrl.addUsersToNetwork(netId, UidRanges(uidRangeArray),
- UidRanges::DEFAULT_SUB_PRIORITY);
+ UidRanges::SUB_PRIORITY_HIGHEST);
return statusFromErrcode(ret);
}
@@ -411,7 +334,7 @@
// NetworkController::removeUsersFromNetwork is thread-safe.
ENFORCE_NETWORK_STACK_PERMISSIONS();
int ret = gCtls->netCtrl.removeUsersFromNetwork(netId, UidRanges(uidRangeArray),
- UidRanges::DEFAULT_SUB_PRIORITY);
+ UidRanges::SUB_PRIORITY_HIGHEST);
return statusFromErrcode(ret);
}
@@ -786,8 +709,7 @@
}
binder::Status NetdNativeService::trafficSwapActiveStatsMap() {
- ENFORCE_NETWORK_STACK_PERMISSIONS();
- return asBinderStatus(gCtls->trafficCtrl.swapActiveStatsMap());
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
binder::Status NetdNativeService::idletimerAddInterface(const std::string& ifName, int32_t timeout,
@@ -828,17 +750,20 @@
return statusFromErrcode(res);
}
-binder::Status NetdNativeService::clatdStart(const std::string& ifName,
- const std::string& nat64Prefix, std::string* v6Addr) {
+// TODO: remark @deprecated in INetd.aidl.
+binder::Status NetdNativeService::clatdStart(const std::string& /* ifName */,
+ const std::string& /* nat64Prefix */,
+ std::string* /* v6Addr */) {
ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
- int res = gCtls->clatdCtrl.startClatd(ifName.c_str(), nat64Prefix, v6Addr);
- return statusFromErrcode(res);
+ // deprecated
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
-binder::Status NetdNativeService::clatdStop(const std::string& ifName) {
+// TODO: remark @deprecated in INetd.aidl.
+binder::Status NetdNativeService::clatdStop(const std::string& /* ifName */) {
ENFORCE_ANY_PERMISSION(PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
- int res = gCtls->clatdCtrl.stopClatd(ifName.c_str());
- return statusFromErrcode(res);
+ // deprecated
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
binder::Status NetdNativeService::ipfwdEnabled(bool* status) {
@@ -891,7 +816,7 @@
binder::Status NetdNativeService::interfaceGetList(std::vector<std::string>* interfaceListResult) {
NETD_LOCKING_RPC(InterfaceController::mutex, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
- const auto& ifaceList = InterfaceController::getIfaceNames();
+ const auto& ifaceList = getIfaceNames();
interfaceListResult->clear();
interfaceListResult->reserve(ifaceList.value().size());
@@ -1180,11 +1105,8 @@
return binder::Status::ok();
}
-binder::Status NetdNativeService::trafficSetNetPermForUids(int32_t permission,
- const std::vector<int32_t>& uids) {
- ENFORCE_NETWORK_STACK_PERMISSIONS();
- gCtls->trafficCtrl.setPermissionForUids(permission, intsToUids(uids));
- return binder::Status::ok();
+binder::Status NetdNativeService::trafficSetNetPermForUids(int32_t, const std::vector<int32_t>&) {
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
binder::Status NetdNativeService::firewallSetFirewallType(int32_t firewallType) {
@@ -1204,37 +1126,21 @@
return statusFromErrcode(res);
}
-binder::Status NetdNativeService::firewallSetUidRule(int32_t childChain, int32_t uid,
- int32_t firewallRule) {
- NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
- auto chain = static_cast<ChildChain>(childChain);
- auto rule = static_cast<FirewallRule>(firewallRule);
-
- int res = gCtls->firewallCtrl.setUidRule(chain, uid, rule);
- return statusFromErrcode(res);
+binder::Status NetdNativeService::firewallSetUidRule(int32_t, int32_t, int32_t) {
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
-binder::Status NetdNativeService::firewallEnableChildChain(int32_t childChain, bool enable) {
- NETD_LOCKING_RPC(gCtls->firewallCtrl.lock, PERM_NETWORK_STACK, PERM_MAINLINE_NETWORK_STACK);
- auto chain = static_cast<ChildChain>(childChain);
-
- int res = gCtls->firewallCtrl.enableChildChains(chain, enable);
- return statusFromErrcode(res);
+binder::Status NetdNativeService::firewallEnableChildChain(int32_t, bool) {
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
-binder::Status NetdNativeService::firewallAddUidInterfaceRules(const std::string& ifName,
- const std::vector<int32_t>& uids) {
- ENFORCE_NETWORK_STACK_PERMISSIONS();
-
- return asBinderStatus(gCtls->trafficCtrl.addUidInterfaceRules(
- RouteController::getIfIndex(ifName.c_str()), uids));
+binder::Status NetdNativeService::firewallAddUidInterfaceRules(const std::string&,
+ const std::vector<int32_t>&) {
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
-binder::Status NetdNativeService::firewallRemoveUidInterfaceRules(
- const std::vector<int32_t>& uids) {
- ENFORCE_NETWORK_STACK_PERMISSIONS();
-
- return asBinderStatus(gCtls->trafficCtrl.removeUidInterfaceRules(uids));
+binder::Status NetdNativeService::firewallRemoveUidInterfaceRules(const std::vector<int32_t>&) {
+ return binder::Status::fromExceptionCode(binder::Status::EX_UNSUPPORTED_OPERATION);
}
binder::Status NetdNativeService::tetherAddForward(const std::string& intIface,
diff --git a/server/NetlinkCommands.cpp b/server/NetlinkCommands.cpp
index acefa8e..7cb08d8 100644
--- a/server/NetlinkCommands.cpp
+++ b/server/NetlinkCommands.cpp
@@ -84,6 +84,11 @@
// Returns -errno if there was an error or if the kernel reported an error.
OPTNONE int sendNetlinkRequest(uint16_t action, uint16_t flags, iovec* iov, int iovlen,
const NetlinkDumpCallback* callback) {
+ int sock = openNetlinkSocket(NETLINK_ROUTE);
+ if (sock < 0) {
+ return sock;
+ }
+
nlmsghdr nlmsg = {
.nlmsg_type = action,
.nlmsg_flags = flags,
@@ -94,14 +99,11 @@
nlmsg.nlmsg_len += iov[i].iov_len;
}
- int sock = openNetlinkSocket(NETLINK_ROUTE);
- if (sock < 0) {
- return sock;
- }
-
+ ssize_t writevRet = writev(sock, iov, iovlen);
+ // Don't let pointers to the stack escape.
+ iov[0] = {nullptr, 0};
int ret = 0;
-
- if (writev(sock, iov, iovlen) == -1) {
+ if (writevRet == -1) {
ret = -errno;
ALOGE("netlink socket connect/writev failed (%s)", strerror(-ret));
close(sock);
diff --git a/server/NetlinkHandler.cpp b/server/NetlinkHandler.cpp
index 525bb2d..a4e05b0 100644
--- a/server/NetlinkHandler.cpp
+++ b/server/NetlinkHandler.cpp
@@ -107,18 +107,6 @@
if (!strcmp(subsys, "net")) {
NetlinkEvent::Action action = evt->getAction();
const char *iface = evt->findParam("INTERFACE");
- if ((action == NetlinkEvent::Action::kAdd) ||
- (action == NetlinkEvent::Action::kLinkUp) ||
- (action == NetlinkEvent::Action::kLinkDown)) {
- const char *ifIndex = evt->findParam("IFINDEX");
- long ifaceIndex = parseIfIndex(ifIndex);
- if (ifaceIndex) {
- gCtls->trafficCtrl.addInterface(iface, ifaceIndex);
- } else {
- ALOGE("invalid interface index: %s(%s)", iface, ifIndex);
- }
- }
-
if (action == NetlinkEvent::Action::kAdd) {
notifyInterfaceAdded(iface);
} else if (action == NetlinkEvent::Action::kRemove) {
diff --git a/server/NetlinkListener.cpp b/server/NetlinkListener.cpp
deleted file mode 100644
index a6e427d..0000000
--- a/server/NetlinkListener.cpp
+++ /dev/null
@@ -1,153 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#define LOG_TAG "NetlinkListener"
-
-#include "NetlinkListener.h"
-
-#include <sstream>
-#include <vector>
-
-#include <linux/netfilter/nfnetlink.h>
-
-#include <log/log.h>
-#include <netdutils/Misc.h>
-#include <netdutils/Syscalls.h>
-
-namespace android {
-namespace net {
-
-using netdutils::Fd;
-using netdutils::Slice;
-using netdutils::Status;
-using netdutils::UniqueFd;
-using netdutils::findWithDefault;
-using netdutils::forEachNetlinkMessage;
-using netdutils::makeSlice;
-using netdutils::sSyscalls;
-using netdutils::status::ok;
-using netdutils::statusFromErrno;
-
-namespace {
-
-constexpr int kNetlinkMsgErrorType = (NFNL_SUBSYS_NONE << 8) | NLMSG_ERROR;
-
-constexpr sockaddr_nl kKernelAddr = {
- .nl_family = AF_NETLINK, .nl_pad = 0, .nl_pid = 0, .nl_groups = 0,
-};
-
-const NetlinkListener::DispatchFn kDefaultDispatchFn = [](const nlmsghdr& nlmsg, const Slice) {
- std::stringstream ss;
- ss << nlmsg;
- ALOGE("unhandled netlink message: %s", ss.str().c_str());
-};
-
-} // namespace
-
-NetlinkListener::NetlinkListener(UniqueFd event, UniqueFd sock, const std::string& name)
- : mEvent(std::move(event)), mSock(std::move(sock)), mThreadName(name) {
- const auto rxErrorHandler = [](const nlmsghdr& nlmsg, const Slice msg) {
- std::stringstream ss;
- ss << nlmsg << " " << msg << " " << netdutils::toHex(msg, 32);
- ALOGE("unhandled netlink message: %s", ss.str().c_str());
- };
- expectOk(NetlinkListener::subscribe(kNetlinkMsgErrorType, rxErrorHandler));
-
- mErrorHandler = [& name = mThreadName](const int fd, const int err) {
- ALOGE("Error on NetlinkListener(%s) fd=%d: %s", name.c_str(), fd, strerror(err));
- };
-
- // Start the thread
- mWorker = std::thread([this]() { run().ignoreError(); });
-}
-
-NetlinkListener::~NetlinkListener() {
- const auto& sys = sSyscalls.get();
- const uint64_t data = 1;
- // eventfd should never enter an error state unexpectedly
- expectOk(sys.write(mEvent, makeSlice(data)).status());
- mWorker.join();
-}
-
-Status NetlinkListener::send(const Slice msg) {
- const auto& sys = sSyscalls.get();
- ASSIGN_OR_RETURN(auto sent, sys.sendto(mSock, msg, 0, kKernelAddr));
- if (sent != msg.size()) {
- return statusFromErrno(EMSGSIZE, "unexpect message size");
- }
- return ok;
-}
-
-Status NetlinkListener::subscribe(uint16_t type, const DispatchFn& fn) {
- std::lock_guard guard(mMutex);
- mDispatchMap[type] = fn;
- return ok;
-}
-
-Status NetlinkListener::unsubscribe(uint16_t type) {
- std::lock_guard guard(mMutex);
- mDispatchMap.erase(type);
- return ok;
-}
-
-void NetlinkListener::registerSkErrorHandler(const SkErrorHandler& handler) {
- mErrorHandler = handler;
-}
-
-Status NetlinkListener::run() {
- std::vector<char> rxbuf(4096);
-
- const auto rxHandler = [this](const nlmsghdr& nlmsg, const Slice& buf) {
- std::lock_guard guard(mMutex);
- const auto& fn = findWithDefault(mDispatchMap, nlmsg.nlmsg_type, kDefaultDispatchFn);
- fn(nlmsg, buf);
- };
-
- if (mThreadName.length() > 0) {
- int ret = pthread_setname_np(pthread_self(), mThreadName.c_str());
- if (ret) {
- ALOGE("thread name set failed, name: %s, ret: %s", mThreadName.c_str(), strerror(ret));
- }
- }
- const auto& sys = sSyscalls.get();
- const std::array<Fd, 2> fds{{{mEvent}, {mSock}}};
- const int events = POLLIN;
- const double timeout = 3600;
- while (true) {
- ASSIGN_OR_RETURN(auto revents, sys.ppoll(fds, events, timeout));
- // After mEvent becomes readable, we should stop servicing mSock and return
- if (revents[0] & POLLIN) {
- break;
- }
- if (revents[1] & (POLLIN|POLLERR)) {
- auto rx = sys.recvfrom(mSock, makeSlice(rxbuf), 0);
- int err = rx.status().code();
- if (err) {
- // Ignore errors. The only error we expect to see here is ENOBUFS, and there's
- // nothing we can do about that. The recvfrom above will already have cleared the
- // error indication and ensured we won't get EPOLLERR again.
- // TODO: Consider using NETLINK_NO_ENOBUFS.
- mErrorHandler(((Fd) mSock).get(), err);
- continue;
- }
- forEachNetlinkMessage(rx.value(), rxHandler);
- }
- }
- return ok;
-}
-
-} // namespace net
-} // namespace android
diff --git a/server/NetlinkListener.h b/server/NetlinkListener.h
deleted file mode 100644
index 6f38829..0000000
--- a/server/NetlinkListener.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETLINK_LISTENER_H
-#define NETLINK_LISTENER_H
-
-#include <functional>
-#include <map>
-#include <mutex>
-#include <thread>
-
-#include <android-base/thread_annotations.h>
-#include <netdutils/Netlink.h>
-#include <netdutils/Slice.h>
-#include <netdutils/Status.h>
-#include <netdutils/UniqueFd.h>
-
-namespace android {
-namespace net {
-
-class NetlinkListenerInterface {
- public:
- using DispatchFn = std::function<void(const nlmsghdr& nlmsg, const netdutils::Slice msg)>;
-
- using SkErrorHandler = std::function<void(const int fd, const int err)>;
-
- virtual ~NetlinkListenerInterface() = default;
-
- // Send message to the kernel using the underlying netlink socket
- virtual netdutils::Status send(const netdutils::Slice msg) = 0;
-
- // Deliver future messages with nlmsghdr.nlmsg_type == type to fn.
- //
- // Threadsafe.
- // All dispatch functions invoked on a single service thread.
- // subscribe() and join() must not be called from the stack of fn().
- virtual netdutils::Status subscribe(uint16_t type, const DispatchFn& fn) = 0;
-
- // Halt delivery of future messages with nlmsghdr.nlmsg_type == type.
- // Threadsafe.
- virtual netdutils::Status unsubscribe(uint16_t type) = 0;
-
- virtual void registerSkErrorHandler(const SkErrorHandler& handler) = 0;
-};
-
-// NetlinkListener manages a netlink socket and associated blocking
-// service thread.
-//
-// This class is written in a generic way to allow multiple different
-// netlink subsystems to share this common infrastructure. If multiple
-// subsystems share the same message delivery requirements (drops ok,
-// no drops) they may share a single listener by calling subscribe()
-// with multiple types.
-//
-// This class is suitable for moderate performance message
-// processing. In particular it avoids extra copies of received
-// message data and allows client code to control which message
-// attributes are processed.
-//
-// Note that NetlinkListener is capable of processing multiple batched
-// netlink messages in a single system call. This is useful to
-// netfilter extensions that allow batching of events like NFLOG.
-class NetlinkListener : public NetlinkListenerInterface {
- public:
- NetlinkListener(netdutils::UniqueFd event, netdutils::UniqueFd sock, const std::string& name);
-
- ~NetlinkListener() override;
-
- netdutils::Status send(const netdutils::Slice msg) override;
-
- netdutils::Status subscribe(uint16_t type, const DispatchFn& fn) override EXCLUDES(mMutex);
-
- netdutils::Status unsubscribe(uint16_t type) override EXCLUDES(mMutex);
-
- void registerSkErrorHandler(const SkErrorHandler& handler) override;
-
- private:
- netdutils::Status run();
-
- const netdutils::UniqueFd mEvent;
- const netdutils::UniqueFd mSock;
- const std::string mThreadName;
- std::mutex mMutex;
- std::map<uint16_t, DispatchFn> mDispatchMap GUARDED_BY(mMutex);
- std::thread mWorker;
- SkErrorHandler mErrorHandler;
-};
-
-} // namespace net
-} // namespace android
-
-#endif /* NETLINK_LISTENER_H */
diff --git a/server/Network.cpp b/server/Network.cpp
index 72a1545..85f942f 100644
--- a/server/Network.cpp
+++ b/server/Network.cpp
@@ -86,7 +86,7 @@
// Check if the user has been added to this network. If yes, the highest priority of matching
// setting is returned by subPriority. Thus caller can make choice among several matching
// networks.
-bool Network::appliesToUser(uid_t uid, uint32_t* subPriority) const {
+bool Network::appliesToUser(uid_t uid, int32_t* subPriority) const {
for (const auto& [priority, uidRanges] : mUidRangeMap) {
if (uidRanges.hasUid(uid)) {
*subPriority = priority;
@@ -96,7 +96,7 @@
return false;
}
-void Network::addToUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority) {
+void Network::addToUidRangeMap(const UidRanges& uidRanges, int32_t subPriority) {
auto iter = mUidRangeMap.find(subPriority);
if (iter != mUidRangeMap.end()) {
iter->second.add(uidRanges);
@@ -105,7 +105,7 @@
}
}
-void Network::removeFromUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority) {
+void Network::removeFromUidRangeMap(const UidRanges& uidRanges, int32_t subPriority) {
auto iter = mUidRangeMap.find(subPriority);
if (iter != mUidRangeMap.end()) {
iter->second.remove(uidRanges);
@@ -113,11 +113,11 @@
mUidRangeMap.erase(subPriority);
}
} else {
- ALOGW("uidRanges with priority %u not found", subPriority);
+ ALOGW("uidRanges with priority %d not found", subPriority);
}
}
-bool Network::canAddUidRanges(const UidRanges& uidRanges, uint32_t subPriority) const {
+bool Network::canAddUidRanges(const UidRanges& uidRanges, int32_t subPriority) const {
if (uidRanges.overlapsSelf()) {
ALOGE("uid range %s overlaps self", uidRanges.toString().c_str());
return false;
@@ -125,7 +125,7 @@
auto iter = mUidRangeMap.find(subPriority);
if (iter != mUidRangeMap.end() && uidRanges.overlaps(iter->second)) {
- ALOGE("uid range %s overlaps priority %u %s", uidRanges.toString().c_str(), subPriority,
+ ALOGE("uid range %s overlaps priority %d %s", uidRanges.toString().c_str(), subPriority,
iter->second.toString().c_str());
return false;
}
diff --git a/server/Network.h b/server/Network.h
index aa1b21a..e18e1cd 100644
--- a/server/Network.h
+++ b/server/Network.h
@@ -24,7 +24,7 @@
namespace android::net {
-typedef std::map<uint32_t, UidRanges> UidRangeMap;
+typedef std::map<int32_t, UidRanges> UidRangeMap;
// A Network represents a collection of interfaces participating as a single administrative unit.
class Network {
@@ -47,11 +47,11 @@
std::string toString() const;
std::string uidRangesToString() const;
- bool appliesToUser(uid_t uid, uint32_t* subPriority) const;
- [[nodiscard]] virtual int addUsers(const UidRanges&, uint32_t /*subPriority*/) {
+ bool appliesToUser(uid_t uid, int32_t* subPriority) const;
+ [[nodiscard]] virtual int addUsers(const UidRanges&, int32_t /*subPriority*/) {
return -EINVAL;
};
- [[nodiscard]] virtual int removeUsers(const UidRanges&, uint32_t /*subPriority*/) {
+ [[nodiscard]] virtual int removeUsers(const UidRanges&, int32_t /*subPriority*/) {
return -EINVAL;
};
bool isSecure() const;
@@ -59,18 +59,18 @@
virtual bool isUnreachable() { return false; }
virtual bool isVirtual() { return false; }
virtual bool canAddUsers() { return false; }
- virtual bool isValidSubPriority(uint32_t /*priority*/) { return false; }
- virtual void addToUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority);
- virtual void removeFromUidRangeMap(const UidRanges& uidRanges, uint32_t subPriority);
+ virtual bool isValidSubPriority(int32_t /*priority*/) { return false; }
+ virtual void addToUidRangeMap(const UidRanges& uidRanges, int32_t subPriority);
+ virtual void removeFromUidRangeMap(const UidRanges& uidRanges, int32_t subPriority);
protected:
- explicit Network(unsigned netId, bool mSecure = false);
- bool canAddUidRanges(const UidRanges& uidRanges, uint32_t subPriority) const;
+ explicit Network(unsigned netId, bool secure = false);
+ bool canAddUidRanges(const UidRanges& uidRanges, int32_t subPriority) const;
const unsigned mNetId;
std::set<std::string> mInterfaces;
// Each subsidiary priority maps to a set of UID ranges of a feature.
- std::map<uint32_t, UidRanges> mUidRangeMap;
+ std::map<int32_t, UidRanges> mUidRangeMap;
const bool mSecure;
private:
diff --git a/server/NetworkController.cpp b/server/NetworkController.cpp
index 602639c..f144139 100644
--- a/server/NetworkController.cpp
+++ b/server/NetworkController.cpp
@@ -36,17 +36,19 @@
#include "DummyNetwork.h"
#include "Fwmark.h"
#include "LocalNetwork.h"
-#include "OffloadUtils.h"
#include "PhysicalNetwork.h"
#include "RouteController.h"
+#include "TcUtils.h"
#include "UnreachableNetwork.h"
#include "VirtualNetwork.h"
#include "netdutils/DumpWriter.h"
+#include "netdutils/Utils.h"
#include "netid_client.h"
#define DBG 0
using android::netdutils::DumpWriter;
+using android::netdutils::getIfaceNames;
namespace android::net {
@@ -150,7 +152,7 @@
// TODO: perhaps only remove the clsact on the interface which is added by
// RouteController::addInterfaceToPhysicalNetwork. Currently, the netd only
// attach the clsact to the interface for the physical network.
- const auto& ifaces = InterfaceController::getIfaceNames();
+ const auto& ifaces = getIfaceNames();
if (isOk(ifaces)) {
for (const std::string& iface : ifaces.value()) {
if (int ifIndex = if_nametoindex(iface.c_str())) {
@@ -437,7 +439,8 @@
return ret;
}
-int NetworkController::createVirtualNetwork(unsigned netId, bool secure, NativeVpnType vpnType) {
+int NetworkController::createVirtualNetwork(unsigned netId, bool secure, NativeVpnType vpnType,
+ bool excludeLocalRoutes) {
ScopedWLock lock(mRWLock);
if (!(MIN_NET_ID <= netId && netId <= MAX_NET_ID)) {
@@ -458,7 +461,7 @@
if (int ret = modifyFallthroughLocked(netId, true)) {
return ret;
}
- mNetworks[netId] = new VirtualNetwork(netId, secure);
+ mNetworks[netId] = new VirtualNetwork(netId, secure, excludeLocalRoutes);
return 0;
}
@@ -617,7 +620,7 @@
} // namespace
int NetworkController::addUsersToNetwork(unsigned netId, const UidRanges& uidRanges,
- uint32_t subPriority) {
+ int32_t subPriority) {
ScopedWLock lock(mRWLock);
Network* network = getNetworkLocked(netId);
if (int ret = isWrongNetworkForUidRanges(netId, network)) {
@@ -627,7 +630,7 @@
}
int NetworkController::removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges,
- uint32_t subPriority) {
+ int32_t subPriority) {
ScopedWLock lock(mRWLock);
Network* network = getNetworkLocked(netId);
if (int ret = isWrongNetworkForUidRanges(netId, network)) {
@@ -768,6 +771,22 @@
}
dw.decIndent();
+ dw.blankline();
+ dw.println("Permission of users:");
+ dw.incIndent();
+ std::vector<uid_t> systemUids;
+ std::vector<uid_t> networkUids;
+ for (const auto& [uid, permission] : mUsers) {
+ if ((permission & PERMISSION_SYSTEM) == PERMISSION_SYSTEM) {
+ systemUids.push_back(uid);
+ } else if ((permission & PERMISSION_NETWORK) == PERMISSION_NETWORK) {
+ networkUids.push_back(uid);
+ }
+ }
+ dw.println("NETWORK: %s", android::base::Join(networkUids, ", ").c_str());
+ dw.println("SYSTEM: %s", android::base::Join(systemUids, ", ").c_str());
+ dw.decIndent();
+
dw.decIndent();
dw.decIndent();
@@ -783,7 +802,7 @@
}
VirtualNetwork* NetworkController::getVirtualNetworkForUserLocked(uid_t uid) const {
- uint32_t subPriority;
+ int32_t subPriority;
for (const auto& [_, network] : mNetworks) {
if (network->isVirtual() && network->appliesToUser(uid, &subPriority)) {
return static_cast<VirtualNetwork*>(network);
@@ -792,17 +811,26 @@
return nullptr;
}
-// Returns a network with the highest subsidiary priority among physical and unreachable networks
-// that applies to uid. For a single subsidiary priority, an uid should belong to only one network.
-// If the uid apply to different network with the same priority at the same time, the behavior is
-// undefined. That is a configuration error.
+// Returns the default network with the highest subsidiary priority among physical and unreachable
+// networks that applies to uid. For a single subsidiary priority, an uid should belong to only one
+// network. If the uid apply to different network with the same priority at the same time, the
+// behavior is undefined. That is a configuration error.
Network* NetworkController::getPhysicalOrUnreachableNetworkForUserLocked(uid_t uid) const {
Network* bestNetwork = nullptr;
- unsigned bestSubPriority = UidRanges::LOWEST_SUB_PRIORITY + 1;
+
+ // In this function, appliesToUser() is used to figure out if this network is the user's default
+ // network (not just if the user has access to this network). Rules at SUB_PRIORITY_NO_DEFAULT
+ // "apply to the user" but do not include a default network rule. Since their subpriority (999)
+ // is greater than SUB_PRIORITY_LOWEST (998), these rules never trump any subpriority that
+ // includes a default network rule (appliesToUser returns the "highest" (=lowest value)
+ // subPriority that includes the uid), and they get filtered out in the if-statement below.
+ int32_t bestSubPriority = UidRanges::SUB_PRIORITY_NO_DEFAULT;
for (const auto& [netId, network] : mNetworks) {
- uint32_t subPriority;
+ int32_t subPriority;
if (!network->isPhysical() && !network->isUnreachable()) continue;
if (!network->appliesToUser(uid, &subPriority)) continue;
+ if (subPriority == UidRanges::SUB_PRIORITY_NO_DEFAULT) continue;
+
if (subPriority < bestSubPriority) {
bestNetwork = network;
bestSubPriority = subPriority;
@@ -836,7 +864,7 @@
return 0;
}
// If the UID wants to use a VPN, it can do so if and only if the VPN applies to the UID.
- uint32_t subPriority;
+ int32_t subPriority;
if (network->isVirtual()) {
return network->appliesToUser(uid, &subPriority) ? 0 : -EPERM;
}
@@ -897,11 +925,13 @@
switch (op) {
case ROUTE_ADD:
- return RouteController::addRoute(interface, destination, nexthop, tableType, mtu);
+ return RouteController::addRoute(interface, destination, nexthop, tableType, mtu,
+ 0 /* priority */);
case ROUTE_UPDATE:
return RouteController::updateRoute(interface, destination, nexthop, tableType, mtu);
case ROUTE_REMOVE:
- return RouteController::removeRoute(interface, destination, nexthop, tableType);
+ return RouteController::removeRoute(interface, destination, nexthop, tableType,
+ 0 /* priority */);
}
return -EINVAL;
}
diff --git a/server/NetworkController.h b/server/NetworkController.h
index a61ac39..e9ef091 100644
--- a/server/NetworkController.h
+++ b/server/NetworkController.h
@@ -107,7 +107,8 @@
[[nodiscard]] int createPhysicalNetwork(unsigned netId, Permission permission);
[[nodiscard]] int createPhysicalOemNetwork(Permission permission, unsigned* netId);
- [[nodiscard]] int createVirtualNetwork(unsigned netId, bool secure, NativeVpnType vpnType);
+ [[nodiscard]] int createVirtualNetwork(unsigned netId, bool secure, NativeVpnType vpnType,
+ bool excludeLocalRoutes);
[[nodiscard]] int destroyNetwork(unsigned netId);
[[nodiscard]] int addInterfaceToNetwork(unsigned netId, const char* interface);
@@ -120,9 +121,9 @@
const std::vector<unsigned>& netIds);
[[nodiscard]] int addUsersToNetwork(unsigned netId, const UidRanges& uidRanges,
- uint32_t subPriority);
+ int32_t subPriority);
[[nodiscard]] int removeUsersFromNetwork(unsigned netId, const UidRanges& uidRanges,
- uint32_t subPriority);
+ int32_t subPriority);
// |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
// route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
diff --git a/server/OWNERS b/server/OWNERS
new file mode 100644
index 0000000..03fedf7
--- /dev/null
+++ b/server/OWNERS
@@ -0,0 +1,3 @@
+# Bug component: 31808
+lorenzo@google.com
+maze@google.com
diff --git a/server/OffloadUtils.cpp b/server/OffloadUtils.cpp
deleted file mode 100644
index 0d9869f..0000000
--- a/server/OffloadUtils.cpp
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-#include "OffloadUtils.h"
-
-#include <arpa/inet.h>
-#include <linux/if.h>
-#include <linux/if_arp.h>
-#include <linux/netlink.h>
-#include <linux/pkt_cls.h>
-#include <linux/pkt_sched.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#define LOG_TAG "OffloadUtils"
-#include <log/log.h>
-
-#include "NetlinkCommands.h"
-#include "android-base/unique_fd.h"
-
-namespace android {
-namespace net {
-
-using std::max;
-
-static int doSIOCGIF(const std::string& interface, int opt) {
- base::unique_fd ufd(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
-
- if (ufd < 0) {
- const int err = errno;
- ALOGE("socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0)");
- return -err;
- };
-
- struct ifreq ifr = {};
- // We use strncpy() instead of strlcpy() since kernel has to be able
- // to handle non-zero terminated junk passed in by userspace anyway,
- // and this way too long interface names (more than IFNAMSIZ-1 = 15
- // characters plus terminating NULL) will not get truncated to 15
- // characters and zero-terminated and thus potentially erroneously
- // match a truncated interface if one were to exist.
- strncpy(ifr.ifr_name, interface.c_str(), sizeof(ifr.ifr_name));
-
- if (ioctl(ufd, opt, &ifr, sizeof(ifr))) return -errno;
-
- if (opt == SIOCGIFHWADDR) return ifr.ifr_hwaddr.sa_family;
- if (opt == SIOCGIFMTU) return ifr.ifr_mtu;
- return -EINVAL;
-}
-
-int hardwareAddressType(const std::string& interface) {
- return doSIOCGIF(interface, SIOCGIFHWADDR);
-}
-
-int deviceMTU(const std::string& interface) {
- return doSIOCGIF(interface, SIOCGIFMTU);
-}
-
-base::Result<bool> isEthernet(const std::string& interface) {
- int rv = hardwareAddressType(interface);
- if (rv < 0) {
- errno = -rv;
- return ErrnoErrorf("Get hardware address type of interface {} failed", interface);
- }
-
- switch (rv) {
- case ARPHRD_ETHER:
- return true;
- case ARPHRD_NONE:
- case ARPHRD_RAWIP: // in Linux 4.14+ rmnet support was upstreamed and this is 519
- case 530: // this is ARPHRD_RAWIP on some Android 4.9 kernels with rmnet
- return false;
- default:
- errno = EAFNOSUPPORT; // Address family not supported
- return ErrnoErrorf("Unknown hardware address type {} on interface {}", rv, interface);
- }
-}
-
-// TODO: use //system/netd/server/NetlinkCommands.cpp:openNetlinkSocket(protocol)
-// and //system/netd/server/SockDiag.cpp:checkError(fd)
-static int sendAndProcessNetlinkResponse(const void* req, int len) {
- base::unique_fd fd(socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE));
- if (fd == -1) {
- const int err = errno;
- ALOGE("socket(AF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_ROUTE)");
- return -err;
- }
-
- static constexpr int on = 1;
- int rv = setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, &on, sizeof(on));
- if (rv) ALOGE("setsockopt(fd, SOL_NETLINK, NETLINK_CAP_ACK, %d)", on);
-
- // this is needed to get sane strace netlink parsing, it allocates the pid
- rv = bind(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR));
- if (rv) {
- const int err = errno;
- ALOGE("bind(fd, {AF_NETLINK, 0, 0})");
- return -err;
- }
-
- // we do not want to receive messages from anyone besides the kernel
- rv = connect(fd, (const struct sockaddr*)&KERNEL_NLADDR, sizeof(KERNEL_NLADDR));
- if (rv) {
- const int err = errno;
- ALOGE("connect(fd, {AF_NETLINK, 0, 0})");
- return -err;
- }
-
- rv = send(fd, req, len, 0);
- if (rv == -1) return -errno;
- if (rv != len) return -EMSGSIZE;
-
- struct {
- nlmsghdr h;
- nlmsgerr e;
- char buf[256];
- } resp = {};
-
- rv = recv(fd, &resp, sizeof(resp), MSG_TRUNC);
-
- if (rv == -1) {
- const int err = errno;
- ALOGE("recv() failed");
- return -err;
- }
-
- if (rv < (int)NLMSG_SPACE(sizeof(struct nlmsgerr))) {
- ALOGE("recv() returned short packet: %d", rv);
- return -EMSGSIZE;
- }
-
- if (resp.h.nlmsg_len != (unsigned)rv) {
- ALOGE("recv() returned invalid header length: %d != %d", resp.h.nlmsg_len, rv);
- return -EBADMSG;
- }
-
- if (resp.h.nlmsg_type != NLMSG_ERROR) {
- ALOGE("recv() did not return NLMSG_ERROR message: %d", resp.h.nlmsg_type);
- return -EBADMSG;
- }
-
- return resp.e.error; // returns 0 on success
-}
-
-// ADD: nlMsgType=RTM_NEWQDISC nlMsgFlags=NLM_F_EXCL|NLM_F_CREATE
-// REPLACE: nlMsgType=RTM_NEWQDISC nlMsgFlags=NLM_F_CREATE|NLM_F_REPLACE
-// DEL: nlMsgType=RTM_DELQDISC nlMsgFlags=0
-int doTcQdiscClsact(int ifIndex, uint16_t nlMsgType, uint16_t nlMsgFlags) {
- // This is the name of the qdisc we are attaching.
- // Some hoop jumping to make this compile time constant with known size,
- // so that the structure declaration is well defined at compile time.
-#define CLSACT "clsact"
- // sizeof() includes the terminating NULL
- static constexpr size_t ASCIIZ_LEN_CLSACT = sizeof(CLSACT);
-
- const struct {
- nlmsghdr n;
- tcmsg t;
- struct {
- nlattr attr;
- char str[NLMSG_ALIGN(ASCIIZ_LEN_CLSACT)];
- } kind;
- } req = {
- .n =
- {
- .nlmsg_len = sizeof(req),
- .nlmsg_type = nlMsgType,
- .nlmsg_flags = static_cast<__u16>(NETLINK_REQUEST_FLAGS | nlMsgFlags),
- },
- .t =
- {
- .tcm_family = AF_UNSPEC,
- .tcm_ifindex = ifIndex,
- .tcm_handle = TC_H_MAKE(TC_H_CLSACT, 0),
- .tcm_parent = TC_H_CLSACT,
- },
- .kind =
- {
- .attr =
- {
- .nla_len = NLA_HDRLEN + ASCIIZ_LEN_CLSACT,
- .nla_type = TCA_KIND,
- },
- .str = CLSACT,
- },
- };
-#undef CLSACT
-
- return sendAndProcessNetlinkResponse(&req, sizeof(req));
-}
-
-// The priority of clat hook - must be after tethering.
-constexpr uint16_t PRIO_CLAT = 4;
-
-// tc filter add dev .. in/egress prio 4 protocol ipv6/ip bpf object-pinned /sys/fs/bpf/...
-// direct-action
-int tcFilterAddDevBpf(int ifIndex, bool ingress, uint16_t proto, int bpfFd, bool ethernet) {
- // This is the name of the filter we're attaching (ie. this is the 'bpf'
- // packet classifier enabled by kernel config option CONFIG_NET_CLS_BPF.
- //
- // We go through some hoops in order to make this compile time constants
- // so that we can define the struct further down the function with the
- // field for this sized correctly already during the build.
-#define BPF "bpf"
- // sizeof() includes the terminating NULL
- static constexpr size_t ASCIIZ_LEN_BPF = sizeof(BPF);
-
- // This is to replicate program name suffix used by 'tc' Linux cli
- // when it attaches programs.
-#define FSOBJ_SUFFIX ":[*fsobj]"
-
- // This macro expands (from header files) to:
- // prog_clatd_schedcls_ingress6_clat_rawip:[*fsobj]
- // and is the name of the pinned ingress ebpf program for ARPHRD_RAWIP interfaces.
- // (also compatible with anything that has 0 size L2 header)
- static constexpr char name_clat_rx_rawip[] = CLAT_INGRESS6_PROG_RAWIP_NAME FSOBJ_SUFFIX;
-
- // This macro expands (from header files) to:
- // prog_clatd_schedcls_ingress6_clat_ether:[*fsobj]
- // and is the name of the pinned ingress ebpf program for ARPHRD_ETHER interfaces.
- // (also compatible with anything that has standard ethernet header)
- static constexpr char name_clat_rx_ether[] = CLAT_INGRESS6_PROG_ETHER_NAME FSOBJ_SUFFIX;
-
- // This macro expands (from header files) to:
- // prog_clatd_schedcls_egress4_clat_rawip:[*fsobj]
- // and is the name of the pinned egress ebpf program for ARPHRD_RAWIP interfaces.
- // (also compatible with anything that has 0 size L2 header)
- static constexpr char name_clat_tx_rawip[] = CLAT_EGRESS4_PROG_RAWIP_NAME FSOBJ_SUFFIX;
-
- // This macro expands (from header files) to:
- // prog_clatd_schedcls_egress4_clat_ether:[*fsobj]
- // and is the name of the pinned egress ebpf program for ARPHRD_ETHER interfaces.
- // (also compatible with anything that has standard ethernet header)
- static constexpr char name_clat_tx_ether[] = CLAT_EGRESS4_PROG_ETHER_NAME FSOBJ_SUFFIX;
-
-#undef FSOBJ_SUFFIX
-
- // The actual name we'll use is determined at run time via 'ethernet' and 'ingress'
- // booleans. We need to compile time allocate enough space in the struct
- // hence this macro magic to make sure we have enough space for either
- // possibility. In practice some of these are actually the same size.
- static constexpr size_t ASCIIZ_MAXLEN_NAME = max({
- sizeof(name_clat_rx_rawip),
- sizeof(name_clat_rx_ether),
- sizeof(name_clat_tx_rawip),
- sizeof(name_clat_tx_ether),
- });
-
- // These are not compile time constants: 'name' is used in strncpy below
- const char* const name_clat_rx = ethernet ? name_clat_rx_ether : name_clat_rx_rawip;
- const char* const name_clat_tx = ethernet ? name_clat_tx_ether : name_clat_tx_rawip;
- const char* const name = ingress ? name_clat_rx : name_clat_tx;
-
- struct {
- nlmsghdr n;
- tcmsg t;
- struct {
- nlattr attr;
- char str[NLMSG_ALIGN(ASCIIZ_LEN_BPF)];
- } kind;
- struct {
- nlattr attr;
- struct {
- nlattr attr;
- __u32 u32;
- } fd;
- struct {
- nlattr attr;
- char str[NLMSG_ALIGN(ASCIIZ_MAXLEN_NAME)];
- } name;
- struct {
- nlattr attr;
- __u32 u32;
- } flags;
- } options;
- } req = {
- .n =
- {
- .nlmsg_len = sizeof(req),
- .nlmsg_type = RTM_NEWTFILTER,
- .nlmsg_flags = NETLINK_REQUEST_FLAGS | NLM_F_EXCL | NLM_F_CREATE,
- },
- .t =
- {
- .tcm_family = AF_UNSPEC,
- .tcm_ifindex = ifIndex,
- .tcm_handle = TC_H_UNSPEC,
- .tcm_parent = TC_H_MAKE(TC_H_CLSACT,
- ingress ? TC_H_MIN_INGRESS : TC_H_MIN_EGRESS),
- .tcm_info = static_cast<__u32>((PRIO_CLAT << 16) | htons(proto)),
- },
- .kind =
- {
- .attr =
- {
- .nla_len = sizeof(req.kind),
- .nla_type = TCA_KIND,
- },
- .str = BPF,
- },
- .options =
- {
- .attr =
- {
- .nla_len = sizeof(req.options),
- .nla_type = NLA_F_NESTED | TCA_OPTIONS,
- },
- .fd =
- {
- .attr =
- {
- .nla_len = sizeof(req.options.fd),
- .nla_type = TCA_BPF_FD,
- },
- .u32 = static_cast<__u32>(bpfFd),
- },
- .name =
- {
- .attr =
- {
- .nla_len = sizeof(req.options.name),
- .nla_type = TCA_BPF_NAME,
- },
- // Visible via 'tc filter show', but
- // is overwritten by strncpy below
- .str = "placeholder",
- },
- .flags =
- {
- .attr =
- {
- .nla_len = sizeof(req.options.flags),
- .nla_type = TCA_BPF_FLAGS,
- },
- .u32 = TCA_BPF_FLAG_ACT_DIRECT,
- },
- },
- };
-#undef BPF
-
- strncpy(req.options.name.str, name, sizeof(req.options.name.str));
-
- return sendAndProcessNetlinkResponse(&req, sizeof(req));
-}
-
-// tc filter del dev .. in/egress prio 4 protocol ..
-int tcFilterDelDev(int ifIndex, bool ingress, uint16_t proto) {
- const struct {
- nlmsghdr n;
- tcmsg t;
- } req = {
- .n =
- {
- .nlmsg_len = sizeof(req),
- .nlmsg_type = RTM_DELTFILTER,
- .nlmsg_flags = NETLINK_REQUEST_FLAGS,
- },
- .t =
- {
- .tcm_family = AF_UNSPEC,
- .tcm_ifindex = ifIndex,
- .tcm_handle = TC_H_UNSPEC,
- .tcm_parent = TC_H_MAKE(TC_H_CLSACT,
- ingress ? TC_H_MIN_INGRESS : TC_H_MIN_EGRESS),
- .tcm_info = static_cast<__u32>((PRIO_CLAT << 16) | htons(proto)),
- },
- };
-
- return sendAndProcessNetlinkResponse(&req, sizeof(req));
-}
-
-} // namespace net
-} // namespace android
diff --git a/server/OffloadUtils.h b/server/OffloadUtils.h
deleted file mode 100644
index 684ffb3..0000000
--- a/server/OffloadUtils.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2019 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
-
-#include <android-base/result.h>
-#include <errno.h>
-#include <linux/if_ether.h>
-#include <linux/if_link.h>
-#include <linux/rtnetlink.h>
-
-#include <string>
-
-#include "bpf/BpfUtils.h"
-#include "netdbpf/bpf_shared.h"
-
-namespace android {
-namespace net {
-
-// For better code clarity - do not change values - used for booleans like
-// with_ethernet_header or isEthernet.
-constexpr bool RAWIP = false;
-constexpr bool ETHER = true;
-
-// For better code clarity when used for 'bool ingress' parameter.
-constexpr bool EGRESS = false;
-constexpr bool INGRESS = true;
-
-// this returns an ARPHRD_* constant or a -errno
-int hardwareAddressType(const std::string& interface);
-
-// return MTU or -errno
-int deviceMTU(const std::string& interface);
-
-base::Result<bool> isEthernet(const std::string& interface);
-
-inline int getClatEgress4MapFd(void) {
- const int fd = bpf::mapRetrieveRW(CLAT_EGRESS4_MAP_PATH);
- return (fd == -1) ? -errno : fd;
-}
-
-inline int getClatEgress4ProgFd(bool with_ethernet_header) {
- const int fd = bpf::retrieveProgram(with_ethernet_header ? CLAT_EGRESS4_PROG_ETHER_PATH
- : CLAT_EGRESS4_PROG_RAWIP_PATH);
- return (fd == -1) ? -errno : fd;
-}
-
-inline int getClatIngress6MapFd(void) {
- const int fd = bpf::mapRetrieveRW(CLAT_INGRESS6_MAP_PATH);
- return (fd == -1) ? -errno : fd;
-}
-
-inline int getClatIngress6ProgFd(bool with_ethernet_header) {
- const int fd = bpf::retrieveProgram(with_ethernet_header ? CLAT_INGRESS6_PROG_ETHER_PATH
- : CLAT_INGRESS6_PROG_RAWIP_PATH);
- return (fd == -1) ? -errno : fd;
-}
-
-int doTcQdiscClsact(int ifIndex, uint16_t nlMsgType, uint16_t nlMsgFlags);
-
-inline int tcQdiscAddDevClsact(int ifIndex) {
- return doTcQdiscClsact(ifIndex, RTM_NEWQDISC, NLM_F_EXCL | NLM_F_CREATE);
-}
-
-inline int tcQdiscReplaceDevClsact(int ifIndex) {
- return doTcQdiscClsact(ifIndex, RTM_NEWQDISC, NLM_F_CREATE | NLM_F_REPLACE);
-}
-
-inline int tcQdiscDelDevClsact(int ifIndex) {
- return doTcQdiscClsact(ifIndex, RTM_DELQDISC, 0);
-}
-
-// tc filter add dev .. in/egress prio 4 protocol ipv6/ip bpf object-pinned /sys/fs/bpf/...
-// direct-action
-int tcFilterAddDevBpf(int ifIndex, bool ingress, uint16_t proto, int bpfFd, bool ethernet);
-
-// tc filter add dev .. ingress prio 4 protocol ipv6 bpf object-pinned /sys/fs/bpf/... direct-action
-inline int tcFilterAddDevIngressClatIpv6(int ifIndex, int bpfFd, bool ethernet) {
- return tcFilterAddDevBpf(ifIndex, INGRESS, ETH_P_IPV6, bpfFd, ethernet);
-}
-
-// tc filter add dev .. egress prio 4 protocol ip bpf object-pinned /sys/fs/bpf/... direct-action
-inline int tcFilterAddDevEgressClatIpv4(int ifIndex, int bpfFd, bool ethernet) {
- return tcFilterAddDevBpf(ifIndex, EGRESS, ETH_P_IP, bpfFd, ethernet);
-}
-
-// tc filter del dev .. in/egress prio .. protocol ..
-int tcFilterDelDev(int ifIndex, bool ingress, uint16_t proto);
-
-// tc filter del dev .. ingress prio 4 protocol ipv6
-inline int tcFilterDelDevIngressClatIpv6(int ifIndex) {
- return tcFilterDelDev(ifIndex, INGRESS, ETH_P_IPV6);
-}
-
-// tc filter del dev .. egress prio 4 protocol ip
-inline int tcFilterDelDevEgressClatIpv4(int ifIndex) {
- return tcFilterDelDev(ifIndex, EGRESS, ETH_P_IP);
-}
-
-} // namespace net
-} // namespace android
diff --git a/server/OffloadUtilsTest.cpp b/server/OffloadUtilsTest.cpp
deleted file mode 100644
index 16c108b..0000000
--- a/server/OffloadUtilsTest.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/*
- * Copyright 2019 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.
- *
- * OffloadUtilsTest.cpp - unit tests for OffloadUtils.cpp
- */
-
-#include <gtest/gtest.h>
-
-#include "OffloadUtils.h"
-
-#include <linux/if_arp.h>
-#include <stdlib.h>
-#include <sys/wait.h>
-
-#include "bpf/BpfUtils.h"
-#include "netdbpf/bpf_shared.h"
-
-namespace android {
-namespace net {
-
-class OffloadUtilsTest : public ::testing::Test {
- public:
- void SetUp() {}
-};
-
-TEST_F(OffloadUtilsTest, HardwareAddressTypeOfNonExistingIf) {
- ASSERT_EQ(-ENODEV, hardwareAddressType("not_existing_if"));
-}
-
-TEST_F(OffloadUtilsTest, HardwareAddressTypeOfLoopback) {
- ASSERT_EQ(ARPHRD_LOOPBACK, hardwareAddressType("lo"));
-}
-
-// If wireless 'wlan0' interface exists it should be Ethernet.
-TEST_F(OffloadUtilsTest, HardwareAddressTypeOfWireless) {
- int type = hardwareAddressType("wlan0");
- if (type == -ENODEV) return;
-
- ASSERT_EQ(ARPHRD_ETHER, type);
-}
-
-// If cellular 'rmnet_data0' interface exists it should
-// *probably* not be Ethernet and instead be RawIp.
-TEST_F(OffloadUtilsTest, HardwareAddressTypeOfCellular) {
- int type = hardwareAddressType("rmnet_data0");
- if (type == -ENODEV) return;
-
- ASSERT_NE(ARPHRD_ETHER, type);
-
- // ARPHRD_RAWIP is 530 on some pre-4.14 Qualcomm devices.
- if (type == 530) return;
-
- ASSERT_EQ(ARPHRD_RAWIP, type);
-}
-
-TEST_F(OffloadUtilsTest, IsEthernetOfNonExistingIf) {
- auto res = isEthernet("not_existing_if");
- ASSERT_FALSE(res.ok());
- ASSERT_EQ(ENODEV, res.error().code());
-}
-
-TEST_F(OffloadUtilsTest, IsEthernetOfLoopback) {
- auto res = isEthernet("lo");
- ASSERT_FALSE(res.ok());
- ASSERT_EQ(EAFNOSUPPORT, res.error().code());
-}
-
-// If wireless 'wlan0' interface exists it should be Ethernet.
-// See also HardwareAddressTypeOfWireless.
-TEST_F(OffloadUtilsTest, IsEthernetOfWireless) {
- auto res = isEthernet("wlan0");
- if (!res.ok() && res.error().code() == ENODEV) return;
-
- ASSERT_RESULT_OK(res);
- ASSERT_TRUE(res.value());
-}
-
-// If cellular 'rmnet_data0' interface exists it should
-// *probably* not be Ethernet and instead be RawIp.
-// See also HardwareAddressTypeOfCellular.
-TEST_F(OffloadUtilsTest, IsEthernetOfCellular) {
- auto res = isEthernet("rmnet_data0");
- if (!res.ok() && res.error().code() == ENODEV) return;
-
- ASSERT_RESULT_OK(res);
- ASSERT_FALSE(res.value());
-}
-
-TEST_F(OffloadUtilsTest, DeviceMTUOfNonExistingIf) {
- ASSERT_EQ(-ENODEV, deviceMTU("not_existing_if"));
-}
-
-TEST_F(OffloadUtilsTest, DeviceMTUofLoopback) {
- ASSERT_EQ(65536, deviceMTU("lo"));
-}
-
-TEST_F(OffloadUtilsTest, GetClatEgress4MapFd) {
- int fd = getClatEgress4MapFd();
- ASSERT_GE(fd, 3); // 0,1,2 - stdin/out/err, thus fd >= 3
- EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
- close(fd);
-}
-
-TEST_F(OffloadUtilsTest, GetClatEgress4RawIpProgFd) {
- int fd = getClatEgress4ProgFd(RAWIP);
- ASSERT_GE(fd, 3);
- EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
- close(fd);
-}
-
-TEST_F(OffloadUtilsTest, GetClatEgress4EtherProgFd) {
- int fd = getClatEgress4ProgFd(ETHER);
- ASSERT_GE(fd, 3);
- EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
- close(fd);
-}
-
-TEST_F(OffloadUtilsTest, GetClatIngress6MapFd) {
- int fd = getClatIngress6MapFd();
- ASSERT_GE(fd, 3); // 0,1,2 - stdin/out/err, thus fd >= 3
- EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
- close(fd);
-}
-
-TEST_F(OffloadUtilsTest, GetClatIngress6RawIpProgFd) {
- int fd = getClatIngress6ProgFd(RAWIP);
- ASSERT_GE(fd, 3);
- EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
- close(fd);
-}
-
-TEST_F(OffloadUtilsTest, GetClatIngress6EtherProgFd) {
- int fd = getClatIngress6ProgFd(ETHER);
- ASSERT_GE(fd, 3);
- EXPECT_EQ(FD_CLOEXEC, fcntl(fd, F_GETFD));
- close(fd);
-}
-
-// See Linux kernel source in include/net/flow.h
-#define LOOPBACK_IFINDEX 1
-
-TEST_F(OffloadUtilsTest, AttachReplaceDetachClsactLo) {
- // This attaches and detaches a configuration-less and thus no-op clsact
- // qdisc to loopback interface (and it takes fractions of a second)
- EXPECT_EQ(0, tcQdiscAddDevClsact(LOOPBACK_IFINDEX));
- EXPECT_EQ(0, tcQdiscReplaceDevClsact(LOOPBACK_IFINDEX));
- EXPECT_EQ(0, tcQdiscDelDevClsact(LOOPBACK_IFINDEX));
- EXPECT_EQ(-EINVAL, tcQdiscDelDevClsact(LOOPBACK_IFINDEX));
-}
-
-static void checkAttachDetachBpfFilterClsactLo(const bool ingress, const bool ethernet) {
- // Older kernels return EINVAL instead of ENOENT due to lacking proper error propagation...
- const int errNOENT = android::bpf::isAtLeastKernelVersion(4, 19, 0) ? ENOENT : EINVAL;
-
- int clatBpfFd = ingress ? getClatIngress6ProgFd(ethernet) : getClatEgress4ProgFd(ethernet);
- ASSERT_GE(clatBpfFd, 3);
-
- // This attaches and detaches a clsact plus ebpf program to loopback
- // interface, but it should not affect traffic by virtue of us not
- // actually populating the ebpf control map.
- // Furthermore: it only takes fractions of a second.
- EXPECT_EQ(-EINVAL, tcFilterDelDevIngressClatIpv6(LOOPBACK_IFINDEX));
- EXPECT_EQ(-EINVAL, tcFilterDelDevEgressClatIpv4(LOOPBACK_IFINDEX));
- EXPECT_EQ(0, tcQdiscAddDevClsact(LOOPBACK_IFINDEX));
- EXPECT_EQ(-errNOENT, tcFilterDelDevIngressClatIpv6(LOOPBACK_IFINDEX));
- EXPECT_EQ(-errNOENT, tcFilterDelDevEgressClatIpv4(LOOPBACK_IFINDEX));
- if (ingress) {
- EXPECT_EQ(0, tcFilterAddDevIngressClatIpv6(LOOPBACK_IFINDEX, clatBpfFd, ethernet));
- EXPECT_EQ(0, tcFilterDelDevIngressClatIpv6(LOOPBACK_IFINDEX));
- } else {
- EXPECT_EQ(0, tcFilterAddDevEgressClatIpv4(LOOPBACK_IFINDEX, clatBpfFd, ethernet));
- EXPECT_EQ(0, tcFilterDelDevEgressClatIpv4(LOOPBACK_IFINDEX));
- }
- EXPECT_EQ(-errNOENT, tcFilterDelDevIngressClatIpv6(LOOPBACK_IFINDEX));
- EXPECT_EQ(-errNOENT, tcFilterDelDevEgressClatIpv4(LOOPBACK_IFINDEX));
- EXPECT_EQ(0, tcQdiscDelDevClsact(LOOPBACK_IFINDEX));
- EXPECT_EQ(-EINVAL, tcFilterDelDevIngressClatIpv6(LOOPBACK_IFINDEX));
- EXPECT_EQ(-EINVAL, tcFilterDelDevEgressClatIpv4(LOOPBACK_IFINDEX));
-
- close(clatBpfFd);
-}
-
-TEST_F(OffloadUtilsTest, CheckAttachBpfFilterRawIpClsactEgressLo) {
- checkAttachDetachBpfFilterClsactLo(EGRESS, RAWIP);
-}
-
-TEST_F(OffloadUtilsTest, CheckAttachBpfFilterEthernetClsactEgressLo) {
- checkAttachDetachBpfFilterClsactLo(EGRESS, ETHER);
-}
-
-TEST_F(OffloadUtilsTest, CheckAttachBpfFilterRawIpClsactIngressLo) {
- checkAttachDetachBpfFilterClsactLo(INGRESS, RAWIP);
-}
-
-TEST_F(OffloadUtilsTest, CheckAttachBpfFilterEthernetClsactIngressLo) {
- checkAttachDetachBpfFilterClsactLo(INGRESS, ETHER);
-}
-
-} // namespace net
-} // namespace android
diff --git a/server/PhysicalNetwork.cpp b/server/PhysicalNetwork.cpp
index 7b9a19a..bb3f653 100644
--- a/server/PhysicalNetwork.cpp
+++ b/server/PhysicalNetwork.cpp
@@ -84,14 +84,20 @@
}
void PhysicalNetwork::invalidateRouteCache(const std::string& interface) {
+ // This method invalidates all socket destination cache entries in the kernel by creating and
+ // removing a low-priority route.
+ // This number is an arbitrary number that need to be higher than any other route created either
+ // by netd or by an IPv6 RouterAdvertisement.
+ int priority = 100000;
+
for (const auto& dst : { "0.0.0.0/0", "::/0" }) {
// If any of these operations fail, there's no point in logging because RouteController will
// have already logged a message. There's also no point returning an error since there's
// nothing we can do.
(void)RouteController::addRoute(interface.c_str(), dst, "throw", RouteController::INTERFACE,
- 0 /* mtu */);
- (void) RouteController::removeRoute(interface.c_str(), dst, "throw",
- RouteController::INTERFACE);
+ 0 /* mtu */, priority);
+ (void)RouteController::removeRoute(interface.c_str(), dst, "throw",
+ RouteController::INTERFACE, priority);
}
}
@@ -158,7 +164,7 @@
return 0;
}
-int PhysicalNetwork::addUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+int PhysicalNetwork::addUsers(const UidRanges& uidRanges, int32_t subPriority) {
if (!isValidSubPriority(subPriority) || !canAddUidRanges(uidRanges, subPriority)) {
return -EINVAL;
}
@@ -175,7 +181,7 @@
return 0;
}
-int PhysicalNetwork::removeUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+int PhysicalNetwork::removeUsers(const UidRanges& uidRanges, int32_t subPriority) {
if (!isValidSubPriority(subPriority)) return -EINVAL;
for (const std::string& interface : mInterfaces) {
@@ -230,9 +236,11 @@
return 0;
}
-bool PhysicalNetwork::isValidSubPriority(uint32_t priority) {
- return priority >= UidRanges::DEFAULT_SUB_PRIORITY &&
- priority <= UidRanges::LOWEST_SUB_PRIORITY;
+bool PhysicalNetwork::isValidSubPriority(int32_t priority) {
+ // SUB_PRIORITY_NO_DEFAULT is a special value, see UidRanges.h.
+ return (priority >= UidRanges::SUB_PRIORITY_HIGHEST &&
+ priority <= UidRanges::SUB_PRIORITY_LOWEST) ||
+ priority == UidRanges::SUB_PRIORITY_NO_DEFAULT;
}
} // namespace android::net
diff --git a/server/PhysicalNetwork.h b/server/PhysicalNetwork.h
index d9461b2..f114cca 100644
--- a/server/PhysicalNetwork.h
+++ b/server/PhysicalNetwork.h
@@ -42,8 +42,8 @@
[[nodiscard]] int addAsDefault();
[[nodiscard]] int removeAsDefault();
- [[nodiscard]] int addUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
- [[nodiscard]] int removeUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
+ [[nodiscard]] int addUsers(const UidRanges& uidRanges, int32_t subPriority) override;
+ [[nodiscard]] int removeUsers(const UidRanges& uidRanges, int32_t subPriority) override;
bool isPhysical() override { return true; }
bool canAddUsers() override { return true; }
@@ -53,7 +53,7 @@
[[nodiscard]] int removeInterface(const std::string& interface) override;
int destroySocketsLackingPermission(Permission permission);
void invalidateRouteCache(const std::string& interface);
- bool isValidSubPriority(uint32_t priority) override;
+ bool isValidSubPriority(int32_t priority) override;
Delegate* const mDelegate;
Permission mPermission;
diff --git a/server/RouteController.cpp b/server/RouteController.cpp
index ba305e6..d63dbd2 100644
--- a/server/RouteController.cpp
+++ b/server/RouteController.cpp
@@ -31,7 +31,7 @@
#include "Fwmark.h"
#include "NetdConstants.h"
#include "NetlinkCommands.h"
-#include "OffloadUtils.h"
+#include "TcUtils.h"
#include <android-base/file.h>
#include <android-base/stringprintf.h>
@@ -43,12 +43,11 @@
using android::base::StartsWith;
using android::base::StringPrintf;
using android::base::WriteStringToFile;
-using android::net::UidRangeParcel;
namespace android::net {
auto RouteController::iptablesRestoreCommandFunction = execIptablesRestoreCommand;
-
+auto RouteController::ifNameToIndexFunction = if_nametoindex;
// BEGIN CONSTANTS --------------------------------------------------------------------------------
const uint32_t ROUTE_TABLE_LOCAL_NETWORK = 97;
@@ -62,10 +61,6 @@
const char* const ROUTE_TABLE_NAME_LOCAL = "local";
const char* const ROUTE_TABLE_NAME_MAIN = "main";
-// None of our regular routes specify priority, which causes them to have the default priority.
-// For default throw routes, we use a fixed priority of 100000.
-uint32_t PRIO_THROW = 100000;
-
const char* const RouteController::LOCAL_MANGLE_INPUT = "routectrl_mangle_INPUT";
const uint8_t AF_FAMILIES[] = {AF_INET, AF_INET6};
@@ -80,7 +75,6 @@
const bool ACTION_DEL = false;
const bool MODIFY_NON_UID_BASED_RULES = true;
-const char* const RT_TABLES_PATH = "/data/misc/net/rt_tables";
const mode_t RT_TABLES_MODE = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; // mode 0644, rw-r--r--
// Avoids "non-constant-expression cannot be narrowed from type 'unsigned int' to 'unsigned short'"
@@ -131,8 +125,16 @@
static void maybeModifyQdiscClsact(const char* interface, bool add);
+static uint32_t getRouteTableIndexFromGlobalRouteTableIndex(uint32_t index, bool local) {
+ // The local table is
+ // "global table - ROUTE_TABLE_OFFSET_FROM_INDEX + ROUTE_TABLE_OFFSET_FROM_INDEX_FOR_LOCAL"
+ const uint32_t localTableOffset = RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX_FOR_LOCAL -
+ RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX;
+ return local ? index + localTableOffset : index;
+}
+
// Caller must hold sInterfaceToTableLock.
-uint32_t RouteController::getRouteTableForInterfaceLocked(const char* interface) {
+uint32_t RouteController::getRouteTableForInterfaceLocked(const char* interface, bool local) {
// If we already know the routing table for this interface name, use it.
// This ensures we can remove rules and routes for an interface that has been removed,
// or has been removed and re-added with a different interface index.
@@ -142,19 +144,22 @@
// if the same interface disconnects and then reconnects with a different interface ID
// when the reconnect happens the interface will not be in the map, and the code will
// determine the new routing table from the interface ID, below.
+ //
+ // sInterfaceToTable stores the *global* routing table for the interface, and the local table is
+ // "global table - ROUTE_TABLE_OFFSET_FROM_INDEX + ROUTE_TABLE_OFFSET_FROM_INDEX_FOR_LOCAL"
auto iter = sInterfaceToTable.find(interface);
if (iter != sInterfaceToTable.end()) {
- return iter->second;
+ return getRouteTableIndexFromGlobalRouteTableIndex(iter->second, local);
}
- uint32_t index = if_nametoindex(interface);
+ uint32_t index = RouteController::ifNameToIndexFunction(interface);
if (index == 0) {
ALOGE("cannot find interface %s: %s", interface, strerror(errno));
return RT_TABLE_UNSPEC;
}
index += RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX;
sInterfaceToTable[interface] = index;
- return index;
+ return getRouteTableIndexFromGlobalRouteTableIndex(index, local);
}
uint32_t RouteController::getIfIndex(const char* interface) {
@@ -179,9 +184,9 @@
return ifindex - ROUTE_TABLE_OFFSET_FROM_INDEX;
}
-uint32_t RouteController::getRouteTableForInterface(const char* interface) {
+uint32_t RouteController::getRouteTableForInterface(const char* interface, bool local) {
std::lock_guard lock(sInterfaceToTableLock);
- return getRouteTableForInterfaceLocked(interface);
+ return getRouteTableForInterfaceLocked(interface, local);
}
void addTableName(uint32_t table, const std::string& name, std::string* contents) {
@@ -205,8 +210,13 @@
addTableName(ROUTE_TABLE_LEGACY_SYSTEM, ROUTE_TABLE_NAME_LEGACY_SYSTEM, &contents);
std::lock_guard lock(sInterfaceToTableLock);
- for (const auto& entry : sInterfaceToTable) {
- addTableName(entry.second, entry.first, &contents);
+ for (const auto& [ifName, ifIndex] : sInterfaceToTable) {
+ addTableName(ifIndex, ifName, &contents);
+ // Add table for the local route of the network. It's expected to be used for excluding the
+ // local traffic in the VPN network.
+ // Start from ROUTE_TABLE_OFFSET_FROM_INDEX_FOR_LOCAL plus with the interface table index.
+ uint32_t offset = ROUTE_TABLE_OFFSET_FROM_INDEX_FOR_LOCAL - ROUTE_TABLE_OFFSET_FROM_INDEX;
+ addTableName(offset + ifIndex, ifName + INTERFACE_LOCAL_SUFFIX, &contents);
}
if (!WriteStringToFile(contents, RT_TABLES_PATH, RT_TABLES_MODE, AID_SYSTEM, AID_WIFI)) {
@@ -243,10 +253,15 @@
// range (inclusive). Otherwise, the rule matches packets from all UIDs.
//
// Returns 0 on success or negative errno on failure.
-[[nodiscard]] static int modifyIpRule(uint16_t action, uint32_t priority, uint8_t ruleType,
+[[nodiscard]] static int modifyIpRule(uint16_t action, int32_t priority, uint8_t ruleType,
uint32_t table, uint32_t fwmark, uint32_t mask,
const char* iif, const char* oif, uid_t uidStart,
uid_t uidEnd) {
+ if (priority < 0) {
+ ALOGE("invalid IP-rule priority %d", priority);
+ return -ERANGE;
+ }
+
// Ensure that if you set a bit in the fwmark, it's not being ignored by the mask.
if (fwmark & ~mask) {
ALOGE("mask 0x%x does not select all the bits set in fwmark 0x%x", mask, fwmark);
@@ -330,14 +345,14 @@
return 0;
}
-[[nodiscard]] static int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table,
+[[nodiscard]] static int modifyIpRule(uint16_t action, int32_t priority, uint32_t table,
uint32_t fwmark, uint32_t mask, const char* iif,
const char* oif, uid_t uidStart, uid_t uidEnd) {
return modifyIpRule(action, priority, FR_ACT_TO_TBL, table, fwmark, mask, iif, oif, uidStart,
uidEnd);
}
-[[nodiscard]] static int modifyIpRule(uint16_t action, uint32_t priority, uint32_t table,
+[[nodiscard]] static int modifyIpRule(uint16_t action, int32_t priority, uint32_t table,
uint32_t fwmark, uint32_t mask) {
return modifyIpRule(action, priority, table, fwmark, mask, IIF_NONE, OIF_NONE, INVALID_UID,
INVALID_UID);
@@ -346,7 +361,7 @@
// Adds or deletes an IPv4 or IPv6 route.
// Returns 0 on success or negative errno on failure.
int modifyIpRoute(uint16_t action, uint16_t flags, uint32_t table, const char* interface,
- const char* destination, const char* nexthop, uint32_t mtu) {
+ const char* destination, const char* nexthop, uint32_t mtu, uint32_t priority) {
// At least the destination must be non-null.
if (!destination) {
ALOGE("null destination");
@@ -387,7 +402,8 @@
} else {
// If an interface was specified, find the ifindex.
if (interface != OIF_NONE) {
- ifindex = if_nametoindex(interface);
+ ifindex = RouteController::ifNameToIndexFunction(interface);
+
if (!ifindex) {
ALOGE("cannot find interface %s", interface);
return -ENODEV;
@@ -401,8 +417,6 @@
}
}
- bool isDefaultThrowRoute = (type == RTN_THROW && prefixLength == 0);
-
// Assemble a rtmsg and put it in an array of iovec structures.
rtmsg route = {
.rtm_family = family,
@@ -416,21 +430,21 @@
rtattr rtaGateway = { U16_RTA_LENGTH(rawLength), RTA_GATEWAY };
iovec iov[] = {
- { nullptr, 0 },
- { &route, sizeof(route) },
- { &RTATTR_TABLE, sizeof(RTATTR_TABLE) },
- { &table, sizeof(table) },
- { &rtaDst, sizeof(rtaDst) },
- { rawAddress, static_cast<size_t>(rawLength) },
- { &RTATTR_OIF, interface != OIF_NONE ? sizeof(RTATTR_OIF) : 0 },
- { &ifindex, interface != OIF_NONE ? sizeof(ifindex) : 0 },
- { &rtaGateway, nexthop ? sizeof(rtaGateway) : 0 },
- { rawNexthop, nexthop ? static_cast<size_t>(rawLength) : 0 },
- { &RTATTR_METRICS, mtu != 0 ? sizeof(RTATTR_METRICS) : 0 },
- { &RTATTRX_MTU, mtu != 0 ? sizeof(RTATTRX_MTU) : 0 },
- { &mtu, mtu != 0 ? sizeof(mtu) : 0 },
- { &RTATTR_PRIO, isDefaultThrowRoute ? sizeof(RTATTR_PRIO) : 0 },
- { &PRIO_THROW, isDefaultThrowRoute ? sizeof(PRIO_THROW) : 0 },
+ {nullptr, 0},
+ {&route, sizeof(route)},
+ {&RTATTR_TABLE, sizeof(RTATTR_TABLE)},
+ {&table, sizeof(table)},
+ {&rtaDst, sizeof(rtaDst)},
+ {rawAddress, static_cast<size_t>(rawLength)},
+ {&RTATTR_OIF, interface != OIF_NONE ? sizeof(RTATTR_OIF) : 0},
+ {&ifindex, interface != OIF_NONE ? sizeof(ifindex) : 0},
+ {&rtaGateway, nexthop ? sizeof(rtaGateway) : 0},
+ {rawNexthop, nexthop ? static_cast<size_t>(rawLength) : 0},
+ {&RTATTR_METRICS, mtu != 0 ? sizeof(RTATTR_METRICS) : 0},
+ {&RTATTRX_MTU, mtu != 0 ? sizeof(RTATTRX_MTU) : 0},
+ {&mtu, mtu != 0 ? sizeof(mtu) : 0},
+ {&RTATTR_PRIO, priority != 0 ? sizeof(RTATTR_PRIO) : 0},
+ {&priority, priority != 0 ? sizeof(priority) : 0},
};
// Allow creating multiple link-local routes in the same table, so we can make IPv6
@@ -492,19 +506,21 @@
// have, if they are subject to this VPN, their traffic has to go through it. Allows the traffic to
// bypass the VPN if the protectedFromVpn bit is set.
[[nodiscard]] static int modifyVpnUidRangeRule(uint32_t table, uid_t uidStart, uid_t uidEnd,
- uint32_t subPriority, bool secure, bool add) {
+ int32_t subPriority, bool secure, bool add,
+ bool excludeLocalRoutes) {
Fwmark fwmark;
Fwmark mask;
fwmark.protectedFromVpn = false;
mask.protectedFromVpn = true;
- uint32_t priority;
+ int32_t priority;
if (secure) {
priority = RULE_PRIORITY_SECURE_VPN;
} else {
- priority = RULE_PRIORITY_BYPASSABLE_VPN;
+ priority = excludeLocalRoutes ? RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION
+ : RULE_PRIORITY_BYPASSABLE_VPN_NO_LOCAL_EXCLUSION;
fwmark.explicitlySelected = false;
mask.explicitlySelected = true;
@@ -520,7 +536,7 @@
// This is needed for DnsProxyListener to correctly resolve a request for a user who is in the
// target set, but where the DnsProxyListener itself is not.
[[nodiscard]] static int modifyVpnSystemPermissionRule(unsigned netId, uint32_t table, bool secure,
- bool add) {
+ bool add, bool excludeLocalRoutes) {
Fwmark fwmark;
Fwmark mask;
@@ -530,7 +546,14 @@
fwmark.permission = PERMISSION_SYSTEM;
mask.permission = PERMISSION_SYSTEM;
- uint32_t priority = secure ? RULE_PRIORITY_SECURE_VPN : RULE_PRIORITY_BYPASSABLE_VPN;
+ uint32_t priority;
+
+ if (secure) {
+ priority = RULE_PRIORITY_SECURE_VPN;
+ } else {
+ priority = excludeLocalRoutes ? RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION
+ : RULE_PRIORITY_BYPASSABLE_VPN_NO_LOCAL_EXCLUSION;
+ }
return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, priority, table, fwmark.intValue,
mask.intValue);
@@ -545,7 +568,7 @@
// modifyNetworkPermission().
[[nodiscard]] static int modifyExplicitNetworkRule(unsigned netId, uint32_t table,
Permission permission, uid_t uidStart,
- uid_t uidEnd, uint32_t subPriority, bool add) {
+ uid_t uidEnd, int32_t subPriority, bool add) {
Fwmark fwmark;
Fwmark mask;
@@ -569,7 +592,7 @@
// the outgoing interface (typically for link-local communications).
[[nodiscard]] static int modifyOutputInterfaceRules(const char* interface, uint32_t table,
Permission permission, uid_t uidStart,
- uid_t uidEnd, uint32_t subPriority, bool add) {
+ uid_t uidEnd, int32_t subPriority, bool add) {
Fwmark fwmark;
Fwmark mask;
@@ -615,6 +638,26 @@
INVALID_UID);
}
+int RouteController::modifyVpnLocalExclusionRule(bool add, const char* physicalInterface) {
+ uint32_t table = getRouteTableForInterface(physicalInterface, true /* local */);
+ if (table == RT_TABLE_UNSPEC) {
+ return -ESRCH;
+ }
+
+ Fwmark fwmark;
+ Fwmark mask;
+
+ fwmark.explicitlySelected = false;
+ mask.explicitlySelected = true;
+
+ fwmark.permission = PERMISSION_NONE;
+ mask.permission = PERMISSION_NONE;
+
+ return modifyIpRule(add ? RTM_NEWRULE : RTM_DELRULE, RULE_PRIORITY_LOCAL_ROUTES, table,
+ fwmark.intValue, mask.intValue, IIF_LOOPBACK, OIF_NONE, INVALID_UID,
+ INVALID_UID);
+}
+
// A rule to enable split tunnel VPNs.
//
// If a packet with a VPN's netId doesn't find a route in the VPN's routing table, it's allowed to
@@ -622,7 +665,7 @@
int RouteController::modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
const char* physicalInterface,
Permission permission) {
- uint32_t table = getRouteTableForInterface(physicalInterface);
+ uint32_t table = getRouteTableForInterface(physicalInterface, false /* local */);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
}
@@ -670,7 +713,7 @@
[[nodiscard]] static int addLocalNetworkRules(unsigned localNetId) {
if (int ret = modifyExplicitNetworkRule(localNetId, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE,
INVALID_UID, INVALID_UID,
- UidRanges::DEFAULT_SUB_PRIORITY, ACTION_ADD)) {
+ UidRanges::SUB_PRIORITY_HIGHEST, ACTION_ADD)) {
return ret;
}
@@ -687,7 +730,7 @@
/* static */
int RouteController::configureDummyNetwork() {
const char *interface = DummyNetwork::INTERFACE_NAME;
- uint32_t table = getRouteTableForInterface(interface);
+ uint32_t table = getRouteTableForInterface(interface, false /* local */);
if (table == RT_TABLE_UNSPEC) {
// getRouteTableForInterface has already logged an error.
return -ESRCH;
@@ -702,19 +745,19 @@
}
if ((ret = modifyOutputInterfaceRules(interface, table, PERMISSION_NONE, INVALID_UID,
- INVALID_UID, UidRanges::DEFAULT_SUB_PRIORITY,
+ INVALID_UID, UidRanges::SUB_PRIORITY_HIGHEST,
ACTION_ADD))) {
ALOGE("Can't create oif rules for %s: %s", interface, strerror(-ret));
return ret;
}
if ((ret = modifyIpRoute(RTM_NEWROUTE, NETLINK_ROUTE_CREATE_FLAGS, table, interface,
- "0.0.0.0/0", nullptr, 0 /* mtu */))) {
+ "0.0.0.0/0", nullptr, 0 /* mtu */, 0 /* priority */))) {
return ret;
}
if ((ret = modifyIpRoute(RTM_NEWROUTE, NETLINK_ROUTE_CREATE_FLAGS, table, interface, "::/0",
- nullptr, 0 /* mtu */))) {
+ nullptr, 0 /* mtu */, 0 /* priority */))) {
return ret;
}
@@ -736,12 +779,12 @@
}
maybeModifyQdiscClsact(interface, add);
return modifyOutputInterfaceRules(interface, ROUTE_TABLE_LOCAL_NETWORK, PERMISSION_NONE,
- INVALID_UID, INVALID_UID, UidRanges::DEFAULT_SUB_PRIORITY,
+ INVALID_UID, INVALID_UID, UidRanges::SUB_PRIORITY_HIGHEST,
add);
}
[[nodiscard]] static int modifyUidNetworkRule(unsigned netId, uint32_t table, uid_t uidStart,
- uid_t uidEnd, uint32_t subPriority, bool add,
+ uid_t uidEnd, int32_t subPriority, bool add,
bool explicitSelect) {
if ((uidStart == INVALID_UID) || (uidEnd == INVALID_UID)) {
ALOGE("modifyUidNetworkRule, invalid UIDs (%u, %u)", uidStart, uidEnd);
@@ -769,7 +812,7 @@
}
[[nodiscard]] static int modifyUidDefaultNetworkRule(uint32_t table, uid_t uidStart, uid_t uidEnd,
- uint32_t subPriority, bool add) {
+ int32_t subPriority, bool add) {
if ((uidStart == INVALID_UID) || (uidEnd == INVALID_UID)) {
ALOGE("modifyUidDefaultNetworkRule, invalid UIDs (%u, %u)", uidStart, uidEnd);
return -EUSERS;
@@ -794,7 +837,7 @@
int RouteController::modifyPhysicalNetwork(unsigned netId, const char* interface,
const UidRangeMap& uidRangeMap, Permission permission,
bool add, bool modifyNonUidBasedRules) {
- uint32_t table = getRouteTableForInterface(interface);
+ uint32_t table = getRouteTableForInterface(interface, false /* local */);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
}
@@ -809,9 +852,13 @@
add, IMPLICIT)) {
return ret;
}
- if (int ret = modifyUidDefaultNetworkRule(table, range.start, range.stop, subPriority,
- add)) {
- return ret;
+ // SUB_PRIORITY_NO_DEFAULT is "special" and does not require a
+ // default network rule, see UidRanges.h.
+ if (subPriority != UidRanges::SUB_PRIORITY_NO_DEFAULT) {
+ if (int ret = modifyUidDefaultNetworkRule(table, range.start, range.stop,
+ subPriority, add)) {
+ return ret;
+ }
}
}
}
@@ -825,11 +872,11 @@
return ret;
}
if (int ret = modifyExplicitNetworkRule(netId, table, permission, INVALID_UID, INVALID_UID,
- UidRanges::DEFAULT_SUB_PRIORITY, add)) {
+ UidRanges::SUB_PRIORITY_HIGHEST, add)) {
return ret;
}
if (int ret = modifyOutputInterfaceRules(interface, table, permission, INVALID_UID, INVALID_UID,
- UidRanges::DEFAULT_SUB_PRIORITY, add)) {
+ UidRanges::SUB_PRIORITY_HIGHEST, add)) {
return ret;
}
@@ -860,7 +907,7 @@
}
[[nodiscard]] static int modifyUidUnreachableRule(unsigned netId, uid_t uidStart, uid_t uidEnd,
- uint32_t subPriority, bool add,
+ int32_t subPriority, bool add,
bool explicitSelect) {
if ((uidStart == INVALID_UID) || (uidEnd == INVALID_UID)) {
ALOGE("modifyUidUnreachableRule, invalid UIDs (%u, %u)", uidStart, uidEnd);
@@ -888,7 +935,7 @@
}
[[nodiscard]] static int modifyUidDefaultUnreachableRule(uid_t uidStart, uid_t uidEnd,
- uint32_t subPriority, bool add) {
+ int32_t subPriority, bool add) {
if ((uidStart == INVALID_UID) || (uidEnd == INVALID_UID)) {
ALOGE("modifyUidDefaultUnreachableRule, invalid UIDs (%u, %u)", uidStart, uidEnd);
return -EUSERS;
@@ -951,8 +998,8 @@
int RouteController::modifyVirtualNetwork(unsigned netId, const char* interface,
const UidRangeMap& uidRangeMap, bool secure, bool add,
- bool modifyNonUidBasedRules) {
- uint32_t table = getRouteTableForInterface(interface);
+ bool modifyNonUidBasedRules, bool excludeLocalRoutes) {
+ uint32_t table = getRouteTableForInterface(interface, false /* false */);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
}
@@ -960,7 +1007,7 @@
for (const auto& [subPriority, uidRanges] : uidRangeMap) {
for (const UidRangeParcel& range : uidRanges.getRanges()) {
if (int ret = modifyVpnUidRangeRule(table, range.start, range.stop, subPriority, secure,
- add)) {
+ add, excludeLocalRoutes)) {
return ret;
}
if (int ret = modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, range.start,
@@ -981,11 +1028,12 @@
if (int ret = modifyVpnOutputToLocalRule(interface, add)) {
return ret;
}
- if (int ret = modifyVpnSystemPermissionRule(netId, table, secure, add)) {
+ if (int ret =
+ modifyVpnSystemPermissionRule(netId, table, secure, add, excludeLocalRoutes)) {
return ret;
}
return modifyExplicitNetworkRule(netId, table, PERMISSION_NONE, UID_ROOT, UID_ROOT,
- UidRanges::DEFAULT_SUB_PRIORITY, add);
+ UidRanges::SUB_PRIORITY_HIGHEST, add);
}
return 0;
@@ -993,7 +1041,7 @@
int RouteController::modifyDefaultNetwork(uint16_t action, const char* interface,
Permission permission) {
- uint32_t table = getRouteTableForInterface(interface);
+ uint32_t table = getRouteTableForInterface(interface, false /* local */);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
}
@@ -1013,7 +1061,7 @@
int RouteController::modifyTetheredNetwork(uint16_t action, const char* inputInterface,
const char* outputInterface) {
- uint32_t table = getRouteTableForInterface(outputInterface);
+ uint32_t table = getRouteTableForInterface(outputInterface, false /* local */);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
}
@@ -1026,11 +1074,11 @@
// Returns 0 on success or negative errno on failure.
int RouteController::modifyRoute(uint16_t action, uint16_t flags, const char* interface,
const char* destination, const char* nexthop, TableType tableType,
- int mtu) {
+ int mtu, int priority) {
uint32_t table;
switch (tableType) {
case RouteController::INTERFACE: {
- table = getRouteTableForInterface(interface);
+ table = getRouteTableForInterface(interface, false /* local */);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
}
@@ -1050,7 +1098,7 @@
}
}
- int ret = modifyIpRoute(action, flags, table, interface, destination, nexthop, mtu);
+ int ret = modifyIpRoute(action, flags, table, interface, destination, nexthop, mtu, priority);
// Trying to add a route that already exists shouldn't cause an error.
if (ret && !(action == RTM_NEWROUTE && ret == -EEXIST)) {
return ret;
@@ -1068,7 +1116,7 @@
if (StartsWith(interface, "v4-") && add) return;
// The interface may have already gone away in the delete case.
- uint32_t ifindex = if_nametoindex(interface);
+ uint32_t ifindex = RouteController::ifNameToIndexFunction(interface);
if (!ifindex) {
ALOGE("cannot find interface %s", interface);
return;
@@ -1127,11 +1175,22 @@
return rtNetlinkFlush(RTM_GETROUTE, RTM_DELROUTE, "routes", shouldDelete);
}
-// Returns 0 on success or negative errno on failure.
int RouteController::flushRoutes(const char* interface) {
+ // Try to flush both local and global routing tables.
+ //
+ // Flush local first because flush global routing tables may erase the sInterfaceToTable map.
+ // Then the fake <iface>_local interface will be unable to find the index because the local
+ // interface depends physical interface to find the correct index.
+ int ret = flushRoutes(interface, true);
+ ret |= flushRoutes(interface, false);
+ return ret;
+}
+
+// Returns 0 on success or negative errno on failure.
+int RouteController::flushRoutes(const char* interface, bool local) {
std::lock_guard lock(sInterfaceToTableLock);
- uint32_t table = getRouteTableForInterfaceLocked(interface);
+ uint32_t table = getRouteTableForInterfaceLocked(interface, local);
if (table == RT_TABLE_UNSPEC) {
return -ESRCH;
}
@@ -1140,7 +1199,8 @@
// If we failed to flush routes, the caller may elect to keep this interface around, so keep
// track of its name.
- if (ret == 0) {
+ // Skip erasing local fake interface since it does not exist in sInterfaceToTable.
+ if (ret == 0 && !local) {
sInterfaceToTable.erase(interface);
}
@@ -1192,6 +1252,7 @@
MODIFY_NON_UID_BASED_RULES)) {
return ret;
}
+
maybeModifyQdiscClsact(interface, ACTION_ADD);
updateTableNamesFile();
return 0;
@@ -1204,21 +1265,25 @@
MODIFY_NON_UID_BASED_RULES)) {
return ret;
}
+
if (int ret = flushRoutes(interface)) {
return ret;
}
+
if (int ret = clearTetheringRules(interface)) {
return ret;
}
+
maybeModifyQdiscClsact(interface, ACTION_DEL);
updateTableNamesFile();
return 0;
}
int RouteController::addInterfaceToVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRangeMap& uidRangeMap) {
+ bool secure, const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes) {
if (int ret = modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_ADD,
- MODIFY_NON_UID_BASED_RULES)) {
+ MODIFY_NON_UID_BASED_RULES, excludeLocalRoutes)) {
return ret;
}
updateTableNamesFile();
@@ -1226,10 +1291,10 @@
}
int RouteController::removeInterfaceFromVirtualNetwork(unsigned netId, const char* interface,
- bool secure,
- const UidRangeMap& uidRangeMap) {
+ bool secure, const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes) {
if (int ret = modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_DEL,
- MODIFY_NON_UID_BASED_RULES)) {
+ MODIFY_NON_UID_BASED_RULES, excludeLocalRoutes)) {
return ret;
}
if (int ret = flushRoutes(interface)) {
@@ -1263,15 +1328,17 @@
}
int RouteController::addUsersToVirtualNetwork(unsigned netId, const char* interface, bool secure,
- const UidRangeMap& uidRangeMap) {
+ const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes) {
return modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_ADD,
- !MODIFY_NON_UID_BASED_RULES);
+ !MODIFY_NON_UID_BASED_RULES, excludeLocalRoutes);
}
int RouteController::removeUsersFromVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRangeMap& uidRangeMap) {
+ bool secure, const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes) {
return modifyVirtualNetwork(netId, interface, uidRangeMap, secure, ACTION_DEL,
- !MODIFY_NON_UID_BASED_RULES);
+ !MODIFY_NON_UID_BASED_RULES, excludeLocalRoutes);
}
int RouteController::addInterfaceToDefaultNetwork(const char* interface, Permission permission) {
@@ -1284,21 +1351,21 @@
}
int RouteController::addRoute(const char* interface, const char* destination, const char* nexthop,
- TableType tableType, int mtu) {
+ TableType tableType, int mtu, int priority) {
return modifyRoute(RTM_NEWROUTE, NETLINK_ROUTE_CREATE_FLAGS, interface, destination, nexthop,
- tableType, mtu);
+ tableType, mtu, priority);
}
int RouteController::removeRoute(const char* interface, const char* destination,
- const char* nexthop, TableType tableType) {
+ const char* nexthop, TableType tableType, int priority) {
return modifyRoute(RTM_DELROUTE, NETLINK_REQUEST_FLAGS, interface, destination, nexthop,
- tableType, 0);
+ tableType, 0 /* mtu */, priority);
}
int RouteController::updateRoute(const char* interface, const char* destination,
const char* nexthop, TableType tableType, int mtu) {
return modifyRoute(RTM_NEWROUTE, NETLINK_ROUTE_REPLACE_FLAGS, interface, destination, nexthop,
- tableType, mtu);
+ tableType, mtu, 0 /* priority */);
}
int RouteController::enableTethering(const char* inputInterface, const char* outputInterface) {
@@ -1311,13 +1378,21 @@
int RouteController::addVirtualNetworkFallthrough(unsigned vpnNetId, const char* physicalInterface,
Permission permission) {
- return modifyVpnFallthroughRule(RTM_NEWRULE, vpnNetId, physicalInterface, permission);
+ if (int ret = modifyVpnFallthroughRule(RTM_NEWRULE, vpnNetId, physicalInterface, permission)) {
+ return ret;
+ }
+
+ return modifyVpnLocalExclusionRule(true /* add */, physicalInterface);
}
int RouteController::removeVirtualNetworkFallthrough(unsigned vpnNetId,
const char* physicalInterface,
Permission permission) {
- return modifyVpnFallthroughRule(RTM_DELRULE, vpnNetId, physicalInterface, permission);
+ if (int ret = modifyVpnFallthroughRule(RTM_DELRULE, vpnNetId, physicalInterface, permission)) {
+ return ret;
+ }
+
+ return modifyVpnLocalExclusionRule(false /* add */, physicalInterface);
}
int RouteController::addUsersToPhysicalNetwork(unsigned netId, const char* interface,
diff --git a/server/RouteController.h b/server/RouteController.h
index 38d2d62..9b04cfd 100644
--- a/server/RouteController.h
+++ b/server/RouteController.h
@@ -16,8 +16,9 @@
#pragma once
-#include "NetdConstants.h" // IptablesTarget
-#include "Network.h" // UidRangeMap
+#include "InterfaceController.h" // getParameter
+#include "NetdConstants.h" // IptablesTarget
+#include "Network.h" // UidRangeMap
#include "Permission.h"
#include <android-base/thread_annotations.h>
@@ -30,11 +31,11 @@
namespace android::net {
// clang-format off
-const uint32_t RULE_PRIORITY_VPN_OVERRIDE_SYSTEM = 10000;
-const uint32_t RULE_PRIORITY_VPN_OVERRIDE_OIF = 11000;
-const uint32_t RULE_PRIORITY_VPN_OUTPUT_TO_LOCAL = 12000;
-const uint32_t RULE_PRIORITY_SECURE_VPN = 13000;
-const uint32_t RULE_PRIORITY_PROHIBIT_NON_VPN = 14000;
+constexpr int32_t RULE_PRIORITY_VPN_OVERRIDE_SYSTEM = 10000;
+constexpr int32_t RULE_PRIORITY_VPN_OVERRIDE_OIF = 11000;
+constexpr int32_t RULE_PRIORITY_VPN_OUTPUT_TO_LOCAL = 12000;
+constexpr int32_t RULE_PRIORITY_SECURE_VPN = 13000;
+constexpr int32_t RULE_PRIORITY_PROHIBIT_NON_VPN = 14000;
// Rules used when applications explicitly select a network that they have permission to use only
// because they are in the list of UID ranges for that network.
//
@@ -42,21 +43,23 @@
// not have the necessary permission bits in the fwmark. We cannot just give any socket on any of
// these networks the permission bits, because if the UID that created the socket loses access to
// the network, then the socket must not match any rule that selects that network.
-const uint32_t RULE_PRIORITY_UID_EXPLICIT_NETWORK = 15000;
-const uint32_t RULE_PRIORITY_EXPLICIT_NETWORK = 16000;
-const uint32_t RULE_PRIORITY_OUTPUT_INTERFACE = 17000;
-const uint32_t RULE_PRIORITY_LEGACY_SYSTEM = 18000;
-const uint32_t RULE_PRIORITY_LEGACY_NETWORK = 19000;
-const uint32_t RULE_PRIORITY_LOCAL_NETWORK = 20000;
-const uint32_t RULE_PRIORITY_TETHERING = 21000;
+constexpr int32_t RULE_PRIORITY_UID_EXPLICIT_NETWORK = 15000;
+constexpr int32_t RULE_PRIORITY_EXPLICIT_NETWORK = 16000;
+constexpr int32_t RULE_PRIORITY_OUTPUT_INTERFACE = 17000;
+constexpr int32_t RULE_PRIORITY_LEGACY_SYSTEM = 18000;
+constexpr int32_t RULE_PRIORITY_LEGACY_NETWORK = 19000;
+constexpr int32_t RULE_PRIORITY_LOCAL_NETWORK = 20000;
+constexpr int32_t RULE_PRIORITY_TETHERING = 21000;
// Implicit rules for sockets that connected on a given network because the network was the default
// network for the UID.
-const uint32_t RULE_PRIORITY_UID_IMPLICIT_NETWORK = 22000;
-const uint32_t RULE_PRIORITY_IMPLICIT_NETWORK = 23000;
-const uint32_t RULE_PRIORITY_BYPASSABLE_VPN = 24000;
-// reserved for RULE_PRIORITY_UID_VPN_FALLTHROUGH = 25000;
-const uint32_t RULE_PRIORITY_VPN_FALLTHROUGH = 26000;
-const uint32_t RULE_PRIORITY_UID_DEFAULT_NETWORK = 27000;
+constexpr int32_t RULE_PRIORITY_UID_IMPLICIT_NETWORK = 22000;
+constexpr int32_t RULE_PRIORITY_IMPLICIT_NETWORK = 23000;
+constexpr int32_t RULE_PRIORITY_BYPASSABLE_VPN_NO_LOCAL_EXCLUSION = 24000;
+// Rules used for excluding local route in the VPN network.
+constexpr int32_t RULE_PRIORITY_LOCAL_ROUTES = 25000;
+constexpr int32_t RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION = 26000;
+constexpr int32_t RULE_PRIORITY_VPN_FALLTHROUGH = 27000;
+constexpr int32_t RULE_PRIORITY_UID_DEFAULT_NETWORK = 28000;
// Rule used when framework wants to disable default network from specified applications. There will
// be a small interval the same uid range exists in both UID_DEFAULT_UNREACHABLE and
// UID_DEFAULT_NETWORK when framework is switching user preferences.
@@ -71,9 +74,9 @@
// The priority is lower than UID_DEFAULT_NETWORK. Otherwise, the app will be told by
// ConnectivityService that it has a network in step 1 of the second case. But if it tries to use
// the network, it will not work. That will potentially cause a user-visible error.
-const uint32_t RULE_PRIORITY_UID_DEFAULT_UNREACHABLE = 28000;
-const uint32_t RULE_PRIORITY_DEFAULT_NETWORK = 29000;
-const uint32_t RULE_PRIORITY_UNREACHABLE = 32000;
+constexpr int32_t RULE_PRIORITY_UID_DEFAULT_UNREACHABLE = 29000;
+constexpr int32_t RULE_PRIORITY_DEFAULT_NETWORK = 30000;
+constexpr int32_t RULE_PRIORITY_UNREACHABLE = 32000;
// clang-format on
class UidRanges;
@@ -89,7 +92,11 @@
};
static const int ROUTE_TABLE_OFFSET_FROM_INDEX = 1000;
+ // Offset for the table of virtual local network created from the physical interface.
+ static const int ROUTE_TABLE_OFFSET_FROM_INDEX_FOR_LOCAL = 1000000000;
+ static constexpr const char* INTERFACE_LOCAL_SUFFIX = "_local";
+ static constexpr const char* RT_TABLES_PATH = "/data/misc/net/rt_tables";
static const char* const LOCAL_MANGLE_INPUT;
[[nodiscard]] static int Init(unsigned localNetId);
@@ -116,20 +123,24 @@
[[nodiscard]] static int addInterfaceToVirtualNetwork(unsigned netId, const char* interface,
bool secure,
- const UidRangeMap& uidRangeMap);
+ const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes);
[[nodiscard]] static int removeInterfaceFromVirtualNetwork(unsigned netId,
const char* interface, bool secure,
- const UidRangeMap& uidRangeMap);
+ const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes);
[[nodiscard]] static int modifyPhysicalNetworkPermission(unsigned netId, const char* interface,
Permission oldPermission,
Permission newPermission);
[[nodiscard]] static int addUsersToVirtualNetwork(unsigned netId, const char* interface,
- bool secure, const UidRangeMap& uidRangeMap);
+ bool secure, const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes);
[[nodiscard]] static int removeUsersFromVirtualNetwork(unsigned netId, const char* interface,
bool secure,
- const UidRangeMap& uidRangeMap);
+ const UidRangeMap& uidRangeMap,
+ bool excludeLocalRoutes);
[[nodiscard]] static int addUsersToRejectNonSecureNetworkRule(const UidRanges& uidRanges);
[[nodiscard]] static int removeUsersFromRejectNonSecureNetworkRule(const UidRanges& uidRanges);
@@ -142,9 +153,10 @@
// |nexthop| can be NULL (to indicate a directly-connected route), "unreachable" (to indicate a
// route that's blocked), "throw" (to indicate the lack of a match), or a regular IP address.
[[nodiscard]] static int addRoute(const char* interface, const char* destination,
- const char* nexthop, TableType tableType, int mtu);
+ const char* nexthop, TableType tableType, int mtu,
+ int priority);
[[nodiscard]] static int removeRoute(const char* interface, const char* destination,
- const char* nexthop, TableType tableType);
+ const char* nexthop, TableType tableType, int priority);
[[nodiscard]] static int updateRoute(const char* interface, const char* destination,
const char* nexthop, TableType tableType, int mtu);
@@ -175,8 +187,9 @@
// For testing.
static int (*iptablesRestoreCommandFunction)(IptablesTarget, const std::string&,
const std::string&, std::string *);
+ static uint32_t (*ifNameToIndexFunction)(const char*);
-private:
+ private:
friend class RouteControllerTest;
static std::mutex sInterfaceToTableLock;
@@ -184,10 +197,13 @@
static int configureDummyNetwork();
[[nodiscard]] static int flushRoutes(const char* interface) EXCLUDES(sInterfaceToTableLock);
+ [[nodiscard]] static int flushRoutes(const char* interface, bool local)
+ EXCLUDES(sInterfaceToTableLock);
[[nodiscard]] static int flushRoutes(uint32_t table);
- static uint32_t getRouteTableForInterfaceLocked(const char* interface)
+ static uint32_t getRouteTableForInterfaceLocked(const char* interface, bool local)
REQUIRES(sInterfaceToTableLock);
- static uint32_t getRouteTableForInterface(const char *interface) EXCLUDES(sInterfaceToTableLock);
+ static uint32_t getRouteTableForInterface(const char* interface, bool local)
+ EXCLUDES(sInterfaceToTableLock);
static int modifyDefaultNetwork(uint16_t action, const char* interface, Permission permission);
static int modifyPhysicalNetwork(unsigned netId, const char* interface,
const UidRangeMap& uidRangeMap, Permission permission,
@@ -195,15 +211,16 @@
static int modifyUnreachableNetwork(unsigned netId, const UidRangeMap& uidRangeMap, bool add);
static int modifyRoute(uint16_t action, uint16_t flags, const char* interface,
const char* destination, const char* nexthop, TableType tableType,
- int mtu);
+ int mtu, int priority);
static int modifyTetheredNetwork(uint16_t action, const char* inputInterface,
const char* outputInterface);
static int modifyVpnFallthroughRule(uint16_t action, unsigned vpnNetId,
const char* physicalInterface, Permission permission);
static int modifyVirtualNetwork(unsigned netId, const char* interface,
const UidRangeMap& uidRangeMap, bool secure, bool add,
- bool modifyNonUidBasedRules);
+ bool modifyNonUidBasedRules, bool excludeLocalRoutes);
static void updateTableNamesFile() EXCLUDES(sInterfaceToTableLock);
+ static int modifyVpnLocalExclusionRule(bool add, const char* physicalInterface);
};
// Public because they are called by by RouteControllerTest.cpp.
@@ -211,7 +228,7 @@
// functions public.
[[nodiscard]] int modifyIpRoute(uint16_t action, uint16_t flags, uint32_t table,
const char* interface, const char* destination, const char* nexthop,
- uint32_t mtu);
+ uint32_t mtu, uint32_t priority);
uint32_t getRulePriority(const nlmsghdr *nlh);
[[nodiscard]] int modifyIncomingPacketMark(unsigned netId, const char* interface,
Permission permission, bool add);
diff --git a/server/RouteControllerTest.cpp b/server/RouteControllerTest.cpp
index e85a83c..8bdc879 100644
--- a/server/RouteControllerTest.cpp
+++ b/server/RouteControllerTest.cpp
@@ -17,6 +17,7 @@
*/
#include <gtest/gtest.h>
+#include <fstream>
#include "Fwmark.h"
#include "IptablesBaseTest.h"
@@ -27,6 +28,13 @@
using android::base::StringPrintf;
+static const char* TEST_IFACE1 = "netdtest1";
+static const char* TEST_IFACE2 = "netdtest2";
+static const uint32_t TEST_IFACE1_INDEX = 901;
+static const uint32_t TEST_IFACE2_INDEX = 902;
+// See Linux kernel source in include/net/flow.h
+#define LOOPBACK_IFINDEX 1
+
namespace android {
namespace net {
@@ -34,11 +42,20 @@
public:
RouteControllerTest() {
RouteController::iptablesRestoreCommandFunction = fakeExecIptablesRestoreCommand;
+ RouteController::ifNameToIndexFunction = fakeIfaceNameToIndexFunction;
}
int flushRoutes(uint32_t a) {
return RouteController::flushRoutes(a);
}
+
+ uint32_t static fakeIfaceNameToIndexFunction(const char* iface) {
+ // "lo" is the same as the real one
+ if (!strcmp(iface, "lo")) return LOOPBACK_IFINDEX;
+ if (!strcmp(iface, TEST_IFACE1)) return TEST_IFACE1_INDEX;
+ if (!strcmp(iface, TEST_IFACE2)) return TEST_IFACE2_INDEX;
+ return 0;
+ }
};
TEST_F(RouteControllerTest, TestGetRulePriority) {
@@ -80,23 +97,20 @@
"Test table2 number too large");
EXPECT_EQ(0, modifyIpRoute(RTM_NEWROUTE, NETLINK_ROUTE_CREATE_FLAGS, table1, "lo",
- "192.0.2.2/32", nullptr, 0 /* mtu */));
+ "192.0.2.2/32", nullptr, 0 /* mtu */, 0 /* priority */));
EXPECT_EQ(0, modifyIpRoute(RTM_NEWROUTE, NETLINK_ROUTE_CREATE_FLAGS, table1, "lo",
- "192.0.2.3/32", nullptr, 0 /* mtu */));
+ "192.0.2.3/32", nullptr, 0 /* mtu */, 0 /* priority */));
EXPECT_EQ(0, modifyIpRoute(RTM_NEWROUTE, NETLINK_ROUTE_CREATE_FLAGS, table2, "lo",
- "192.0.2.4/32", nullptr, 0 /* mtu */));
+ "192.0.2.4/32", nullptr, 0 /* mtu */, 0 /* priority */));
EXPECT_EQ(0, flushRoutes(table1));
- EXPECT_EQ(-ESRCH,
- modifyIpRoute(RTM_DELROUTE, NETLINK_ROUTE_CREATE_FLAGS, table1, "lo", "192.0.2.2/32",
- nullptr, 0 /* mtu */));
- EXPECT_EQ(-ESRCH,
- modifyIpRoute(RTM_DELROUTE, NETLINK_ROUTE_CREATE_FLAGS, table1, "lo", "192.0.2.3/32",
- nullptr, 0 /* mtu */));
- EXPECT_EQ(0,
- modifyIpRoute(RTM_DELROUTE, NETLINK_ROUTE_CREATE_FLAGS, table2, "lo", "192.0.2.4/32",
- nullptr, 0 /* mtu */));
+ EXPECT_EQ(-ESRCH, modifyIpRoute(RTM_DELROUTE, NETLINK_ROUTE_CREATE_FLAGS, table1, "lo",
+ "192.0.2.2/32", nullptr, 0 /* mtu */, 0 /* priority */));
+ EXPECT_EQ(-ESRCH, modifyIpRoute(RTM_DELROUTE, NETLINK_ROUTE_CREATE_FLAGS, table1, "lo",
+ "192.0.2.3/32", nullptr, 0 /* mtu */, 0 /* priority */));
+ EXPECT_EQ(0, modifyIpRoute(RTM_DELROUTE, NETLINK_ROUTE_CREATE_FLAGS, table2, "lo",
+ "192.0.2.4/32", nullptr, 0 /* mtu */, 0 /* priority */));
}
TEST_F(RouteControllerTest, TestModifyIncomingPacketMark) {
@@ -118,5 +132,46 @@
mask)});
}
+bool hasLocalInterfaceInRouteTable(const char* iface) {
+ // Calculate the table index from interface index
+ std::string index = std::to_string(RouteController::ROUTE_TABLE_OFFSET_FROM_INDEX_FOR_LOCAL +
+ RouteController::ifNameToIndexFunction(iface));
+ std::string localIface =
+ index + " " + std::string(iface) + std::string(RouteController::INTERFACE_LOCAL_SUFFIX);
+ std::string line;
+
+ std::ifstream input(RouteController::RT_TABLES_PATH);
+ while (std::getline(input, line)) {
+ if (line.find(localIface) != std::string::npos) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+TEST_F(RouteControllerTest, TestCreateVirtualLocalInterfaceTable) {
+ static constexpr int TEST_NETID = 65500;
+ std::map<int32_t, UidRanges> uidRangeMap;
+ EXPECT_EQ(0, RouteController::addInterfaceToVirtualNetwork(TEST_NETID, TEST_IFACE1, false,
+ uidRangeMap, false));
+ // Expect to create <iface>_local in the routing table
+ EXPECT_TRUE(hasLocalInterfaceInRouteTable(TEST_IFACE1));
+ // Add another interface, <TEST_IFACE2>_local should also be created
+ EXPECT_EQ(0, RouteController::addInterfaceToVirtualNetwork(TEST_NETID, TEST_IFACE2, false,
+ uidRangeMap, false));
+ EXPECT_TRUE(hasLocalInterfaceInRouteTable(TEST_IFACE2));
+ // Remove TEST_IFACE1
+ EXPECT_EQ(0, RouteController::removeInterfaceFromVirtualNetwork(TEST_NETID, TEST_IFACE1, false,
+ uidRangeMap, false));
+ // Interface remove should also remove the virtual local interface for routing table
+ EXPECT_FALSE(hasLocalInterfaceInRouteTable(TEST_IFACE1));
+ // <TEST_IFACE2> should still in the routing table
+ EXPECT_TRUE(hasLocalInterfaceInRouteTable(TEST_IFACE2));
+ EXPECT_EQ(0, RouteController::removeInterfaceFromVirtualNetwork(TEST_NETID, TEST_IFACE2, false,
+ uidRangeMap, false));
+ EXPECT_FALSE(hasLocalInterfaceInRouteTable(TEST_IFACE2));
+}
+
} // namespace net
} // namespace android
diff --git a/server/SockDiag.cpp b/server/SockDiag.cpp
index b3d9150..49ca8d7 100644
--- a/server/SockDiag.cpp
+++ b/server/SockDiag.cpp
@@ -133,7 +133,10 @@
}
request.nlh.nlmsg_len = len;
- if (writev(mSock, iov, iovcnt) != (ssize_t) len) {
+ ssize_t writevRet = writev(mSock, iov, iovcnt);
+ // Don't let pointers to the stack escape.
+ iov[0] = {nullptr, 0};
+ if (writevRet != (ssize_t)len) {
return -errno;
}
@@ -315,11 +318,12 @@
return ret;
}
- auto destroyAll = [ifindex](uint8_t, const inet_diag_msg* msg) {
+ // Destroy all sockets on the address, except link-local sockets where ifindex doesn't match.
+ auto shouldDestroy = [ifindex](uint8_t, const inet_diag_msg* msg) {
return ifindex == 0 || ifindex == (int)msg->id.idiag_if;
};
- return readDiagMsg(proto, destroyAll);
+ return readDiagMsg(proto, shouldDestroy);
}
int SockDiag::destroySockets(const char* addrstr, int ifindex) {
diff --git a/server/TcUtils.h b/server/TcUtils.h
new file mode 100644
index 0000000..d205c04
--- /dev/null
+++ b/server/TcUtils.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2019 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
+
+#include <android-base/result.h>
+#include <errno.h>
+#include <linux/if_ether.h>
+#include <linux/if_link.h>
+#include <linux/rtnetlink.h>
+#include <tcutils/tcutils.h>
+
+#include <string>
+
+#include "bpf/BpfUtils.h"
+#include "bpf_shared.h"
+
+namespace android {
+namespace net {
+
+// For better code clarity - do not change values - used for booleans like
+// with_ethernet_header or isEthernet.
+constexpr bool RAWIP = false;
+constexpr bool ETHER = true;
+
+// For better code clarity when used for 'bool ingress' parameter.
+constexpr bool EGRESS = false;
+constexpr bool INGRESS = true;
+
+// The priority of clat hook - must be after tethering.
+constexpr uint16_t PRIO_CLAT = 4;
+
+inline base::Result<bool> isEthernet(const std::string& interface) {
+ bool result = false;
+ if (int error = ::android::isEthernet(interface.c_str(), result)) {
+ errno = error;
+ return ErrnoErrorf("isEthernet failed for interface {}", interface);
+ }
+ return result;
+}
+
+inline int getClatEgress4MapFd(void) {
+ const int fd = bpf::mapRetrieveRW(CLAT_EGRESS4_MAP_PATH);
+ return (fd == -1) ? -errno : fd;
+}
+
+inline int getClatIngress6MapFd(void) {
+ const int fd = bpf::mapRetrieveRW(CLAT_INGRESS6_MAP_PATH);
+ return (fd == -1) ? -errno : fd;
+}
+
+inline int tcQdiscAddDevClsact(int ifIndex) {
+ return doTcQdiscClsact(ifIndex, RTM_NEWQDISC, NLM_F_EXCL | NLM_F_CREATE);
+}
+
+inline int tcQdiscReplaceDevClsact(int ifIndex) {
+ return doTcQdiscClsact(ifIndex, RTM_NEWQDISC, NLM_F_CREATE | NLM_F_REPLACE);
+}
+
+inline int tcQdiscDelDevClsact(int ifIndex) {
+ return doTcQdiscClsact(ifIndex, RTM_DELQDISC, 0);
+}
+
+// tc filter add dev .. ingress prio 4 protocol ipv6 bpf object-pinned /sys/fs/bpf/... direct-action
+inline int tcFilterAddDevIngressClatIpv6(int ifIndex, const std::string& bpfProgPath) {
+ return tcAddBpfFilter(ifIndex, INGRESS, PRIO_CLAT, ETH_P_IPV6, bpfProgPath.c_str());
+}
+
+// tc filter add dev .. egress prio 4 protocol ip bpf object-pinned /sys/fs/bpf/... direct-action
+inline int tcFilterAddDevEgressClatIpv4(int ifIndex, const std::string& bpfProgPath) {
+ return tcAddBpfFilter(ifIndex, EGRESS, PRIO_CLAT, ETH_P_IP, bpfProgPath.c_str());
+}
+
+// tc filter del dev .. ingress prio 4 protocol ipv6
+inline int tcFilterDelDevIngressClatIpv6(int ifIndex) {
+ return tcDeleteFilter(ifIndex, INGRESS, PRIO_CLAT, ETH_P_IPV6);
+}
+
+// tc filter del dev .. egress prio 4 protocol ip
+inline int tcFilterDelDevEgressClatIpv4(int ifIndex) {
+ return tcDeleteFilter(ifIndex, EGRESS, PRIO_CLAT, ETH_P_IP);
+}
+
+} // namespace net
+} // namespace android
diff --git a/server/TetherController.cpp b/server/TetherController.cpp
index 325fc41..7919357 100644
--- a/server/TetherController.cpp
+++ b/server/TetherController.cpp
@@ -51,8 +51,8 @@
#include "InterfaceController.h"
#include "NetdConstants.h"
#include "NetworkController.h"
-#include "OffloadUtils.h"
#include "Permission.h"
+#include "TcUtils.h"
#include "TetherController.h"
#include "android/net/TetherOffloadRuleParcel.h"
@@ -350,8 +350,7 @@
ALOGD("Stopping tethering services");
- kill(mDaemonPid, SIGTERM);
- waitpid(mDaemonPid, nullptr, 0);
+ ::stopProcess(mDaemonPid, "tethering(dnsmasq)");
mDaemonPid = 0;
close(mDaemonFd);
mDaemonFd = -1;
@@ -879,7 +878,7 @@
* which is what TetherController sets up.
* The 1st matches rx, and sets up the pair for the tx side.
*/
- if (!stats.intIface[0]) {
+ if (stats.intIface.empty()) {
ALOGV("0Filter RX iface_in=%s iface_out=%s rx_bytes=%" PRId64 " rx_packets=%" PRId64
" ", iface0.c_str(), iface1.c_str(), bytes, packets);
stats.intIface = iface0;
diff --git a/server/TetherController.h b/server/TetherController.h
index 585686a..b4472bd 100644
--- a/server/TetherController.h
+++ b/server/TetherController.h
@@ -28,7 +28,7 @@
#include "NetdConstants.h"
#include "android-base/result.h"
#include "bpf/BpfMap.h"
-#include "netdbpf/bpf_shared.h"
+#include "bpf_shared.h"
#include "android/net/TetherOffloadRuleParcel.h"
diff --git a/server/TetherControllerTest.cpp b/server/TetherControllerTest.cpp
index e700f60..0c72bb4 100644
--- a/server/TetherControllerTest.cpp
+++ b/server/TetherControllerTest.cpp
@@ -33,7 +33,7 @@
#include <netdutils/StatusOr.h>
#include "IptablesBaseTest.h"
-#include "OffloadUtils.h"
+#include "TcUtils.h"
#include "TetherController.h"
using android::base::Join;
diff --git a/server/TrafficController.cpp b/server/TrafficController.cpp
deleted file mode 100644
index 1f678cb..0000000
--- a/server/TrafficController.cpp
+++ /dev/null
@@ -1,1038 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#define LOG_TAG "TrafficController"
-#include <inttypes.h>
-#include <linux/bpf.h>
-#include <linux/if_ether.h>
-#include <linux/in.h>
-#include <linux/inet_diag.h>
-#include <linux/netlink.h>
-#include <linux/sock_diag.h>
-#include <linux/unistd.h>
-#include <net/if.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-#include <mutex>
-#include <unordered_set>
-#include <vector>
-
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-#include <android-base/unique_fd.h>
-#include <netdutils/StatusOr.h>
-
-#include <netdutils/Misc.h>
-#include <netdutils/Syscalls.h>
-#include <processgroup/processgroup.h>
-#include "TrafficController.h"
-#include "bpf/BpfMap.h"
-
-#include "FirewallController.h"
-#include "InterfaceController.h"
-#include "NetlinkListener.h"
-#include "netdutils/DumpWriter.h"
-#include "qtaguid/qtaguid.h"
-
-namespace android {
-namespace net {
-
-using base::StringPrintf;
-using base::unique_fd;
-using bpf::getSocketCookie;
-using bpf::NONEXISTENT_COOKIE;
-using bpf::OVERFLOW_COUNTERSET;
-using bpf::retrieveProgram;
-using bpf::synchronizeKernelRCU;
-using netdutils::DumpWriter;
-using netdutils::extract;
-using netdutils::ScopedIndent;
-using netdutils::Slice;
-using netdutils::sSyscalls;
-using netdutils::Status;
-using netdutils::statusFromErrno;
-using netdutils::StatusOr;
-using netdutils::status::ok;
-
-constexpr int kSockDiagMsgType = SOCK_DIAG_BY_FAMILY;
-constexpr int kSockDiagDoneMsgType = NLMSG_DONE;
-constexpr int PER_UID_STATS_ENTRIES_LIMIT = 500;
-// At most 90% of the stats map may be used by tagged traffic entries. This ensures
-// that 10% of the map is always available to count untagged traffic, one entry per UID.
-// Otherwise, apps would be able to avoid data usage accounting entirely by filling up the
-// map with tagged traffic entries.
-constexpr int TOTAL_UID_STATS_ENTRIES_LIMIT = STATS_MAP_SIZE * 0.9;
-
-static_assert(BPF_PERMISSION_INTERNET == INetd::PERMISSION_INTERNET,
- "Mismatch between BPF and AIDL permissions: PERMISSION_INTERNET");
-static_assert(BPF_PERMISSION_UPDATE_DEVICE_STATS == INetd::PERMISSION_UPDATE_DEVICE_STATS,
- "Mismatch between BPF and AIDL permissions: PERMISSION_UPDATE_DEVICE_STATS");
-static_assert(STATS_MAP_SIZE - TOTAL_UID_STATS_ENTRIES_LIMIT > 100,
- "The limit for stats map is to high, stats data may be lost due to overflow");
-
-#define FLAG_MSG_TRANS(result, flag, value) \
- do { \
- if ((value) & (flag)) { \
- (result).append(" " #flag); \
- (value) &= ~(flag); \
- } \
- } while (0)
-
-const std::string uidMatchTypeToString(uint8_t match) {
- std::string matchType;
- FLAG_MSG_TRANS(matchType, HAPPY_BOX_MATCH, match);
- FLAG_MSG_TRANS(matchType, PENALTY_BOX_MATCH, match);
- FLAG_MSG_TRANS(matchType, DOZABLE_MATCH, match);
- FLAG_MSG_TRANS(matchType, STANDBY_MATCH, match);
- FLAG_MSG_TRANS(matchType, POWERSAVE_MATCH, match);
- FLAG_MSG_TRANS(matchType, RESTRICTED_MATCH, match);
- FLAG_MSG_TRANS(matchType, IIF_MATCH, match);
- if (match) {
- return StringPrintf("Unknown match: %u", match);
- }
- return matchType;
-}
-
-bool TrafficController::hasUpdateDeviceStatsPermission(uid_t uid) {
- // This implementation is the same logic as method ActivityManager#checkComponentPermission.
- // It implies that the calling uid can never be the same as PER_USER_RANGE.
- uint32_t appId = uid % PER_USER_RANGE;
- return ((appId == AID_ROOT) || (appId == AID_SYSTEM) ||
- mPrivilegedUser.find(appId) != mPrivilegedUser.end());
-}
-
-const std::string UidPermissionTypeToString(int permission) {
- if (permission == INetd::PERMISSION_NONE) {
- return "PERMISSION_NONE";
- }
- if (permission == INetd::PERMISSION_UNINSTALLED) {
- // This should never appear in the map, complain loudly if it does.
- return "PERMISSION_UNINSTALLED error!";
- }
- std::string permissionType;
- FLAG_MSG_TRANS(permissionType, BPF_PERMISSION_INTERNET, permission);
- FLAG_MSG_TRANS(permissionType, BPF_PERMISSION_UPDATE_DEVICE_STATS, permission);
- if (permission) {
- return StringPrintf("Unknown permission: %u", permission);
- }
- return permissionType;
-}
-
-StatusOr<std::unique_ptr<NetlinkListenerInterface>> TrafficController::makeSkDestroyListener() {
- const auto& sys = sSyscalls.get();
- ASSIGN_OR_RETURN(auto event, sys.eventfd(0, EFD_CLOEXEC));
- const int domain = AF_NETLINK;
- const int type = SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK;
- const int protocol = NETLINK_INET_DIAG;
- ASSIGN_OR_RETURN(auto sock, sys.socket(domain, type, protocol));
-
- // TODO: if too many sockets are closed too quickly, we can overflow the socket buffer, and
- // some entries in mCookieTagMap will not be freed. In order to fix this we would need to
- // periodically dump all sockets and remove the tag entries for sockets that have been closed.
- // For now, set a large-enough buffer that we can close hundreds of sockets without getting
- // ENOBUFS and leaking mCookieTagMap entries.
- int rcvbuf = 512 * 1024;
- auto ret = sys.setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf));
- if (!ret.ok()) {
- ALOGW("Failed to set SkDestroyListener buffer size to %d: %s", rcvbuf, ret.msg().c_str());
- }
-
- sockaddr_nl addr = {
- .nl_family = AF_NETLINK,
- .nl_groups = 1 << (SKNLGRP_INET_TCP_DESTROY - 1) | 1 << (SKNLGRP_INET_UDP_DESTROY - 1) |
- 1 << (SKNLGRP_INET6_TCP_DESTROY - 1) | 1 << (SKNLGRP_INET6_UDP_DESTROY - 1)};
- RETURN_IF_NOT_OK(sys.bind(sock, addr));
-
- const sockaddr_nl kernel = {.nl_family = AF_NETLINK};
- RETURN_IF_NOT_OK(sys.connect(sock, kernel));
-
- std::unique_ptr<NetlinkListenerInterface> listener =
- std::make_unique<NetlinkListener>(std::move(event), std::move(sock), "SkDestroyListen");
-
- return listener;
-}
-
-TrafficController::TrafficController()
- : mPerUidStatsEntriesLimit(PER_UID_STATS_ENTRIES_LIMIT),
- mTotalUidStatsEntriesLimit(TOTAL_UID_STATS_ENTRIES_LIMIT) {}
-
-TrafficController::TrafficController(uint32_t perUidLimit, uint32_t totalLimit)
- : mPerUidStatsEntriesLimit(perUidLimit), mTotalUidStatsEntriesLimit(totalLimit) {}
-
-Status TrafficController::initMaps() {
- std::lock_guard guard(mMutex);
-
- RETURN_IF_NOT_OK(mCookieTagMap.init(COOKIE_TAG_MAP_PATH));
- RETURN_IF_NOT_OK(mUidCounterSetMap.init(UID_COUNTERSET_MAP_PATH));
- RETURN_IF_NOT_OK(mAppUidStatsMap.init(APP_UID_STATS_MAP_PATH));
- RETURN_IF_NOT_OK(mStatsMapA.init(STATS_MAP_A_PATH));
- RETURN_IF_NOT_OK(mStatsMapB.init(STATS_MAP_B_PATH));
- RETURN_IF_NOT_OK(mIfaceIndexNameMap.init(IFACE_INDEX_NAME_MAP_PATH));
- RETURN_IF_NOT_OK(mIfaceStatsMap.init(IFACE_STATS_MAP_PATH));
-
- RETURN_IF_NOT_OK(mConfigurationMap.init(CONFIGURATION_MAP_PATH));
- RETURN_IF_NOT_OK(
- mConfigurationMap.writeValue(UID_RULES_CONFIGURATION_KEY, DEFAULT_CONFIG, BPF_ANY));
- RETURN_IF_NOT_OK(mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY, SELECT_MAP_A,
- BPF_ANY));
-
- RETURN_IF_NOT_OK(mUidOwnerMap.init(UID_OWNER_MAP_PATH));
- RETURN_IF_NOT_OK(mUidOwnerMap.clear());
- RETURN_IF_NOT_OK(mUidPermissionMap.init(UID_PERMISSION_MAP_PATH));
-
- return netdutils::status::ok;
-}
-
-static Status attachProgramToCgroup(const char* programPath, const unique_fd& cgroupFd,
- bpf_attach_type type) {
- unique_fd cgroupProg(retrieveProgram(programPath));
- if (cgroupProg == -1) {
- int ret = errno;
- ALOGE("Failed to get program from %s: %s", programPath, strerror(ret));
- return statusFromErrno(ret, "cgroup program get failed");
- }
- if (android::bpf::attachProgram(type, cgroupProg, cgroupFd)) {
- int ret = errno;
- ALOGE("Program from %s attach failed: %s", programPath, strerror(ret));
- return statusFromErrno(ret, "program attach failed");
- }
- return netdutils::status::ok;
-}
-
-static Status initPrograms() {
- std::string cg2_path;
-
- if (!CgroupGetControllerPath(CGROUPV2_CONTROLLER_NAME, &cg2_path)) {
- int ret = errno;
- ALOGE("Failed to find cgroup v2 root");
- return statusFromErrno(ret, "Failed to find cgroup v2 root");
- }
-
- unique_fd cg_fd(open(cg2_path.c_str(), O_DIRECTORY | O_RDONLY | O_CLOEXEC));
- if (cg_fd == -1) {
- int ret = errno;
- ALOGE("Failed to open the cgroup directory: %s", strerror(ret));
- return statusFromErrno(ret, "Open the cgroup directory failed");
- }
- RETURN_IF_NOT_OK(attachProgramToCgroup(BPF_EGRESS_PROG_PATH, cg_fd, BPF_CGROUP_INET_EGRESS));
- RETURN_IF_NOT_OK(attachProgramToCgroup(BPF_INGRESS_PROG_PATH, cg_fd, BPF_CGROUP_INET_INGRESS));
-
- // For the devices that support cgroup socket filter, the socket filter
- // should be loaded successfully by bpfloader. So we attach the filter to
- // cgroup if the program is pinned properly.
- // TODO: delete the if statement once all devices should support cgroup
- // socket filter (ie. the minimum kernel version required is 4.14).
- if (!access(CGROUP_SOCKET_PROG_PATH, F_OK)) {
- RETURN_IF_NOT_OK(
- attachProgramToCgroup(CGROUP_SOCKET_PROG_PATH, cg_fd, BPF_CGROUP_INET_SOCK_CREATE));
- }
- return netdutils::status::ok;
-}
-
-Status TrafficController::start() {
- /* When netd restarts from a crash without total system reboot, the program
- * is still attached to the cgroup, detach it so the program can be freed
- * and we can load and attach new program into the target cgroup.
- *
- * TODO: Scrape existing socket when run-time restart and clean up the map
- * if the socket no longer exist
- */
-
- RETURN_IF_NOT_OK(initMaps());
-
- RETURN_IF_NOT_OK(initPrograms());
-
- // Fetch the list of currently-existing interfaces. At this point NetlinkHandler is
- // already running, so it will call addInterface() when any new interface appears.
- std::map<std::string, uint32_t> ifacePairs;
- ASSIGN_OR_RETURN(ifacePairs, InterfaceController::getIfaceList());
- for (const auto& ifacePair:ifacePairs) {
- addInterface(ifacePair.first.c_str(), ifacePair.second);
- }
-
- auto result = makeSkDestroyListener();
- if (!isOk(result)) {
- ALOGE("Unable to create SkDestroyListener: %s", toString(result).c_str());
- } else {
- mSkDestroyListener = std::move(result.value());
- }
- // Rx handler extracts nfgenmsg looks up and invokes registered dispatch function.
- const auto rxHandler = [this](const nlmsghdr&, const Slice msg) {
- std::lock_guard guard(mMutex);
- inet_diag_msg diagmsg = {};
- if (extract(msg, diagmsg) < sizeof(inet_diag_msg)) {
- ALOGE("Unrecognized netlink message: %s", toString(msg).c_str());
- return;
- }
- uint64_t sock_cookie = static_cast<uint64_t>(diagmsg.id.idiag_cookie[0]) |
- (static_cast<uint64_t>(diagmsg.id.idiag_cookie[1]) << 32);
-
- Status s = mCookieTagMap.deleteValue(sock_cookie);
- if (!isOk(s) && s.code() != ENOENT) {
- ALOGE("Failed to delete cookie %" PRIx64 ": %s", sock_cookie, toString(s).c_str());
- return;
- }
- };
- expectOk(mSkDestroyListener->subscribe(kSockDiagMsgType, rxHandler));
-
- // In case multiple netlink message comes in as a stream, we need to handle the rxDone message
- // properly.
- const auto rxDoneHandler = [](const nlmsghdr&, const Slice msg) {
- // Ignore NLMSG_DONE messages
- inet_diag_msg diagmsg = {};
- extract(msg, diagmsg);
- };
- expectOk(mSkDestroyListener->subscribe(kSockDiagDoneMsgType, rxDoneHandler));
-
- return netdutils::status::ok;
-}
-
-int TrafficController::tagSocket(int sockFd, uint32_t tag, uid_t uid, uid_t callingUid) {
- std::lock_guard guard(mMutex);
- if (uid != callingUid && !hasUpdateDeviceStatsPermission(callingUid)) {
- return -EPERM;
- }
-
- uint64_t sock_cookie = getSocketCookie(sockFd);
- if (sock_cookie == NONEXISTENT_COOKIE) return -errno;
- UidTagValue newKey = {.uid = (uint32_t)uid, .tag = tag};
-
- uint32_t totalEntryCount = 0;
- uint32_t perUidEntryCount = 0;
- // Now we go through the stats map and count how many entries are associated
- // with target uid. If the uid entry hit the limit for each uid, we block
- // the request to prevent the map from overflow. It is safe here to iterate
- // over the map since when mMutex is hold, system server cannot toggle
- // the live stats map and clean it. So nobody can delete entries from the map.
- const auto countUidStatsEntries = [uid, &totalEntryCount, &perUidEntryCount](
- const StatsKey& key,
- const BpfMap<StatsKey, StatsValue>&) {
- if (key.uid == uid) {
- perUidEntryCount++;
- }
- totalEntryCount++;
- return base::Result<void>();
- };
- auto configuration = mConfigurationMap.readValue(CURRENT_STATS_MAP_CONFIGURATION_KEY);
- if (!configuration.ok()) {
- ALOGE("Failed to get current configuration: %s, fd: %d",
- strerror(configuration.error().code()), mConfigurationMap.getMap().get());
- return -configuration.error().code();
- }
- if (configuration.value() != SELECT_MAP_A && configuration.value() != SELECT_MAP_B) {
- ALOGE("unknown configuration value: %d", configuration.value());
- return -EINVAL;
- }
-
- BpfMap<StatsKey, StatsValue>& currentMap =
- (configuration.value() == SELECT_MAP_A) ? mStatsMapA : mStatsMapB;
- base::Result<void> res = currentMap.iterate(countUidStatsEntries);
- if (!res.ok()) {
- ALOGE("Failed to count the stats entry in map %d: %s", currentMap.getMap().get(),
- strerror(res.error().code()));
- return -res.error().code();
- }
-
- if (totalEntryCount > mTotalUidStatsEntriesLimit ||
- perUidEntryCount > mPerUidStatsEntriesLimit) {
- ALOGE("Too many stats entries in the map, total count: %u, uid(%u) count: %u, blocking tag"
- " request to prevent map overflow",
- totalEntryCount, uid, perUidEntryCount);
- return -EMFILE;
- }
- // Update the tag information of a socket to the cookieUidMap. Use BPF_ANY
- // flag so it will insert a new entry to the map if that value doesn't exist
- // yet. And update the tag if there is already a tag stored. Since the eBPF
- // program in kernel only read this map, and is protected by rcu read lock. It
- // should be fine to cocurrently update the map while eBPF program is running.
- res = mCookieTagMap.writeValue(sock_cookie, newKey, BPF_ANY);
- if (!res.ok()) {
- ALOGE("Failed to tag the socket: %s, fd: %d", strerror(res.error().code()),
- mCookieTagMap.getMap().get());
- return -res.error().code();
- }
- return 0;
-}
-
-int TrafficController::untagSocket(int sockFd) {
- std::lock_guard guard(mMutex);
- uint64_t sock_cookie = getSocketCookie(sockFd);
-
- if (sock_cookie == NONEXISTENT_COOKIE) return -errno;
- base::Result<void> res = mCookieTagMap.deleteValue(sock_cookie);
- if (!res.ok()) {
- ALOGE("Failed to untag socket: %s\n", strerror(res.error().code()));
- return -res.error().code();
- }
- return 0;
-}
-
-int TrafficController::setCounterSet(int counterSetNum, uid_t uid, uid_t callingUid) {
- if (counterSetNum < 0 || counterSetNum >= OVERFLOW_COUNTERSET) return -EINVAL;
-
- std::lock_guard guard(mMutex);
- if (!hasUpdateDeviceStatsPermission(callingUid)) return -EPERM;
-
- // The default counter set for all uid is 0, so deleting the current counterset for that uid
- // will automatically set it to 0.
- if (counterSetNum == 0) {
- Status res = mUidCounterSetMap.deleteValue(uid);
- if (isOk(res) || (!isOk(res) && res.code() == ENOENT)) {
- return 0;
- } else {
- ALOGE("Failed to delete the counterSet: %s\n", strerror(res.code()));
- return -res.code();
- }
- }
- uint8_t tmpCounterSetNum = (uint8_t)counterSetNum;
- Status res = mUidCounterSetMap.writeValue(uid, tmpCounterSetNum, BPF_ANY);
- if (!isOk(res)) {
- ALOGE("Failed to set the counterSet: %s, fd: %d", strerror(res.code()),
- mUidCounterSetMap.getMap().get());
- return -res.code();
- }
- return 0;
-}
-
-// This method only get called by system_server when an app get uinstalled, it
-// is called inside removeUidsLocked() while holding mStatsLock. So it is safe
-// to iterate and modify the stats maps.
-int TrafficController::deleteTagData(uint32_t tag, uid_t uid, uid_t callingUid) {
- std::lock_guard guard(mMutex);
- if (!hasUpdateDeviceStatsPermission(callingUid)) return -EPERM;
-
- // First we go through the cookieTagMap to delete the target uid tag combination. Or delete all
- // the tags related to the uid if the tag is 0.
- const auto deleteMatchedCookieEntries = [uid, tag](const uint64_t& key,
- const UidTagValue& value,
- BpfMap<uint64_t, UidTagValue>& map) {
- if (value.uid == uid && (value.tag == tag || tag == 0)) {
- auto res = map.deleteValue(key);
- if (res.ok() || (res.error().code() == ENOENT)) {
- return base::Result<void>();
- }
- ALOGE("Failed to delete data(cookie = %" PRIu64 "): %s\n", key,
- strerror(res.error().code()));
- }
- // Move forward to next cookie in the map.
- return base::Result<void>();
- };
- mCookieTagMap.iterateWithValue(deleteMatchedCookieEntries);
- // Now we go through the Tag stats map and delete the data entry with correct uid and tag
- // combination. Or all tag stats under that uid if the target tag is 0.
- const auto deleteMatchedUidTagEntries = [uid, tag](const StatsKey& key,
- BpfMap<StatsKey, StatsValue>& map) {
- if (key.uid == uid && (key.tag == tag || tag == 0)) {
- auto res = map.deleteValue(key);
- if (res.ok() || (res.error().code() == ENOENT)) {
- //Entry is deleted, use the current key to get a new nextKey;
- return base::Result<void>();
- }
- ALOGE("Failed to delete data(uid=%u, tag=%u): %s\n", key.uid, key.tag,
- strerror(res.error().code()));
- }
- return base::Result<void>();
- };
- mStatsMapB.iterate(deleteMatchedUidTagEntries);
- mStatsMapA.iterate(deleteMatchedUidTagEntries);
- // If the tag is not zero, we already deleted all the data entry required. If tag is 0, we also
- // need to delete the stats stored in uidStatsMap and counterSet map.
- if (tag != 0) return 0;
-
- auto res = mUidCounterSetMap.deleteValue(uid);
- if (!res.ok() && res.error().code() != ENOENT) {
- ALOGE("Failed to delete counterSet data(uid=%u, tag=%u): %s\n", uid, tag,
- strerror(res.error().code()));
- }
-
- auto deleteAppUidStatsEntry = [uid](const uint32_t& key,
- BpfMap<uint32_t, StatsValue>& map) -> base::Result<void> {
- if (key == uid) {
- auto res = map.deleteValue(key);
- if (res.ok() || (res.error().code() == ENOENT)) {
- return {};
- }
- ALOGE("Failed to delete data(uid=%u): %s", key, strerror(res.error().code()));
- }
- return {};
- };
- mAppUidStatsMap.iterate(deleteAppUidStatsEntry);
- return 0;
-}
-
-int TrafficController::addInterface(const char* name, uint32_t ifaceIndex) {
- IfaceValue iface;
- if (ifaceIndex == 0) {
- ALOGE("Unknown interface %s(%d)", name, ifaceIndex);
- return -1;
- }
-
- strlcpy(iface.name, name, sizeof(IfaceValue));
- Status res = mIfaceIndexNameMap.writeValue(ifaceIndex, iface, BPF_ANY);
- if (!isOk(res)) {
- ALOGE("Failed to add iface %s(%d): %s", name, ifaceIndex, strerror(res.code()));
- return -res.code();
- }
- return 0;
-}
-
-Status TrafficController::updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
- FirewallType type) {
- std::lock_guard guard(mMutex);
- if ((rule == ALLOW && type == ALLOWLIST) || (rule == DENY && type == DENYLIST)) {
- RETURN_IF_NOT_OK(addRule(uid, match));
- } else if ((rule == ALLOW && type == DENYLIST) || (rule == DENY && type == ALLOWLIST)) {
- RETURN_IF_NOT_OK(removeRule(uid, match));
- } else {
- //Cannot happen.
- return statusFromErrno(EINVAL, "");
- }
- return netdutils::status::ok;
-}
-
-Status TrafficController::removeRule(uint32_t uid, UidOwnerMatchType match) {
- auto oldMatch = mUidOwnerMap.readValue(uid);
- if (oldMatch.ok()) {
- UidOwnerValue newMatch = {
- .iif = (match == IIF_MATCH) ? 0 : oldMatch.value().iif,
- .rule = static_cast<uint8_t>(oldMatch.value().rule & ~match),
- };
- if (newMatch.rule == 0) {
- RETURN_IF_NOT_OK(mUidOwnerMap.deleteValue(uid));
- } else {
- RETURN_IF_NOT_OK(mUidOwnerMap.writeValue(uid, newMatch, BPF_ANY));
- }
- } else {
- return statusFromErrno(ENOENT, StringPrintf("uid: %u does not exist in map", uid));
- }
- return netdutils::status::ok;
-}
-
-Status TrafficController::addRule(uint32_t uid, UidOwnerMatchType match, uint32_t iif) {
- // iif should be non-zero if and only if match == MATCH_IIF
- if (match == IIF_MATCH && iif == 0) {
- return statusFromErrno(EINVAL, "Interface match must have nonzero interface index");
- } else if (match != IIF_MATCH && iif != 0) {
- return statusFromErrno(EINVAL, "Non-interface match must have zero interface index");
- }
- auto oldMatch = mUidOwnerMap.readValue(uid);
- if (oldMatch.ok()) {
- UidOwnerValue newMatch = {
- .iif = iif ? iif : oldMatch.value().iif,
- .rule = static_cast<uint8_t>(oldMatch.value().rule | match),
- };
- RETURN_IF_NOT_OK(mUidOwnerMap.writeValue(uid, newMatch, BPF_ANY));
- } else {
- UidOwnerValue newMatch = {
- .iif = iif,
- .rule = static_cast<uint8_t>(match),
- };
- RETURN_IF_NOT_OK(mUidOwnerMap.writeValue(uid, newMatch, BPF_ANY));
- }
- return netdutils::status::ok;
-}
-
-Status TrafficController::updateUidOwnerMap(const std::vector<uint32_t>& appUids,
- UidOwnerMatchType matchType,
- BandwidthController::IptOp op) {
- std::lock_guard guard(mMutex);
- for (uint32_t uid : appUids) {
- if (op == BandwidthController::IptOpDelete) {
- RETURN_IF_NOT_OK(removeRule(uid, matchType));
- } else if (op == BandwidthController::IptOpInsert) {
- RETURN_IF_NOT_OK(addRule(uid, matchType));
- } else {
- // Cannot happen.
- return statusFromErrno(EINVAL, StringPrintf("invalid IptOp: %d, %d", op, matchType));
- }
- }
- return netdutils::status::ok;
-}
-
-int TrafficController::changeUidOwnerRule(ChildChain chain, uid_t uid, FirewallRule rule,
- FirewallType type) {
- Status res;
- switch (chain) {
- case DOZABLE:
- res = updateOwnerMapEntry(DOZABLE_MATCH, uid, rule, type);
- break;
- case STANDBY:
- res = updateOwnerMapEntry(STANDBY_MATCH, uid, rule, type);
- break;
- case POWERSAVE:
- res = updateOwnerMapEntry(POWERSAVE_MATCH, uid, rule, type);
- break;
- case RESTRICTED:
- res = updateOwnerMapEntry(RESTRICTED_MATCH, uid, rule, type);
- break;
- case NONE:
- default:
- return -EINVAL;
- }
- if (!isOk(res)) {
- ALOGE("change uid(%u) rule of %d failed: %s, rule: %d, type: %d", uid, chain,
- res.msg().c_str(), rule, type);
- return -res.code();
- }
- return 0;
-}
-
-Status TrafficController::replaceRulesInMap(const UidOwnerMatchType match,
- const std::vector<int32_t>& uids) {
- std::lock_guard guard(mMutex);
- std::set<int32_t> uidSet(uids.begin(), uids.end());
- std::vector<uint32_t> uidsToDelete;
- auto getUidsToDelete = [&uidsToDelete, &uidSet](const uint32_t& key,
- const BpfMap<uint32_t, UidOwnerValue>&) {
- if (uidSet.find((int32_t) key) == uidSet.end()) {
- uidsToDelete.push_back(key);
- }
- return base::Result<void>();
- };
- RETURN_IF_NOT_OK(mUidOwnerMap.iterate(getUidsToDelete));
-
- for(auto uid : uidsToDelete) {
- RETURN_IF_NOT_OK(removeRule(uid, match));
- }
-
- for (auto uid : uids) {
- RETURN_IF_NOT_OK(addRule(uid, match));
- }
- return netdutils::status::ok;
-}
-
-Status TrafficController::addUidInterfaceRules(const int iif,
- const std::vector<int32_t>& uidsToAdd) {
- if (!iif) {
- return statusFromErrno(EINVAL, "Interface rule must specify interface");
- }
- std::lock_guard guard(mMutex);
-
- for (auto uid : uidsToAdd) {
- netdutils::Status result = addRule(uid, IIF_MATCH, iif);
- if (!isOk(result)) {
- ALOGW("addRule failed(%d): uid=%d iif=%d", result.code(), uid, iif);
- }
- }
- return netdutils::status::ok;
-}
-
-Status TrafficController::removeUidInterfaceRules(const std::vector<int32_t>& uidsToDelete) {
- std::lock_guard guard(mMutex);
-
- for (auto uid : uidsToDelete) {
- netdutils::Status result = removeRule(uid, IIF_MATCH);
- if (!isOk(result)) {
- ALOGW("removeRule failed(%d): uid=%d", result.code(), uid);
- }
- }
- return netdutils::status::ok;
-}
-
-int TrafficController::replaceUidOwnerMap(const std::string& name, bool isAllowlist __unused,
- const std::vector<int32_t>& uids) {
- // FirewallRule rule = isAllowlist ? ALLOW : DENY;
- // FirewallType type = isAllowlist ? ALLOWLIST : DENYLIST;
- Status res;
- if (!name.compare(FirewallController::LOCAL_DOZABLE)) {
- res = replaceRulesInMap(DOZABLE_MATCH, uids);
- } else if (!name.compare(FirewallController::LOCAL_STANDBY)) {
- res = replaceRulesInMap(STANDBY_MATCH, uids);
- } else if (!name.compare(FirewallController::LOCAL_POWERSAVE)) {
- res = replaceRulesInMap(POWERSAVE_MATCH, uids);
- } else if (!name.compare(FirewallController::LOCAL_RESTRICTED)) {
- res = replaceRulesInMap(RESTRICTED_MATCH, uids);
- } else {
- ALOGE("unknown chain name: %s", name.c_str());
- return -EINVAL;
- }
- if (!isOk(res)) {
- ALOGE("Failed to clean up chain: %s: %s", name.c_str(), res.msg().c_str());
- return -res.code();
- }
- return 0;
-}
-
-int TrafficController::toggleUidOwnerMap(ChildChain chain, bool enable) {
- std::lock_guard guard(mMutex);
- uint32_t key = UID_RULES_CONFIGURATION_KEY;
- auto oldConfiguration = mConfigurationMap.readValue(key);
- if (!oldConfiguration.ok()) {
- ALOGE("Cannot read the old configuration from map: %s",
- oldConfiguration.error().message().c_str());
- return -oldConfiguration.error().code();
- }
- Status res;
- BpfConfig newConfiguration;
- uint8_t match;
- switch (chain) {
- case DOZABLE:
- match = DOZABLE_MATCH;
- break;
- case STANDBY:
- match = STANDBY_MATCH;
- break;
- case POWERSAVE:
- match = POWERSAVE_MATCH;
- break;
- case RESTRICTED:
- match = RESTRICTED_MATCH;
- break;
- default:
- return -EINVAL;
- }
- newConfiguration =
- enable ? (oldConfiguration.value() | match) : (oldConfiguration.value() & (~match));
- res = mConfigurationMap.writeValue(key, newConfiguration, BPF_EXIST);
- if (!isOk(res)) {
- ALOGE("Failed to toggleUidOwnerMap(%d): %s", chain, res.msg().c_str());
- }
- return -res.code();
-}
-
-Status TrafficController::swapActiveStatsMap() {
- std::lock_guard guard(mMutex);
-
- uint32_t key = CURRENT_STATS_MAP_CONFIGURATION_KEY;
- auto oldConfiguration = mConfigurationMap.readValue(key);
- if (!oldConfiguration.ok()) {
- ALOGE("Cannot read the old configuration from map: %s",
- oldConfiguration.error().message().c_str());
- return Status(oldConfiguration.error().code(), oldConfiguration.error().message());
- }
-
- // Write to the configuration map to inform the kernel eBPF program to switch
- // from using one map to the other. Use flag BPF_EXIST here since the map should
- // be already populated in initMaps.
- uint8_t newConfigure = (oldConfiguration.value() == SELECT_MAP_A) ? SELECT_MAP_B : SELECT_MAP_A;
- auto res = mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY, newConfigure,
- BPF_EXIST);
- if (!res.ok()) {
- ALOGE("Failed to toggle the stats map: %s", strerror(res.error().code()));
- return res;
- }
- // After changing the config, we need to make sure all the current running
- // eBPF programs are finished and all the CPUs are aware of this config change
- // before we modify the old map. So we do a special hack here to wait for
- // the kernel to do a synchronize_rcu(). Once the kernel called
- // synchronize_rcu(), the config we just updated will be available to all cores
- // and the next eBPF programs triggered inside the kernel will use the new
- // map configuration. So once this function returns we can safely modify the
- // old stats map without concerning about race between the kernel and
- // userspace.
- int ret = synchronizeKernelRCU();
- if (ret) {
- ALOGE("map swap synchronize_rcu() ended with failure: %s", strerror(-ret));
- return statusFromErrno(-ret, "map swap synchronize_rcu() failed");
- }
- return netdutils::status::ok;
-}
-
-void TrafficController::setPermissionForUids(int permission, const std::vector<uid_t>& uids) {
- std::lock_guard guard(mMutex);
- if (permission == INetd::PERMISSION_UNINSTALLED) {
- for (uid_t uid : uids) {
- // Clean up all permission information for the related uid if all the
- // packages related to it are uninstalled.
- mPrivilegedUser.erase(uid);
- Status ret = mUidPermissionMap.deleteValue(uid);
- if (!isOk(ret) && ret.code() != ENOENT) {
- ALOGE("Failed to clean up the permission for %u: %s", uid, strerror(ret.code()));
- }
- }
- return;
- }
-
- bool privileged = (permission & INetd::PERMISSION_UPDATE_DEVICE_STATS);
-
- for (uid_t uid : uids) {
- if (privileged) {
- mPrivilegedUser.insert(uid);
- } else {
- mPrivilegedUser.erase(uid);
- }
-
- // The map stores all the permissions that the UID has, except if the only permission
- // the UID has is the INTERNET permission, then the UID should not appear in the map.
- if (permission != INetd::PERMISSION_INTERNET) {
- Status ret = mUidPermissionMap.writeValue(uid, permission, BPF_ANY);
- if (!isOk(ret)) {
- ALOGE("Failed to set permission: %s of uid(%u) to permission map: %s",
- UidPermissionTypeToString(permission).c_str(), uid, strerror(ret.code()));
- }
- } else {
- Status ret = mUidPermissionMap.deleteValue(uid);
- if (!isOk(ret) && ret.code() != ENOENT) {
- ALOGE("Failed to remove uid %u from permission map: %s", uid, strerror(ret.code()));
- }
- }
- }
-}
-
-std::string getProgramStatus(const char *path) {
- int ret = access(path, R_OK);
- if (ret == 0) {
- return StringPrintf("OK");
- }
- if (ret != 0 && errno == ENOENT) {
- return StringPrintf("program is missing at: %s", path);
- }
- return StringPrintf("check Program %s error: %s", path, strerror(errno));
-}
-
-std::string getMapStatus(const base::unique_fd& map_fd, const char* path) {
- if (map_fd.get() < 0) {
- return StringPrintf("map fd lost");
- }
- if (access(path, F_OK) != 0) {
- return StringPrintf("map not pinned to location: %s", path);
- }
- return StringPrintf("OK");
-}
-
-// NOLINTNEXTLINE(google-runtime-references): grandfathered pass by non-const reference
-void dumpBpfMap(const std::string& mapName, DumpWriter& dw, const std::string& header) {
- dw.blankline();
- dw.println("%s:", mapName.c_str());
- if (!header.empty()) {
- dw.println(header);
- }
-}
-
-const String16 TrafficController::DUMP_KEYWORD = String16("trafficcontroller");
-
-void TrafficController::dump(DumpWriter& dw, bool verbose) {
- std::lock_guard guard(mMutex);
- ScopedIndent indentTop(dw);
- dw.println("TrafficController");
-
- ScopedIndent indentPreBpfModule(dw);
-
- dw.blankline();
- dw.println("mCookieTagMap status: %s",
- getMapStatus(mCookieTagMap.getMap(), COOKIE_TAG_MAP_PATH).c_str());
- dw.println("mUidCounterSetMap status: %s",
- getMapStatus(mUidCounterSetMap.getMap(), UID_COUNTERSET_MAP_PATH).c_str());
- dw.println("mAppUidStatsMap status: %s",
- getMapStatus(mAppUidStatsMap.getMap(), APP_UID_STATS_MAP_PATH).c_str());
- dw.println("mStatsMapA status: %s",
- getMapStatus(mStatsMapA.getMap(), STATS_MAP_A_PATH).c_str());
- dw.println("mStatsMapB status: %s",
- getMapStatus(mStatsMapB.getMap(), STATS_MAP_B_PATH).c_str());
- dw.println("mIfaceIndexNameMap status: %s",
- getMapStatus(mIfaceIndexNameMap.getMap(), IFACE_INDEX_NAME_MAP_PATH).c_str());
- dw.println("mIfaceStatsMap status: %s",
- getMapStatus(mIfaceStatsMap.getMap(), IFACE_STATS_MAP_PATH).c_str());
- dw.println("mConfigurationMap status: %s",
- getMapStatus(mConfigurationMap.getMap(), CONFIGURATION_MAP_PATH).c_str());
- dw.println("mUidOwnerMap status: %s",
- getMapStatus(mUidOwnerMap.getMap(), UID_OWNER_MAP_PATH).c_str());
-
- dw.blankline();
- dw.println("Cgroup ingress program status: %s",
- getProgramStatus(BPF_INGRESS_PROG_PATH).c_str());
- dw.println("Cgroup egress program status: %s", getProgramStatus(BPF_EGRESS_PROG_PATH).c_str());
- dw.println("xt_bpf ingress program status: %s",
- getProgramStatus(XT_BPF_INGRESS_PROG_PATH).c_str());
- dw.println("xt_bpf egress program status: %s",
- getProgramStatus(XT_BPF_EGRESS_PROG_PATH).c_str());
- dw.println("xt_bpf bandwidth allowlist program status: %s",
- getProgramStatus(XT_BPF_ALLOWLIST_PROG_PATH).c_str());
- dw.println("xt_bpf bandwidth denylist program status: %s",
- getProgramStatus(XT_BPF_DENYLIST_PROG_PATH).c_str());
-
- if (!verbose) {
- return;
- }
-
- dw.blankline();
- dw.println("BPF map content:");
-
- ScopedIndent indentForMapContent(dw);
-
- // Print CookieTagMap content.
- dumpBpfMap("mCookieTagMap", dw, "");
- const auto printCookieTagInfo = [&dw](const uint64_t& key, const UidTagValue& value,
- const BpfMap<uint64_t, UidTagValue>&) {
- dw.println("cookie=%" PRIu64 " tag=0x%x uid=%u", key, value.tag, value.uid);
- return base::Result<void>();
- };
- base::Result<void> res = mCookieTagMap.iterateWithValue(printCookieTagInfo);
- if (!res.ok()) {
- dw.println("mCookieTagMap print end with error: %s", res.error().message().c_str());
- }
-
- // Print UidCounterSetMap Content
- dumpBpfMap("mUidCounterSetMap", dw, "");
- const auto printUidInfo = [&dw](const uint32_t& key, const uint8_t& value,
- const BpfMap<uint32_t, uint8_t>&) {
- dw.println("%u %u", key, value);
- return base::Result<void>();
- };
- res = mUidCounterSetMap.iterateWithValue(printUidInfo);
- if (!res.ok()) {
- dw.println("mUidCounterSetMap print end with error: %s", res.error().message().c_str());
- }
-
- // Print AppUidStatsMap content
- std::string appUidStatsHeader = StringPrintf("uid rxBytes rxPackets txBytes txPackets");
- dumpBpfMap("mAppUidStatsMap:", dw, appUidStatsHeader);
- auto printAppUidStatsInfo = [&dw](const uint32_t& key, const StatsValue& value,
- const BpfMap<uint32_t, StatsValue>&) {
- dw.println("%u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, key, value.rxBytes,
- value.rxPackets, value.txBytes, value.txPackets);
- return base::Result<void>();
- };
- res = mAppUidStatsMap.iterateWithValue(printAppUidStatsInfo);
- if (!res.ok()) {
- dw.println("mAppUidStatsMap print end with error: %s", res.error().message().c_str());
- }
-
- // Print uidStatsMap content
- std::string statsHeader = StringPrintf("ifaceIndex ifaceName tag_hex uid_int cnt_set rxBytes"
- " rxPackets txBytes txPackets");
- dumpBpfMap("mStatsMapA", dw, statsHeader);
- const auto printStatsInfo = [&dw, this](const StatsKey& key, const StatsValue& value,
- const BpfMap<StatsKey, StatsValue>&) {
- uint32_t ifIndex = key.ifaceIndex;
- auto ifname = mIfaceIndexNameMap.readValue(ifIndex);
- if (!ifname.ok()) {
- ifname = IfaceValue{"unknown"};
- }
- dw.println("%u %s 0x%x %u %u %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, ifIndex,
- ifname.value().name, key.tag, key.uid, key.counterSet, value.rxBytes,
- value.rxPackets, value.txBytes, value.txPackets);
- return base::Result<void>();
- };
- res = mStatsMapA.iterateWithValue(printStatsInfo);
- if (!res.ok()) {
- dw.println("mStatsMapA print end with error: %s", res.error().message().c_str());
- }
-
- // Print TagStatsMap content.
- dumpBpfMap("mStatsMapB", dw, statsHeader);
- res = mStatsMapB.iterateWithValue(printStatsInfo);
- if (!res.ok()) {
- dw.println("mStatsMapB print end with error: %s", res.error().message().c_str());
- }
-
- // Print ifaceIndexToNameMap content.
- dumpBpfMap("mIfaceIndexNameMap", dw, "");
- const auto printIfaceNameInfo = [&dw](const uint32_t& key, const IfaceValue& value,
- const BpfMap<uint32_t, IfaceValue>&) {
- const char* ifname = value.name;
- dw.println("ifaceIndex=%u ifaceName=%s", key, ifname);
- return base::Result<void>();
- };
- res = mIfaceIndexNameMap.iterateWithValue(printIfaceNameInfo);
- if (!res.ok()) {
- dw.println("mIfaceIndexNameMap print end with error: %s", res.error().message().c_str());
- }
-
- // Print ifaceStatsMap content
- std::string ifaceStatsHeader = StringPrintf("ifaceIndex ifaceName rxBytes rxPackets txBytes"
- " txPackets");
- dumpBpfMap("mIfaceStatsMap:", dw, ifaceStatsHeader);
- const auto printIfaceStatsInfo = [&dw, this](const uint32_t& key, const StatsValue& value,
- const BpfMap<uint32_t, StatsValue>&) {
- auto ifname = mIfaceIndexNameMap.readValue(key);
- if (!ifname.ok()) {
- ifname = IfaceValue{"unknown"};
- }
- dw.println("%u %s %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64, key, ifname.value().name,
- value.rxBytes, value.rxPackets, value.txBytes, value.txPackets);
- return base::Result<void>();
- };
- res = mIfaceStatsMap.iterateWithValue(printIfaceStatsInfo);
- if (!res.ok()) {
- dw.println("mIfaceStatsMap print end with error: %s", res.error().message().c_str());
- }
-
- dw.blankline();
-
- uint32_t key = UID_RULES_CONFIGURATION_KEY;
- auto configuration = mConfigurationMap.readValue(key);
- if (configuration.ok()) {
- dw.println("current ownerMatch configuration: %d%s", configuration.value(),
- uidMatchTypeToString(configuration.value()).c_str());
- } else {
- dw.println("mConfigurationMap read ownerMatch configure failed with error: %s",
- configuration.error().message().c_str());
- }
-
- key = CURRENT_STATS_MAP_CONFIGURATION_KEY;
- configuration = mConfigurationMap.readValue(key);
- if (configuration.ok()) {
- const char* statsMapDescription = "???";
- switch (configuration.value()) {
- case SELECT_MAP_A:
- statsMapDescription = "SELECT_MAP_A";
- break;
- case SELECT_MAP_B:
- statsMapDescription = "SELECT_MAP_B";
- break;
- // No default clause, so if we ever add a third map, this code will fail to build.
- }
- dw.println("current statsMap configuration: %d %s", configuration.value(),
- statsMapDescription);
- } else {
- dw.println("mConfigurationMap read stats map configure failed with error: %s",
- configuration.error().message().c_str());
- }
- dumpBpfMap("mUidOwnerMap", dw, "");
- const auto printUidMatchInfo = [&dw, this](const uint32_t& key, const UidOwnerValue& value,
- const BpfMap<uint32_t, UidOwnerValue>&) {
- if (value.rule & IIF_MATCH) {
- auto ifname = mIfaceIndexNameMap.readValue(value.iif);
- if (ifname.ok()) {
- dw.println("%u %s %s", key, uidMatchTypeToString(value.rule).c_str(),
- ifname.value().name);
- } else {
- dw.println("%u %s %u", key, uidMatchTypeToString(value.rule).c_str(), value.iif);
- }
- } else {
- dw.println("%u %s", key, uidMatchTypeToString(value.rule).c_str());
- }
- return base::Result<void>();
- };
- res = mUidOwnerMap.iterateWithValue(printUidMatchInfo);
- if (!res.ok()) {
- dw.println("mUidOwnerMap print end with error: %s", res.error().message().c_str());
- }
- dumpBpfMap("mUidPermissionMap", dw, "");
- const auto printUidPermissionInfo = [&dw](const uint32_t& key, const int& value,
- const BpfMap<uint32_t, uint8_t>&) {
- dw.println("%u %s", key, UidPermissionTypeToString(value).c_str());
- return base::Result<void>();
- };
- res = mUidPermissionMap.iterateWithValue(printUidPermissionInfo);
- if (!res.ok()) {
- dw.println("mUidPermissionMap print end with error: %s", res.error().message().c_str());
- }
-
- dumpBpfMap("mPrivilegedUser", dw, "");
- for (uid_t uid : mPrivilegedUser) {
- dw.println("%u ALLOW_UPDATE_DEVICE_STATS", (uint32_t)uid);
- }
-}
-
-} // namespace net
-} // namespace android
diff --git a/server/TrafficController.h b/server/TrafficController.h
deleted file mode 100644
index 2e79959..0000000
--- a/server/TrafficController.h
+++ /dev/null
@@ -1,254 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#ifndef NETD_SERVER_TRAFFIC_CONTROLLER_H
-#define NETD_SERVER_TRAFFIC_CONTROLLER_H
-
-#include <linux/bpf.h>
-
-#include "BandwidthController.h"
-#include "FirewallController.h"
-#include "NetlinkListener.h"
-#include "Network.h"
-#include "android-base/thread_annotations.h"
-#include "android-base/unique_fd.h"
-#include "bpf/BpfMap.h"
-#include "netdbpf/bpf_shared.h"
-#include "netdutils/DumpWriter.h"
-#include "netdutils/StatusOr.h"
-#include "utils/String16.h"
-
-using android::bpf::BpfMap;
-
-namespace android {
-namespace net {
-
-class TrafficController {
- public:
- TrafficController();
- /*
- * Initialize the whole controller
- */
- netdutils::Status start();
- /*
- * Tag the socket with the specified tag and uid. In the qtaguid module, the
- * first tag request that grab the spinlock of rb_tree can update the tag
- * information first and other request need to wait until it finish. All the
- * tag request will be addressed in the order of they obtaining the spinlock.
- * In the eBPF implementation, the kernel will try to update the eBPF map
- * entry with the tag request. And the hashmap update process is protected by
- * the spinlock initialized with the map. So the behavior of two modules
- * should be the same. No additional lock needed.
- */
- int tagSocket(int sockFd, uint32_t tag, uid_t uid, uid_t callingUid) EXCLUDES(mMutex);
-
- /*
- * The untag process is similiar to tag socket and both old qtaguid module and
- * new eBPF module have spinlock inside the kernel for concurrent update. No
- * external lock is required.
- */
- int untagSocket(int sockFd);
-
- /*
- * Similiar as above, no external lock required.
- */
- int setCounterSet(int counterSetNum, uid_t uid, uid_t callingUid) EXCLUDES(mMutex);
-
- /*
- * When deleting a tag data, the qtaguid module will grab the spinlock of each
- * related rb_tree one by one and delete the tag information, counterSet
- * information, iface stats information and uid stats information one by one.
- * The new eBPF implementation is done similiarly by removing the entry on
- * each map one by one. And deleting processes are also protected by the
- * spinlock of the map. So no additional lock is required.
- */
- int deleteTagData(uint32_t tag, uid_t uid, uid_t callingUid) EXCLUDES(mMutex);
-
- /*
- * Swap the stats map config from current active stats map to the idle one.
- */
- netdutils::Status swapActiveStatsMap() EXCLUDES(mMutex);
-
- /*
- * Add the interface name and index pair into the eBPF map.
- */
- int addInterface(const char* name, uint32_t ifaceIndex);
-
- int changeUidOwnerRule(ChildChain chain, const uid_t uid, FirewallRule rule, FirewallType type);
-
- int removeUidOwnerRule(const uid_t uid);
-
- int replaceUidOwnerMap(const std::string& name, bool isAllowlist,
- const std::vector<int32_t>& uids);
-
- netdutils::Status updateOwnerMapEntry(UidOwnerMatchType match, uid_t uid, FirewallRule rule,
- FirewallType type) EXCLUDES(mMutex);
-
- void dump(netdutils::DumpWriter& dw, bool verbose) EXCLUDES(mMutex);
-
- netdutils::Status replaceRulesInMap(UidOwnerMatchType match, const std::vector<int32_t>& uids)
- EXCLUDES(mMutex);
-
- netdutils::Status addUidInterfaceRules(const int ifIndex, const std::vector<int32_t>& uids)
- EXCLUDES(mMutex);
- netdutils::Status removeUidInterfaceRules(const std::vector<int32_t>& uids) EXCLUDES(mMutex);
-
- netdutils::Status updateUidOwnerMap(const std::vector<uint32_t>& appStrUids,
- UidOwnerMatchType matchType, BandwidthController::IptOp op)
- EXCLUDES(mMutex);
- static const String16 DUMP_KEYWORD;
-
- int toggleUidOwnerMap(ChildChain chain, bool enable) EXCLUDES(mMutex);
-
- static netdutils::StatusOr<std::unique_ptr<NetlinkListenerInterface>> makeSkDestroyListener();
-
- void setPermissionForUids(int permission, const std::vector<uid_t>& uids) EXCLUDES(mMutex);
-
- private:
- /*
- * mCookieTagMap: Store the corresponding tag and uid for a specific socket.
- * DO NOT hold any locks when modifying this map, otherwise when the untag
- * operation is waiting for a lock hold by other process and there are more
- * sockets being closed than can fit in the socket buffer of the netlink socket
- * that receives them, then the kernel will drop some of these sockets and we
- * won't delete their tags.
- * Map Key: uint64_t socket cookie
- * Map Value: UidTagValue, contains a uint32 uid and a uint32 tag.
- */
- BpfMap<uint64_t, UidTagValue> mCookieTagMap GUARDED_BY(mMutex);
-
- /*
- * mUidCounterSetMap: Store the counterSet of a specific uid.
- * Map Key: uint32 uid.
- * Map Value: uint32 counterSet specifies if the traffic is a background
- * or foreground traffic.
- */
- BpfMap<uint32_t, uint8_t> mUidCounterSetMap GUARDED_BY(mMutex);
-
- /*
- * mAppUidStatsMap: Store the total traffic stats for a uid regardless of
- * tag, counterSet and iface. The stats is used by TrafficStats.getUidStats
- * API to return persistent stats for a specific uid since device boot.
- */
- BpfMap<uint32_t, StatsValue> mAppUidStatsMap;
-
- /*
- * mStatsMapA/mStatsMapB: Store the traffic statistics for a specific
- * combination of uid, tag, iface and counterSet. These two maps contain
- * both tagged and untagged traffic.
- * Map Key: StatsKey contains the uid, tag, counterSet and ifaceIndex
- * information.
- * Map Value: Stats, contains packet count and byte count of each
- * transport protocol on egress and ingress direction.
- */
- BpfMap<StatsKey, StatsValue> mStatsMapA GUARDED_BY(mMutex);
-
- BpfMap<StatsKey, StatsValue> mStatsMapB GUARDED_BY(mMutex);
-
- /*
- * mIfaceIndexNameMap: Store the index name pair of each interface show up
- * on the device since boot. The interface index is used by the eBPF program
- * to correctly match the iface name when receiving a packet.
- */
- BpfMap<uint32_t, IfaceValue> mIfaceIndexNameMap;
-
- /*
- * mIfaceStataMap: Store per iface traffic stats gathered from xt_bpf
- * filter.
- */
- BpfMap<uint32_t, StatsValue> mIfaceStatsMap;
-
- /*
- * mConfigurationMap: Store the current network policy about uid filtering
- * and the current stats map in use. There are two configuration entries in
- * the map right now:
- * - Entry with UID_RULES_CONFIGURATION_KEY:
- * Store the configuration for the current uid rules. It indicates the device
- * is in doze/powersave/standby/restricted mode.
- * - Entry with CURRENT_STATS_MAP_CONFIGURATION_KEY:
- * Stores the current live stats map that kernel program is writing to.
- * Userspace can do scraping and cleaning job on the other one depending on the
- * current configs.
- */
- BpfMap<uint32_t, uint8_t> mConfigurationMap GUARDED_BY(mMutex);
-
- /*
- * mUidOwnerMap: Store uids that are used for bandwidth control uid match.
- */
- BpfMap<uint32_t, UidOwnerValue> mUidOwnerMap GUARDED_BY(mMutex);
-
- /*
- * mUidOwnerMap: Store uids that are used for INTERNET permission check.
- */
- BpfMap<uint32_t, uint8_t> mUidPermissionMap GUARDED_BY(mMutex);
-
- std::unique_ptr<NetlinkListenerInterface> mSkDestroyListener;
-
- netdutils::Status removeRule(uint32_t uid, UidOwnerMatchType match) REQUIRES(mMutex);
-
- netdutils::Status addRule(uint32_t uid, UidOwnerMatchType match, uint32_t iif = 0)
- REQUIRES(mMutex);
-
- // mMutex guards all accesses to mConfigurationMap, mUidOwnerMap, mUidPermissionMap,
- // mStatsMapA, mStatsMapB and mPrivilegedUser. It is designed to solve the following
- // problems:
- // 1. Prevent concurrent access and modification to mConfigurationMap, mUidOwnerMap,
- // mUidPermissionMap, and mPrivilegedUser. These data members are controlled by netd but can
- // be modified from different threads. TrafficController provides several APIs directly
- // called by the binder RPC, and different binder threads can concurrently access these data
- // members mentioned above. Some of the data members such as mUidPermissionMap and
- // mPrivilegedUsers are also accessed from a different thread when tagging sockets or
- // setting the counterSet through FwmarkServer
- // 2. Coordinate the deletion of uid stats in mStatsMapA and mStatsMapB. The system server
- // always call into netd to ask for a live stats map change before it pull and clean up the
- // stats from the inactive map. The mMutex will block netd from accessing the stats map when
- // the mConfigurationMap is updating the current stats map so netd will not accidentally
- // read the map that system_server is cleaning up.
- std::mutex mMutex;
-
- // The limit on the number of stats entries a uid can have in the per uid stats map.
- // TrafficController will block that specific uid from tagging new sockets after the limit is
- // reached.
- const uint32_t mPerUidStatsEntriesLimit;
-
- // The limit on the total number of stats entries in the per uid stats map. TrafficController
- // will block all tagging requests after the limit is reached.
- const uint32_t mTotalUidStatsEntriesLimit;
-
- netdutils::Status loadAndAttachProgram(bpf_attach_type type, const char* path, const char* name,
- base::unique_fd& cg_fd);
-
- netdutils::Status initMaps() EXCLUDES(mMutex);
-
- // Keep track of uids that have permission UPDATE_DEVICE_STATS so we don't
- // need to call back to system server for permission check.
- std::set<uid_t> mPrivilegedUser GUARDED_BY(mMutex);
-
- UidOwnerMatchType jumpOpToMatch(BandwidthController::IptJumpOp jumpHandling);
-
- bool hasUpdateDeviceStatsPermission(uid_t uid) REQUIRES(mMutex);
-
- // For testing
- TrafficController(uint32_t perUidLimit, uint32_t totalLimit);
-
- // For testing
- friend class TrafficControllerTest;
-};
-
-} // namespace net
-} // namespace android
-
-#endif // NETD_SERVER_TRAFFIC_CONTROLLER_H
diff --git a/server/TrafficControllerTest.cpp b/server/TrafficControllerTest.cpp
deleted file mode 100644
index 159fb08..0000000
--- a/server/TrafficControllerTest.cpp
+++ /dev/null
@@ -1,880 +0,0 @@
-/*
- * Copyright 2017 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.
- *
- * TrafficControllerTest.cpp - unit tests for TrafficController.cpp
- */
-
-#include <cstdint>
-#include <string>
-#include <vector>
-
-#include <fcntl.h>
-#include <inttypes.h>
-#include <linux/inet_diag.h>
-#include <linux/sock_diag.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-#include <gtest/gtest.h>
-
-#include <android-base/stringprintf.h>
-#include <android-base/strings.h>
-
-#include <netdutils/MockSyscalls.h>
-
-#include "FirewallController.h"
-#include "TrafficController.h"
-#include "bpf/BpfUtils.h"
-
-using namespace android::bpf; // NOLINT(google-build-using-namespace): grandfathered
-
-namespace android {
-namespace net {
-
-using base::Result;
-using netdutils::isOk;
-
-constexpr int TEST_MAP_SIZE = 10;
-constexpr int TEST_COOKIE = 1;
-constexpr uid_t TEST_UID = 10086;
-constexpr uid_t TEST_UID2 = 54321;
-constexpr uid_t TEST_UID3 = 98765;
-constexpr uint32_t TEST_TAG = 42;
-constexpr uint32_t TEST_COUNTERSET = 1;
-constexpr uint32_t DEFAULT_COUNTERSET = 0;
-constexpr uint32_t TEST_PER_UID_STATS_ENTRIES_LIMIT = 3;
-constexpr uint32_t TEST_TOTAL_UID_STATS_ENTRIES_LIMIT = 7;
-
-#define ASSERT_VALID(x) ASSERT_TRUE((x).isValid())
-
-class TrafficControllerTest : public ::testing::Test {
- protected:
- TrafficControllerTest()
- : mTc(TEST_PER_UID_STATS_ENTRIES_LIMIT, TEST_TOTAL_UID_STATS_ENTRIES_LIMIT) {}
- TrafficController mTc;
- BpfMap<uint64_t, UidTagValue> mFakeCookieTagMap;
- BpfMap<uint32_t, uint8_t> mFakeUidCounterSetMap;
- BpfMap<uint32_t, StatsValue> mFakeAppUidStatsMap;
- BpfMap<StatsKey, StatsValue> mFakeStatsMapA;
- BpfMap<uint32_t, uint8_t> mFakeConfigurationMap;
- BpfMap<uint32_t, UidOwnerValue> mFakeUidOwnerMap;
- BpfMap<uint32_t, uint8_t> mFakeUidPermissionMap;
-
- void SetUp() {
- std::lock_guard guard(mTc.mMutex);
- ASSERT_EQ(0, setrlimitForTest());
-
- mFakeCookieTagMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint64_t), sizeof(UidTagValue),
- TEST_MAP_SIZE, 0));
- ASSERT_VALID(mFakeCookieTagMap);
-
- mFakeUidCounterSetMap.reset(
- createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
- ASSERT_VALID(mFakeUidCounterSetMap);
-
- mFakeAppUidStatsMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(StatsValue),
- TEST_MAP_SIZE, 0));
- ASSERT_VALID(mFakeAppUidStatsMap);
-
- mFakeStatsMapA.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(StatsKey), sizeof(StatsValue),
- TEST_MAP_SIZE, 0));
- ASSERT_VALID(mFakeStatsMapA);
-
- mFakeConfigurationMap.reset(
- createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), 1, 0));
- ASSERT_VALID(mFakeConfigurationMap);
-
- mFakeUidOwnerMap.reset(createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(UidOwnerValue),
- TEST_MAP_SIZE, 0));
- ASSERT_VALID(mFakeUidOwnerMap);
- mFakeUidPermissionMap.reset(
- createMap(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint8_t), TEST_MAP_SIZE, 0));
- ASSERT_VALID(mFakeUidPermissionMap);
-
- mTc.mCookieTagMap.reset(dupFd(mFakeCookieTagMap.getMap()));
- ASSERT_VALID(mTc.mCookieTagMap);
- mTc.mUidCounterSetMap.reset(dupFd(mFakeUidCounterSetMap.getMap()));
- ASSERT_VALID(mTc.mUidCounterSetMap);
- mTc.mAppUidStatsMap.reset(dupFd(mFakeAppUidStatsMap.getMap()));
- ASSERT_VALID(mTc.mAppUidStatsMap);
- mTc.mStatsMapA.reset(dupFd(mFakeStatsMapA.getMap()));
- ASSERT_VALID(mTc.mStatsMapA);
- mTc.mConfigurationMap.reset(dupFd(mFakeConfigurationMap.getMap()));
- ASSERT_VALID(mTc.mConfigurationMap);
-
- // Always write to stats map A by default.
- ASSERT_RESULT_OK(mTc.mConfigurationMap.writeValue(CURRENT_STATS_MAP_CONFIGURATION_KEY,
- SELECT_MAP_A, BPF_ANY));
- mTc.mUidOwnerMap.reset(dupFd(mFakeUidOwnerMap.getMap()));
- ASSERT_VALID(mTc.mUidOwnerMap);
- mTc.mUidPermissionMap.reset(dupFd(mFakeUidPermissionMap.getMap()));
- ASSERT_VALID(mTc.mUidPermissionMap);
- mTc.mPrivilegedUser.clear();
- }
-
- int dupFd(const android::base::unique_fd& mapFd) {
- return fcntl(mapFd.get(), F_DUPFD_CLOEXEC, 0);
- }
-
- int setUpSocketAndTag(int protocol, uint64_t* cookie, uint32_t tag, uid_t uid,
- uid_t callingUid) {
- int sock = socket(protocol, SOCK_STREAM | SOCK_CLOEXEC, 0);
- EXPECT_LE(0, sock);
- *cookie = getSocketCookie(sock);
- EXPECT_NE(NONEXISTENT_COOKIE, *cookie);
- EXPECT_EQ(0, mTc.tagSocket(sock, tag, uid, callingUid));
- return sock;
- }
-
- void expectUidTag(uint64_t cookie, uid_t uid, uint32_t tag) {
- Result<UidTagValue> tagResult = mFakeCookieTagMap.readValue(cookie);
- ASSERT_RESULT_OK(tagResult);
- EXPECT_EQ(uid, tagResult.value().uid);
- EXPECT_EQ(tag, tagResult.value().tag);
- }
-
- void expectNoTag(uint64_t cookie) { EXPECT_FALSE(mFakeCookieTagMap.readValue(cookie).ok()); }
-
- void populateFakeStats(uint64_t cookie, uint32_t uid, uint32_t tag, StatsKey* key) {
- UidTagValue cookieMapkey = {.uid = (uint32_t)uid, .tag = tag};
- EXPECT_RESULT_OK(mFakeCookieTagMap.writeValue(cookie, cookieMapkey, BPF_ANY));
- *key = {.uid = uid, .tag = tag, .counterSet = TEST_COUNTERSET, .ifaceIndex = 1};
- StatsValue statsMapValue = {.rxPackets = 1, .rxBytes = 100};
- uint8_t counterSet = TEST_COUNTERSET;
- EXPECT_RESULT_OK(mFakeUidCounterSetMap.writeValue(uid, counterSet, BPF_ANY));
- EXPECT_RESULT_OK(mFakeStatsMapA.writeValue(*key, statsMapValue, BPF_ANY));
- key->tag = 0;
- EXPECT_RESULT_OK(mFakeStatsMapA.writeValue(*key, statsMapValue, BPF_ANY));
- EXPECT_RESULT_OK(mFakeAppUidStatsMap.writeValue(uid, statsMapValue, BPF_ANY));
- // put tag information back to statsKey
- key->tag = tag;
- }
-
- void checkUidOwnerRuleForChain(ChildChain chain, UidOwnerMatchType match) {
- uint32_t uid = TEST_UID;
- EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, DENYLIST));
- Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
- EXPECT_RESULT_OK(value);
- EXPECT_TRUE(value.value().rule & match);
-
- uid = TEST_UID2;
- EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, ALLOWLIST));
- value = mFakeUidOwnerMap.readValue(uid);
- EXPECT_RESULT_OK(value);
- EXPECT_TRUE(value.value().rule & match);
-
- EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, DENY, ALLOWLIST));
- value = mFakeUidOwnerMap.readValue(uid);
- EXPECT_FALSE(value.ok());
- EXPECT_EQ(ENOENT, value.error().code());
-
- uid = TEST_UID;
- EXPECT_EQ(0, mTc.changeUidOwnerRule(chain, uid, ALLOW, DENYLIST));
- value = mFakeUidOwnerMap.readValue(uid);
- EXPECT_FALSE(value.ok());
- EXPECT_EQ(ENOENT, value.error().code());
-
- uid = TEST_UID3;
- EXPECT_EQ(-ENOENT, mTc.changeUidOwnerRule(chain, uid, ALLOW, DENYLIST));
- value = mFakeUidOwnerMap.readValue(uid);
- EXPECT_FALSE(value.ok());
- EXPECT_EQ(ENOENT, value.error().code());
- }
-
- void checkEachUidValue(const std::vector<int32_t>& uids, UidOwnerMatchType match) {
- for (uint32_t uid : uids) {
- Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
- EXPECT_RESULT_OK(value);
- EXPECT_TRUE(value.value().rule & match);
- }
- std::set<uint32_t> uidSet(uids.begin(), uids.end());
- const auto checkNoOtherUid = [&uidSet](const int32_t& key,
- const BpfMap<uint32_t, UidOwnerValue>&) {
- EXPECT_NE(uidSet.end(), uidSet.find(key));
- return Result<void>();
- };
- EXPECT_RESULT_OK(mFakeUidOwnerMap.iterate(checkNoOtherUid));
- }
-
- void checkUidMapReplace(const std::string& name, const std::vector<int32_t>& uids,
- UidOwnerMatchType match) {
- bool isAllowlist = true;
- EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isAllowlist, uids));
- checkEachUidValue(uids, match);
-
- isAllowlist = false;
- EXPECT_EQ(0, mTc.replaceUidOwnerMap(name, isAllowlist, uids));
- checkEachUidValue(uids, match);
- }
-
- void expectUidOwnerMapValues(const std::vector<uint32_t>& appUids, uint8_t expectedRule,
- uint32_t expectedIif) {
- for (uint32_t uid : appUids) {
- Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
- EXPECT_RESULT_OK(value);
- EXPECT_EQ(expectedRule, value.value().rule)
- << "Expected rule for UID " << uid << " to be " << expectedRule << ", but was "
- << value.value().rule;
- EXPECT_EQ(expectedIif, value.value().iif)
- << "Expected iif for UID " << uid << " to be " << expectedIif << ", but was "
- << value.value().iif;
- }
- }
-
- template <class Key, class Value>
- void expectMapEmpty(BpfMap<Key, Value>& map) {
- auto isEmpty = map.isEmpty();
- EXPECT_RESULT_OK(isEmpty);
- EXPECT_TRUE(isEmpty.value());
- }
-
- void expectUidPermissionMapValues(const std::vector<uid_t>& appUids, uint8_t expectedValue) {
- for (uid_t uid : appUids) {
- Result<uint8_t> value = mFakeUidPermissionMap.readValue(uid);
- EXPECT_RESULT_OK(value);
- EXPECT_EQ(expectedValue, value.value())
- << "Expected value for UID " << uid << " to be " << expectedValue
- << ", but was " << value.value();
- }
- }
-
- void expectPrivilegedUserSet(const std::vector<uid_t>& appUids) {
- std::lock_guard guard(mTc.mMutex);
- EXPECT_EQ(appUids.size(), mTc.mPrivilegedUser.size());
- for (uid_t uid : appUids) {
- EXPECT_NE(mTc.mPrivilegedUser.end(), mTc.mPrivilegedUser.find(uid));
- }
- }
-
- void expectPrivilegedUserSetEmpty() {
- std::lock_guard guard(mTc.mMutex);
- EXPECT_TRUE(mTc.mPrivilegedUser.empty());
- }
-
- void addPrivilegedUid(uid_t uid) {
- std::vector privilegedUid = {uid};
- mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, privilegedUid);
- }
-
- void removePrivilegedUid(uid_t uid) {
- std::vector privilegedUid = {uid};
- mTc.setPermissionForUids(INetd::PERMISSION_NONE, privilegedUid);
- }
-
- void expectFakeStatsUnchanged(uint64_t cookie, uint32_t tag, uint32_t uid,
- StatsKey tagStatsMapKey) {
- Result<UidTagValue> cookieMapResult = mFakeCookieTagMap.readValue(cookie);
- EXPECT_RESULT_OK(cookieMapResult);
- EXPECT_EQ(uid, cookieMapResult.value().uid);
- EXPECT_EQ(tag, cookieMapResult.value().tag);
- Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
- EXPECT_RESULT_OK(counterSetResult);
- EXPECT_EQ(TEST_COUNTERSET, counterSetResult.value());
- Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
- EXPECT_RESULT_OK(statsMapResult);
- EXPECT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
- EXPECT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
- tagStatsMapKey.tag = 0;
- statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
- EXPECT_RESULT_OK(statsMapResult);
- EXPECT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
- EXPECT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
- auto appStatsResult = mFakeAppUidStatsMap.readValue(uid);
- EXPECT_RESULT_OK(appStatsResult);
- EXPECT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
- EXPECT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
- }
-
- void expectTagSocketReachLimit(uint32_t tag, uint32_t uid) {
- int sock = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
- EXPECT_LE(0, sock);
- if (sock < 0) return;
- uint64_t sockCookie = getSocketCookie(sock);
- EXPECT_NE(NONEXISTENT_COOKIE, sockCookie);
- EXPECT_EQ(-EMFILE, mTc.tagSocket(sock, tag, uid, uid));
- expectNoTag(sockCookie);
-
- // Delete stats entries then tag socket success
- EXPECT_EQ(0, mTc.deleteTagData(0, uid, 0));
- EXPECT_EQ(0, mTc.tagSocket(sock, tag, uid, uid));
- expectUidTag(sockCookie, uid, tag);
- }
-};
-
-TEST_F(TrafficControllerTest, TestTagSocketV4) {
- uint64_t sockCookie;
- int v4socket = setUpSocketAndTag(AF_INET, &sockCookie, TEST_TAG, TEST_UID, TEST_UID);
- expectUidTag(sockCookie, TEST_UID, TEST_TAG);
- ASSERT_EQ(0, mTc.untagSocket(v4socket));
- expectNoTag(sockCookie);
- expectMapEmpty(mFakeCookieTagMap);
-}
-
-TEST_F(TrafficControllerTest, TestReTagSocket) {
- uint64_t sockCookie;
- int v4socket = setUpSocketAndTag(AF_INET, &sockCookie, TEST_TAG, TEST_UID, TEST_UID);
- expectUidTag(sockCookie, TEST_UID, TEST_TAG);
- ASSERT_EQ(0, mTc.tagSocket(v4socket, TEST_TAG + 1, TEST_UID + 1, TEST_UID + 1));
- expectUidTag(sockCookie, TEST_UID + 1, TEST_TAG + 1);
-}
-
-TEST_F(TrafficControllerTest, TestTagTwoSockets) {
- uint64_t sockCookie1;
- uint64_t sockCookie2;
- int v4socket1 = setUpSocketAndTag(AF_INET, &sockCookie1, TEST_TAG, TEST_UID, TEST_UID);
- setUpSocketAndTag(AF_INET, &sockCookie2, TEST_TAG, TEST_UID, TEST_UID);
- expectUidTag(sockCookie1, TEST_UID, TEST_TAG);
- expectUidTag(sockCookie2, TEST_UID, TEST_TAG);
- ASSERT_EQ(0, mTc.untagSocket(v4socket1));
- expectNoTag(sockCookie1);
- expectUidTag(sockCookie2, TEST_UID, TEST_TAG);
- ASSERT_FALSE(mFakeCookieTagMap.getNextKey(sockCookie2).ok());
-}
-
-TEST_F(TrafficControllerTest, TestTagSocketV6) {
- uint64_t sockCookie;
- int v6socket = setUpSocketAndTag(AF_INET6, &sockCookie, TEST_TAG, TEST_UID, TEST_UID);
- expectUidTag(sockCookie, TEST_UID, TEST_TAG);
- ASSERT_EQ(0, mTc.untagSocket(v6socket));
- expectNoTag(sockCookie);
- expectMapEmpty(mFakeCookieTagMap);
-}
-
-TEST_F(TrafficControllerTest, TestTagInvalidSocket) {
- int invalidSocket = -1;
- ASSERT_GT(0, mTc.tagSocket(invalidSocket, TEST_TAG, TEST_UID, TEST_UID));
- expectMapEmpty(mFakeCookieTagMap);
-}
-
-TEST_F(TrafficControllerTest, TestTagSocketWithoutPermission) {
- int sock = socket(AF_INET6, SOCK_STREAM | SOCK_CLOEXEC, 0);
- ASSERT_NE(-1, sock);
- ASSERT_EQ(-EPERM, mTc.tagSocket(sock, TEST_TAG, TEST_UID, TEST_UID2));
- expectMapEmpty(mFakeCookieTagMap);
-}
-
-TEST_F(TrafficControllerTest, TestTagSocketWithPermission) {
- // Grant permission to calling uid.
- std::vector<uid_t> callingUid = {TEST_UID2};
- mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, callingUid);
-
- // Tag a socket to a different uid other then callingUid.
- uint64_t sockCookie;
- int v6socket = setUpSocketAndTag(AF_INET6, &sockCookie, TEST_TAG, TEST_UID, TEST_UID2);
- expectUidTag(sockCookie, TEST_UID, TEST_TAG);
- EXPECT_EQ(0, mTc.untagSocket(v6socket));
- expectNoTag(sockCookie);
- expectMapEmpty(mFakeCookieTagMap);
-
- // Clean up the permission
- mTc.setPermissionForUids(INetd::PERMISSION_NONE, callingUid);
- expectPrivilegedUserSetEmpty();
-}
-
-TEST_F(TrafficControllerTest, TestUntagInvalidSocket) {
- int invalidSocket = -1;
- ASSERT_GT(0, mTc.untagSocket(invalidSocket));
- int v4socket = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
- ASSERT_GT(0, mTc.untagSocket(v4socket));
- expectMapEmpty(mFakeCookieTagMap);
-}
-
-TEST_F(TrafficControllerTest, TestTagSocketReachLimitFail) {
- uid_t uid = TEST_UID;
- StatsKey tagStatsMapKey[4];
- for (int i = 0; i < 3; i++) {
- uint64_t cookie = TEST_COOKIE + i;
- uint32_t tag = TEST_TAG + i;
- populateFakeStats(cookie, uid, tag, &tagStatsMapKey[i]);
- }
- expectTagSocketReachLimit(TEST_TAG, TEST_UID);
-}
-
-TEST_F(TrafficControllerTest, TestTagSocketReachTotalLimitFail) {
- StatsKey tagStatsMapKey[4];
- for (int i = 0; i < 4; i++) {
- uint64_t cookie = TEST_COOKIE + i;
- uint32_t tag = TEST_TAG + i;
- uid_t uid = TEST_UID + i;
- populateFakeStats(cookie, uid, tag, &tagStatsMapKey[i]);
- }
- expectTagSocketReachLimit(TEST_TAG, TEST_UID);
-}
-
-TEST_F(TrafficControllerTest, TestSetCounterSet) {
- uid_t callingUid = TEST_UID2;
- addPrivilegedUid(callingUid);
- ASSERT_EQ(0, mTc.setCounterSet(TEST_COUNTERSET, TEST_UID, callingUid));
- uid_t uid = TEST_UID;
- Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
- ASSERT_RESULT_OK(counterSetResult);
- ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
- ASSERT_EQ(0, mTc.setCounterSet(DEFAULT_COUNTERSET, TEST_UID, callingUid));
- ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
- expectMapEmpty(mFakeUidCounterSetMap);
-}
-
-TEST_F(TrafficControllerTest, TestSetCounterSetWithoutPermission) {
- ASSERT_EQ(-EPERM, mTc.setCounterSet(TEST_COUNTERSET, TEST_UID, TEST_UID2));
- uid_t uid = TEST_UID;
- ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
- expectMapEmpty(mFakeUidCounterSetMap);
-}
-
-TEST_F(TrafficControllerTest, TestSetInvalidCounterSet) {
- uid_t callingUid = TEST_UID2;
- addPrivilegedUid(callingUid);
- ASSERT_GT(0, mTc.setCounterSet(OVERFLOW_COUNTERSET, TEST_UID, callingUid));
- uid_t uid = TEST_UID;
- ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
- expectMapEmpty(mFakeUidCounterSetMap);
-}
-
-TEST_F(TrafficControllerTest, TestDeleteTagDataWithoutPermission) {
- uint64_t cookie = 1;
- uid_t uid = TEST_UID;
- uint32_t tag = TEST_TAG;
- StatsKey tagStatsMapKey;
- populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
- ASSERT_EQ(-EPERM, mTc.deleteTagData(0, TEST_UID, TEST_UID2));
-
- expectFakeStatsUnchanged(cookie, tag, uid, tagStatsMapKey);
-}
-
-TEST_F(TrafficControllerTest, TestDeleteTagData) {
- uid_t callingUid = TEST_UID2;
- addPrivilegedUid(callingUid);
- uint64_t cookie = 1;
- uid_t uid = TEST_UID;
- uint32_t tag = TEST_TAG;
- StatsKey tagStatsMapKey;
- populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
- ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID, callingUid));
- ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie).ok());
- Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
- ASSERT_RESULT_OK(counterSetResult);
- ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
- ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey).ok());
- tagStatsMapKey.tag = 0;
- Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey);
- ASSERT_RESULT_OK(statsMapResult);
- ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
- ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
- auto appStatsResult = mFakeAppUidStatsMap.readValue(TEST_UID);
- ASSERT_RESULT_OK(appStatsResult);
- ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
- ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
-}
-
-TEST_F(TrafficControllerTest, TestDeleteAllUidData) {
- uid_t callingUid = TEST_UID2;
- addPrivilegedUid(callingUid);
- uint64_t cookie = 1;
- uid_t uid = TEST_UID;
- uint32_t tag = TEST_TAG;
- StatsKey tagStatsMapKey;
- populateFakeStats(cookie, uid, tag, &tagStatsMapKey);
- ASSERT_EQ(0, mTc.deleteTagData(0, TEST_UID, callingUid));
- ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie).ok());
- ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid).ok());
- ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey).ok());
- tagStatsMapKey.tag = 0;
- ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey).ok());
- ASSERT_FALSE(mFakeAppUidStatsMap.readValue(TEST_UID).ok());
-}
-
-TEST_F(TrafficControllerTest, TestDeleteDataWithTwoTags) {
- uid_t callingUid = TEST_UID2;
- addPrivilegedUid(callingUid);
- uint64_t cookie1 = 1;
- uint64_t cookie2 = 2;
- uid_t uid = TEST_UID;
- uint32_t tag1 = TEST_TAG;
- uint32_t tag2 = TEST_TAG + 1;
- StatsKey tagStatsMapKey1;
- StatsKey tagStatsMapKey2;
- populateFakeStats(cookie1, uid, tag1, &tagStatsMapKey1);
- populateFakeStats(cookie2, uid, tag2, &tagStatsMapKey2);
- ASSERT_EQ(0, mTc.deleteTagData(TEST_TAG, TEST_UID, callingUid));
- ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie1).ok());
- Result<UidTagValue> cookieMapResult = mFakeCookieTagMap.readValue(cookie2);
- ASSERT_RESULT_OK(cookieMapResult);
- ASSERT_EQ(TEST_UID, cookieMapResult.value().uid);
- ASSERT_EQ(TEST_TAG + 1, cookieMapResult.value().tag);
- Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid);
- ASSERT_RESULT_OK(counterSetResult);
- ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
- ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey1).ok());
- Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey2);
- ASSERT_RESULT_OK(statsMapResult);
- ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
- ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
-}
-
-TEST_F(TrafficControllerTest, TestDeleteDataWithTwoUids) {
- uid_t callingUid = TEST_UID2;
- addPrivilegedUid(callingUid);
- uint64_t cookie1 = 1;
- uint64_t cookie2 = 2;
- uid_t uid1 = TEST_UID;
- uid_t uid2 = TEST_UID + 1;
- uint32_t tag = TEST_TAG;
- StatsKey tagStatsMapKey1;
- StatsKey tagStatsMapKey2;
- populateFakeStats(cookie1, uid1, tag, &tagStatsMapKey1);
- populateFakeStats(cookie2, uid2, tag, &tagStatsMapKey2);
-
- // Delete the stats of one of the uid. Check if it is properly collected by
- // removedStats.
- ASSERT_EQ(0, mTc.deleteTagData(0, uid2, callingUid));
- ASSERT_FALSE(mFakeCookieTagMap.readValue(cookie2).ok());
- Result<uint8_t> counterSetResult = mFakeUidCounterSetMap.readValue(uid1);
- ASSERT_RESULT_OK(counterSetResult);
- ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
- ASSERT_FALSE(mFakeUidCounterSetMap.readValue(uid2).ok());
- ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey2).ok());
- tagStatsMapKey2.tag = 0;
- ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey2).ok());
- ASSERT_FALSE(mFakeAppUidStatsMap.readValue(uid2).ok());
- tagStatsMapKey1.tag = 0;
- Result<StatsValue> statsMapResult = mFakeStatsMapA.readValue(tagStatsMapKey1);
- ASSERT_RESULT_OK(statsMapResult);
- ASSERT_EQ((uint64_t)1, statsMapResult.value().rxPackets);
- ASSERT_EQ((uint64_t)100, statsMapResult.value().rxBytes);
- auto appStatsResult = mFakeAppUidStatsMap.readValue(uid1);
- ASSERT_RESULT_OK(appStatsResult);
- ASSERT_EQ((uint64_t)1, appStatsResult.value().rxPackets);
- ASSERT_EQ((uint64_t)100, appStatsResult.value().rxBytes);
-
- // Delete the stats of the other uid.
- ASSERT_EQ(0, mTc.deleteTagData(0, uid1, callingUid));
- ASSERT_FALSE(mFakeStatsMapA.readValue(tagStatsMapKey1).ok());
- ASSERT_FALSE(mFakeAppUidStatsMap.readValue(uid1).ok());
-}
-
-TEST_F(TrafficControllerTest, TestUpdateOwnerMapEntry) {
- uint32_t uid = TEST_UID;
- ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, DENY, DENYLIST)));
- Result<UidOwnerValue> value = mFakeUidOwnerMap.readValue(uid);
- ASSERT_RESULT_OK(value);
- ASSERT_TRUE(value.value().rule & STANDBY_MATCH);
-
- ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, ALLOW, ALLOWLIST)));
- value = mFakeUidOwnerMap.readValue(uid);
- ASSERT_RESULT_OK(value);
- ASSERT_TRUE(value.value().rule & DOZABLE_MATCH);
-
- ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(DOZABLE_MATCH, uid, DENY, ALLOWLIST)));
- value = mFakeUidOwnerMap.readValue(uid);
- ASSERT_RESULT_OK(value);
- ASSERT_FALSE(value.value().rule & DOZABLE_MATCH);
-
- ASSERT_TRUE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, DENYLIST)));
- ASSERT_FALSE(mFakeUidOwnerMap.readValue(uid).ok());
-
- uid = TEST_UID2;
- ASSERT_FALSE(isOk(mTc.updateOwnerMapEntry(STANDBY_MATCH, uid, ALLOW, DENYLIST)));
- ASSERT_FALSE(mFakeUidOwnerMap.readValue(uid).ok());
-}
-
-TEST_F(TrafficControllerTest, TestChangeUidOwnerRule) {
- checkUidOwnerRuleForChain(DOZABLE, DOZABLE_MATCH);
- checkUidOwnerRuleForChain(STANDBY, STANDBY_MATCH);
- checkUidOwnerRuleForChain(POWERSAVE, POWERSAVE_MATCH);
- checkUidOwnerRuleForChain(RESTRICTED, RESTRICTED_MATCH);
- ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(NONE, TEST_UID, ALLOW, ALLOWLIST));
- ASSERT_EQ(-EINVAL, mTc.changeUidOwnerRule(INVALID_CHAIN, TEST_UID, ALLOW, ALLOWLIST));
-}
-
-TEST_F(TrafficControllerTest, TestReplaceUidOwnerMap) {
- std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
- checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
- checkUidMapReplace("fw_standby", uids, STANDBY_MATCH);
- checkUidMapReplace("fw_powersave", uids, POWERSAVE_MATCH);
- checkUidMapReplace("fw_restricted", uids, RESTRICTED_MATCH);
- ASSERT_EQ(-EINVAL, mTc.replaceUidOwnerMap("unknow", true, uids));
-}
-
-TEST_F(TrafficControllerTest, TestReplaceSameChain) {
- std::vector<int32_t> uids = {TEST_UID, TEST_UID2, TEST_UID3};
- checkUidMapReplace("fw_dozable", uids, DOZABLE_MATCH);
- std::vector<int32_t> newUids = {TEST_UID2, TEST_UID3};
- checkUidMapReplace("fw_dozable", newUids, DOZABLE_MATCH);
-}
-
-TEST_F(TrafficControllerTest, TestDenylistUidMatch) {
- std::vector<uint32_t> appUids = {1000, 1001, 10012};
- ASSERT_TRUE(isOk(
- mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH, BandwidthController::IptOpInsert)));
- expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);
- ASSERT_TRUE(isOk(
- mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH, BandwidthController::IptOpDelete)));
- expectMapEmpty(mFakeUidOwnerMap);
-}
-
-TEST_F(TrafficControllerTest, TestAllowlistUidMatch) {
- std::vector<uint32_t> appUids = {1000, 1001, 10012};
- ASSERT_TRUE(isOk(
- mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, BandwidthController::IptOpInsert)));
- expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
- ASSERT_TRUE(isOk(
- mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, BandwidthController::IptOpDelete)));
- expectMapEmpty(mFakeUidOwnerMap);
-}
-
-TEST_F(TrafficControllerTest, TestReplaceMatchUid) {
- std::vector<uint32_t> appUids = {1000, 1001, 10012};
- // Add appUids to the denylist and expect that their values are all PENALTY_BOX_MATCH.
- ASSERT_TRUE(isOk(
- mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH, BandwidthController::IptOpInsert)));
- expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);
-
- // Add the same UIDs to the allowlist and expect that we get PENALTY_BOX_MATCH |
- // HAPPY_BOX_MATCH.
- ASSERT_TRUE(isOk(
- mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, BandwidthController::IptOpInsert)));
- expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH | PENALTY_BOX_MATCH, 0);
-
- // Remove the same UIDs from the allowlist and check the PENALTY_BOX_MATCH is still there.
- ASSERT_TRUE(isOk(
- mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, BandwidthController::IptOpDelete)));
- expectUidOwnerMapValues(appUids, PENALTY_BOX_MATCH, 0);
-
- // Remove the same UIDs from the denylist and check the map is empty.
- ASSERT_TRUE(isOk(
- mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH, BandwidthController::IptOpDelete)));
- ASSERT_FALSE(mFakeUidOwnerMap.getFirstKey().ok());
-}
-
-TEST_F(TrafficControllerTest, TestDeleteWrongMatchSilentlyFails) {
- std::vector<uint32_t> appUids = {1000, 1001, 10012};
- // If the uid does not exist in the map, trying to delete a rule about it will fail.
- ASSERT_FALSE(isOk(
- mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, BandwidthController::IptOpDelete)));
- expectMapEmpty(mFakeUidOwnerMap);
-
- // Add denylist rules for appUids.
- ASSERT_TRUE(isOk(
- mTc.updateUidOwnerMap(appUids, HAPPY_BOX_MATCH, BandwidthController::IptOpInsert)));
- expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
-
- // Delete (non-existent) denylist rules for appUids, and check that this silently does
- // nothing if the uid is in the map but does not have denylist match. This is required because
- // NetworkManagementService will try to remove a uid from denylist after adding it to the
- // allowlist and if the remove fails it will not update the uid status.
- ASSERT_TRUE(isOk(
- mTc.updateUidOwnerMap(appUids, PENALTY_BOX_MATCH, BandwidthController::IptOpDelete)));
- expectUidOwnerMapValues(appUids, HAPPY_BOX_MATCH, 0);
-}
-
-TEST_F(TrafficControllerTest, TestAddUidInterfaceFilteringRules) {
- int iif0 = 15;
- ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif0, {1000, 1001})));
- expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
-
- // Add some non-overlapping new uids. They should coexist with existing rules
- int iif1 = 16;
- ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {2000, 2001})));
- expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
- expectUidOwnerMapValues({2000, 2001}, IIF_MATCH, iif1);
-
- // Overwrite some existing uids
- int iif2 = 17;
- ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif2, {1000, 2000})));
- expectUidOwnerMapValues({1001}, IIF_MATCH, iif0);
- expectUidOwnerMapValues({2001}, IIF_MATCH, iif1);
- expectUidOwnerMapValues({1000, 2000}, IIF_MATCH, iif2);
-}
-
-TEST_F(TrafficControllerTest, TestRemoveUidInterfaceFilteringRules) {
- int iif0 = 15;
- int iif1 = 16;
- ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif0, {1000, 1001})));
- ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {2000, 2001})));
- expectUidOwnerMapValues({1000, 1001}, IIF_MATCH, iif0);
- expectUidOwnerMapValues({2000, 2001}, IIF_MATCH, iif1);
-
- // Rmove some uids
- ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1001, 2001})));
- expectUidOwnerMapValues({1000}, IIF_MATCH, iif0);
- expectUidOwnerMapValues({2000}, IIF_MATCH, iif1);
- checkEachUidValue({1000, 2000}, IIF_MATCH); // Make sure there are only two uids remaining
-
- // Remove non-existent uids shouldn't fail
- ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({2000, 3000})));
- expectUidOwnerMapValues({1000}, IIF_MATCH, iif0);
- checkEachUidValue({1000}, IIF_MATCH); // Make sure there are only one uid remaining
-
- // Remove everything
- ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({1000})));
- expectMapEmpty(mFakeUidOwnerMap);
-}
-
-TEST_F(TrafficControllerTest, TestUidInterfaceFilteringRulesCoexistWithExistingMatches) {
- // Set up existing PENALTY_BOX_MATCH rules
- ASSERT_TRUE(isOk(mTc.updateUidOwnerMap({1000, 1001, 10012}, PENALTY_BOX_MATCH,
- BandwidthController::IptOpInsert)));
- expectUidOwnerMapValues({1000, 1001, 10012}, PENALTY_BOX_MATCH, 0);
-
- // Add some partially-overlapping uid owner rules and check result
- int iif1 = 32;
- ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {10012, 10013, 10014})));
- expectUidOwnerMapValues({1000, 1001}, PENALTY_BOX_MATCH, 0);
- expectUidOwnerMapValues({10012}, PENALTY_BOX_MATCH | IIF_MATCH, iif1);
- expectUidOwnerMapValues({10013, 10014}, IIF_MATCH, iif1);
-
- // Removing some PENALTY_BOX_MATCH rules should not change uid interface rule
- ASSERT_TRUE(isOk(mTc.updateUidOwnerMap({1001, 10012}, PENALTY_BOX_MATCH,
- BandwidthController::IptOpDelete)));
- expectUidOwnerMapValues({1000}, PENALTY_BOX_MATCH, 0);
- expectUidOwnerMapValues({10012, 10013, 10014}, IIF_MATCH, iif1);
-
- // Remove all uid interface rules
- ASSERT_TRUE(isOk(mTc.removeUidInterfaceRules({10012, 10013, 10014})));
- expectUidOwnerMapValues({1000}, PENALTY_BOX_MATCH, 0);
- // Make sure these are the only uids left
- checkEachUidValue({1000}, PENALTY_BOX_MATCH);
-}
-
-TEST_F(TrafficControllerTest, TestUidInterfaceFilteringRulesCoexistWithNewMatches) {
- int iif1 = 56;
- // Set up existing uid interface rules
- ASSERT_TRUE(isOk(mTc.addUidInterfaceRules(iif1, {10001, 10002})));
- expectUidOwnerMapValues({10001, 10002}, IIF_MATCH, iif1);
-
- // Add some partially-overlapping doze rules
- EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_dozable", true, {10002, 10003}));
- expectUidOwnerMapValues({10001}, IIF_MATCH, iif1);
- expectUidOwnerMapValues({10002}, DOZABLE_MATCH | IIF_MATCH, iif1);
- expectUidOwnerMapValues({10003}, DOZABLE_MATCH, 0);
-
- // Introduce a third rule type (powersave) on various existing UIDs
- EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_powersave", true, {10000, 10001, 10002, 10003}));
- expectUidOwnerMapValues({10000}, POWERSAVE_MATCH, 0);
- expectUidOwnerMapValues({10001}, POWERSAVE_MATCH | IIF_MATCH, iif1);
- expectUidOwnerMapValues({10002}, POWERSAVE_MATCH | DOZABLE_MATCH | IIF_MATCH, iif1);
- expectUidOwnerMapValues({10003}, POWERSAVE_MATCH | DOZABLE_MATCH, 0);
-
- // Remove all doze rules
- EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_dozable", true, {}));
- expectUidOwnerMapValues({10000}, POWERSAVE_MATCH, 0);
- expectUidOwnerMapValues({10001}, POWERSAVE_MATCH | IIF_MATCH, iif1);
- expectUidOwnerMapValues({10002}, POWERSAVE_MATCH | IIF_MATCH, iif1);
- expectUidOwnerMapValues({10003}, POWERSAVE_MATCH, 0);
-
- // Remove all powersave rules, expect ownerMap to only have uid interface rules left
- EXPECT_EQ(0, mTc.replaceUidOwnerMap("fw_powersave", true, {}));
- expectUidOwnerMapValues({10001, 10002}, IIF_MATCH, iif1);
- // Make sure these are the only uids left
- checkEachUidValue({10001, 10002}, IIF_MATCH);
-}
-
-TEST_F(TrafficControllerTest, TestGrantInternetPermission) {
- std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
-
- mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, appUids);
- expectMapEmpty(mFakeUidPermissionMap);
- expectPrivilegedUserSetEmpty();
-}
-
-TEST_F(TrafficControllerTest, TestRevokeInternetPermission) {
- std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
-
- mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
- expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
-}
-
-TEST_F(TrafficControllerTest, TestPermissionUninstalled) {
- std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
-
- mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
- expectUidPermissionMapValues(appUids, INetd::PERMISSION_UPDATE_DEVICE_STATS);
- expectPrivilegedUserSet(appUids);
-
- std::vector<uid_t> uidToRemove = {TEST_UID};
- mTc.setPermissionForUids(INetd::PERMISSION_UNINSTALLED, uidToRemove);
-
- std::vector<uid_t> uidRemain = {TEST_UID3, TEST_UID2};
- expectUidPermissionMapValues(uidRemain, INetd::PERMISSION_UPDATE_DEVICE_STATS);
- expectPrivilegedUserSet(uidRemain);
-
- mTc.setPermissionForUids(INetd::PERMISSION_UNINSTALLED, uidRemain);
- expectMapEmpty(mFakeUidPermissionMap);
- expectPrivilegedUserSetEmpty();
-}
-
-TEST_F(TrafficControllerTest, TestGrantUpdateStatsPermission) {
- std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
-
- mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
- expectUidPermissionMapValues(appUids, INetd::PERMISSION_UPDATE_DEVICE_STATS);
- expectPrivilegedUserSet(appUids);
-
- mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
- expectPrivilegedUserSetEmpty();
- expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
-}
-
-TEST_F(TrafficControllerTest, TestRevokeUpdateStatsPermission) {
- std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
-
- mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
- expectPrivilegedUserSet(appUids);
-
- std::vector<uid_t> uidToRemove = {TEST_UID};
- mTc.setPermissionForUids(INetd::PERMISSION_NONE, uidToRemove);
-
- std::vector<uid_t> uidRemain = {TEST_UID3, TEST_UID2};
- expectPrivilegedUserSet(uidRemain);
-
- mTc.setPermissionForUids(INetd::PERMISSION_NONE, uidRemain);
- expectPrivilegedUserSetEmpty();
-}
-
-TEST_F(TrafficControllerTest, TestGrantWrongPermission) {
- std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
-
- mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
- expectPrivilegedUserSetEmpty();
- expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
-}
-
-TEST_F(TrafficControllerTest, TestGrantDuplicatePermissionSlientlyFail) {
- std::vector<uid_t> appUids = {TEST_UID, TEST_UID2, TEST_UID3};
-
- mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, appUids);
- expectMapEmpty(mFakeUidPermissionMap);
-
- std::vector<uid_t> uidToAdd = {TEST_UID};
- mTc.setPermissionForUids(INetd::PERMISSION_INTERNET, uidToAdd);
-
- expectPrivilegedUserSetEmpty();
-
- mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
- expectUidPermissionMapValues(appUids, INetd::PERMISSION_NONE);
-
- mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, appUids);
- expectPrivilegedUserSet(appUids);
-
- mTc.setPermissionForUids(INetd::PERMISSION_UPDATE_DEVICE_STATS, uidToAdd);
- expectPrivilegedUserSet(appUids);
-
- mTc.setPermissionForUids(INetd::PERMISSION_NONE, appUids);
- expectPrivilegedUserSetEmpty();
-}
-
-} // namespace net
-} // namespace android
diff --git a/server/UidRanges.cpp b/server/UidRanges.cpp
index 093a1e2..c90f30b 100644
--- a/server/UidRanges.cpp
+++ b/server/UidRanges.cpp
@@ -36,6 +36,12 @@
return lhs.start != rhs.start ? (lhs.start < rhs.start) : (lhs.stop < rhs.stop);
};
+// Check whether two uid ranges have overlapped uid. For any uid included in both ranges, it is
+// considered as overlap.
+bool isOverlapped(const UidRangeParcel& r1, const UidRangeParcel& r2) {
+ return (r1.stop >= r2.start) && (r1.start <= r2.stop);
+}
+
UidRangeParcel makeUidRangeParcel(int start, int stop) {
UidRangeParcel res;
res.start = start;
@@ -127,10 +133,6 @@
mRanges.erase(end, mRanges.end());
}
-bool UidRanges::isOverlapped(const UidRangeParcel& r1, const UidRangeParcel& r2) const {
- return (r1.stop >= r2.start) && (r1.start <= r2.stop);
-}
-
bool UidRanges::overlapsSelf() const {
// Compare each element one by one
for (size_t i = 0; i < mRanges.size(); i++) {
@@ -143,12 +145,20 @@
return false;
}
+// std::binary_search cannot do partial match. For example, an uid range x-y not only overlaps with
+// x-y, but also w-x, y-z, w-z, ...etc. Therefore, we need a specialized binary search.
bool UidRanges::overlaps(const UidRanges& other) const {
- for (const auto& thisRange : mRanges) {
- for (const auto& inputRange : other.getRanges()) {
- if (isOverlapped(thisRange, inputRange)) {
- return true;
- }
+ for (const auto& target : other.getRanges()) {
+ int first = 0;
+ int end = mRanges.size() - 1;
+
+ while (first <= end) {
+ int middle = (first + end) / 2;
+ if (isOverlapped(mRanges[middle], target)) return true;
+ if (compUidRangeParcel(mRanges[middle], target))
+ first = middle + 1;
+ else
+ end = middle - 1;
}
}
return false;
diff --git a/server/UidRanges.h b/server/UidRanges.h
index 99e7a99..9123eb1 100644
--- a/server/UidRanges.h
+++ b/server/UidRanges.h
@@ -28,8 +28,14 @@
class UidRanges {
public:
- static constexpr int DEFAULT_SUB_PRIORITY = 0;
- static constexpr int LOWEST_SUB_PRIORITY = 999;
+ static constexpr int SUB_PRIORITY_HIGHEST = 0;
+ static constexpr int SUB_PRIORITY_LOWEST = 998;
+ // "Special" value used for giving UIDs access to a network (by installing explicit and implicit
+ // network rules) without automatically making that network default. This rule works in
+ // conjunction with the other subpriorities, meaning that the network could still be configured
+ // as the app's default using one of the lower values (0-998).
+ // Note: SUB_PRIORITY_NO_DEFAULT *must* be SUB_PRIORITY_LOWEST + 1!
+ static constexpr int SUB_PRIORITY_NO_DEFAULT = 999;
UidRanges() {}
UidRanges(const std::vector<android::net::UidRangeParcel>& ranges);
@@ -50,9 +56,7 @@
bool empty() const { return mRanges.empty(); }
private:
- // a utility to check if two UidRangeParcels have uid overlap.
- bool isOverlapped(const UidRangeParcel& r1, const UidRangeParcel& r2) const;
-
+ // Keep it sorted. The overlaps() implements binary search, which requires a sorted data.
std::vector<UidRangeParcel> mRanges;
};
diff --git a/server/UnreachableNetwork.cpp b/server/UnreachableNetwork.cpp
index 2f801f0..6880225 100644
--- a/server/UnreachableNetwork.cpp
+++ b/server/UnreachableNetwork.cpp
@@ -26,7 +26,7 @@
// The unreachable network is used to reject traffic. It is used for system purposes only.
UnreachableNetwork::UnreachableNetwork(unsigned netId) : Network(netId) {}
-int UnreachableNetwork::addUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+int UnreachableNetwork::addUsers(const UidRanges& uidRanges, int32_t subPriority) {
if (!isValidSubPriority(subPriority) || !canAddUidRanges(uidRanges, subPriority)) {
return -EINVAL;
}
@@ -40,7 +40,7 @@
return 0;
}
-int UnreachableNetwork::removeUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+int UnreachableNetwork::removeUsers(const UidRanges& uidRanges, int32_t subPriority) {
if (!isValidSubPriority(subPriority)) return -EINVAL;
int ret =
@@ -53,9 +53,9 @@
return 0;
}
-bool UnreachableNetwork::isValidSubPriority(uint32_t priority) {
- return priority >= UidRanges::DEFAULT_SUB_PRIORITY &&
- priority <= UidRanges::LOWEST_SUB_PRIORITY;
+bool UnreachableNetwork::isValidSubPriority(int32_t priority) {
+ return priority >= UidRanges::SUB_PRIORITY_HIGHEST &&
+ priority <= UidRanges::SUB_PRIORITY_LOWEST;
}
} // namespace net
diff --git a/server/UnreachableNetwork.h b/server/UnreachableNetwork.h
index f1547d6..d2cefde 100644
--- a/server/UnreachableNetwork.h
+++ b/server/UnreachableNetwork.h
@@ -23,14 +23,14 @@
class UnreachableNetwork : public Network {
public:
explicit UnreachableNetwork(unsigned netId);
- [[nodiscard]] int addUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
- [[nodiscard]] int removeUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
+ [[nodiscard]] int addUsers(const UidRanges& uidRanges, int32_t subPriority) override;
+ [[nodiscard]] int removeUsers(const UidRanges& uidRanges, int32_t subPriority) override;
bool isUnreachable() override { return true; }
bool canAddUsers() override { return true; }
private:
std::string getTypeString() const override { return "UNREACHABLE"; };
- bool isValidSubPriority(uint32_t priority) override;
+ bool isValidSubPriority(int32_t priority) override;
};
} // namespace android::net
\ No newline at end of file
diff --git a/server/VirtualNetwork.cpp b/server/VirtualNetwork.cpp
index 1906e20..495fd16 100644
--- a/server/VirtualNetwork.cpp
+++ b/server/VirtualNetwork.cpp
@@ -27,18 +27,20 @@
namespace android {
namespace net {
-VirtualNetwork::VirtualNetwork(unsigned netId, bool secure) : Network(netId, secure) {}
+VirtualNetwork::VirtualNetwork(unsigned netId, bool secure, bool excludeLocalRoutes)
+ : Network(netId, secure), mExcludeLocalRoutes(excludeLocalRoutes) {}
VirtualNetwork::~VirtualNetwork() {}
-int VirtualNetwork::addUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+int VirtualNetwork::addUsers(const UidRanges& uidRanges, int32_t subPriority) {
if (!isValidSubPriority(subPriority) || !canAddUidRanges(uidRanges, subPriority)) {
return -EINVAL;
}
for (const std::string& interface : mInterfaces) {
int ret = RouteController::addUsersToVirtualNetwork(mNetId, interface.c_str(), mSecure,
- {{subPriority, uidRanges}});
+ {{subPriority, uidRanges}},
+ mExcludeLocalRoutes);
if (ret) {
ALOGE("failed to add users on interface %s of netId %u", interface.c_str(), mNetId);
return ret;
@@ -48,12 +50,13 @@
return 0;
}
-int VirtualNetwork::removeUsers(const UidRanges& uidRanges, uint32_t subPriority) {
+int VirtualNetwork::removeUsers(const UidRanges& uidRanges, int32_t subPriority) {
if (!isValidSubPriority(subPriority)) return -EINVAL;
for (const std::string& interface : mInterfaces) {
int ret = RouteController::removeUsersFromVirtualNetwork(mNetId, interface.c_str(), mSecure,
- {{subPriority, uidRanges}});
+ {{subPriority, uidRanges}},
+ mExcludeLocalRoutes);
if (ret) {
ALOGE("failed to remove users on interface %s of netId %u", interface.c_str(), mNetId);
return ret;
@@ -67,8 +70,8 @@
if (hasInterface(interface)) {
return 0;
}
- if (int ret = RouteController::addInterfaceToVirtualNetwork(mNetId, interface.c_str(), mSecure,
- mUidRangeMap)) {
+ if (int ret = RouteController::addInterfaceToVirtualNetwork(
+ mNetId, interface.c_str(), mSecure, mUidRangeMap, mExcludeLocalRoutes)) {
ALOGE("failed to add interface %s to VPN netId %u", interface.c_str(), mNetId);
return ret;
}
@@ -80,8 +83,8 @@
if (!hasInterface(interface)) {
return 0;
}
- if (int ret = RouteController::removeInterfaceFromVirtualNetwork(mNetId, interface.c_str(),
- mSecure, mUidRangeMap)) {
+ if (int ret = RouteController::removeInterfaceFromVirtualNetwork(
+ mNetId, interface.c_str(), mSecure, mUidRangeMap, mExcludeLocalRoutes)) {
ALOGE("failed to remove interface %s from VPN netId %u", interface.c_str(), mNetId);
return ret;
}
@@ -89,9 +92,9 @@
return 0;
}
-bool VirtualNetwork::isValidSubPriority(uint32_t priority) {
+bool VirtualNetwork::isValidSubPriority(int32_t priority) {
// Only supports default subsidiary permissions.
- return priority == UidRanges::DEFAULT_SUB_PRIORITY;
+ return priority == UidRanges::SUB_PRIORITY_HIGHEST;
}
} // namespace net
diff --git a/server/VirtualNetwork.h b/server/VirtualNetwork.h
index 20c9e2c..63bc589 100644
--- a/server/VirtualNetwork.h
+++ b/server/VirtualNetwork.h
@@ -28,21 +28,25 @@
// Only a few privileged UIDs may skip the VPN and go directly to the underlying physical network.
//
// A non-secure VPN ("bypassable" VPN) also grabs all user traffic by default. But all apps are
-// permitted to skip it and pick any other network for their connections.
+// permitted to skip it and pick any other network for their connections. A bypassable VPN may
+// optionally exclude local routes, which means it will not grab traffic that is destined to IP
+// addresses considered to be on the local link.
class VirtualNetwork : public Network {
public:
- VirtualNetwork(unsigned netId, bool secure);
- virtual ~VirtualNetwork();
- [[nodiscard]] int addUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
- [[nodiscard]] int removeUsers(const UidRanges& uidRanges, uint32_t subPriority) override;
- bool isVirtual() override { return true; }
- bool canAddUsers() override { return true; }
+ explicit VirtualNetwork(unsigned netId, bool secure, bool excludeLocalRoutes = false);
+ virtual ~VirtualNetwork();
+ [[nodiscard]] int addUsers(const UidRanges& uidRanges, int32_t subPriority) override;
+ [[nodiscard]] int removeUsers(const UidRanges& uidRanges, int32_t subPriority) override;
+ bool isVirtual() override { return true; }
+ bool canAddUsers() override { return true; }
- private:
- std::string getTypeString() const override { return "VIRTUAL"; };
- [[nodiscard]] int addInterface(const std::string& interface) override;
- [[nodiscard]] int removeInterface(const std::string& interface) override;
- bool isValidSubPriority(uint32_t priority) override;
+private:
+ std::string getTypeString() const override { return "VIRTUAL"; };
+ [[nodiscard]] int addInterface(const std::string& interface) override;
+ [[nodiscard]] int removeInterface(const std::string& interface) override;
+ bool isValidSubPriority(int32_t priority) override;
+ // Whether the local traffic will be excluded from the VPN network.
+ [[maybe_unused]] const bool mExcludeLocalRoutes;
};
} // namespace android::net
diff --git a/server/XfrmController.cpp b/server/XfrmController.cpp
index 24168a2..51710c8 100644
--- a/server/XfrmController.cpp
+++ b/server/XfrmController.cpp
@@ -66,10 +66,11 @@
#include "netdutils/Fd.h"
#include "netdutils/Slice.h"
#include "netdutils/Syscalls.h"
+#include "netdutils/Utils.h"
-using android::net::INetd;
using android::netdutils::DumpWriter;
using android::netdutils::Fd;
+using android::netdutils::getIfaceNames;
using android::netdutils::ScopedIndent;
using android::netdutils::Slice;
using android::netdutils::Status;
@@ -410,7 +411,7 @@
}
netdutils::Status XfrmController::flushInterfaces() {
- const auto& ifaces = InterfaceController::getIfaceNames();
+ const auto& ifaces = getIfaceNames();
RETURN_IF_NOT_OK(ifaces);
const String8 ifPrefix8 = String8(INetd::IPSEC_INTERFACE_PREFIX().string());
diff --git a/server/aidl_api/netd_aidl_interface/1/.hash b/server/aidl_api/netd_aidl_interface/1/.hash
deleted file mode 100644
index d33e903..0000000
--- a/server/aidl_api/netd_aidl_interface/1/.hash
+++ /dev/null
@@ -1 +0,0 @@
-69c2ac134efbb31e9591d7e5c3640fb839e23bdb
diff --git a/server/aidl_api/netd_aidl_interface/1/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/1/android/net/INetd.aidl
deleted file mode 100644
index 664c643..0000000
--- a/server/aidl_api/netd_aidl_interface/1/android/net/INetd.aidl
+++ /dev/null
@@ -1,132 +0,0 @@
-package android.net;
-interface INetd {
- boolean isAlive();
- boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isWhitelist, in int[] uids);
- boolean bandwidthEnableDataSaver(boolean enable);
- void networkCreatePhysical(int netId, int permission);
- void networkCreateVpn(int netId, boolean secure);
- void networkDestroy(int netId);
- void networkAddInterface(int netId, in @utf8InCpp String iface);
- void networkRemoveInterface(int netId, in @utf8InCpp String iface);
- void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
- void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
- boolean tetherApplyDnsInterfaces();
- android.net.TetherStatsParcel[] tetherGetStats();
- void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
- void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
- void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
- int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
- void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
- void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
- void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
- void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
- void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void strictUidCleartextPenalty(int uid, int policyPenalty);
- @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
- void clatdStop(in @utf8InCpp String ifName);
- boolean ipfwdEnabled();
- @utf8InCpp String[] ipfwdGetRequesterList();
- void ipfwdEnableForwarding(in @utf8InCpp String requester);
- void ipfwdDisableForwarding(in @utf8InCpp String requester);
- void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
- void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
- void bandwidthSetGlobalAlert(long bytes);
- void bandwidthAddNaughtyApp(int uid);
- void bandwidthRemoveNaughtyApp(int uid);
- void bandwidthAddNiceApp(int uid);
- void bandwidthRemoveNiceApp(int uid);
- void tetherStart(in @utf8InCpp String[] dhcpRanges);
- void tetherStop();
- boolean tetherIsEnabled();
- void tetherInterfaceAdd(in @utf8InCpp String ifName);
- void tetherInterfaceRemove(in @utf8InCpp String ifName);
- @utf8InCpp String[] tetherInterfaceList();
- void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
- @utf8InCpp String[] tetherDnsList();
- void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- int networkGetDefault();
- void networkSetDefault(int netId);
- void networkClearDefault();
- void networkSetPermissionForNetwork(int netId, int permission);
- void networkSetPermissionForUser(int permission, in int[] uids);
- void networkClearPermissionForUser(in int[] uids);
- void trafficSetNetPermForUids(int permission, in int[] uids);
- void networkSetProtectAllow(int uid);
- void networkSetProtectDeny(int uid);
- boolean networkCanProtect(int uid);
- void firewallSetFirewallType(int firewalltype);
- void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
- void firewallSetUidRule(int childChain, int uid, int firewallRule);
- void firewallEnableChildChain(int childChain, boolean enable);
- @utf8InCpp String[] interfaceGetList();
- android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
- void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
- void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
- void interfaceClearAddrs(in @utf8InCpp String ifName);
- void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
- void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
- void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
- void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
- const int IPV4 = 4;
- const int IPV6 = 6;
- const int CONF = 1;
- const int NEIGH = 2;
- const String IPSEC_INTERFACE_PREFIX = "ipsec";
- const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
- const int IPV6_ADDR_GEN_MODE_NONE = 1;
- const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
- const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
- const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
- const int PENALTY_POLICY_ACCEPT = 1;
- const int PENALTY_POLICY_LOG = 2;
- const int PENALTY_POLICY_REJECT = 3;
- const int LOCAL_NET_ID = 99;
- const String NEXTHOP_NONE = "";
- const String NEXTHOP_UNREACHABLE = "unreachable";
- const String NEXTHOP_THROW = "throw";
- const int PERMISSION_NONE = 0;
- const int PERMISSION_NETWORK = 1;
- const int PERMISSION_SYSTEM = 2;
- const int NO_PERMISSIONS = 0;
- const int PERMISSION_INTERNET = 4;
- const int PERMISSION_UPDATE_DEVICE_STATS = 8;
- const int PERMISSION_UNINSTALLED = -1;
- const int FIREWALL_WHITELIST = 0;
- const int FIREWALL_BLACKLIST = 1;
- const int FIREWALL_RULE_ALLOW = 1;
- const int FIREWALL_RULE_DENY = 2;
- const int FIREWALL_CHAIN_NONE = 0;
- const int FIREWALL_CHAIN_DOZABLE = 1;
- const int FIREWALL_CHAIN_STANDBY = 2;
- const int FIREWALL_CHAIN_POWERSAVE = 3;
- const String IF_STATE_UP = "up";
- const String IF_STATE_DOWN = "down";
- const String IF_FLAG_BROADCAST = "broadcast";
- const String IF_FLAG_LOOPBACK = "loopback";
- const String IF_FLAG_POINTOPOINT = "point-to-point";
- const String IF_FLAG_RUNNING = "running";
- const String IF_FLAG_MULTICAST = "multicast";
-}
diff --git a/server/aidl_api/netd_aidl_interface/1/android/net/INetdUnsolicitedEventListener.aidl b/server/aidl_api/netd_aidl_interface/1/android/net/INetdUnsolicitedEventListener.aidl
deleted file mode 100644
index 18631ff..0000000
--- a/server/aidl_api/netd_aidl_interface/1/android/net/INetdUnsolicitedEventListener.aidl
+++ /dev/null
@@ -1,14 +0,0 @@
-package android.net;
-interface INetdUnsolicitedEventListener {
- oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
- oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
- oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
- oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAdded(@utf8InCpp String ifName);
- oneway void onInterfaceRemoved(@utf8InCpp String ifName);
- oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
- oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
- oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
- oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
-}
diff --git a/server/aidl_api/netd_aidl_interface/1/android/net/InterfaceConfigurationParcel.aidl b/server/aidl_api/netd_aidl_interface/1/android/net/InterfaceConfigurationParcel.aidl
deleted file mode 100644
index 93407dc..0000000
--- a/server/aidl_api/netd_aidl_interface/1/android/net/InterfaceConfigurationParcel.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.net;
-parcelable InterfaceConfigurationParcel {
- @utf8InCpp String ifName;
- @utf8InCpp String hwAddr;
- @utf8InCpp String ipv4Addr;
- int prefixLength;
- @utf8InCpp String[] flags;
-}
diff --git a/server/aidl_api/netd_aidl_interface/1/android/net/TetherStatsParcel.aidl b/server/aidl_api/netd_aidl_interface/1/android/net/TetherStatsParcel.aidl
deleted file mode 100644
index d1782bb..0000000
--- a/server/aidl_api/netd_aidl_interface/1/android/net/TetherStatsParcel.aidl
+++ /dev/null
@@ -1,8 +0,0 @@
-package android.net;
-parcelable TetherStatsParcel {
- @utf8InCpp String iface;
- long rxBytes;
- long rxPackets;
- long txBytes;
- long txPackets;
-}
diff --git a/server/aidl_api/netd_aidl_interface/1/android/net/UidRangeParcel.aidl b/server/aidl_api/netd_aidl_interface/1/android/net/UidRangeParcel.aidl
deleted file mode 100644
index d3bc7ed..0000000
--- a/server/aidl_api/netd_aidl_interface/1/android/net/UidRangeParcel.aidl
+++ /dev/null
@@ -1,5 +0,0 @@
-package android.net;
-parcelable UidRangeParcel {
- int start;
- int stop;
-}
diff --git a/server/aidl_api/netd_aidl_interface/2/.hash b/server/aidl_api/netd_aidl_interface/2/.hash
deleted file mode 100644
index 5fc5b2d..0000000
--- a/server/aidl_api/netd_aidl_interface/2/.hash
+++ /dev/null
@@ -1 +0,0 @@
-e395d63302c47e7d2dac0d503045779029ff598b
diff --git a/server/aidl_api/netd_aidl_interface/2/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/2/android/net/INetd.aidl
deleted file mode 100644
index 0e2d5f4..0000000
--- a/server/aidl_api/netd_aidl_interface/2/android/net/INetd.aidl
+++ /dev/null
@@ -1,153 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-interface INetd {
- boolean isAlive();
- boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isWhitelist, in int[] uids);
- boolean bandwidthEnableDataSaver(boolean enable);
- void networkCreatePhysical(int netId, int permission);
- void networkCreateVpn(int netId, boolean secure);
- void networkDestroy(int netId);
- void networkAddInterface(int netId, in @utf8InCpp String iface);
- void networkRemoveInterface(int netId, in @utf8InCpp String iface);
- void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
- void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
- boolean tetherApplyDnsInterfaces();
- android.net.TetherStatsParcel[] tetherGetStats();
- void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
- void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
- void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
- int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
- void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
- void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
- void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
- void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
- void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void strictUidCleartextPenalty(int uid, int policyPenalty);
- @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
- void clatdStop(in @utf8InCpp String ifName);
- boolean ipfwdEnabled();
- @utf8InCpp String[] ipfwdGetRequesterList();
- void ipfwdEnableForwarding(in @utf8InCpp String requester);
- void ipfwdDisableForwarding(in @utf8InCpp String requester);
- void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
- void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
- void bandwidthSetGlobalAlert(long bytes);
- void bandwidthAddNaughtyApp(int uid);
- void bandwidthRemoveNaughtyApp(int uid);
- void bandwidthAddNiceApp(int uid);
- void bandwidthRemoveNiceApp(int uid);
- void tetherStart(in @utf8InCpp String[] dhcpRanges);
- void tetherStop();
- boolean tetherIsEnabled();
- void tetherInterfaceAdd(in @utf8InCpp String ifName);
- void tetherInterfaceRemove(in @utf8InCpp String ifName);
- @utf8InCpp String[] tetherInterfaceList();
- void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
- @utf8InCpp String[] tetherDnsList();
- void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- int networkGetDefault();
- void networkSetDefault(int netId);
- void networkClearDefault();
- void networkSetPermissionForNetwork(int netId, int permission);
- void networkSetPermissionForUser(int permission, in int[] uids);
- void networkClearPermissionForUser(in int[] uids);
- void trafficSetNetPermForUids(int permission, in int[] uids);
- void networkSetProtectAllow(int uid);
- void networkSetProtectDeny(int uid);
- boolean networkCanProtect(int uid);
- void firewallSetFirewallType(int firewalltype);
- void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
- void firewallSetUidRule(int childChain, int uid, int firewallRule);
- void firewallEnableChildChain(int childChain, boolean enable);
- @utf8InCpp String[] interfaceGetList();
- android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
- void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
- void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
- void interfaceClearAddrs(in @utf8InCpp String ifName);
- void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
- void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
- void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
- void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
- void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
- void firewallRemoveUidInterfaceRules(in int[] uids);
- void trafficSwapActiveStatsMap();
- IBinder getOemNetd();
- const int IPV4 = 4;
- const int IPV6 = 6;
- const int CONF = 1;
- const int NEIGH = 2;
- const String IPSEC_INTERFACE_PREFIX = "ipsec";
- const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
- const int IPV6_ADDR_GEN_MODE_NONE = 1;
- const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
- const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
- const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
- const int PENALTY_POLICY_ACCEPT = 1;
- const int PENALTY_POLICY_LOG = 2;
- const int PENALTY_POLICY_REJECT = 3;
- const int LOCAL_NET_ID = 99;
- const String NEXTHOP_NONE = "";
- const String NEXTHOP_UNREACHABLE = "unreachable";
- const String NEXTHOP_THROW = "throw";
- const int PERMISSION_NONE = 0;
- const int PERMISSION_NETWORK = 1;
- const int PERMISSION_SYSTEM = 2;
- const int NO_PERMISSIONS = 0;
- const int PERMISSION_INTERNET = 4;
- const int PERMISSION_UPDATE_DEVICE_STATS = 8;
- const int PERMISSION_UNINSTALLED = -1;
- const int FIREWALL_WHITELIST = 0;
- const int FIREWALL_BLACKLIST = 1;
- const int FIREWALL_RULE_ALLOW = 1;
- const int FIREWALL_RULE_DENY = 2;
- const int FIREWALL_CHAIN_NONE = 0;
- const int FIREWALL_CHAIN_DOZABLE = 1;
- const int FIREWALL_CHAIN_STANDBY = 2;
- const int FIREWALL_CHAIN_POWERSAVE = 3;
- const String IF_STATE_UP = "up";
- const String IF_STATE_DOWN = "down";
- const String IF_FLAG_BROADCAST = "broadcast";
- const String IF_FLAG_LOOPBACK = "loopback";
- const String IF_FLAG_POINTOPOINT = "point-to-point";
- const String IF_FLAG_RUNNING = "running";
- const String IF_FLAG_MULTICAST = "multicast";
-}
diff --git a/server/aidl_api/netd_aidl_interface/2/android/net/INetdUnsolicitedEventListener.aidl b/server/aidl_api/netd_aidl_interface/2/android/net/INetdUnsolicitedEventListener.aidl
deleted file mode 100644
index 621f1cf..0000000
--- a/server/aidl_api/netd_aidl_interface/2/android/net/INetdUnsolicitedEventListener.aidl
+++ /dev/null
@@ -1,31 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-interface INetdUnsolicitedEventListener {
- oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
- oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
- oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
- oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAdded(@utf8InCpp String ifName);
- oneway void onInterfaceRemoved(@utf8InCpp String ifName);
- oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
- oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
- oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
- oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
-}
diff --git a/server/aidl_api/netd_aidl_interface/2/android/net/InterfaceConfigurationParcel.aidl b/server/aidl_api/netd_aidl_interface/2/android/net/InterfaceConfigurationParcel.aidl
deleted file mode 100644
index 18de61f..0000000
--- a/server/aidl_api/netd_aidl_interface/2/android/net/InterfaceConfigurationParcel.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable InterfaceConfigurationParcel {
- @utf8InCpp String ifName;
- @utf8InCpp String hwAddr;
- @utf8InCpp String ipv4Addr;
- int prefixLength;
- @utf8InCpp String[] flags;
-}
diff --git a/server/aidl_api/netd_aidl_interface/2/android/net/TetherStatsParcel.aidl b/server/aidl_api/netd_aidl_interface/2/android/net/TetherStatsParcel.aidl
deleted file mode 100644
index c0ba676..0000000
--- a/server/aidl_api/netd_aidl_interface/2/android/net/TetherStatsParcel.aidl
+++ /dev/null
@@ -1,25 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable TetherStatsParcel {
- @utf8InCpp String iface;
- long rxBytes;
- long rxPackets;
- long txBytes;
- long txPackets;
-}
diff --git a/server/aidl_api/netd_aidl_interface/2/android/net/UidRangeParcel.aidl b/server/aidl_api/netd_aidl_interface/2/android/net/UidRangeParcel.aidl
deleted file mode 100644
index c2c35db..0000000
--- a/server/aidl_api/netd_aidl_interface/2/android/net/UidRangeParcel.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable UidRangeParcel {
- int start;
- int stop;
-}
diff --git a/server/aidl_api/netd_aidl_interface/3/.hash b/server/aidl_api/netd_aidl_interface/3/.hash
deleted file mode 100644
index 59cf708..0000000
--- a/server/aidl_api/netd_aidl_interface/3/.hash
+++ /dev/null
@@ -1 +0,0 @@
-e17c1f9b2068b539b22e3a4a447edea3c80aee4b
diff --git a/server/aidl_api/netd_aidl_interface/3/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/3/android/net/INetd.aidl
deleted file mode 100644
index 135b738..0000000
--- a/server/aidl_api/netd_aidl_interface/3/android/net/INetd.aidl
+++ /dev/null
@@ -1,161 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetd {
- boolean isAlive();
- boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isWhitelist, in int[] uids);
- boolean bandwidthEnableDataSaver(boolean enable);
- void networkCreatePhysical(int netId, int permission);
- void networkCreateVpn(int netId, boolean secure);
- void networkDestroy(int netId);
- void networkAddInterface(int netId, in @utf8InCpp String iface);
- void networkRemoveInterface(int netId, in @utf8InCpp String iface);
- void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
- void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
- boolean tetherApplyDnsInterfaces();
- android.net.TetherStatsParcel[] tetherGetStats();
- void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
- void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
- void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
- int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
- void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
- void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
- void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
- void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
- void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void strictUidCleartextPenalty(int uid, int policyPenalty);
- @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
- void clatdStop(in @utf8InCpp String ifName);
- boolean ipfwdEnabled();
- @utf8InCpp String[] ipfwdGetRequesterList();
- void ipfwdEnableForwarding(in @utf8InCpp String requester);
- void ipfwdDisableForwarding(in @utf8InCpp String requester);
- void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
- void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
- void bandwidthSetGlobalAlert(long bytes);
- void bandwidthAddNaughtyApp(int uid);
- void bandwidthRemoveNaughtyApp(int uid);
- void bandwidthAddNiceApp(int uid);
- void bandwidthRemoveNiceApp(int uid);
- void tetherStart(in @utf8InCpp String[] dhcpRanges);
- void tetherStop();
- boolean tetherIsEnabled();
- void tetherInterfaceAdd(in @utf8InCpp String ifName);
- void tetherInterfaceRemove(in @utf8InCpp String ifName);
- @utf8InCpp String[] tetherInterfaceList();
- void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
- @utf8InCpp String[] tetherDnsList();
- void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- int networkGetDefault();
- void networkSetDefault(int netId);
- void networkClearDefault();
- void networkSetPermissionForNetwork(int netId, int permission);
- void networkSetPermissionForUser(int permission, in int[] uids);
- void networkClearPermissionForUser(in int[] uids);
- void trafficSetNetPermForUids(int permission, in int[] uids);
- void networkSetProtectAllow(int uid);
- void networkSetProtectDeny(int uid);
- boolean networkCanProtect(int uid);
- void firewallSetFirewallType(int firewalltype);
- void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
- void firewallSetUidRule(int childChain, int uid, int firewallRule);
- void firewallEnableChildChain(int childChain, boolean enable);
- @utf8InCpp String[] interfaceGetList();
- android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
- void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
- void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
- void interfaceClearAddrs(in @utf8InCpp String ifName);
- void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
- void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
- void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
- void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
- void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
- void firewallRemoveUidInterfaceRules(in int[] uids);
- void trafficSwapActiveStatsMap();
- IBinder getOemNetd();
- void tetherStartWithConfiguration(in android.net.TetherConfigParcel config);
- android.net.MarkMaskParcel getFwmarkForNetwork(int netId);
- void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void tetherOffloadRuleAdd(in android.net.TetherOffloadRuleParcel rule);
- void tetherOffloadRuleRemove(in android.net.TetherOffloadRuleParcel rule);
- const int IPV4 = 4;
- const int IPV6 = 6;
- const int CONF = 1;
- const int NEIGH = 2;
- const String IPSEC_INTERFACE_PREFIX = "ipsec";
- const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
- const int IPV6_ADDR_GEN_MODE_NONE = 1;
- const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
- const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
- const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
- const int PENALTY_POLICY_ACCEPT = 1;
- const int PENALTY_POLICY_LOG = 2;
- const int PENALTY_POLICY_REJECT = 3;
- const int LOCAL_NET_ID = 99;
- const String NEXTHOP_NONE = "";
- const String NEXTHOP_UNREACHABLE = "unreachable";
- const String NEXTHOP_THROW = "throw";
- const int PERMISSION_NONE = 0;
- const int PERMISSION_NETWORK = 1;
- const int PERMISSION_SYSTEM = 2;
- const int NO_PERMISSIONS = 0;
- const int PERMISSION_INTERNET = 4;
- const int PERMISSION_UPDATE_DEVICE_STATS = 8;
- const int PERMISSION_UNINSTALLED = -1;
- const int FIREWALL_WHITELIST = 0;
- const int FIREWALL_BLACKLIST = 1;
- const int FIREWALL_RULE_ALLOW = 1;
- const int FIREWALL_RULE_DENY = 2;
- const int FIREWALL_CHAIN_NONE = 0;
- const int FIREWALL_CHAIN_DOZABLE = 1;
- const int FIREWALL_CHAIN_STANDBY = 2;
- const int FIREWALL_CHAIN_POWERSAVE = 3;
- const String IF_STATE_UP = "up";
- const String IF_STATE_DOWN = "down";
- const String IF_FLAG_BROADCAST = "broadcast";
- const String IF_FLAG_LOOPBACK = "loopback";
- const String IF_FLAG_POINTOPOINT = "point-to-point";
- const String IF_FLAG_RUNNING = "running";
- const String IF_FLAG_MULTICAST = "multicast";
-}
diff --git a/server/aidl_api/netd_aidl_interface/3/android/net/INetdUnsolicitedEventListener.aidl b/server/aidl_api/netd_aidl_interface/3/android/net/INetdUnsolicitedEventListener.aidl
deleted file mode 100644
index 4459363..0000000
--- a/server/aidl_api/netd_aidl_interface/3/android/net/INetdUnsolicitedEventListener.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetdUnsolicitedEventListener {
- oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
- oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
- oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
- oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAdded(@utf8InCpp String ifName);
- oneway void onInterfaceRemoved(@utf8InCpp String ifName);
- oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
- oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
- oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
- oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
-}
diff --git a/server/aidl_api/netd_aidl_interface/3/android/net/InterfaceConfigurationParcel.aidl b/server/aidl_api/netd_aidl_interface/3/android/net/InterfaceConfigurationParcel.aidl
deleted file mode 100644
index 01e0f95..0000000
--- a/server/aidl_api/netd_aidl_interface/3/android/net/InterfaceConfigurationParcel.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable InterfaceConfigurationParcel {
- @utf8InCpp String ifName;
- @utf8InCpp String hwAddr;
- @utf8InCpp String ipv4Addr;
- int prefixLength;
- @utf8InCpp String[] flags;
-}
diff --git a/server/aidl_api/netd_aidl_interface/3/android/net/MarkMaskParcel.aidl b/server/aidl_api/netd_aidl_interface/3/android/net/MarkMaskParcel.aidl
deleted file mode 100644
index 62be838..0000000
--- a/server/aidl_api/netd_aidl_interface/3/android/net/MarkMaskParcel.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable MarkMaskParcel {
- int mark;
- int mask;
-}
diff --git a/server/aidl_api/netd_aidl_interface/3/android/net/RouteInfoParcel.aidl b/server/aidl_api/netd_aidl_interface/3/android/net/RouteInfoParcel.aidl
deleted file mode 100644
index 5e0ee62..0000000
--- a/server/aidl_api/netd_aidl_interface/3/android/net/RouteInfoParcel.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable RouteInfoParcel {
- @utf8InCpp String destination;
- @utf8InCpp String ifName;
- @utf8InCpp String nextHop;
- int mtu;
-}
diff --git a/server/aidl_api/netd_aidl_interface/3/android/net/TetherConfigParcel.aidl b/server/aidl_api/netd_aidl_interface/3/android/net/TetherConfigParcel.aidl
deleted file mode 100644
index b136454..0000000
--- a/server/aidl_api/netd_aidl_interface/3/android/net/TetherConfigParcel.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherConfigParcel {
- boolean usingLegacyDnsProxy;
- @utf8InCpp String[] dhcpRanges;
-}
diff --git a/server/aidl_api/netd_aidl_interface/3/android/net/TetherOffloadRuleParcel.aidl b/server/aidl_api/netd_aidl_interface/3/android/net/TetherOffloadRuleParcel.aidl
deleted file mode 100644
index 3abf0f8..0000000
--- a/server/aidl_api/netd_aidl_interface/3/android/net/TetherOffloadRuleParcel.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherOffloadRuleParcel {
- int inputInterfaceIndex;
- int outputInterfaceIndex;
- byte[] destination;
- int prefixLength;
- byte[] srcL2Address;
- byte[] dstL2Address;
-}
diff --git a/server/aidl_api/netd_aidl_interface/3/android/net/TetherStatsParcel.aidl b/server/aidl_api/netd_aidl_interface/3/android/net/TetherStatsParcel.aidl
deleted file mode 100644
index 71ffb9b..0000000
--- a/server/aidl_api/netd_aidl_interface/3/android/net/TetherStatsParcel.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherStatsParcel {
- @utf8InCpp String iface;
- long rxBytes;
- long rxPackets;
- long txBytes;
- long txPackets;
-}
diff --git a/server/aidl_api/netd_aidl_interface/3/android/net/UidRangeParcel.aidl b/server/aidl_api/netd_aidl_interface/3/android/net/UidRangeParcel.aidl
deleted file mode 100644
index 84ff457..0000000
--- a/server/aidl_api/netd_aidl_interface/3/android/net/UidRangeParcel.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable UidRangeParcel {
- int start;
- int stop;
-}
diff --git a/server/aidl_api/netd_aidl_interface/4/.hash b/server/aidl_api/netd_aidl_interface/4/.hash
deleted file mode 100644
index 0c3f810..0000000
--- a/server/aidl_api/netd_aidl_interface/4/.hash
+++ /dev/null
@@ -1 +0,0 @@
-63adaa5098e4d8621e90c5a84f7cb93505c79311
diff --git a/server/aidl_api/netd_aidl_interface/4/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/4/android/net/INetd.aidl
deleted file mode 100644
index 47e2931..0000000
--- a/server/aidl_api/netd_aidl_interface/4/android/net/INetd.aidl
+++ /dev/null
@@ -1,164 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetd {
- boolean isAlive();
- boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isWhitelist, in int[] uids);
- boolean bandwidthEnableDataSaver(boolean enable);
- void networkCreatePhysical(int netId, int permission);
- void networkCreateVpn(int netId, boolean secure);
- void networkDestroy(int netId);
- void networkAddInterface(int netId, in @utf8InCpp String iface);
- void networkRemoveInterface(int netId, in @utf8InCpp String iface);
- void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
- void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
- boolean tetherApplyDnsInterfaces();
- android.net.TetherStatsParcel[] tetherGetStats();
- void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
- void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
- void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
- int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
- void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
- void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
- void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
- void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
- void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void strictUidCleartextPenalty(int uid, int policyPenalty);
- @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
- void clatdStop(in @utf8InCpp String ifName);
- boolean ipfwdEnabled();
- @utf8InCpp String[] ipfwdGetRequesterList();
- void ipfwdEnableForwarding(in @utf8InCpp String requester);
- void ipfwdDisableForwarding(in @utf8InCpp String requester);
- void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
- void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
- void bandwidthSetGlobalAlert(long bytes);
- void bandwidthAddNaughtyApp(int uid);
- void bandwidthRemoveNaughtyApp(int uid);
- void bandwidthAddNiceApp(int uid);
- void bandwidthRemoveNiceApp(int uid);
- void tetherStart(in @utf8InCpp String[] dhcpRanges);
- void tetherStop();
- boolean tetherIsEnabled();
- void tetherInterfaceAdd(in @utf8InCpp String ifName);
- void tetherInterfaceRemove(in @utf8InCpp String ifName);
- @utf8InCpp String[] tetherInterfaceList();
- void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
- @utf8InCpp String[] tetherDnsList();
- void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- int networkGetDefault();
- void networkSetDefault(int netId);
- void networkClearDefault();
- void networkSetPermissionForNetwork(int netId, int permission);
- void networkSetPermissionForUser(int permission, in int[] uids);
- void networkClearPermissionForUser(in int[] uids);
- void trafficSetNetPermForUids(int permission, in int[] uids);
- void networkSetProtectAllow(int uid);
- void networkSetProtectDeny(int uid);
- boolean networkCanProtect(int uid);
- void firewallSetFirewallType(int firewalltype);
- void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
- void firewallSetUidRule(int childChain, int uid, int firewallRule);
- void firewallEnableChildChain(int childChain, boolean enable);
- @utf8InCpp String[] interfaceGetList();
- android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
- void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
- void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
- void interfaceClearAddrs(in @utf8InCpp String ifName);
- void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
- void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
- void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
- void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
- void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
- void firewallRemoveUidInterfaceRules(in int[] uids);
- void trafficSwapActiveStatsMap();
- IBinder getOemNetd();
- void tetherStartWithConfiguration(in android.net.TetherConfigParcel config);
- android.net.MarkMaskParcel getFwmarkForNetwork(int netId);
- void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void tetherOffloadRuleAdd(in android.net.TetherOffloadRuleParcel rule);
- void tetherOffloadRuleRemove(in android.net.TetherOffloadRuleParcel rule);
- android.net.TetherStatsParcel[] tetherOffloadGetStats();
- void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
- android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
- const int IPV4 = 4;
- const int IPV6 = 6;
- const int CONF = 1;
- const int NEIGH = 2;
- const String IPSEC_INTERFACE_PREFIX = "ipsec";
- const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
- const int IPV6_ADDR_GEN_MODE_NONE = 1;
- const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
- const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
- const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
- const int PENALTY_POLICY_ACCEPT = 1;
- const int PENALTY_POLICY_LOG = 2;
- const int PENALTY_POLICY_REJECT = 3;
- const int LOCAL_NET_ID = 99;
- const String NEXTHOP_NONE = "";
- const String NEXTHOP_UNREACHABLE = "unreachable";
- const String NEXTHOP_THROW = "throw";
- const int PERMISSION_NONE = 0;
- const int PERMISSION_NETWORK = 1;
- const int PERMISSION_SYSTEM = 2;
- const int NO_PERMISSIONS = 0;
- const int PERMISSION_INTERNET = 4;
- const int PERMISSION_UPDATE_DEVICE_STATS = 8;
- const int PERMISSION_UNINSTALLED = -1;
- const int FIREWALL_WHITELIST = 0;
- const int FIREWALL_BLACKLIST = 1;
- const int FIREWALL_RULE_ALLOW = 1;
- const int FIREWALL_RULE_DENY = 2;
- const int FIREWALL_CHAIN_NONE = 0;
- const int FIREWALL_CHAIN_DOZABLE = 1;
- const int FIREWALL_CHAIN_STANDBY = 2;
- const int FIREWALL_CHAIN_POWERSAVE = 3;
- const String IF_STATE_UP = "up";
- const String IF_STATE_DOWN = "down";
- const String IF_FLAG_BROADCAST = "broadcast";
- const String IF_FLAG_LOOPBACK = "loopback";
- const String IF_FLAG_POINTOPOINT = "point-to-point";
- const String IF_FLAG_RUNNING = "running";
- const String IF_FLAG_MULTICAST = "multicast";
-}
diff --git a/server/aidl_api/netd_aidl_interface/4/android/net/INetdUnsolicitedEventListener.aidl b/server/aidl_api/netd_aidl_interface/4/android/net/INetdUnsolicitedEventListener.aidl
deleted file mode 100644
index 4459363..0000000
--- a/server/aidl_api/netd_aidl_interface/4/android/net/INetdUnsolicitedEventListener.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetdUnsolicitedEventListener {
- oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
- oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
- oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
- oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAdded(@utf8InCpp String ifName);
- oneway void onInterfaceRemoved(@utf8InCpp String ifName);
- oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
- oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
- oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
- oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
-}
diff --git a/server/aidl_api/netd_aidl_interface/4/android/net/InterfaceConfigurationParcel.aidl b/server/aidl_api/netd_aidl_interface/4/android/net/InterfaceConfigurationParcel.aidl
deleted file mode 100644
index 01e0f95..0000000
--- a/server/aidl_api/netd_aidl_interface/4/android/net/InterfaceConfigurationParcel.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable InterfaceConfigurationParcel {
- @utf8InCpp String ifName;
- @utf8InCpp String hwAddr;
- @utf8InCpp String ipv4Addr;
- int prefixLength;
- @utf8InCpp String[] flags;
-}
diff --git a/server/aidl_api/netd_aidl_interface/4/android/net/MarkMaskParcel.aidl b/server/aidl_api/netd_aidl_interface/4/android/net/MarkMaskParcel.aidl
deleted file mode 100644
index 62be838..0000000
--- a/server/aidl_api/netd_aidl_interface/4/android/net/MarkMaskParcel.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable MarkMaskParcel {
- int mark;
- int mask;
-}
diff --git a/server/aidl_api/netd_aidl_interface/4/android/net/RouteInfoParcel.aidl b/server/aidl_api/netd_aidl_interface/4/android/net/RouteInfoParcel.aidl
deleted file mode 100644
index 5e0ee62..0000000
--- a/server/aidl_api/netd_aidl_interface/4/android/net/RouteInfoParcel.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable RouteInfoParcel {
- @utf8InCpp String destination;
- @utf8InCpp String ifName;
- @utf8InCpp String nextHop;
- int mtu;
-}
diff --git a/server/aidl_api/netd_aidl_interface/4/android/net/TetherConfigParcel.aidl b/server/aidl_api/netd_aidl_interface/4/android/net/TetherConfigParcel.aidl
deleted file mode 100644
index b136454..0000000
--- a/server/aidl_api/netd_aidl_interface/4/android/net/TetherConfigParcel.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherConfigParcel {
- boolean usingLegacyDnsProxy;
- @utf8InCpp String[] dhcpRanges;
-}
diff --git a/server/aidl_api/netd_aidl_interface/4/android/net/TetherOffloadRuleParcel.aidl b/server/aidl_api/netd_aidl_interface/4/android/net/TetherOffloadRuleParcel.aidl
deleted file mode 100644
index c9d8458..0000000
--- a/server/aidl_api/netd_aidl_interface/4/android/net/TetherOffloadRuleParcel.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherOffloadRuleParcel {
- int inputInterfaceIndex;
- int outputInterfaceIndex;
- byte[] destination;
- int prefixLength;
- byte[] srcL2Address;
- byte[] dstL2Address;
- int pmtu = 1500;
-}
diff --git a/server/aidl_api/netd_aidl_interface/4/android/net/TetherStatsParcel.aidl b/server/aidl_api/netd_aidl_interface/4/android/net/TetherStatsParcel.aidl
deleted file mode 100644
index 0b0960e..0000000
--- a/server/aidl_api/netd_aidl_interface/4/android/net/TetherStatsParcel.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherStatsParcel {
- @utf8InCpp String iface;
- long rxBytes;
- long rxPackets;
- long txBytes;
- long txPackets;
- int ifIndex = 0;
-}
diff --git a/server/aidl_api/netd_aidl_interface/4/android/net/UidRangeParcel.aidl b/server/aidl_api/netd_aidl_interface/4/android/net/UidRangeParcel.aidl
deleted file mode 100644
index 84ff457..0000000
--- a/server/aidl_api/netd_aidl_interface/4/android/net/UidRangeParcel.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable UidRangeParcel {
- int start;
- int stop;
-}
diff --git a/server/aidl_api/netd_aidl_interface/5/.hash b/server/aidl_api/netd_aidl_interface/5/.hash
deleted file mode 100644
index a6ced45..0000000
--- a/server/aidl_api/netd_aidl_interface/5/.hash
+++ /dev/null
@@ -1 +0,0 @@
-d97c56dd789cee9eeb5cdcec43a99df0a01873a5
diff --git a/server/aidl_api/netd_aidl_interface/5/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/5/android/net/INetd.aidl
deleted file mode 100644
index b30748a..0000000
--- a/server/aidl_api/netd_aidl_interface/5/android/net/INetd.aidl
+++ /dev/null
@@ -1,167 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetd {
- boolean isAlive();
- boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isAllowlist, in int[] uids);
- boolean bandwidthEnableDataSaver(boolean enable);
- void networkCreatePhysical(int netId, int permission);
- void networkCreateVpn(int netId, boolean secure);
- void networkDestroy(int netId);
- void networkAddInterface(int netId, in @utf8InCpp String iface);
- void networkRemoveInterface(int netId, in @utf8InCpp String iface);
- void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
- void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
- boolean tetherApplyDnsInterfaces();
- android.net.TetherStatsParcel[] tetherGetStats();
- void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
- void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
- void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
- int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
- void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
- void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
- void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
- void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
- void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void strictUidCleartextPenalty(int uid, int policyPenalty);
- @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
- void clatdStop(in @utf8InCpp String ifName);
- boolean ipfwdEnabled();
- @utf8InCpp String[] ipfwdGetRequesterList();
- void ipfwdEnableForwarding(in @utf8InCpp String requester);
- void ipfwdDisableForwarding(in @utf8InCpp String requester);
- void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
- void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
- void bandwidthSetGlobalAlert(long bytes);
- void bandwidthAddNaughtyApp(int uid);
- void bandwidthRemoveNaughtyApp(int uid);
- void bandwidthAddNiceApp(int uid);
- void bandwidthRemoveNiceApp(int uid);
- void tetherStart(in @utf8InCpp String[] dhcpRanges);
- void tetherStop();
- boolean tetherIsEnabled();
- void tetherInterfaceAdd(in @utf8InCpp String ifName);
- void tetherInterfaceRemove(in @utf8InCpp String ifName);
- @utf8InCpp String[] tetherInterfaceList();
- void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
- @utf8InCpp String[] tetherDnsList();
- void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- int networkGetDefault();
- void networkSetDefault(int netId);
- void networkClearDefault();
- void networkSetPermissionForNetwork(int netId, int permission);
- void networkSetPermissionForUser(int permission, in int[] uids);
- void networkClearPermissionForUser(in int[] uids);
- void trafficSetNetPermForUids(int permission, in int[] uids);
- void networkSetProtectAllow(int uid);
- void networkSetProtectDeny(int uid);
- boolean networkCanProtect(int uid);
- void firewallSetFirewallType(int firewalltype);
- void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
- void firewallSetUidRule(int childChain, int uid, int firewallRule);
- void firewallEnableChildChain(int childChain, boolean enable);
- @utf8InCpp String[] interfaceGetList();
- android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
- void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
- void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
- void interfaceClearAddrs(in @utf8InCpp String ifName);
- void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
- void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
- void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
- void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
- void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
- void firewallRemoveUidInterfaceRules(in int[] uids);
- void trafficSwapActiveStatsMap();
- IBinder getOemNetd();
- void tetherStartWithConfiguration(in android.net.TetherConfigParcel config);
- android.net.MarkMaskParcel getFwmarkForNetwork(int netId);
- void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void tetherOffloadRuleAdd(in android.net.TetherOffloadRuleParcel rule);
- void tetherOffloadRuleRemove(in android.net.TetherOffloadRuleParcel rule);
- android.net.TetherStatsParcel[] tetherOffloadGetStats();
- void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
- android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
- const int IPV4 = 4;
- const int IPV6 = 6;
- const int CONF = 1;
- const int NEIGH = 2;
- const String IPSEC_INTERFACE_PREFIX = "ipsec";
- const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
- const int IPV6_ADDR_GEN_MODE_NONE = 1;
- const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
- const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
- const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
- const int PENALTY_POLICY_ACCEPT = 1;
- const int PENALTY_POLICY_LOG = 2;
- const int PENALTY_POLICY_REJECT = 3;
- const int LOCAL_NET_ID = 99;
- const String NEXTHOP_NONE = "";
- const String NEXTHOP_UNREACHABLE = "unreachable";
- const String NEXTHOP_THROW = "throw";
- const int PERMISSION_NONE = 0;
- const int PERMISSION_NETWORK = 1;
- const int PERMISSION_SYSTEM = 2;
- const int NO_PERMISSIONS = 0;
- const int PERMISSION_INTERNET = 4;
- const int PERMISSION_UPDATE_DEVICE_STATS = 8;
- const int PERMISSION_UNINSTALLED = -1;
- const @JavaPassthrough(annotation="@Deprecated") int FIREWALL_WHITELIST = 0;
- const int FIREWALL_ALLOWLIST = 0;
- const @JavaPassthrough(annotation="@Deprecated") int FIREWALL_BLACKLIST = 1;
- const int FIREWALL_DENYLIST = 1;
- const int FIREWALL_RULE_ALLOW = 1;
- const int FIREWALL_RULE_DENY = 2;
- const int FIREWALL_CHAIN_NONE = 0;
- const int FIREWALL_CHAIN_DOZABLE = 1;
- const int FIREWALL_CHAIN_STANDBY = 2;
- const int FIREWALL_CHAIN_POWERSAVE = 3;
- const int FIREWALL_CHAIN_RESTRICTED = 4;
- const String IF_STATE_UP = "up";
- const String IF_STATE_DOWN = "down";
- const String IF_FLAG_BROADCAST = "broadcast";
- const String IF_FLAG_LOOPBACK = "loopback";
- const String IF_FLAG_POINTOPOINT = "point-to-point";
- const String IF_FLAG_RUNNING = "running";
- const String IF_FLAG_MULTICAST = "multicast";
-}
diff --git a/server/aidl_api/netd_aidl_interface/5/android/net/INetdUnsolicitedEventListener.aidl b/server/aidl_api/netd_aidl_interface/5/android/net/INetdUnsolicitedEventListener.aidl
deleted file mode 100644
index 4459363..0000000
--- a/server/aidl_api/netd_aidl_interface/5/android/net/INetdUnsolicitedEventListener.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetdUnsolicitedEventListener {
- oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
- oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
- oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
- oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAdded(@utf8InCpp String ifName);
- oneway void onInterfaceRemoved(@utf8InCpp String ifName);
- oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
- oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
- oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
- oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
-}
diff --git a/server/aidl_api/netd_aidl_interface/5/android/net/InterfaceConfigurationParcel.aidl b/server/aidl_api/netd_aidl_interface/5/android/net/InterfaceConfigurationParcel.aidl
deleted file mode 100644
index 01e0f95..0000000
--- a/server/aidl_api/netd_aidl_interface/5/android/net/InterfaceConfigurationParcel.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable InterfaceConfigurationParcel {
- @utf8InCpp String ifName;
- @utf8InCpp String hwAddr;
- @utf8InCpp String ipv4Addr;
- int prefixLength;
- @utf8InCpp String[] flags;
-}
diff --git a/server/aidl_api/netd_aidl_interface/5/android/net/MarkMaskParcel.aidl b/server/aidl_api/netd_aidl_interface/5/android/net/MarkMaskParcel.aidl
deleted file mode 100644
index 62be838..0000000
--- a/server/aidl_api/netd_aidl_interface/5/android/net/MarkMaskParcel.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable MarkMaskParcel {
- int mark;
- int mask;
-}
diff --git a/server/aidl_api/netd_aidl_interface/5/android/net/RouteInfoParcel.aidl b/server/aidl_api/netd_aidl_interface/5/android/net/RouteInfoParcel.aidl
deleted file mode 100644
index 5e0ee62..0000000
--- a/server/aidl_api/netd_aidl_interface/5/android/net/RouteInfoParcel.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable RouteInfoParcel {
- @utf8InCpp String destination;
- @utf8InCpp String ifName;
- @utf8InCpp String nextHop;
- int mtu;
-}
diff --git a/server/aidl_api/netd_aidl_interface/5/android/net/TetherConfigParcel.aidl b/server/aidl_api/netd_aidl_interface/5/android/net/TetherConfigParcel.aidl
deleted file mode 100644
index b136454..0000000
--- a/server/aidl_api/netd_aidl_interface/5/android/net/TetherConfigParcel.aidl
+++ /dev/null
@@ -1,23 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherConfigParcel {
- boolean usingLegacyDnsProxy;
- @utf8InCpp String[] dhcpRanges;
-}
diff --git a/server/aidl_api/netd_aidl_interface/5/android/net/TetherOffloadRuleParcel.aidl b/server/aidl_api/netd_aidl_interface/5/android/net/TetherOffloadRuleParcel.aidl
deleted file mode 100644
index c9d8458..0000000
--- a/server/aidl_api/netd_aidl_interface/5/android/net/TetherOffloadRuleParcel.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherOffloadRuleParcel {
- int inputInterfaceIndex;
- int outputInterfaceIndex;
- byte[] destination;
- int prefixLength;
- byte[] srcL2Address;
- byte[] dstL2Address;
- int pmtu = 1500;
-}
diff --git a/server/aidl_api/netd_aidl_interface/5/android/net/TetherStatsParcel.aidl b/server/aidl_api/netd_aidl_interface/5/android/net/TetherStatsParcel.aidl
deleted file mode 100644
index 0b0960e..0000000
--- a/server/aidl_api/netd_aidl_interface/5/android/net/TetherStatsParcel.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherStatsParcel {
- @utf8InCpp String iface;
- long rxBytes;
- long rxPackets;
- long txBytes;
- long txPackets;
- int ifIndex = 0;
-}
diff --git a/server/aidl_api/netd_aidl_interface/5/android/net/UidRangeParcel.aidl b/server/aidl_api/netd_aidl_interface/5/android/net/UidRangeParcel.aidl
deleted file mode 100644
index debc6be..0000000
--- a/server/aidl_api/netd_aidl_interface/5/android/net/UidRangeParcel.aidl
+++ /dev/null
@@ -1,24 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
-parcelable UidRangeParcel {
- int start;
- int stop;
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/.hash b/server/aidl_api/netd_aidl_interface/6/.hash
deleted file mode 100644
index f5acf5d..0000000
--- a/server/aidl_api/netd_aidl_interface/6/.hash
+++ /dev/null
@@ -1 +0,0 @@
-b08451d9673b09cba84f1fd8740e1fdac64ff7be
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/INetd.aidl
deleted file mode 100644
index a7952f2..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/INetd.aidl
+++ /dev/null
@@ -1,198 +0,0 @@
-/**
- * Copyright (c) 2016, 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetd {
- boolean isAlive();
- boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isAllowlist, in int[] uids);
- boolean bandwidthEnableDataSaver(boolean enable);
- /**
- * @deprecated use networkCreate() instead.
- */
- void networkCreatePhysical(int netId, int permission);
- /**
- * @deprecated use networkCreate() instead.
- */
- void networkCreateVpn(int netId, boolean secure);
- void networkDestroy(int netId);
- void networkAddInterface(int netId, in @utf8InCpp String iface);
- void networkRemoveInterface(int netId, in @utf8InCpp String iface);
- void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
- void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
- boolean tetherApplyDnsInterfaces();
- android.net.TetherStatsParcel[] tetherGetStats();
- void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
- void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
- void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
- int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
- void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
- void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
- void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
- void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
- void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void strictUidCleartextPenalty(int uid, int policyPenalty);
- @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
- void clatdStop(in @utf8InCpp String ifName);
- boolean ipfwdEnabled();
- @utf8InCpp String[] ipfwdGetRequesterList();
- void ipfwdEnableForwarding(in @utf8InCpp String requester);
- void ipfwdDisableForwarding(in @utf8InCpp String requester);
- void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
- void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
- void bandwidthSetGlobalAlert(long bytes);
- void bandwidthAddNaughtyApp(int uid);
- void bandwidthRemoveNaughtyApp(int uid);
- void bandwidthAddNiceApp(int uid);
- void bandwidthRemoveNiceApp(int uid);
- void tetherStart(in @utf8InCpp String[] dhcpRanges);
- void tetherStop();
- boolean tetherIsEnabled();
- void tetherInterfaceAdd(in @utf8InCpp String ifName);
- void tetherInterfaceRemove(in @utf8InCpp String ifName);
- @utf8InCpp String[] tetherInterfaceList();
- void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
- @utf8InCpp String[] tetherDnsList();
- void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- int networkGetDefault();
- void networkSetDefault(int netId);
- void networkClearDefault();
- void networkSetPermissionForNetwork(int netId, int permission);
- void networkSetPermissionForUser(int permission, in int[] uids);
- void networkClearPermissionForUser(in int[] uids);
- void trafficSetNetPermForUids(int permission, in int[] uids);
- void networkSetProtectAllow(int uid);
- void networkSetProtectDeny(int uid);
- boolean networkCanProtect(int uid);
- void firewallSetFirewallType(int firewalltype);
- void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
- void firewallSetUidRule(int childChain, int uid, int firewallRule);
- void firewallEnableChildChain(int childChain, boolean enable);
- @utf8InCpp String[] interfaceGetList();
- android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
- void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
- void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
- void interfaceClearAddrs(in @utf8InCpp String ifName);
- void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
- void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
- void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
- void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
- void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
- void firewallRemoveUidInterfaceRules(in int[] uids);
- void trafficSwapActiveStatsMap();
- IBinder getOemNetd();
- void tetherStartWithConfiguration(in android.net.TetherConfigParcel config);
- android.net.MarkMaskParcel getFwmarkForNetwork(int netId);
- void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void tetherOffloadRuleAdd(in android.net.TetherOffloadRuleParcel rule);
- void tetherOffloadRuleRemove(in android.net.TetherOffloadRuleParcel rule);
- android.net.TetherStatsParcel[] tetherOffloadGetStats();
- void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
- android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
- void networkCreate(in android.net.NativeNetworkConfig config);
- const int IPV4 = 4;
- const int IPV6 = 6;
- const int CONF = 1;
- const int NEIGH = 2;
- const String IPSEC_INTERFACE_PREFIX = "ipsec";
- const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
- const int IPV6_ADDR_GEN_MODE_NONE = 1;
- const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
- const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
- const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
- const int PENALTY_POLICY_ACCEPT = 1;
- const int PENALTY_POLICY_LOG = 2;
- const int PENALTY_POLICY_REJECT = 3;
- const int LOCAL_NET_ID = 99;
- const int DUMMY_NET_ID = 51;
- const int UNREACHABLE_NET_ID = 52;
- const String NEXTHOP_NONE = "";
- const String NEXTHOP_UNREACHABLE = "unreachable";
- const String NEXTHOP_THROW = "throw";
- const int PERMISSION_NONE = 0;
- const int PERMISSION_NETWORK = 1;
- const int PERMISSION_SYSTEM = 2;
- const int NO_PERMISSIONS = 0;
- const int PERMISSION_INTERNET = 4;
- const int PERMISSION_UPDATE_DEVICE_STATS = 8;
- const int PERMISSION_UNINSTALLED = -1;
- /**
- * @deprecated use FIREWALL_ALLOWLIST.
- */
- const int FIREWALL_WHITELIST = 0;
- const int FIREWALL_ALLOWLIST = 0;
- /**
- * @deprecated use FIREWALL_DENYLIST.
- */
- const int FIREWALL_BLACKLIST = 1;
- const int FIREWALL_DENYLIST = 1;
- const int FIREWALL_RULE_ALLOW = 1;
- const int FIREWALL_RULE_DENY = 2;
- const int FIREWALL_CHAIN_NONE = 0;
- const int FIREWALL_CHAIN_DOZABLE = 1;
- const int FIREWALL_CHAIN_STANDBY = 2;
- const int FIREWALL_CHAIN_POWERSAVE = 3;
- const int FIREWALL_CHAIN_RESTRICTED = 4;
- const String IF_STATE_UP = "up";
- const String IF_STATE_DOWN = "down";
- const String IF_FLAG_BROADCAST = "broadcast";
- const String IF_FLAG_LOOPBACK = "loopback";
- const String IF_FLAG_POINTOPOINT = "point-to-point";
- const String IF_FLAG_RUNNING = "running";
- const String IF_FLAG_MULTICAST = "multicast";
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/INetdUnsolicitedEventListener.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/INetdUnsolicitedEventListener.aidl
deleted file mode 100644
index 31775df..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/INetdUnsolicitedEventListener.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (c) 2018, 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetdUnsolicitedEventListener {
- oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
- oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
- oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
- oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAdded(@utf8InCpp String ifName);
- oneway void onInterfaceRemoved(@utf8InCpp String ifName);
- oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
- oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
- oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
- oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/InterfaceConfigurationParcel.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/InterfaceConfigurationParcel.aidl
deleted file mode 100644
index 1869d8d..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/InterfaceConfigurationParcel.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable InterfaceConfigurationParcel {
- @utf8InCpp String ifName;
- @utf8InCpp String hwAddr;
- @utf8InCpp String ipv4Addr;
- int prefixLength;
- @utf8InCpp String[] flags;
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/MarkMaskParcel.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/MarkMaskParcel.aidl
deleted file mode 100644
index 8ea20d1..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/MarkMaskParcel.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable MarkMaskParcel {
- int mark;
- int mask;
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/NativeNetworkConfig.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/NativeNetworkConfig.aidl
deleted file mode 100644
index 76562b2..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/NativeNetworkConfig.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
-parcelable NativeNetworkConfig {
- int netId;
- android.net.NativeNetworkType networkType = android.net.NativeNetworkType.PHYSICAL;
- int permission;
- boolean secure;
- android.net.NativeVpnType vpnType = android.net.NativeVpnType.PLATFORM;
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/NativeNetworkType.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/NativeNetworkType.aidl
deleted file mode 100644
index 06c8979..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/NativeNetworkType.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-@Backing(type="int")
-enum NativeNetworkType {
- PHYSICAL = 0,
- VIRTUAL = 1,
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/NativeVpnType.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/NativeVpnType.aidl
deleted file mode 100644
index 8a8be83..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/NativeVpnType.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-@Backing(type="int")
-enum NativeVpnType {
- SERVICE = 1,
- PLATFORM = 2,
- LEGACY = 3,
- OEM = 4,
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/RouteInfoParcel.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/RouteInfoParcel.aidl
deleted file mode 100644
index 5ef95e6..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/RouteInfoParcel.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Copyright (c) 2020, 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable RouteInfoParcel {
- @utf8InCpp String destination;
- @utf8InCpp String ifName;
- @utf8InCpp String nextHop;
- int mtu;
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/TetherConfigParcel.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/TetherConfigParcel.aidl
deleted file mode 100644
index 7b39c22..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/TetherConfigParcel.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherConfigParcel {
- boolean usingLegacyDnsProxy;
- @utf8InCpp String[] dhcpRanges;
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/TetherOffloadRuleParcel.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/TetherOffloadRuleParcel.aidl
deleted file mode 100644
index 983e986..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/TetherOffloadRuleParcel.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherOffloadRuleParcel {
- int inputInterfaceIndex;
- int outputInterfaceIndex;
- byte[] destination;
- int prefixLength;
- byte[] srcL2Address;
- byte[] dstL2Address;
- int pmtu = 1500;
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/TetherStatsParcel.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/TetherStatsParcel.aidl
deleted file mode 100644
index 5f1b722..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/TetherStatsParcel.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherStatsParcel {
- @utf8InCpp String iface;
- long rxBytes;
- long rxPackets;
- long txBytes;
- long txPackets;
- int ifIndex = 0;
-}
diff --git a/server/aidl_api/netd_aidl_interface/6/android/net/UidRangeParcel.aidl b/server/aidl_api/netd_aidl_interface/6/android/net/UidRangeParcel.aidl
deleted file mode 100644
index 72e987a..0000000
--- a/server/aidl_api/netd_aidl_interface/6/android/net/UidRangeParcel.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
-parcelable UidRangeParcel {
- int start;
- int stop;
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/.hash b/server/aidl_api/netd_aidl_interface/7/.hash
deleted file mode 100644
index cad59df..0000000
--- a/server/aidl_api/netd_aidl_interface/7/.hash
+++ /dev/null
@@ -1 +0,0 @@
-850353de5d19a0dd718f8fd20791f0532e6a34c7
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/INetd.aidl
deleted file mode 100644
index ec03d86..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/INetd.aidl
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * Copyright (c) 2016, 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetd {
- boolean isAlive();
- boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isAllowlist, in int[] uids);
- boolean bandwidthEnableDataSaver(boolean enable);
- /**
- * @deprecated use networkCreate() instead.
- */
- void networkCreatePhysical(int netId, int permission);
- /**
- * @deprecated use networkCreate() instead.
- */
- void networkCreateVpn(int netId, boolean secure);
- void networkDestroy(int netId);
- void networkAddInterface(int netId, in @utf8InCpp String iface);
- void networkRemoveInterface(int netId, in @utf8InCpp String iface);
- void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
- void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
- boolean tetherApplyDnsInterfaces();
- android.net.TetherStatsParcel[] tetherGetStats();
- void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
- void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
- void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
- int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
- void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
- void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
- void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
- void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
- void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void strictUidCleartextPenalty(int uid, int policyPenalty);
- @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
- void clatdStop(in @utf8InCpp String ifName);
- boolean ipfwdEnabled();
- @utf8InCpp String[] ipfwdGetRequesterList();
- void ipfwdEnableForwarding(in @utf8InCpp String requester);
- void ipfwdDisableForwarding(in @utf8InCpp String requester);
- void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
- void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
- void bandwidthSetGlobalAlert(long bytes);
- void bandwidthAddNaughtyApp(int uid);
- void bandwidthRemoveNaughtyApp(int uid);
- void bandwidthAddNiceApp(int uid);
- void bandwidthRemoveNiceApp(int uid);
- void tetherStart(in @utf8InCpp String[] dhcpRanges);
- void tetherStop();
- boolean tetherIsEnabled();
- void tetherInterfaceAdd(in @utf8InCpp String ifName);
- void tetherInterfaceRemove(in @utf8InCpp String ifName);
- @utf8InCpp String[] tetherInterfaceList();
- void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
- @utf8InCpp String[] tetherDnsList();
- void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- int networkGetDefault();
- void networkSetDefault(int netId);
- void networkClearDefault();
- void networkSetPermissionForNetwork(int netId, int permission);
- void networkSetPermissionForUser(int permission, in int[] uids);
- void networkClearPermissionForUser(in int[] uids);
- void trafficSetNetPermForUids(int permission, in int[] uids);
- void networkSetProtectAllow(int uid);
- void networkSetProtectDeny(int uid);
- boolean networkCanProtect(int uid);
- void firewallSetFirewallType(int firewalltype);
- void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
- void firewallSetUidRule(int childChain, int uid, int firewallRule);
- void firewallEnableChildChain(int childChain, boolean enable);
- @utf8InCpp String[] interfaceGetList();
- android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
- void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
- void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
- void interfaceClearAddrs(in @utf8InCpp String ifName);
- void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
- void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
- void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
- void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
- void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
- void firewallRemoveUidInterfaceRules(in int[] uids);
- void trafficSwapActiveStatsMap();
- IBinder getOemNetd();
- void tetherStartWithConfiguration(in android.net.TetherConfigParcel config);
- android.net.MarkMaskParcel getFwmarkForNetwork(int netId);
- void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void tetherOffloadRuleAdd(in android.net.TetherOffloadRuleParcel rule);
- void tetherOffloadRuleRemove(in android.net.TetherOffloadRuleParcel rule);
- android.net.TetherStatsParcel[] tetherOffloadGetStats();
- void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
- android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
- void networkCreate(in android.net.NativeNetworkConfig config);
- void networkAddUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
- void networkRemoveUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
- const int IPV4 = 4;
- const int IPV6 = 6;
- const int CONF = 1;
- const int NEIGH = 2;
- const String IPSEC_INTERFACE_PREFIX = "ipsec";
- const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
- const int IPV6_ADDR_GEN_MODE_NONE = 1;
- const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
- const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
- const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
- const int PENALTY_POLICY_ACCEPT = 1;
- const int PENALTY_POLICY_LOG = 2;
- const int PENALTY_POLICY_REJECT = 3;
- const int LOCAL_NET_ID = 99;
- const int DUMMY_NET_ID = 51;
- const int UNREACHABLE_NET_ID = 52;
- const String NEXTHOP_NONE = "";
- const String NEXTHOP_UNREACHABLE = "unreachable";
- const String NEXTHOP_THROW = "throw";
- const int PERMISSION_NONE = 0;
- const int PERMISSION_NETWORK = 1;
- const int PERMISSION_SYSTEM = 2;
- const int NO_PERMISSIONS = 0;
- const int PERMISSION_INTERNET = 4;
- const int PERMISSION_UPDATE_DEVICE_STATS = 8;
- const int PERMISSION_UNINSTALLED = -1;
- /**
- * @deprecated use FIREWALL_ALLOWLIST.
- */
- const int FIREWALL_WHITELIST = 0;
- const int FIREWALL_ALLOWLIST = 0;
- /**
- * @deprecated use FIREWALL_DENYLIST.
- */
- const int FIREWALL_BLACKLIST = 1;
- const int FIREWALL_DENYLIST = 1;
- const int FIREWALL_RULE_ALLOW = 1;
- const int FIREWALL_RULE_DENY = 2;
- const int FIREWALL_CHAIN_NONE = 0;
- const int FIREWALL_CHAIN_DOZABLE = 1;
- const int FIREWALL_CHAIN_STANDBY = 2;
- const int FIREWALL_CHAIN_POWERSAVE = 3;
- const int FIREWALL_CHAIN_RESTRICTED = 4;
- const String IF_STATE_UP = "up";
- const String IF_STATE_DOWN = "down";
- const String IF_FLAG_BROADCAST = "broadcast";
- const String IF_FLAG_LOOPBACK = "loopback";
- const String IF_FLAG_POINTOPOINT = "point-to-point";
- const String IF_FLAG_RUNNING = "running";
- const String IF_FLAG_MULTICAST = "multicast";
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/INetdUnsolicitedEventListener.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/INetdUnsolicitedEventListener.aidl
deleted file mode 100644
index 31775df..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/INetdUnsolicitedEventListener.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (c) 2018, 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetdUnsolicitedEventListener {
- oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
- oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
- oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
- oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAdded(@utf8InCpp String ifName);
- oneway void onInterfaceRemoved(@utf8InCpp String ifName);
- oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
- oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
- oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
- oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/InterfaceConfigurationParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/InterfaceConfigurationParcel.aidl
deleted file mode 100644
index 1869d8d..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/InterfaceConfigurationParcel.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable InterfaceConfigurationParcel {
- @utf8InCpp String ifName;
- @utf8InCpp String hwAddr;
- @utf8InCpp String ipv4Addr;
- int prefixLength;
- @utf8InCpp String[] flags;
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/MarkMaskParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/MarkMaskParcel.aidl
deleted file mode 100644
index 8ea20d1..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/MarkMaskParcel.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable MarkMaskParcel {
- int mark;
- int mask;
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkConfig.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkConfig.aidl
deleted file mode 100644
index 76562b2..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkConfig.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
-parcelable NativeNetworkConfig {
- int netId;
- android.net.NativeNetworkType networkType = android.net.NativeNetworkType.PHYSICAL;
- int permission;
- boolean secure;
- android.net.NativeVpnType vpnType = android.net.NativeVpnType.PLATFORM;
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkType.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkType.aidl
deleted file mode 100644
index 06c8979..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/NativeNetworkType.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-@Backing(type="int")
-enum NativeNetworkType {
- PHYSICAL = 0,
- VIRTUAL = 1,
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/NativeVpnType.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/NativeVpnType.aidl
deleted file mode 100644
index 8a8be83..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/NativeVpnType.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-@Backing(type="int")
-enum NativeVpnType {
- SERVICE = 1,
- PLATFORM = 2,
- LEGACY = 3,
- OEM = 4,
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/RouteInfoParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/RouteInfoParcel.aidl
deleted file mode 100644
index 5ef95e6..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/RouteInfoParcel.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Copyright (c) 2020, 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable RouteInfoParcel {
- @utf8InCpp String destination;
- @utf8InCpp String ifName;
- @utf8InCpp String nextHop;
- int mtu;
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/TetherConfigParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/TetherConfigParcel.aidl
deleted file mode 100644
index 7b39c22..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/TetherConfigParcel.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherConfigParcel {
- boolean usingLegacyDnsProxy;
- @utf8InCpp String[] dhcpRanges;
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/TetherOffloadRuleParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/TetherOffloadRuleParcel.aidl
deleted file mode 100644
index 983e986..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/TetherOffloadRuleParcel.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherOffloadRuleParcel {
- int inputInterfaceIndex;
- int outputInterfaceIndex;
- byte[] destination;
- int prefixLength;
- byte[] srcL2Address;
- byte[] dstL2Address;
- int pmtu = 1500;
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/TetherStatsParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/TetherStatsParcel.aidl
deleted file mode 100644
index 5f1b722..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/TetherStatsParcel.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherStatsParcel {
- @utf8InCpp String iface;
- long rxBytes;
- long rxPackets;
- long txBytes;
- long txPackets;
- int ifIndex = 0;
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/UidRangeParcel.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/UidRangeParcel.aidl
deleted file mode 100644
index 72e987a..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/UidRangeParcel.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
-parcelable UidRangeParcel {
- int start;
- int stop;
-}
diff --git a/server/aidl_api/netd_aidl_interface/7/android/net/netd/aidl/NativeUidRangeConfig.aidl b/server/aidl_api/netd_aidl_interface/7/android/net/netd/aidl/NativeUidRangeConfig.aidl
deleted file mode 100644
index 9bb679f..0000000
--- a/server/aidl_api/netd_aidl_interface/7/android/net/netd/aidl/NativeUidRangeConfig.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.netd.aidl;
-/* @hide */
-@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
-parcelable NativeUidRangeConfig {
- int netId;
- android.net.UidRangeParcel[] uidRanges;
- int subPriority;
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
deleted file mode 100644
index ec03d86..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/INetd.aidl
+++ /dev/null
@@ -1,200 +0,0 @@
-/**
- * Copyright (c) 2016, 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetd {
- boolean isAlive();
- boolean firewallReplaceUidChain(in @utf8InCpp String chainName, boolean isAllowlist, in int[] uids);
- boolean bandwidthEnableDataSaver(boolean enable);
- /**
- * @deprecated use networkCreate() instead.
- */
- void networkCreatePhysical(int netId, int permission);
- /**
- * @deprecated use networkCreate() instead.
- */
- void networkCreateVpn(int netId, boolean secure);
- void networkDestroy(int netId);
- void networkAddInterface(int netId, in @utf8InCpp String iface);
- void networkRemoveInterface(int netId, in @utf8InCpp String iface);
- void networkAddUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRemoveUidRanges(int netId, in android.net.UidRangeParcel[] uidRanges);
- void networkRejectNonSecureVpn(boolean add, in android.net.UidRangeParcel[] uidRanges);
- void socketDestroy(in android.net.UidRangeParcel[] uidRanges, in int[] exemptUids);
- boolean tetherApplyDnsInterfaces();
- android.net.TetherStatsParcel[] tetherGetStats();
- void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString, int prefixLength);
- @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter);
- void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname, in @utf8InCpp String parameter, in @utf8InCpp String value);
- void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
- int ipSecAllocateSpi(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecAddSecurityAssociation(int transformId, int mode, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int underlyingNetId, int spi, int markValue, int markMask, in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits, in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits, in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits, int encapType, int encapLocalPort, int encapRemotePort, int interfaceId);
- void ipSecDeleteSecurityAssociation(int transformId, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecApplyTransportModeTransform(in ParcelFileDescriptor socket, int transformId, int direction, in @utf8InCpp String sourceAddress, in @utf8InCpp String destinationAddress, int spi);
- void ipSecRemoveTransportModeTransform(in ParcelFileDescriptor socket);
- void ipSecAddSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecUpdateSecurityPolicy(int transformId, int selAddrFamily, int direction, in @utf8InCpp String tmplSrcAddress, in @utf8InCpp String tmplDstAddress, int spi, int markValue, int markMask, int interfaceId);
- void ipSecDeleteSecurityPolicy(int transformId, int selAddrFamily, int direction, int markValue, int markMask, int interfaceId);
- void ipSecAddTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecUpdateTunnelInterface(in @utf8InCpp String deviceName, in @utf8InCpp String localAddress, in @utf8InCpp String remoteAddress, int iKey, int oKey, int interfaceId);
- void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
- void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
- void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
- void idletimerAddInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void idletimerRemoveInterface(in @utf8InCpp String ifName, int timeout, in @utf8InCpp String classLabel);
- void strictUidCleartextPenalty(int uid, int policyPenalty);
- @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
- void clatdStop(in @utf8InCpp String ifName);
- boolean ipfwdEnabled();
- @utf8InCpp String[] ipfwdGetRequesterList();
- void ipfwdEnableForwarding(in @utf8InCpp String requester);
- void ipfwdDisableForwarding(in @utf8InCpp String requester);
- void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
- void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
- void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
- void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
- void bandwidthSetGlobalAlert(long bytes);
- void bandwidthAddNaughtyApp(int uid);
- void bandwidthRemoveNaughtyApp(int uid);
- void bandwidthAddNiceApp(int uid);
- void bandwidthRemoveNiceApp(int uid);
- void tetherStart(in @utf8InCpp String[] dhcpRanges);
- void tetherStop();
- boolean tetherIsEnabled();
- void tetherInterfaceAdd(in @utf8InCpp String ifName);
- void tetherInterfaceRemove(in @utf8InCpp String ifName);
- @utf8InCpp String[] tetherInterfaceList();
- void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
- @utf8InCpp String[] tetherDnsList();
- void networkAddRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkRemoveRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop);
- void networkAddLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- void networkRemoveLegacyRoute(int netId, in @utf8InCpp String ifName, in @utf8InCpp String destination, in @utf8InCpp String nextHop, int uid);
- int networkGetDefault();
- void networkSetDefault(int netId);
- void networkClearDefault();
- void networkSetPermissionForNetwork(int netId, int permission);
- void networkSetPermissionForUser(int permission, in int[] uids);
- void networkClearPermissionForUser(in int[] uids);
- void trafficSetNetPermForUids(int permission, in int[] uids);
- void networkSetProtectAllow(int uid);
- void networkSetProtectDeny(int uid);
- boolean networkCanProtect(int uid);
- void firewallSetFirewallType(int firewalltype);
- void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
- void firewallSetUidRule(int childChain, int uid, int firewallRule);
- void firewallEnableChildChain(int childChain, boolean enable);
- @utf8InCpp String[] interfaceGetList();
- android.net.InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
- void interfaceSetCfg(in android.net.InterfaceConfigurationParcel cfg);
- void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
- void interfaceClearAddrs(in @utf8InCpp String ifName);
- void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
- void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
- void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
- void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
- void registerUnsolicitedEventListener(android.net.INetdUnsolicitedEventListener listener);
- void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
- void firewallRemoveUidInterfaceRules(in int[] uids);
- void trafficSwapActiveStatsMap();
- IBinder getOemNetd();
- void tetherStartWithConfiguration(in android.net.TetherConfigParcel config);
- android.net.MarkMaskParcel getFwmarkForNetwork(int netId);
- void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
- void tetherOffloadRuleAdd(in android.net.TetherOffloadRuleParcel rule);
- void tetherOffloadRuleRemove(in android.net.TetherOffloadRuleParcel rule);
- android.net.TetherStatsParcel[] tetherOffloadGetStats();
- void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
- android.net.TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
- void networkCreate(in android.net.NativeNetworkConfig config);
- void networkAddUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
- void networkRemoveUidRangesParcel(in android.net.netd.aidl.NativeUidRangeConfig uidRangesConfig);
- const int IPV4 = 4;
- const int IPV6 = 6;
- const int CONF = 1;
- const int NEIGH = 2;
- const String IPSEC_INTERFACE_PREFIX = "ipsec";
- const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
- const int IPV6_ADDR_GEN_MODE_NONE = 1;
- const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
- const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
- const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
- const int PENALTY_POLICY_ACCEPT = 1;
- const int PENALTY_POLICY_LOG = 2;
- const int PENALTY_POLICY_REJECT = 3;
- const int LOCAL_NET_ID = 99;
- const int DUMMY_NET_ID = 51;
- const int UNREACHABLE_NET_ID = 52;
- const String NEXTHOP_NONE = "";
- const String NEXTHOP_UNREACHABLE = "unreachable";
- const String NEXTHOP_THROW = "throw";
- const int PERMISSION_NONE = 0;
- const int PERMISSION_NETWORK = 1;
- const int PERMISSION_SYSTEM = 2;
- const int NO_PERMISSIONS = 0;
- const int PERMISSION_INTERNET = 4;
- const int PERMISSION_UPDATE_DEVICE_STATS = 8;
- const int PERMISSION_UNINSTALLED = -1;
- /**
- * @deprecated use FIREWALL_ALLOWLIST.
- */
- const int FIREWALL_WHITELIST = 0;
- const int FIREWALL_ALLOWLIST = 0;
- /**
- * @deprecated use FIREWALL_DENYLIST.
- */
- const int FIREWALL_BLACKLIST = 1;
- const int FIREWALL_DENYLIST = 1;
- const int FIREWALL_RULE_ALLOW = 1;
- const int FIREWALL_RULE_DENY = 2;
- const int FIREWALL_CHAIN_NONE = 0;
- const int FIREWALL_CHAIN_DOZABLE = 1;
- const int FIREWALL_CHAIN_STANDBY = 2;
- const int FIREWALL_CHAIN_POWERSAVE = 3;
- const int FIREWALL_CHAIN_RESTRICTED = 4;
- const String IF_STATE_UP = "up";
- const String IF_STATE_DOWN = "down";
- const String IF_FLAG_BROADCAST = "broadcast";
- const String IF_FLAG_LOOPBACK = "loopback";
- const String IF_FLAG_POINTOPOINT = "point-to-point";
- const String IF_FLAG_RUNNING = "running";
- const String IF_FLAG_MULTICAST = "multicast";
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/INetdUnsolicitedEventListener.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/INetdUnsolicitedEventListener.aidl
deleted file mode 100644
index 31775df..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/INetdUnsolicitedEventListener.aidl
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * Copyright (c) 2018, 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-interface INetdUnsolicitedEventListener {
- oneway void onInterfaceClassActivityChanged(boolean isActive, int timerLabel, long timestampNs, int uid);
- oneway void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
- oneway void onInterfaceDnsServerInfo(@utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
- oneway void onInterfaceAddressUpdated(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAddressRemoved(@utf8InCpp String addr, @utf8InCpp String ifName, int flags, int scope);
- oneway void onInterfaceAdded(@utf8InCpp String ifName);
- oneway void onInterfaceRemoved(@utf8InCpp String ifName);
- oneway void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
- oneway void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
- oneway void onRouteChanged(boolean updated, @utf8InCpp String route, @utf8InCpp String gateway, @utf8InCpp String ifName);
- oneway void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/InterfaceConfigurationParcel.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/InterfaceConfigurationParcel.aidl
deleted file mode 100644
index 1869d8d..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/InterfaceConfigurationParcel.aidl
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable InterfaceConfigurationParcel {
- @utf8InCpp String ifName;
- @utf8InCpp String hwAddr;
- @utf8InCpp String ipv4Addr;
- int prefixLength;
- @utf8InCpp String[] flags;
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/MarkMaskParcel.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/MarkMaskParcel.aidl
deleted file mode 100644
index 8ea20d1..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/MarkMaskParcel.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable MarkMaskParcel {
- int mark;
- int mask;
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkConfig.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkConfig.aidl
deleted file mode 100644
index 76562b2..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkConfig.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
-parcelable NativeNetworkConfig {
- int netId;
- android.net.NativeNetworkType networkType = android.net.NativeNetworkType.PHYSICAL;
- int permission;
- boolean secure;
- android.net.NativeVpnType vpnType = android.net.NativeVpnType.PLATFORM;
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkType.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkType.aidl
deleted file mode 100644
index 06c8979..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/NativeNetworkType.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-@Backing(type="int")
-enum NativeNetworkType {
- PHYSICAL = 0,
- VIRTUAL = 1,
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/NativeVpnType.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/NativeVpnType.aidl
deleted file mode 100644
index 8a8be83..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/NativeVpnType.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-@Backing(type="int")
-enum NativeVpnType {
- SERVICE = 1,
- PLATFORM = 2,
- LEGACY = 3,
- OEM = 4,
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/RouteInfoParcel.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/RouteInfoParcel.aidl
deleted file mode 100644
index 5ef95e6..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/RouteInfoParcel.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * Copyright (c) 2020, 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-parcelable RouteInfoParcel {
- @utf8InCpp String destination;
- @utf8InCpp String ifName;
- @utf8InCpp String nextHop;
- int mtu;
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/TetherConfigParcel.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/TetherConfigParcel.aidl
deleted file mode 100644
index 7b39c22..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/TetherConfigParcel.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherConfigParcel {
- boolean usingLegacyDnsProxy;
- @utf8InCpp String[] dhcpRanges;
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/TetherOffloadRuleParcel.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/TetherOffloadRuleParcel.aidl
deleted file mode 100644
index 983e986..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/TetherOffloadRuleParcel.aidl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherOffloadRuleParcel {
- int inputInterfaceIndex;
- int outputInterfaceIndex;
- byte[] destination;
- int prefixLength;
- byte[] srcL2Address;
- byte[] dstL2Address;
- int pmtu = 1500;
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/TetherStatsParcel.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/TetherStatsParcel.aidl
deleted file mode 100644
index 5f1b722..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/TetherStatsParcel.aidl
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-parcelable TetherStatsParcel {
- @utf8InCpp String iface;
- long rxBytes;
- long rxPackets;
- long txBytes;
- long txPackets;
- int ifIndex = 0;
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/UidRangeParcel.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/UidRangeParcel.aidl
deleted file mode 100644
index 72e987a..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/UidRangeParcel.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net;
-/* @hide */
-@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
-parcelable UidRangeParcel {
- int start;
- int stop;
-}
diff --git a/server/aidl_api/netd_aidl_interface/current/android/net/netd/aidl/NativeUidRangeConfig.aidl b/server/aidl_api/netd_aidl_interface/current/android/net/netd/aidl/NativeUidRangeConfig.aidl
deleted file mode 100644
index 9bb679f..0000000
--- a/server/aidl_api/netd_aidl_interface/current/android/net/netd/aidl/NativeUidRangeConfig.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL file. Do not edit it manually. There are
-// two cases:
-// 1). this is a frozen version file - do not edit this in any case.
-// 2). this is a 'current' file. If you make a backwards compatible change to
-// the interface (from the latest frozen version), the build system will
-// prompt you to update this file with `m <name>-update-api`.
-//
-// You must not make a backward incompatible change to any AIDL file built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.netd.aidl;
-/* @hide */
-@JavaDerive(equals=true, toString=true) @JavaOnlyImmutable
-parcelable NativeUidRangeConfig {
- int netId;
- android.net.UidRangeParcel[] uidRanges;
- int subPriority;
-}
diff --git a/server/aidl_api/netd_event_listener_interface/1/.hash b/server/aidl_api/netd_event_listener_interface/1/.hash
deleted file mode 100644
index f39f730..0000000
--- a/server/aidl_api/netd_event_listener_interface/1/.hash
+++ /dev/null
@@ -1 +0,0 @@
-8e27594d285ca7c567d87e8cf74766c27647e02b
diff --git a/server/aidl_api/netd_event_listener_interface/1/android/net/metrics/INetdEventListener.aidl b/server/aidl_api/netd_event_listener_interface/1/android/net/metrics/INetdEventListener.aidl
deleted file mode 100644
index 9898a67..0000000
--- a/server/aidl_api/netd_event_listener_interface/1/android/net/metrics/INetdEventListener.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a frozen snapshot of an AIDL interface (or parcelable). Do not
-// try to edit this file. It looks like you are doing that because you have
-// modified an AIDL interface in a backward-incompatible way, e.g., deleting a
-// function from an interface or a field from a parcelable and it broke the
-// build. That breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.metrics;
-interface INetdEventListener {
- oneway void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs, @utf8InCpp String hostname, in @utf8InCpp String[] ipAddresses, int ipAddressesCount, int uid);
- oneway void onPrivateDnsValidationEvent(int netId, String ipAddress, String hostname, boolean validated);
- oneway void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port, int uid);
- oneway void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader, in byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs);
- oneway void onTcpSocketStatsEvent(in int[] networkIds, in int[] sentPackets, in int[] lostPackets, in int[] rttUs, in int[] sentAckDiffMs);
- oneway void onNat64PrefixEvent(int netId, boolean added, @utf8InCpp String prefixString, int prefixLength);
- const int EVENT_GETADDRINFO = 1;
- const int EVENT_GETHOSTBYNAME = 2;
- const int EVENT_GETHOSTBYADDR = 3;
- const int EVENT_RES_NSEND = 4;
- const int REPORTING_LEVEL_NONE = 0;
- const int REPORTING_LEVEL_METRICS = 1;
- const int REPORTING_LEVEL_FULL = 2;
- const int DNS_REPORTED_IP_ADDRESSES_LIMIT = 10;
-}
diff --git a/server/aidl_api/netd_event_listener_interface/current/android/net/metrics/INetdEventListener.aidl b/server/aidl_api/netd_event_listener_interface/current/android/net/metrics/INetdEventListener.aidl
deleted file mode 100644
index d71c3f2..0000000
--- a/server/aidl_api/netd_event_listener_interface/current/android/net/metrics/INetdEventListener.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
-///////////////////////////////////////////////////////////////////////////////
-
-// This file is a snapshot of an AIDL interface (or parcelable). Do not try to
-// edit this file. It looks like you are doing that because you have modified
-// an AIDL interface in a backward-incompatible way, e.g., deleting a function
-// from an interface or a field from a parcelable and it broke the build. That
-// breakage is intended.
-//
-// You must not make a backward incompatible changes to the AIDL files built
-// with the aidl_interface module type with versions property set. The module
-// type is used to build AIDL files in a way that they can be used across
-// independently updatable components of the system. If a device is shipped
-// with such a backward incompatible change, it has a high risk of breaking
-// later when a module using the interface is updated, e.g., Mainline modules.
-
-package android.net.metrics;
-/* @hide */
-interface INetdEventListener {
- oneway void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs, @utf8InCpp String hostname, in @utf8InCpp String[] ipAddresses, int ipAddressesCount, int uid);
- oneway void onPrivateDnsValidationEvent(int netId, String ipAddress, String hostname, boolean validated);
- oneway void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port, int uid);
- oneway void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader, in byte[] dstHw, String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs);
- oneway void onTcpSocketStatsEvent(in int[] networkIds, in int[] sentPackets, in int[] lostPackets, in int[] rttUs, in int[] sentAckDiffMs);
- oneway void onNat64PrefixEvent(int netId, boolean added, @utf8InCpp String prefixString, int prefixLength);
- const int EVENT_GETADDRINFO = 1;
- const int EVENT_GETHOSTBYNAME = 2;
- const int EVENT_GETHOSTBYADDR = 3;
- const int EVENT_RES_NSEND = 4;
- const int REPORTING_LEVEL_NONE = 0;
- const int REPORTING_LEVEL_METRICS = 1;
- const int REPORTING_LEVEL_FULL = 2;
- const int DNS_REPORTED_IP_ADDRESSES_LIMIT = 10;
-}
diff --git a/server/binder/android/net/INetd.aidl b/server/binder/android/net/INetd.aidl
deleted file mode 100644
index d6398c1..0000000
--- a/server/binder/android/net/INetd.aidl
+++ /dev/null
@@ -1,1380 +0,0 @@
-/**
- * Copyright (c) 2016, 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.
- */
-
-package android.net;
-
-import android.net.INetdUnsolicitedEventListener;
-import android.net.InterfaceConfigurationParcel;
-import android.net.MarkMaskParcel;
-import android.net.NativeNetworkConfig;
-import android.net.RouteInfoParcel;
-import android.net.TetherConfigParcel;
-import android.net.TetherOffloadRuleParcel;
-import android.net.TetherStatsParcel;
-import android.net.UidRangeParcel;
-import android.net.netd.aidl.NativeUidRangeConfig;
-
-/** {@hide} */
-interface INetd {
- /**
- * Returns true if the service is responding.
- */
- boolean isAlive();
-
- /**
- * Replaces the contents of the specified UID-based firewall chain.
- *
- * The chain may be an allowlist chain or a denylist chain. A denylist chain contains DROP
- * rules for the specified UIDs and a RETURN rule at the end. An allowlist chain contains RETURN
- * rules for the system UID range (0 to {@code UID_APP} - 1), RETURN rules for for the specified
- * UIDs, and a DROP rule at the end. The chain will be created if it does not exist.
- *
- * @param chainName The name of the chain to replace.
- * @param isAllowlist Whether this is an allowlist or denylist chain.
- * @param uids The list of UIDs to allow/deny.
- * @return true if the chain was successfully replaced, false otherwise.
- */
- boolean firewallReplaceUidChain(in @utf8InCpp String chainName,
- boolean isAllowlist,
- in int[] uids);
-
- /**
- * Enables or disables data saver mode on costly network interfaces.
- *
- * - When disabled, all packets to/from apps in the penalty box chain are rejected on costly
- * interfaces. Traffic to/from other apps or on other network interfaces is allowed.
- * - When enabled, only apps that are in the happy box chain and not in the penalty box chain
- * are allowed network connectivity on costly interfaces. All other packets on these
- * interfaces are rejected. The happy box chain always contains all system UIDs; to disallow
- * traffic from system UIDs, place them in the penalty box chain.
- *
- * By default, data saver mode is disabled. This command has no effect but might still return an
- * error) if {@code enable} is the same as the current value.
- *
- * @param enable whether to enable or disable data saver mode.
- * @return true if the if the operation was successful, false otherwise.
- */
- boolean bandwidthEnableDataSaver(boolean enable);
-
- /**
- * Creates a physical network (i.e., one containing physical interfaces.
- * @deprecated use networkCreate() instead.
- *
- * @param netId the networkId to create.
- * @param permission the permission necessary to use the network. Must be one of
- * PERMISSION_NONE/PERMISSION_NETWORK/PERMISSION_SYSTEM.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkCreatePhysical(int netId, int permission);
-
- /**
- * Creates a VPN network.
- * @deprecated use networkCreate() instead.
- *
- * @param netId the network to create.
- * @param secure whether unprivileged apps are allowed to bypass the VPN.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkCreateVpn(int netId, boolean secure);
-
- /**
- * Destroys a network. Any interfaces added to the network are removed, and the network ceases
- * to be the default network.
- *
- * @param netId the network to destroy.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkDestroy(int netId);
-
- /**
- * Adds an interface to a network. The interface must not be assigned to any network, including
- * the specified network.
- *
- * @param netId the network to add the interface to.
- * @param interface the name of the interface to add.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkAddInterface(int netId, in @utf8InCpp String iface);
-
- /**
- * Adds an interface to a network. The interface must be assigned to the specified network.
- *
- * @param netId the network to remove the interface from.
- * @param interface the name of the interface to remove.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkRemoveInterface(int netId, in @utf8InCpp String iface);
-
- /**
- * Adds the specified UID ranges to the specified network. The network can be physical or
- * virtual. Traffic from the UID ranges will be routed to the network by default.
- *
- * @param netId the network ID of the network to add the ranges to.
- * @param uidRanges a set of non-overlapping ranges of UIDs to add. These exact ranges
- * must not overlap with existing ranges assigned to this network.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkAddUidRanges(int netId, in UidRangeParcel[] uidRanges);
-
- /**
- * Remove the specified UID ranges from the specified network. The network can be physical or
- * virtual. Traffic from the UID ranges will no longer be routed to the network by default.
- *
- * @param netId the network ID of the network to remove the ranges from.
- * @param uidRanges a set of non-overlapping ranges of UIDs to remove. These exact ranges
- * must already be assigned to this network.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkRemoveUidRanges(int netId, in UidRangeParcel[] uidRanges);
-
- /**
- * Adds or removes one rule for each supplied UID range to prohibit all network activity outside
- * of secure VPN.
- *
- * When a UID is covered by one of these rules, traffic sent through any socket that is not
- * protected or explicitly overriden by the system will be rejected. The kernel will respond
- * with an ICMP prohibit message.
- *
- * Initially, there are no such rules. Any rules that are added will only last until the next
- * restart of netd or the device.
- *
- * @param add {@code true} if the specified UID ranges should be denied access to any network
- * which is not secure VPN by adding rules, {@code false} to remove existing rules.
- * @param uidRanges a set of non-overlapping, contiguous ranges of UIDs to which to apply or
- * remove this restriction.
- * <p> Added rules should not overlap with existing rules. Likewise, removed rules should
- * each correspond to an existing rule.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkRejectNonSecureVpn(boolean add, in UidRangeParcel[] uidRanges);
-
- /**
- * Administratively closes sockets belonging to the specified UIDs.
- */
- void socketDestroy(in UidRangeParcel[] uidRanges, in int[] exemptUids);
-
- /**
- * Instruct the tethering DNS server to reevaluated serving interfaces.
- * This is needed to for the DNS server to observe changes in the set
- * of potential listening IP addresses. (Listening on wildcard addresses
- * can turn the device into an open resolver; b/7530468)
- *
- * TODO: Return something richer than just a boolean.
- */
- boolean tetherApplyDnsInterfaces();
-
- /**
- * Return tethering statistics.
- *
- * @return an array of TetherStatsParcel, where each entry contains the upstream interface
- * name and its tethering statistics since netd startup.
- * There will only ever be one entry for a given interface.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- TetherStatsParcel[] tetherGetStats();
-
- /**
- * Add/Remove and IP address from an interface.
- *
- * @param ifName the interface name
- * @param addrString the IP address to add/remove as a string literal
- * @param prefixLength the prefix length associated with this IP address
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void interfaceAddAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString,
- int prefixLength);
- void interfaceDelAddress(in @utf8InCpp String ifName, in @utf8InCpp String addrString,
- int prefixLength);
-
- /**
- * Set and get /proc/sys/net interface configuration parameters.
- *
- * @param ipversion One of IPV4/IPV6 integers, indicating the desired IP version directory.
- * @param which One of CONF/NEIGH integers, indicating the desired parameter category directory.
- * @param ifname The interface name portion of the path; may also be "all" or "default".
- * @param parameter The parameter name portion of the path.
- * @param value The value string to be written into the assembled path.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
-
- const int IPV4 = 4;
- const int IPV6 = 6;
- const int CONF = 1;
- const int NEIGH = 2;
- @utf8InCpp String getProcSysNet(int ipversion, int which, in @utf8InCpp String ifname,
- in @utf8InCpp String parameter);
- void setProcSysNet(int ipversion, int which, in @utf8InCpp String ifname,
- in @utf8InCpp String parameter, in @utf8InCpp String value);
-
- /**
- * Sets owner of socket ParcelFileDescriptor to the new UID, checking to ensure that the caller's
- * uid is that of the old owner's, and that this is a UDP-encap socket
- *
- * @param ParcelFileDescriptor socket Socket file descriptor
- * @param int newUid UID of the new socket fd owner
- */
- void ipSecSetEncapSocketOwner(in ParcelFileDescriptor socket, int newUid);
-
- /**
- * Reserve an SPI from the kernel
- *
- * @param transformId a unique identifier for allocated resources
- * @param sourceAddress InetAddress as string for the sending endpoint
- * @param destinationAddress InetAddress as string for the receiving endpoint
- * @param spi a requested 32-bit unique ID or 0 to request random allocation
- * @return the SPI that was allocated or 0 if failed
- */
- int ipSecAllocateSpi(
- int transformId,
- in @utf8InCpp String sourceAddress,
- in @utf8InCpp String destinationAddress,
- int spi);
-
- /**
- * Create an IpSec Security Association describing how ip(v6) traffic will be encrypted
- * or decrypted.
- *
- * @param transformId a unique identifier for allocated resources
- * @param mode either Transport or Tunnel mode
- * @param sourceAddress InetAddress as string for the sending endpoint
- * @param destinationAddress InetAddress as string for the receiving endpoint
- * @param underlyingNetId the netId of the network to which the SA is applied. Only accepted for
- * tunnel mode SAs.
- * @param spi a 32-bit unique ID allocated to the user
- * @param markValue a 32-bit unique ID chosen by the user
- * @param markMask a 32-bit mask chosen by the user
- * @param authAlgo a string identifying the authentication algorithm to be used
- * @param authKey a byte array containing the authentication key
- * @param authTruncBits the truncation length of the MAC produced by the authentication algorithm
- * @param cryptAlgo a string identifying the encryption algorithm to be used
- * @param cryptKey a byte arrray containing the encryption key
- * @param cryptTruncBits unused parameter
- * @param aeadAlgo a string identifying the authenticated encryption algorithm to be used
- * @param aeadKey a byte arrray containing the key to be used in authenticated encryption
- * @param aeadIcvBits the truncation length of the ICV produced by the authentication algorithm
- * (similar to authTruncBits in function)
- * @param encapType encapsulation type used (if any) for the udp encap socket
- * @param encapLocalPort the port number on the host to be used in encap packets
- * @param encapRemotePort the port number of the remote to be used for encap packets
- * @param interfaceId the identifier for the IPsec tunnel interface.
- * Only accepted for tunnel mode SAs.
- */
- void ipSecAddSecurityAssociation(
- int transformId,
- int mode,
- in @utf8InCpp String sourceAddress,
- in @utf8InCpp String destinationAddress,
- int underlyingNetId,
- int spi,
- int markValue,
- int markMask,
- in @utf8InCpp String authAlgo, in byte[] authKey, in int authTruncBits,
- in @utf8InCpp String cryptAlgo, in byte[] cryptKey, in int cryptTruncBits,
- in @utf8InCpp String aeadAlgo, in byte[] aeadKey, in int aeadIcvBits,
- int encapType,
- int encapLocalPort,
- int encapRemotePort,
- int interfaceId);
-
- /**
- * Delete a previously created security association identified by the provided parameters
- *
- * @param transformId a unique identifier for allocated resources
- * @param sourceAddress InetAddress as string for the sending endpoint
- * @param destinationAddress InetAddress as string for the receiving endpoint
- * @param spi a requested 32-bit unique ID allocated to the user
- * @param markValue a 32-bit unique ID chosen by the user
- * @param markMask a 32-bit mask chosen by the user
- * @param interfaceId the identifier for the IPsec tunnel interface.
- */
- void ipSecDeleteSecurityAssociation(
- int transformId,
- in @utf8InCpp String sourceAddress,
- in @utf8InCpp String destinationAddress,
- int spi,
- int markValue,
- int markMask,
- int interfaceId);
-
- /**
- * Apply a previously created SA to a specified socket, starting IPsec on that socket
- *
- * @param socket a user-provided socket that will have IPsec applied
- * @param transformId a unique identifier for allocated resources
- * @param direction DIRECTION_IN or DIRECTION_OUT
- * @param sourceAddress InetAddress as string for the sending endpoint
- * @param destinationAddress InetAddress as string for the receiving endpoint
- * @param spi a 32-bit unique ID allocated to the user (socket owner)
- */
- void ipSecApplyTransportModeTransform(
- in ParcelFileDescriptor socket,
- int transformId,
- int direction,
- in @utf8InCpp String sourceAddress,
- in @utf8InCpp String destinationAddress,
- int spi);
-
- /**
- * Remove an IPsec SA from a given socket. This will allow unencrypted traffic to flow
- * on that socket if a transform had been previously applied.
- *
- * @param socket a user-provided socket from which to remove any IPsec configuration
- */
- void ipSecRemoveTransportModeTransform(
- in ParcelFileDescriptor socket);
-
- /**
- * Adds an IPsec global policy.
- *
- * @param transformId a unique identifier for allocated resources
- * @param selAddrFamily the address family identifier for the selector
- * @param direction DIRECTION_IN or DIRECTION_OUT
- * @param tmplSrcAddress InetAddress as string for the sending endpoint
- * @param tmplDstAddress InetAddress as string for the receiving endpoint
- * @param spi a 32-bit unique ID allocated to the user
- * @param markValue a 32-bit unique ID chosen by the user
- * @param markMask a 32-bit mask chosen by the user
- * @param interfaceId the identifier for the IPsec tunnel interface.
- */
- void ipSecAddSecurityPolicy(
- int transformId,
- int selAddrFamily,
- int direction,
- in @utf8InCpp String tmplSrcAddress,
- in @utf8InCpp String tmplDstAddress,
- int spi,
- int markValue,
- int markMask,
- int interfaceId);
-
- /**
- * Updates an IPsec global policy.
- *
- * @param transformId a unique identifier for allocated resources
- * @param selAddrFamily the address family identifier for the selector
- * @param direction DIRECTION_IN or DIRECTION_OUT
- * @param tmplSrcAddress InetAddress as string for the sending endpoint
- * @param tmplDstAddress InetAddress as string for the receiving endpoint
- * @param spi a 32-bit unique ID allocated to the user
- * @param markValue a 32-bit unique ID chosen by the user
- * @param markMask a 32-bit mask chosen by the user
- * @param interfaceId the identifier for the IPsec tunnel interface.
- */
- void ipSecUpdateSecurityPolicy(
- int transformId,
- int selAddrFamily,
- int direction,
- in @utf8InCpp String tmplSrcAddress,
- in @utf8InCpp String tmplDstAddress,
- int spi,
- int markValue,
- int markMask,
- int interfaceId);
-
- /**
- * Deletes an IPsec global policy.
- *
- * Deletion of global policies does not do any matching based on the templates, thus
- * template source/destination addresses are not needed (as opposed to add/update).
- *
- * @param transformId a unique identifier for allocated resources
- * @param selAddrFamily the address family identifier for the selector
- * @param direction DIRECTION_IN or DIRECTION_OUT
- * @param markValue a 32-bit unique ID chosen by the user
- * @param markMask a 32-bit mask chosen by the user
- * @param interfaceId the identifier for the IPsec tunnel interface.
- */
- void ipSecDeleteSecurityPolicy(
- int transformId,
- int selAddrFamily,
- int direction,
- int markValue,
- int markMask,
- int interfaceId);
-
- // This could not be declared as @uft8InCpp; thus, when used in native code it must be
- // converted from a UTF-16 string to an ASCII string.
- const String IPSEC_INTERFACE_PREFIX = "ipsec";
-
- /**
- * Add a IPsec Tunnel Interface.
- *
- * @param devName a unique identifier that represents the name of the device
- * @param localAddress InetAddress as string for the local endpoint
- * @param remoteAddress InetAddress as string for the remote endpoint
- * @param iKey, to match Policies and SAs for input packets.
- * @param oKey, to match Policies and SAs for output packets.
- * @param interfaceId the identifier for the IPsec tunnel interface.
- */
- void ipSecAddTunnelInterface(
- in @utf8InCpp String deviceName,
- in @utf8InCpp String localAddress,
- in @utf8InCpp String remoteAddress,
- int iKey,
- int oKey,
- int interfaceId);
-
- /**
- * Update a IPsec Tunnel Interface.
- *
- * @param devName a unique identifier that represents the name of the device
- * @param localAddress InetAddress as string for the local endpoint
- * @param remoteAddress InetAddress as string for the remote endpoint
- * @param iKey, to match Policies and SAs for input packets.
- * @param oKey, to match Policies and SAs for output packets.
- * @param interfaceId the identifier for the IPsec tunnel interface.
- */
- void ipSecUpdateTunnelInterface(
- in @utf8InCpp String deviceName,
- in @utf8InCpp String localAddress,
- in @utf8InCpp String remoteAddress,
- int iKey,
- int oKey,
- int interfaceId);
-
- /**
- * Removes a IPsec Tunnel Interface.
- *
- * @param devName a unique identifier that represents the name of the device
- */
- void ipSecRemoveTunnelInterface(in @utf8InCpp String deviceName);
-
- /**
- * Request notification of wakeup packets arriving on an interface. Notifications will be
- * delivered to INetdEventListener.onWakeupEvent().
- *
- * @param ifName the interface
- * @param prefix arbitrary string used to identify wakeup sources in onWakeupEvent
- */
- void wakeupAddInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
-
- /**
- * Stop notification of wakeup packets arriving on an interface.
- *
- * @param ifName the interface
- * @param prefix arbitrary string used to identify wakeup sources in onWakeupEvent
- */
- void wakeupDelInterface(in @utf8InCpp String ifName, in @utf8InCpp String prefix, int mark, int mask);
-
- const int IPV6_ADDR_GEN_MODE_EUI64 = 0;
- const int IPV6_ADDR_GEN_MODE_NONE = 1;
- const int IPV6_ADDR_GEN_MODE_STABLE_PRIVACY = 2;
- const int IPV6_ADDR_GEN_MODE_RANDOM = 3;
-
- const int IPV6_ADDR_GEN_MODE_DEFAULT = 0;
- /**
- * Set IPv6 address generation mode. IPv6 should be disabled before changing mode.
- *
- * @param mode SLAAC address generation mechanism to use
- */
- void setIPv6AddrGenMode(in @utf8InCpp String ifName, int mode);
-
- /**
- * Add idletimer for specific interface
- *
- * @param ifName Name of target interface
- * @param timeout The time in seconds that will trigger idletimer
- * @param classLabel The unique identifier for this idletimer
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void idletimerAddInterface(
- in @utf8InCpp String ifName,
- int timeout,
- in @utf8InCpp String classLabel);
-
- /**
- * Remove idletimer for specific interface
- *
- * @param ifName Name of target interface
- * @param timeout The time in seconds that will trigger idletimer
- * @param classLabel The unique identifier for this idletimer
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void idletimerRemoveInterface(
- in @utf8InCpp String ifName,
- int timeout,
- in @utf8InCpp String classLabel);
-
- const int PENALTY_POLICY_ACCEPT = 1;
- const int PENALTY_POLICY_LOG = 2;
- const int PENALTY_POLICY_REJECT = 3;
-
- /**
- * Offers to detect sockets sending data not wrapped inside a layer of SSL/TLS encryption.
- *
- * @param uid Uid of the app
- * @param policyPenalty The penalty policy of the app
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void strictUidCleartextPenalty(int uid, int policyPenalty);
-
- /**
- * Start clatd
- *
- * @param ifName interface name to start clatd
- * @param nat64Prefix the NAT64 prefix, e.g., "2001:db8:64::/96".
- * @return a string, the IPv6 address that will be used for 464xlat.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- @utf8InCpp String clatdStart(in @utf8InCpp String ifName, in @utf8InCpp String nat64Prefix);
-
- /**
- * Stop clatd
- *
- * @param ifName interface name to stop clatd
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void clatdStop(in @utf8InCpp String ifName);
-
- /**
- * Get status of IP forwarding
- *
- * @return true if IP forwarding is enabled, false otherwise.
- */
- boolean ipfwdEnabled();
-
- /**
- * Get requester list of IP forwarding
- *
- * @return An array of strings containing requester list of IP forwarding
- */
- @utf8InCpp String[] ipfwdGetRequesterList();
-
- /**
- * Enable IP forwarding for specific requester
- *
- * @param requester requester name to enable IP forwarding. It is a unique name which will be
- * stored in Netd to make sure if any requester needs IP forwarding.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void ipfwdEnableForwarding(in @utf8InCpp String requester);
-
- /**
- * Disable IP forwarding for specific requester
- *
- * @param requester requester name to disable IP forwarding. This name should match the
- * names which are set by ipfwdEnableForwarding.
- * IP forwarding would be disabled if it is the last requester.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void ipfwdDisableForwarding(in @utf8InCpp String requester);
-
- /**
- * Add forwarding ip rule
- *
- * @param fromIface interface name to add forwarding ip rule
- * @param toIface interface name to add forwarding ip rule
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void ipfwdAddInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
-
- /**
- * Remove forwarding ip rule
- *
- * @param fromIface interface name to remove forwarding ip rule
- * @param toIface interface name to remove forwarding ip rule
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void ipfwdRemoveInterfaceForward(in @utf8InCpp String fromIface, in @utf8InCpp String toIface);
-
- /**
- * Set quota for interface
- *
- * @param ifName Name of target interface
- * @param bytes Quota value in bytes
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void bandwidthSetInterfaceQuota(in @utf8InCpp String ifName, long bytes);
-
- /**
- * Remove quota for interface
- *
- * @param ifName Name of target interface
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void bandwidthRemoveInterfaceQuota(in @utf8InCpp String ifName);
-
- /**
- * Set alert for interface
- *
- * @param ifName Name of target interface
- * @param bytes Alert value in bytes
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void bandwidthSetInterfaceAlert(in @utf8InCpp String ifName, long bytes);
-
- /**
- * Remove alert for interface
- *
- * @param ifName Name of target interface
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void bandwidthRemoveInterfaceAlert(in @utf8InCpp String ifName);
-
- /**
- * Set global alert
- *
- * @param bytes Alert value in bytes
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void bandwidthSetGlobalAlert(long bytes);
-
- /**
- * Add naughty app bandwidth rule for specific app
- *
- * @param uid uid of target app
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void bandwidthAddNaughtyApp(int uid);
-
- /**
- * Remove naughty app bandwidth rule for specific app
- *
- * @param uid uid of target app
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void bandwidthRemoveNaughtyApp(int uid);
-
- /**
- * Add nice app bandwidth rule for specific app
- *
- * @param uid uid of target app
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void bandwidthAddNiceApp(int uid);
-
- /**
- * Remove nice app bandwidth rule for specific app
- *
- * @param uid uid of target app
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void bandwidthRemoveNiceApp(int uid);
-
- /**
- * Start tethering
- *
- * @param dhcpRanges dhcp ranges to set.
- * dhcpRanges might contain many addresss {addr1, addr2, aadr3, addr4...}
- * Netd splits them into ranges: addr1-addr2, addr3-addr4, etc.
- * An odd number of addrs will fail.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void tetherStart(in @utf8InCpp String[] dhcpRanges);
-
- /**
- * Stop tethering
- *
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void tetherStop();
-
- /**
- * Get status of tethering
- *
- * @return true if tethering is enabled, false otherwise.
- */
- boolean tetherIsEnabled();
-
- /**
- * Setup interface for tethering
- *
- * @param ifName interface name to add
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void tetherInterfaceAdd(in @utf8InCpp String ifName);
-
- /**
- * Reset interface for tethering
- *
- * @param ifName interface name to remove
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void tetherInterfaceRemove(in @utf8InCpp String ifName);
-
- /**
- * Get the interface list which is stored in netd
- * The list contains the interfaces managed by tetherInterfaceAdd/tetherInterfaceRemove
- *
- * @return An array of strings containing interface list result
- */
- @utf8InCpp String[] tetherInterfaceList();
-
- /**
- * Set DNS forwarder server
- *
- * @param netId the upstream network to forward DNS queries to
- * @param dnsAddrs DNS server address to set
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void tetherDnsSet(int netId, in @utf8InCpp String[] dnsAddrs);
-
- /**
- * Return the DNS list set by tetherDnsSet
- *
- * @return An array of strings containing the list of DNS servers
- */
- @utf8InCpp String[] tetherDnsList();
-
- const int LOCAL_NET_ID = 99;
-
- /**
- * Constant net ID for the "dummy" network.
- *
- * The dummy network is used to blackhole or reject traffic. Any attempt to use it will
- * either drop the packets or fail with ENETUNREACH.
- */
- const int DUMMY_NET_ID = 51;
-
- /**
- * Constant net ID for the "unreachable" network.
- *
- * The unreachable network is used to reject traffic. Any attempt to use it will fail
- * with ENETUNREACH.
- */
- const int UNREACHABLE_NET_ID = 52;
-
- // Route does not specify a next hop
- const String NEXTHOP_NONE = "";
- // Route next hop is unreachable
- const String NEXTHOP_UNREACHABLE = "unreachable";
- // Route next hop is throw
- const String NEXTHOP_THROW = "throw";
-
- /**
- * Add a route for specific network
- *
- * @param netId the network to add the route to
- * @param ifName the name of interface of the route.
- * This interface should be assigned to the netID.
- * @param destination the destination of the route
- * @param nextHop The route's next hop address,
- * or it could be either NEXTHOP_NONE, NEXTHOP_UNREACHABLE, NEXTHOP_THROW.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void networkAddRoute(
- int netId,
- in @utf8InCpp String ifName,
- in @utf8InCpp String destination,
- in @utf8InCpp String nextHop);
-
- /**
- * Remove a route for specific network
- *
- * @param netId the network to remove the route from
- * @param ifName the name of interface of the route.
- * This interface should be assigned to the netID.
- * @param destination the destination of the route
- * @param nextHop The route's next hop address,
- * or it could be either NEXTHOP_NONE, NEXTHOP_UNREACHABLE, NEXTHOP_THROW.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void networkRemoveRoute(
- int netId,
- in @utf8InCpp String ifName,
- in @utf8InCpp String destination,
- in @utf8InCpp String nextHop);
-
- /**
- * Add a route to legacy routing table for specific network
- *
- * @param netId the network to add the route to
- * @param ifName the name of interface of the route.
- * This interface should be assigned to the netID.
- * @param destination the destination of the route
- * @param nextHop The route's next hop address,
- * or it could be either NEXTHOP_NONE, NEXTHOP_UNREACHABLE, NEXTHOP_THROW.
- * @param uid uid of the user
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void networkAddLegacyRoute(
- int netId,
- in @utf8InCpp String ifName,
- in @utf8InCpp String destination,
- in @utf8InCpp String nextHop,
- int uid);
-
- /**
- * Remove a route from legacy routing table for specific network
- *
- * @param netId the network to remove the route from
- * @param ifName the name of interface of the route.
- * This interface should be assigned to the netID.
- * @param destination the destination of the route
- * @param nextHop The route's next hop address,
- * or it could be either NEXTHOP_NONE, NEXTHOP_UNREACHABLE, NEXTHOP_THROW.
- * @param uid uid of the user
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void networkRemoveLegacyRoute(
- int netId,
- in @utf8InCpp String ifName,
- in @utf8InCpp String destination,
- in @utf8InCpp String nextHop,
- int uid);
-
- /**
- * Get default network
- *
- * @return netId of default network
- */
- int networkGetDefault();
-
- /**
- * Set network as default network
- *
- * @param netId the network to set as the default
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void networkSetDefault(int netId);
-
- /**
- * Clear default network
- *
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void networkClearDefault();
-
- /**
- * PERMISSION_NONE is used for regular networks and apps. TODO: use PERMISSION_INTERNET
- * for this instead, and use PERMISSION_NONE to indicate no network permissions at all.
- */
- const int PERMISSION_NONE = 0;
-
- /**
- * PERMISSION_NETWORK represents the CHANGE_NETWORK_STATE permission.
- */
- const int PERMISSION_NETWORK = 1;
-
- /**
- * PERMISSION_SYSTEM represents the ability to use restricted networks. This is mostly
- * equivalent to the CONNECTIVITY_USE_RESTRICTED_NETWORKS permission.
- */
- const int PERMISSION_SYSTEM = 2;
-
- /**
- * NO_PERMISSIONS indicates that this app is installed and doesn't have either
- * PERMISSION_INTERNET or PERMISSION_UPDATE_DEVICE_STATS.
- * TODO: use PERMISSION_NONE to represent this case
- */
- const int NO_PERMISSIONS = 0;
-
- /**
- * PERMISSION_INTERNET indicates that the app can create AF_INET and AF_INET6 sockets
- */
- const int PERMISSION_INTERNET = 4;
-
- /**
- * PERMISSION_UPDATE_DEVICE_STATS is used for system UIDs and privileged apps
- * that have the UPDATE_DEVICE_STATS permission
- */
- const int PERMISSION_UPDATE_DEVICE_STATS = 8;
-
- /**
- * PERMISSION_UNINSTALLED is used when an app is uninstalled from the device. All internet
- * related permissions need to be cleaned
- */
- const int PERMISSION_UNINSTALLED = -1;
-
-
- /**
- * Sets the permission required to access a specific network.
- *
- * @param netId the network to set
- * @param permission network permission to use
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void networkSetPermissionForNetwork(int netId, int permission);
-
- /**
- * Assigns network access permissions to the specified users.
- *
- * @param permission network permission to use
- * @param uids uid of users to set permission
- */
- void networkSetPermissionForUser(int permission, in int[] uids);
-
- /**
- * Clears network access permissions for the specified users.
- *
- * @param uids uid of users to clear permission
- */
- void networkClearPermissionForUser(in int[] uids);
-
- /**
- * Assigns android.permission.INTERNET and/or android.permission.UPDATE_DEVICE_STATS to the uids
- * specified. Or remove all permissions from the uids.
- *
- * @param permission The permission to grant, it could be either PERMISSION_INTERNET and/or
- * PERMISSION_UPDATE_DEVICE_STATS. If the permission is NO_PERMISSIONS, then
- * revoke all permissions for the uids.
- * @param uids uid of users to grant permission
- */
- void trafficSetNetPermForUids(int permission, in int[] uids);
-
- /**
- * Gives the specified user permission to protect sockets from VPNs.
- * Typically used by VPN apps themselves, to ensure that the sockets
- * they use to communicate with the VPN server aren't routed through
- * the VPN network.
- *
- * @param uid uid of user to set
- */
- void networkSetProtectAllow(int uid);
-
- /**
- * Removes the permission to protect sockets from VPN.
- *
- * @param uid uid of user to set
- */
- void networkSetProtectDeny(int uid);
-
- /**
- * Get the status of network protect for user
- *
- * @param uids uid of user
- * @return true if the user can protect sockets from VPN, false otherwise.
- */
- boolean networkCanProtect(int uid);
-
- /** Only allows packets from specific UID/Interface.
- @deprecated use FIREWALL_ALLOWLIST. */
- const int FIREWALL_WHITELIST = 0;
-
- /** Only allows packets from specific UID/Interface. */
- const int FIREWALL_ALLOWLIST = 0;
-
- /** Blocks packets from specific UID/Interface.
- @deprecated use FIREWALL_DENYLIST. */
- const int FIREWALL_BLACKLIST = 1;
-
- /** Blocks packets from specific UID/Interface. */
- const int FIREWALL_DENYLIST = 1;
-
- /**
- * Set type of firewall
- * Type allowlist only allows packets from specific UID/Interface
- * Type denylist blocks packets from specific UID/Interface
- *
- * @param firewalltype type of firewall, either FIREWALL_ALLOWLIST or FIREWALL_DENYLIST
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void firewallSetFirewallType(int firewalltype);
-
- // Specify allow Rule which allows packets
- const int FIREWALL_RULE_ALLOW = 1;
- // Specify deny Rule which drops packets
- const int FIREWALL_RULE_DENY = 2;
-
- // No specific chain is chosen, use general firewall chain(fw_input, fw_output)
- const int FIREWALL_CHAIN_NONE = 0;
- // Specify DOZABLE chain(fw_dozable) which is used in dozable mode
- const int FIREWALL_CHAIN_DOZABLE = 1;
- // Specify STANDBY chain(fw_standby) which is used in standby mode
- const int FIREWALL_CHAIN_STANDBY = 2;
- // Specify POWERSAVE chain(fw_powersave) which is used in power save mode
- const int FIREWALL_CHAIN_POWERSAVE = 3;
- // Specify RESTRICTED chain(fw_restricted) which is used in restricted
- // networking mode
- const int FIREWALL_CHAIN_RESTRICTED = 4;
-
- /**
- * Set firewall rule for interface
- *
- * @param ifName the interface to allow/deny
- * @param firewallRule either FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void firewallSetInterfaceRule(in @utf8InCpp String ifName, int firewallRule);
-
- /**
- * Set firewall rule for uid
- *
- * @param childChain target chain
- * @param uid uid to allow/deny
- * @param firewallRule either FIREWALL_RULE_ALLOW or FIREWALL_RULE_DENY
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void firewallSetUidRule(int childChain, int uid, int firewallRule);
-
- /**
- * Enable/Disable target firewall child chain
- *
- * @param childChain target chain to enable
- * @param enable whether to enable or disable child chain.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void firewallEnableChildChain(int childChain, boolean enable);
-
- /**
- * Get interface list
- *
- * @return An array of strings containing all the interfaces on the system.
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- @utf8InCpp String[] interfaceGetList();
-
- // Must be kept in sync with constant in InterfaceConfiguration.java
- const String IF_STATE_UP = "up";
- const String IF_STATE_DOWN = "down";
-
- const String IF_FLAG_BROADCAST = "broadcast";
- const String IF_FLAG_LOOPBACK = "loopback";
- const String IF_FLAG_POINTOPOINT = "point-to-point";
- const String IF_FLAG_RUNNING = "running";
- const String IF_FLAG_MULTICAST = "multicast";
-
- /**
- * Get interface configuration
- *
- * @param ifName interface name
- * @return An InterfaceConfigurationParcel for the specified interface.
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- InterfaceConfigurationParcel interfaceGetCfg(in @utf8InCpp String ifName);
-
- /**
- * Set interface configuration
- *
- * @param cfg Interface configuration to set
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void interfaceSetCfg(in InterfaceConfigurationParcel cfg);
-
- /**
- * Set interface IPv6 privacy extensions
- *
- * @param ifName interface name
- * @param enable whether to enable or disable this setting.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void interfaceSetIPv6PrivacyExtensions(in @utf8InCpp String ifName, boolean enable);
-
- /**
- * Clear all IP addresses on the given interface
- *
- * @param ifName interface name
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * POSIX errno.
- */
- void interfaceClearAddrs(in @utf8InCpp String ifName);
-
- /**
- * Enable or disable IPv6 on the given interface
- *
- * @param ifName interface name
- * @param enable whether to enable or disable this setting.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void interfaceSetEnableIPv6(in @utf8InCpp String ifName, boolean enable);
-
- /**
- * Set interface MTU
- *
- * @param ifName interface name
- * @param mtu MTU value
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void interfaceSetMtu(in @utf8InCpp String ifName, int mtu);
-
- /**
- * Add forwarding rule/stats on given interface.
- *
- * @param intIface downstream interface
- * @param extIface upstream interface
- */
- void tetherAddForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
-
- /**
- * Remove forwarding rule/stats on given interface.
- *
- * @param intIface downstream interface
- * @param extIface upstream interface
- */
- void tetherRemoveForward(in @utf8InCpp String intIface, in @utf8InCpp String extIface);
-
- /**
- * Set the values of tcp_{rmem,wmem}.
- *
- * @param rmemValues the target values of tcp_rmem, each value is separated by spaces
- * @param wmemValues the target values of tcp_wmem, each value is separated by spaces
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void setTcpRWmemorySize(in @utf8InCpp String rmemValues, in @utf8InCpp String wmemValues);
-
- /**
- * Register unsolicited event listener
- * Netd supports multiple unsolicited event listeners.
- *
- * @param listener unsolicited event listener to register
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void registerUnsolicitedEventListener(INetdUnsolicitedEventListener listener);
-
- /**
- * Add ingress interface filtering rules to a list of UIDs
- *
- * For a given uid, once a filtering rule is added, the kernel will only allow packets from the
- * allowed interface and loopback to be sent to the list of UIDs.
- *
- * Calling this method on one or more UIDs with an existing filtering rule but a different
- * interface name will result in the filtering rule being updated to allow the new interface
- * instead. Otherwise calling this method will not affect existing rules set on other UIDs.
- *
- * @param ifName the name of the interface on which the filtering rules will allow packets to
- be received.
- * @param uids an array of UIDs which the filtering rules will be set
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void firewallAddUidInterfaceRules(in @utf8InCpp String ifName, in int[] uids);
-
- /**
- * Remove ingress interface filtering rules from a list of UIDs
- *
- * Clear the ingress interface filtering rules from the list of UIDs which were previously set
- * by firewallAddUidInterfaceRules(). Ignore any uid which does not have filtering rule.
- *
- * @param uids an array of UIDs from which the filtering rules will be removed
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void firewallRemoveUidInterfaceRules(in int[] uids);
-
- /**
- * Request netd to change the current active network stats map.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void trafficSwapActiveStatsMap();
-
- /**
- * Retrieves OEM netd listener interface
- *
- * @return a IBinder object, it could be casted to oem specific interface.
- */
- IBinder getOemNetd();
-
- /**
- * Start tethering with given configuration
- *
- * @param config config to start tethering.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void tetherStartWithConfiguration(in TetherConfigParcel config);
-
-
- /**
- * Get the fwmark and its net id mask for the given network id.
- *
- * @param netId the network to get the fwmark and mask for.
- * @return A MarkMaskParcel of the given network id.
- */
- MarkMaskParcel getFwmarkForNetwork(int netId);
-
- /**
- * Add a route for specific network
- *
- * @param netId the network to add the route to
- * @param routeInfo parcelable with route information
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void networkAddRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
-
- /**
- * Update a route for specific network
- *
- * @param routeInfo parcelable with route information
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void networkUpdateRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
-
- /**
- * Remove a route for specific network
- *
- * @param routeInfo parcelable with route information
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void networkRemoveRouteParcel(int netId, in android.net.RouteInfoParcel routeInfo);
-
- /**
- * Adds a tethering offload rule, or updates it if it already exists.
- *
- * Currently, only downstream /128 IPv6 entries are supported. An existing rule will be updated
- * if the input interface and destination prefix match. Otherwise, a new rule will be created.
- *
- * @param rule The rule to add or update.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void tetherOffloadRuleAdd(in TetherOffloadRuleParcel rule);
-
- /**
- * Deletes a tethering offload rule.
- *
- * Currently, only downstream /128 IPv6 entries are supported. An existing rule will be deleted
- * if the destination IP address and the source interface match. It is not an error if there is
- * no matching rule to delete.
- *
- * @param rule The rule to delete.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void tetherOffloadRuleRemove(in TetherOffloadRuleParcel rule);
-
- /**
- * Return BPF tethering offload statistics.
- *
- * @return an array of TetherStatsParcel's, where each entry contains the upstream interface
- * index and its tethering statistics since tethering was first started.
- * There will only ever be one entry for a given interface index.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- TetherStatsParcel[] tetherOffloadGetStats();
-
- /**
- * Set a per-interface quota for tethering offload.
- *
- * @param ifIndex Index of upstream interface
- * @param quotaBytes The quota defined as the number of bytes, starting from zero and counting
- * from *now*. A value of QUOTA_UNLIMITED (-1) indicates there is no limit.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- void tetherOffloadSetInterfaceQuota(int ifIndex, long quotaBytes);
-
- /**
- * Return BPF tethering offload statistics and clear the stats for a given upstream.
- *
- * Must only be called once all offload rules have already been deleted for the given upstream
- * interface. The existing stats will be fetched and returned. The stats and the limit for the
- * given upstream interface will be deleted as well.
- *
- * The stats and limit for a given upstream interface must be initialized (using
- * tetherOffloadSetInterfaceQuota) before any offload will occur on that interface.
- *
- * @param ifIndex Index of upstream interface.
- * @return TetherStatsParcel, which contains the given upstream interface index and its
- * tethering statistics since tethering was first started on that upstream interface.
- * @throws ServiceSpecificException in case of failure, with an error code indicating the
- * cause of the failure.
- */
- TetherStatsParcel tetherOffloadGetAndClearStats(int ifIndex);
-
- /**
- * Creates a network.
- *
- * @param config the configuration of network.
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkCreate(in NativeNetworkConfig config);
-
- /**
- * Adds the specified UID ranges to the specified network. The network can be physical or
- * virtual. Traffic from the UID ranges will be routed to the network by default. The possible
- * value of subsidiary priority for physical and unreachable networks is 0-999. 0 is the highest
- * priority. 0 is also the default value. Virtual network supports only the default value.
- *
- * @param NativeUidRangeConfig a parcel contains netId, UID ranges, subsidiary priority, etc.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkAddUidRangesParcel(in NativeUidRangeConfig uidRangesConfig);
-
- /**
- * Removes the specified UID ranges from the specified network. The network can be physical or
- * virtual. Traffic from the UID ranges will no longer be routed to the network by default. The
- * possible value of subsidiary priority for physical and unreachable networks is 0-999. 0 is
- * the highest priority. 0 is also the default value. Virtual network supports only the default
- * value.
- *
- * @param NativeUidRangeConfig a parcel contains netId, UID ranges, subsidiary priority, etc.
- *
- * @throws ServiceSpecificException in case of failure, with an error code corresponding to the
- * unix errno.
- */
- void networkRemoveUidRangesParcel(in NativeUidRangeConfig uidRangesConfig);
-}
diff --git a/server/binder/android/net/INetdUnsolicitedEventListener.aidl b/server/binder/android/net/INetdUnsolicitedEventListener.aidl
deleted file mode 100644
index 652a79c..0000000
--- a/server/binder/android/net/INetdUnsolicitedEventListener.aidl
+++ /dev/null
@@ -1,145 +0,0 @@
-/**
- * Copyright (c) 2018, 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.
- */
-
-package android.net;
-
-/**
- * Unsolicited netd events which are reported by the kernel via netlink.
- * This one-way interface groups asynchronous notifications sent
- * by netd to any process that registered itself via INetd.registerUnsolEventListener.
- *
- * {@hide}
- */
-oneway interface INetdUnsolicitedEventListener {
-
- /**
- * Notifies that an interface has been idle/active for a certain period of time.
- * It is the event for idletimer.
- *
- * @param isActive true for active status, false for idle
- * @param timerLabel unique identifier of the idletimer.
- * Since NMS only set the identifier as int, only report event with int label.
- * @param timestampNs kernel timestamp of this event, 0 for no timestamp
- * @param uid uid of this event, -1 for no uid.
- * It represents the uid that was responsible for waking the radio.
- */
- void onInterfaceClassActivityChanged(
- boolean isActive,
- int timerLabel,
- long timestampNs,
- int uid);
-
- /**
- * Notifies that a specific interface reached its quota limit.
- *
- * @param alertName alert name of the quota limit
- * @param ifName interface which reached the limit
- */
- void onQuotaLimitReached(@utf8InCpp String alertName, @utf8InCpp String ifName);
-
- /**
- * Provides information on IPv6 DNS servers on a specific interface.
- *
- * @param ifName interface name
- * @param lifetimeS lifetime for the DNS servers in seconds
- * @param servers the address of servers.
- * e.g. IpV6: "2001:4860:4860::6464"
- *
- */
- void onInterfaceDnsServerInfo(
- @utf8InCpp String ifName, long lifetimeS, in @utf8InCpp String[] servers);
-
- /**
- * Notifies that an address has updated on a specific interface.
- *
- * @param addr address that is being updated
- * @param ifName the name of the interface on which the address is configured
- * @param flags address flags, see ifa_flags in if_addr.h
- * @param scope current scope of the address
- */
- void onInterfaceAddressUpdated(
- @utf8InCpp String addr,
- @utf8InCpp String ifName,
- int flags,
- int scope);
-
- /**
- * Notifies that an address has been removed on a specific interface.
- *
- * @param addr address of this change
- * @param ifName the name of the interface that changed addresses
- * @param flags address flags, see ifa_flags in if_addr.h
- * @param scope address address scope
- */
- void onInterfaceAddressRemoved(
- @utf8InCpp String addr,
- @utf8InCpp String ifName,
- int flags,
- int scope);
-
- /**
- * Notifies that an interface has been added.
- *
- * @param ifName the name of the added interface
- */
- void onInterfaceAdded(@utf8InCpp String ifName);
-
- /**
- * Notifies that an interface has been removed.
- *
- * @param ifName the name of the removed interface
- */
- void onInterfaceRemoved(@utf8InCpp String ifName);
-
- /**
- * Notifies that the status of the specific interface has changed.
- *
- * @param ifName the name of the interface that changed status
- * @param up true for interface up, false for down
- */
- void onInterfaceChanged(@utf8InCpp String ifName, boolean up);
-
- /**
- * Notifies that the link state of the specific interface has changed.
- *
- * @param ifName the name of the interface whose link state has changed
- * @param up true for interface link state up, false for link state down
- */
- void onInterfaceLinkStateChanged(@utf8InCpp String ifName, boolean up);
-
- /**
- * Notifies that an IP route has changed.
- *
- * @param updated true for update, false for remove
- * @param route destination prefix of this route, e.g., "2001:db8::/64"
- * @param gateway address of gateway, empty string for no gateway
- * @param ifName interface name of this route, empty string for no interface
- */
- void onRouteChanged(
- boolean updated,
- @utf8InCpp String route,
- @utf8InCpp String gateway,
- @utf8InCpp String ifName);
-
- /**
- * Notifies that kernel has detected a socket sending data not wrapped
- * inside a layer of SSL/TLS encryption.
- *
- * @param uid uid of this event
- * @param hex packet content in hex format
- */
- void onStrictCleartextDetected(int uid, @utf8InCpp String hex);
-}
diff --git a/server/binder/android/net/InterfaceConfigurationParcel.aidl b/server/binder/android/net/InterfaceConfigurationParcel.aidl
deleted file mode 100644
index c20792c..0000000
--- a/server/binder/android/net/InterfaceConfigurationParcel.aidl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-package android.net;
-
-/**
- * Configuration details for a network interface.
- *
- * {@hide}
- */
-parcelable InterfaceConfigurationParcel {
- @utf8InCpp String ifName;
- @utf8InCpp String hwAddr;
- @utf8InCpp String ipv4Addr;
- int prefixLength;
- /**
- * Interface flags, String versions of IFF_* defined in netd/if.h
- */
- @utf8InCpp String[] flags;
-}
diff --git a/server/binder/android/net/MarkMaskParcel.aidl b/server/binder/android/net/MarkMaskParcel.aidl
deleted file mode 100644
index 932b7bf..0000000
--- a/server/binder/android/net/MarkMaskParcel.aidl
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-package android.net;
-
-/**
- * Structure that stores a firewall mark and its mask.
- *
- * {@hide}
- */
-parcelable MarkMaskParcel {
- // The fwmark.
- int mark;
- // Net id mask of fwmark.
- int mask;
-}
diff --git a/server/binder/android/net/NativeNetworkConfig.aidl b/server/binder/android/net/NativeNetworkConfig.aidl
deleted file mode 100644
index 2c4f83a..0000000
--- a/server/binder/android/net/NativeNetworkConfig.aidl
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-package android.net;
-
-import android.net.NativeNetworkType;
-import android.net.NativeVpnType;
-
-/**
- * The configuration to create a network.
- *
- * {@hide}
- */
-@JavaDerive(toString=true, equals=true)
-@JavaOnlyImmutable
-parcelable NativeNetworkConfig {
- /** The networkId to create. */
- int netId;
-
- /**
- * The type of network, e.g. physical network or virtual network.
- */
- NativeNetworkType networkType = NativeNetworkType.PHYSICAL;
-
- /**
- * For physical networks. The permission necessary to use the network. Must be one of
- * PERMISSION_NONE/PERMISSION_NETWORK/PERMISSION_SYSTEM. Ignored for all other network types.
- */
- int permission;
-
- /**
- * For virtual networks. Whether unprivileged apps are allowed to bypass the VPN. Ignored for
- * all other network types.
- */
- boolean secure;
-
- /** For virtual networks. The type of VPN to create. Ignored for all other network types. */
- NativeVpnType vpnType = NativeVpnType.PLATFORM;
-}
diff --git a/server/binder/android/net/NativeNetworkType.aidl b/server/binder/android/net/NativeNetworkType.aidl
deleted file mode 100644
index d667029..0000000
--- a/server/binder/android/net/NativeNetworkType.aidl
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-package android.net;
-
-@Backing(type="int")
-enum NativeNetworkType {
- /**
- * Physical network type.
- */
- PHYSICAL = 0,
-
- /**
- * Virtual private network type.
- */
- VIRTUAL = 1,
-}
\ No newline at end of file
diff --git a/server/binder/android/net/NativeVpnType.aidl b/server/binder/android/net/NativeVpnType.aidl
deleted file mode 100644
index cd1b447..0000000
--- a/server/binder/android/net/NativeVpnType.aidl
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-package android.net;
-
-@Backing(type="int")
-enum NativeVpnType {
- /**
- * A VPN created by an app using the VpnService API.
- */
- SERVICE = 1,
-
- /**
- * A VPN created using a VpnManager API such as startProvisionedVpnProfile.
- */
- PLATFORM = 2,
-
- /**
- * An IPsec VPN created by the built-in LegacyVpnRunner.
- */
- LEGACY = 3,
-
- /**
- * An VPN created by OEM code through other means than VpnService or VpnManager.
- */
- OEM = 4,
-}
\ No newline at end of file
diff --git a/server/binder/android/net/RouteInfoParcel.aidl b/server/binder/android/net/RouteInfoParcel.aidl
deleted file mode 100644
index fcc86e3..0000000
--- a/server/binder/android/net/RouteInfoParcel.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/**
- * Copyright (c) 2020, 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.
- */
-
-package android.net;
-
-parcelable RouteInfoParcel {
- // The destination of the route.
- @utf8InCpp String destination;
- // The name of interface of the route. This interface should be assigned to the netID.
- @utf8InCpp String ifName;
- // The route's next hop address, or one of the NEXTHOP_* constants defined in INetd.aidl.
- @utf8InCpp String nextHop;
- // The MTU of the route.
- int mtu;
-}
diff --git a/server/binder/android/net/TetherConfigParcel.aidl b/server/binder/android/net/TetherConfigParcel.aidl
deleted file mode 100644
index 9f371ce..0000000
--- a/server/binder/android/net/TetherConfigParcel.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2019 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.
- */
-
-package android.net;
-
-/**
- * The configuration to start tethering.
- *
- * {@hide}
- */
-parcelable TetherConfigParcel {
- // Whether to enable or disable legacy DNS proxy server.
- boolean usingLegacyDnsProxy;
- // DHCP ranges to set.
- // dhcpRanges might contain many addresss {addr1, addr2, addr3, addr4...}
- // Netd splits them into ranges: addr1-addr2, addr3-addr4, etc.
- // An odd number of addrs will fail.
- @utf8InCpp String[] dhcpRanges;
-}
diff --git a/server/binder/android/net/TetherOffloadRuleParcel.aidl b/server/binder/android/net/TetherOffloadRuleParcel.aidl
deleted file mode 100644
index c549e61..0000000
--- a/server/binder/android/net/TetherOffloadRuleParcel.aidl
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2020 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.
- */
-
-package android.net;
-
-/**
- * Represents a forwarding rule for tethering offload.
- *
- * {@hide}
- */
-parcelable TetherOffloadRuleParcel {
- /** The interface index of the input interface. */
- int inputInterfaceIndex;
-
- /** The interface index of the output interface. */
- int outputInterfaceIndex;
-
- /** The base IP address of the destination prefix as a byte array. */
- byte[] destination;
-
- /** The destination prefix length. */
- int prefixLength;
-
- /** The source link-layer address. Currently, must be a 6-byte MAC address.*/
- byte[] srcL2Address;
-
- /** The destination link-layer address. Currently, must be a 6-byte MAC address. */
- byte[] dstL2Address;
-
- /** The outbound path mtu. */
- int pmtu = 1500;
-}
diff --git a/server/binder/android/net/TetherStatsParcel.aidl b/server/binder/android/net/TetherStatsParcel.aidl
deleted file mode 100644
index 6bf60a8..0000000
--- a/server/binder/android/net/TetherStatsParcel.aidl
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-package android.net;
-
-/**
- * The statistics of tethering interface
- *
- * {@hide}
- */
-parcelable TetherStatsParcel {
- /**
- * Parcel representing tethering interface statistics.
- *
- * This parcel is used by tetherGetStats, tetherOffloadGetStats and
- * tetherOffloadGetAndClearStats in INetd.aidl. tetherGetStats uses this parcel to return the
- * tethering statistics since netd startup and presents the interface via its interface name.
- * Both tetherOffloadGetStats and tetherOffloadGetAndClearStats use this parcel to return
- * the tethering statistics since tethering was first started. They present the interface via
- * its interface index. Note that the interface must be presented by either interface name
- * |iface| or interface index |ifIndex| in this parcel. The unused interface name is set to
- * an empty string "" by default and the unused interface index is set to 0 by default.
- */
-
- /** The interface name. */
- @utf8InCpp String iface;
-
- /** Total number of received bytes. */
- long rxBytes;
-
- /** Total number of received packets. */
- long rxPackets;
-
- /** Total number of transmitted bytes. */
- long txBytes;
-
- /** Total number of transmitted packets. */
- long txPackets;
-
- /** The interface index. */
- int ifIndex = 0;
-}
diff --git a/server/binder/android/net/UidRangeParcel.aidl b/server/binder/android/net/UidRangeParcel.aidl
deleted file mode 100644
index 8f1fef6..0000000
--- a/server/binder/android/net/UidRangeParcel.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 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.
- */
-
-package android.net;
-
-/**
- * An inclusive range of UIDs.
- *
- * {@hide}
- */
-@JavaOnlyImmutable @JavaDerive(toString=true, equals=true)
-parcelable UidRangeParcel {
- int start;
- int stop;
-}
diff --git a/server/binder/android/net/metrics/INetdEventListener.aidl b/server/binder/android/net/metrics/INetdEventListener.aidl
deleted file mode 100644
index ef1b2cb..0000000
--- a/server/binder/android/net/metrics/INetdEventListener.aidl
+++ /dev/null
@@ -1,128 +0,0 @@
-/**
- * Copyright (c) 2016, 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.
- */
-
-package android.net.metrics;
-
-/**
- * Logs netd events.
- *
- * {@hide}
- */
-oneway interface INetdEventListener {
- const int EVENT_GETADDRINFO = 1;
- const int EVENT_GETHOSTBYNAME = 2;
- const int EVENT_GETHOSTBYADDR = 3;
- const int EVENT_RES_NSEND = 4;
-
- const int REPORTING_LEVEL_NONE = 0;
- const int REPORTING_LEVEL_METRICS = 1;
- const int REPORTING_LEVEL_FULL = 2;
-
- // Maximum number of IP addresses logged for DNS lookups before we truncate the full list.
- const int DNS_REPORTED_IP_ADDRESSES_LIMIT = 10;
-
- /**
- * Logs a DNS lookup function call (getaddrinfo and gethostbyname).
- *
- * @param netId the ID of the network the lookup was performed on.
- * @param eventType one of the EVENT_* constants in this interface.
- * @param returnCode the return value of the function call.
- * @param latencyMs the latency of the function call.
- * @param hostname the name that was looked up.
- * @param ipAddresses (possibly a subset of) the IP addresses returned.
- * At most {@link #DNS_REPORTED_IP_ADDRESSES_LIMIT} addresses are logged.
- * @param ipAddressesCount the number of IP addresses returned. May be different from the length
- * of ipAddresses if there were too many addresses to log.
- * @param uid the UID of the application that performed the query.
- */
- void onDnsEvent(int netId, int eventType, int returnCode, int latencyMs,
- @utf8InCpp String hostname, in @utf8InCpp String[] ipAddresses,
- int ipAddressesCount, int uid);
-
- /**
- * Represents a private DNS validation success or failure.
- *
- * @param netId the ID of the network the validation was performed on.
- * @param ipAddress the IP address for which validation was performed.
- * @param hostname the hostname for which validation was performed.
- * @param validated whether or not validation was successful.
- */
- void onPrivateDnsValidationEvent(int netId, String ipAddress, String hostname,
- boolean validated);
-
- /**
- * Logs a single connect library call.
- *
- * @param netId the ID of the network the connect was performed on.
- * @param error 0 if the connect call succeeded, otherwise errno if it failed.
- * @param latencyMs the latency of the connect call.
- * @param ipAddr destination IP address.
- * @param port destination port number.
- * @param uid the UID of the application that performed the connection.
- */
- void onConnectEvent(int netId, int error, int latencyMs, String ipAddr, int port, int uid);
-
- /**
- * Logs a single RX packet which caused the main CPU to exit sleep state.
- * @param prefix arbitrary string provided via wakeupAddInterface()
- * @param uid UID of the destination process or -1 if no UID is available.
- * @param ethertype of the RX packet encoded in an int in native order, or -1 if not available.
- * @param ipNextHeader ip protocol of the RX packet as IPPROTO_* number,
- or -1 if the packet was not IPv4 or IPv6.
- * @param dstHw destination hardware address, or 0 if not available.
- * @param srcIp source IP address, or null if not available.
- * @param dstIp destination IP address, or null if not available.
- * @param srcPort src port of RX packet in native order, or -1 if the packet was not UDP or TCP.
- * @param dstPort dst port of RX packet in native order, or -1 if the packet was not UDP or TCP.
- * @param timestampNs receive timestamp for the offending packet. In units of nanoseconds and
- * synchronized to CLOCK_MONOTONIC.
- */
- void onWakeupEvent(String prefix, int uid, int ethertype, int ipNextHeader, in byte[] dstHw,
- String srcIp, String dstIp, int srcPort, int dstPort, long timestampNs);
-
- /**
- * An event sent after every Netlink sock_diag poll performed by Netd. This reported batch
- * groups TCP socket stats aggregated by network id. Per-network data are stored in a
- * structure-of-arrays style where networkIds, sentPackets, lostPackets, rttUs, and
- * sentAckDiffMs have the same length. Stats for the i-th network is spread across all these
- * arrays at index i.
- * @param networkIds an array of network ids for which there was tcp socket stats to collect in
- * the last sock_diag poll.
- * @param sentPackets an array of packet sent across all TCP sockets still alive and new
- TCP sockets since the last sock_diag poll, summed per network id.
- * @param lostPackets, an array of packet lost across all TCP sockets still alive and new
- TCP sockets since the last sock_diag poll, summed per network id.
- * @param rttUs an array of smoothed round trip times in microseconds, averaged across all TCP
- sockets since the last sock_diag poll for a given network id.
- * @param sentAckDiffMs an array of milliseconds duration between the last packet sent and the
- last ack received for a socket, averaged across all TCP sockets for a network id.
- */
- void onTcpSocketStatsEvent(in int[] networkIds, in int[] sentPackets,
- in int[] lostPackets, in int[] rttUs, in int[] sentAckDiffMs);
-
- /**
- * Represents adding or removing a NAT64 prefix.
- *
- * @param netId the ID of the network the prefix was discovered on.
- * @param added true if the NAT64 prefix was added, or false if the NAT64 prefix was removed.
- * There is only one prefix at a time for each netId. If a prefix is added, it replaces
- * the previous-added prefix.
- * @param prefixString the detected NAT64 prefix as a string literal.
- * @param prefixLength the prefix length associated with this NAT64 prefix.
- */
- void onNat64PrefixEvent(int netId, boolean added, @utf8InCpp String prefixString,
- int prefixLength);
-}
diff --git a/server/binder/android/net/netd/aidl/NativeUidRangeConfig.aidl b/server/binder/android/net/netd/aidl/NativeUidRangeConfig.aidl
deleted file mode 100644
index 99497a8..0000000
--- a/server/binder/android/net/netd/aidl/NativeUidRangeConfig.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-package android.net.netd.aidl;
-
-import android.net.UidRangeParcel;
-
-/**
- * The configuration to add or remove UID ranges.
- *
- * {@hide}
- */
-@JavaDerive(toString=true, equals=true)
-@JavaOnlyImmutable
-parcelable NativeUidRangeConfig {
- /** The network ID of the network to add/remove the ranges to/from. */
- int netId;
-
- /** A set of non-overlapping ranges of UIDs. */
- UidRangeParcel[] uidRanges;
-
- /**
- * The priority of this UID range config. 0 is the highest priority; 999 is the lowest priority.
- * The function of this parameter is to adjust the priority when the same UID is set to
- * different networks for different features.
- */
- int subPriority;
-}
\ No newline at end of file
diff --git a/server/main.cpp b/server/main.cpp
index bc48ac2..0e81d4e 100644
--- a/server/main.cpp
+++ b/server/main.cpp
@@ -34,12 +34,13 @@
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
-#include <libbpf_android.h>
#include <netdutils/Stopwatch.h>
+#include <processgroup/processgroup.h>
#include "Controllers.h"
#include "FwmarkServer.h"
#include "MDnsSdListener.h"
+#include "MDnsService.h"
#include "NFLogListener.h"
#include "NetdConstants.h"
#include "NetdHwService.h"
@@ -47,6 +48,7 @@
#include "NetlinkManager.h"
#include "Process.h"
+#include "NetdUpdatablePublic.h"
#include "netd_resolv/resolv.h"
using android::IPCThreadState;
@@ -57,6 +59,7 @@
using android::net::gCtls;
using android::net::gLog;
using android::net::makeNFLogListener;
+using android::net::MDnsService;
using android::net::NetdHwService;
using android::net::NetdNativeService;
using android::net::NetlinkManager;
@@ -85,7 +88,7 @@
int tagSocketCallback(int sockFd, uint32_t tag, uid_t uid, pid_t) {
// Workaround for secureVPN with VpnIsolation enabled, refer to b/159994981 for details.
if (tag == TAG_SYSTEM_DNS) uid = AID_DNS;
- return gCtls->trafficCtrl.tagSocket(sockFd, tag, uid, geteuid());
+ return libnetd_updatable_tagSocket(sockFd, tag, uid, AID_DNS);
}
bool evaluateDomainNameCallback(const android_net_context&, const char* /*name*/) {
@@ -123,9 +126,17 @@
gLog.info("setCloseOnExec(%s)", sock);
}
- // Make sure BPF programs are loaded before doing anything
- android::bpf::waitForProgsLoaded();
- gLog.info("BPF programs are loaded");
+ std::string cg2_path;
+ if (!CgroupGetControllerPath(CGROUPV2_CONTROLLER_NAME, &cg2_path)) {
+ ALOGE("Failed to find cgroup v2 root %s", strerror(errno));
+ exit(1);
+ }
+
+ if (libnetd_updatable_init(cg2_path.c_str())) {
+ ALOGE("libnetd_updatable_init failed");
+ exit(1);
+ }
+ gLog.info("libnetd_updatable_init success");
NetlinkManager *nm = NetlinkManager::Instance();
if (nm == nullptr) {
@@ -168,13 +179,7 @@
exit(1);
}
- MDnsSdListener mdnsl;
- if (mdnsl.startListener()) {
- ALOGE("Unable to start MDnsSdListener (%s)", strerror(errno));
- exit(1);
- }
-
- FwmarkServer fwmarkServer(&gCtls->netCtrl, &gCtls->eventReporter, &gCtls->trafficCtrl);
+ FwmarkServer fwmarkServer(&gCtls->netCtrl, &gCtls->eventReporter);
if (fwmarkServer.startListener()) {
ALOGE("Unable to start FwmarkServer (%s)", strerror(errno));
exit(1);
@@ -188,6 +193,12 @@
}
gLog.info("Registering NetdNativeService: %" PRId64 "us", subTime.getTimeAndResetUs());
+ if ((ret = MDnsService::start()) != android::OK) {
+ ALOGE("Unable to start MDnsService: %d", ret);
+ exit(1);
+ }
+ gLog.info("Registering MDnsService: %" PRId64 "us", subTime.getTimeAndResetUs());
+
android::net::process::ScopedPidFile pidFile(PID_FILE_PATH);
// Now that netd is ready to process commands, advertise service availability for HAL clients.
diff --git a/server/netd.rc b/server/netd.rc
index e6316c1..3e7aa40 100644
--- a/server/netd.rc
+++ b/server/netd.rc
@@ -1,6 +1,7 @@
service netd /system/bin/netd
class main
capabilities CHOWN DAC_OVERRIDE DAC_READ_SEARCH FOWNER IPC_LOCK KILL NET_ADMIN NET_BIND_SERVICE NET_RAW SETUID SETGID
+ group root net_admin
socket dnsproxyd stream 0660 root inet
socket mdns stream 0660 root system
socket fwmarkd stream 0660 root inet
@@ -10,3 +11,23 @@
# from the DNS resolver APEX. Mark it as updatable so init won't start it until all APEX
# packages are ready.
updatable
+
+# Moved from external/android-clat/vendor-464xlat.rc. Since
+# clatd is modularized and shipped in apex, migrate the
+# clat vendor property to netd.
+#
+# Certain vendors disable 464xlat by setting a vendor property.
+# The connectivity code in the Tethering APEX needs to disable
+# 464xlat when the property is set, but it is only allowed to
+# access non-vendor system properties. So copy the property to
+# a property available to system APIs in android.sysprop.
+#
+# Arguably this script should live close to the code that uses
+# it, but scrips in APEXes are not allowed to use "on property".
+# So put it here close to clatd, which is at least related to
+# 464xlat.
+on property:persist.vendor.net.doxlat=true
+ setprop net.464xlat.cellular.enabled true
+
+on property:persist.vendor.net.doxlat=false
+ setprop net.464xlat.cellular.enabled false
diff --git a/tests/Android.bp b/tests/Android.bp
index c5d9bb5..ff918cc 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -37,7 +37,10 @@
cc_test_library {
name: "libnetd_test_unsol_service",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_shared",
+ "netd_defaults",
+ ],
srcs: [
"TestUnsolService.cpp"
],
@@ -52,7 +55,6 @@
"libnetutils",
"libsysutils",
"libutils",
- "netd_aidl_interface-V7-cpp",
],
}
@@ -74,17 +76,21 @@
"vts"
],
require_root: true,
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_static",
+ "netd_defaults",
+ ],
tidy: false, // cuts test build time by almost 1 minute
srcs: [
":netd_integration_test_shared",
"binder_test.cpp",
"bpf_base_test.cpp",
+ "kernel_test.cpp",
"netd_client_test.cpp",
"netd_test.cpp",
- "netlink_listener_test.cpp",
],
include_dirs: ["system/netd/server"],
+ header_libs: ["bpf_connectivity_headers"],
shared_libs: [
"libbase",
"libbinder",
@@ -97,17 +103,17 @@
"libssl",
"libsysutils",
"libutils",
+ "libvintf",
],
static_libs: [
"libcap",
"libnetd_test_tun_interface",
"libnetd_test_unsol_service",
"libnetd_test_utils",
- "libbpf_android",
- "libnetdbpf",
"libnetdutils",
- "libqtaguid",
- "netd_aidl_interface-V7-cpp",
+ "libnettestutils",
+ "libtcutils",
+ "mdns_aidl_interface-V1-cpp",
"netd_event_listener_interface-V1-cpp",
"oemnetd_aidl_interface-cpp",
],
diff --git a/tests/benchmarks/Android.bp b/tests/benchmarks/Android.bp
index 00c28eb..13c8105 100644
--- a/tests/benchmarks/Android.bp
+++ b/tests/benchmarks/Android.bp
@@ -11,7 +11,10 @@
cc_benchmark {
name: "netd_benchmark",
- defaults: ["netd_defaults"],
+ defaults: [
+ "netd_aidl_interface_lateststable_cpp_static",
+ "netd_defaults",
+ ],
shared_libs: [
"libbase",
"libbinder_ndk",
@@ -22,10 +25,9 @@
],
static_libs: [
"libnetd_test_dnsresponder_ndk",
- "dnsresolver_aidl_interface-lateststable-ndk_platform",
- "netd_aidl_interface-lateststable-cpp", // system/netd/server/UidRanges.h
- "netd_aidl_interface-lateststable-ndk_platform",
- "netd_event_listener_interface-lateststable-ndk_platform",
+ "dnsresolver_aidl_interface-lateststable-ndk",
+ "netd_aidl_interface-lateststable-ndk",
+ "netd_event_listener_interface-lateststable-ndk",
],
aidl: {
include_dirs: ["system/netd/server/binder"],
@@ -47,9 +49,10 @@
name: "bpf_benchmark",
defaults: ["netd_defaults"],
require_root: true,
+ header_libs: ["bpf_headers"],
shared_libs: [
"libbase",
- "libbpf_android",
+ "liblog",
"libnetdutils",
],
srcs: [
diff --git a/tests/binder_test.cpp b/tests/binder_test.cpp
index e80296a..a97af85 100644
--- a/tests/binder_test.cpp
+++ b/tests/binder_test.cpp
@@ -24,10 +24,10 @@
#include <cstdlib>
#include <iostream>
#include <mutex>
+#include <numeric>
#include <regex>
#include <set>
#include <string>
-#include <thread>
#include <vector>
#include <dirent.h>
@@ -54,11 +54,11 @@
#include <binder/IPCThreadState.h>
#include <bpf/BpfMap.h>
#include <bpf/BpfUtils.h>
+#include <bpf_shared.h>
#include <com/android/internal/net/BnOemNetdUnsolicitedEventListener.h>
#include <com/android/internal/net/IOemNetd.h>
#include <cutils/multiuser.h>
#include <gtest/gtest.h>
-#include <netdbpf/bpf_shared.h>
#include <netutils/ifc.h>
#include <utils/Errors.h>
#include "Fwmark.h"
@@ -71,11 +71,19 @@
#include "TestUnsolService.h"
#include "XfrmController.h"
#include "android/net/INetd.h"
+#include "android/net/mdns/aidl/BnMDnsEventListener.h"
+#include "android/net/mdns/aidl/DiscoveryInfo.h"
+#include "android/net/mdns/aidl/GetAddressInfo.h"
+#include "android/net/mdns/aidl/IMDns.h"
+#include "android/net/mdns/aidl/RegistrationInfo.h"
+#include "android/net/mdns/aidl/ResolutionInfo.h"
#include "binder/IServiceManager.h"
#include "netdutils/InternetAddresses.h"
#include "netdutils/Stopwatch.h"
#include "netdutils/Syscalls.h"
+#include "netdutils/Utils.h"
#include "netid_client.h" // NETID_UNSET
+#include "nettestutils/DumpService.h"
#include "test_utils.h"
#include "tun_interface.h"
@@ -95,12 +103,12 @@
using android::String8;
using android::base::Join;
using android::base::make_scope_guard;
-using android::base::ReadFdToString;
using android::base::ReadFileToString;
using android::base::StartsWith;
using android::base::StringPrintf;
using android::base::Trim;
using android::base::unique_fd;
+using android::binder::Status;
using android::net::INetd;
using android::net::InterfaceConfigurationParcel;
using android::net::InterfaceController;
@@ -108,9 +116,11 @@
using android::net::NativeNetworkConfig;
using android::net::NativeNetworkType;
using android::net::NativeVpnType;
-using android::net::RULE_PRIORITY_BYPASSABLE_VPN;
+using android::net::RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION;
+using android::net::RULE_PRIORITY_BYPASSABLE_VPN_NO_LOCAL_EXCLUSION;
using android::net::RULE_PRIORITY_DEFAULT_NETWORK;
using android::net::RULE_PRIORITY_EXPLICIT_NETWORK;
+using android::net::RULE_PRIORITY_LOCAL_ROUTES;
using android::net::RULE_PRIORITY_OUTPUT_INTERFACE;
using android::net::RULE_PRIORITY_PROHIBIT_NON_VPN;
using android::net::RULE_PRIORITY_SECURE_VPN;
@@ -126,7 +136,13 @@
using android::net::TunInterface;
using android::net::UidRangeParcel;
using android::net::UidRanges;
+using android::net::mdns::aidl::DiscoveryInfo;
+using android::net::mdns::aidl::GetAddressInfo;
+using android::net::mdns::aidl::IMDns;
+using android::net::mdns::aidl::RegistrationInfo;
+using android::net::mdns::aidl::ResolutionInfo;
using android::net::netd::aidl::NativeUidRangeConfig;
+using android::netdutils::getIfaceNames;
using android::netdutils::IPAddress;
using android::netdutils::ScopedAddrinfo;
using android::netdutils::sSyscalls;
@@ -209,7 +225,8 @@
unique_fd* acceptedSocket);
void createVpnNetworkWithUid(bool secure, uid_t uid, int vpnNetId = TEST_NETID2,
- int fallthroughNetId = TEST_NETID1);
+ int fallthroughNetId = TEST_NETID1,
+ int nonDefaultNetId = TEST_NETID3);
void createAndSetDefaultNetwork(int netId, const std::string& interface,
int permission = INetd::PERMISSION_NONE);
@@ -226,7 +243,6 @@
int vpnNetId, bool secure,
std::vector<UidRangeParcel>&& appDefaultUidRanges,
std::vector<UidRangeParcel>&& vpnUidRanges);
-
protected:
// Use -1 to represent that default network was not modified because
// real netId must be an unsigned value.
@@ -264,7 +280,7 @@
namespace {
NativeNetworkConfig makeNativeNetworkConfig(int netId, NativeNetworkType networkType,
- int permission, bool secure) {
+ int permission, bool secure, bool excludeLocalRoutes) {
NativeNetworkConfig config = {};
config.netId = netId;
config.networkType = networkType;
@@ -272,6 +288,7 @@
config.secure = secure;
// The vpnType doesn't matter in AOSP. Just pick a well defined one from INetd.
config.vpnType = NativeVpnType::PLATFORM;
+ config.excludeLocalRoutes = excludeLocalRoutes;
return config;
}
@@ -282,7 +299,7 @@
// Note that this networkCreate is never allowed to create reserved network IDs, so
// this call may fail for other reasons than the network already existing.
const auto& config = makeNativeNetworkConfig(netId, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_FALSE(netd->networkCreate(config).isOk());
// Test if the network exist by adding interface. INetd has no dedicated method to query. When
// the network exists and the interface can be added, the function succeeds. When the network
@@ -612,12 +629,15 @@
return res;
}
-NativeUidRangeConfig makeNativeUidRangeConfig(unsigned netId,
- std::vector<UidRangeParcel>&& uidRanges,
- uint32_t subPriority) {
+UidRangeParcel makeUidRangeParcel(int uid) {
+ return makeUidRangeParcel(uid, uid);
+}
+
+NativeUidRangeConfig makeNativeUidRangeConfig(unsigned netId, std::vector<UidRangeParcel> uidRanges,
+ int32_t subPriority) {
NativeUidRangeConfig res;
res.netId = netId;
- res.uidRanges = uidRanges;
+ res.uidRanges = move(uidRanges);
res.subPriority = subPriority;
return res;
@@ -627,7 +647,7 @@
TEST_F(NetdBinderTest, NetworkInterfaces) {
auto config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_EQ(EEXIST, mNetd->networkCreate(config).serviceSpecificErrorCode());
@@ -650,7 +670,7 @@
TEST_F(NetdBinderTest, NetworkUidRules) {
auto config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::VIRTUAL,
- INetd::PERMISSION_NONE, true);
+ INetd::PERMISSION_NONE, true, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_EQ(EEXIST, mNetd->networkCreate(config).serviceSpecificErrorCode());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -817,11 +837,12 @@
sin6_1.sin6_scope_id = if_nametoindex(sTun.name().c_str());
sin6_2.sin6_scope_id = if_nametoindex(sTun2.name().c_str());
- int s1 = socket(AF_INET6, SOCK_STREAM, 0);
+ int s1 = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);
ASSERT_EQ(0, bind(s1, reinterpret_cast<sockaddr*>(&sin6_1), len));
ASSERT_EQ(0, getsockname(s1, reinterpret_cast<sockaddr*>(&sin6_1), &len));
+ // getsockname technically writes to len, but sizeof(sockaddr_in6) doesn't change.
- int s2 = socket(AF_INET6, SOCK_STREAM, 0);
+ int s2 = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);
ASSERT_EQ(0, bind(s2, reinterpret_cast<sockaddr*>(&sin6_2), len));
ASSERT_EQ(0, getsockname(s2, reinterpret_cast<sockaddr*>(&sin6_2), &len));
@@ -842,7 +863,7 @@
status = mNetd->interfaceDelAddress(sTun2.name(), kLinkLocalAddress, 64);
EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
- // The sockets on sTun2 are closed, but the ones on sTun1 remain open.
+ // The client sockets on sTun2 are closed, but the ones on sTun1 remain open.
char buf[1024];
EXPECT_EQ(-1, read(c2, buf, sizeof(buf)));
EXPECT_EQ(ECONNABORTED, errno);
@@ -852,6 +873,12 @@
EXPECT_EQ(3, read(c1, buf, sizeof(buf)));
EXPECT_EQ(-1, write(a2, "foo", 3));
EXPECT_TRUE(errno == ECONNABORTED || errno == ECONNRESET);
+
+ // Check the server sockets too.
+ EXPECT_EQ(-1, accept(s1, nullptr, 0));
+ EXPECT_EQ(EAGAIN, errno);
+ EXPECT_EQ(-1, accept(s2, nullptr, 0));
+ EXPECT_EQ(EINVAL, errno);
}
namespace {
@@ -1296,6 +1323,63 @@
constexpr char STRICT_OUTPUT[] = "st_OUTPUT";
constexpr char STRICT_CLEAR_CAUGHT[] = "st_clear_caught";
+// Output looks like this:
+//
+// IPv4:
+//
+// throw dst proto static scope link
+// unreachable dst proto static scope link
+// dst via nextHop dev ifName proto static
+// dst dev ifName proto static scope link
+//
+// IPv6:
+//
+// throw dst dev lo proto static metric 1024
+// unreachable dst dev lo proto static metric 1024
+// dst via nextHop dev ifName proto static metric 1024
+// dst dev ifName proto static metric 1024
+std::string ipRoutePrefix(const std::string& ifName, const std::string& dst,
+ const std::string& nextHop) {
+ std::string prefixString;
+
+ bool isThrow = nextHop == "throw";
+ bool isUnreachable = nextHop == "unreachable";
+ bool isDefault = (dst == "0.0.0.0/0" || dst == "::/0");
+ bool isIPv6 = dst.find(':') != std::string::npos;
+ bool isThrowOrUnreachable = isThrow || isUnreachable;
+
+ if (isThrowOrUnreachable) {
+ prefixString += nextHop + " ";
+ }
+
+ prefixString += isDefault ? "default" : dst;
+
+ if (!nextHop.empty() && !isThrowOrUnreachable) {
+ prefixString += " via " + nextHop;
+ }
+
+ if (isThrowOrUnreachable) {
+ if (isIPv6) {
+ prefixString += " dev lo";
+ }
+ } else {
+ prefixString += " dev " + ifName;
+ }
+
+ prefixString += " proto static";
+
+ // IPv6 routes report the metric, IPv4 routes report the scope.
+ if (isIPv6) {
+ prefixString += " metric 1024";
+ } else {
+ if (nextHop.empty() || isThrowOrUnreachable) {
+ prefixString += " scope link";
+ }
+ }
+
+ return prefixString;
+}
+
void expectStrictSetUidAccept(const int uid) {
std::string uidRule = StringPrintf("owner UID match %u", uid);
std::string perUidChain = StringPrintf("st_clear_caught_%u", uid);
@@ -1328,6 +1412,153 @@
}
}
+bool ipRuleExists(const char* ipVersion, const std::string& ipRule) {
+ std::vector<std::string> rules = listIpRules(ipVersion);
+ for (const auto& rule : rules) {
+ if (rule.find(ipRule) != std::string::npos) {
+ return true;
+ }
+ }
+ return false;
+}
+
+std::vector<std::string> ipRouteSubstrings(const std::string& ifName, const std::string& dst,
+ const std::string& nextHop, const std::string& mtu) {
+ std::vector<std::string> routeSubstrings;
+
+ routeSubstrings.push_back(ipRoutePrefix(ifName, dst, nextHop));
+
+ if (!mtu.empty()) {
+ // Add separate substring to match mtu value.
+ // This is needed because on some devices "error -11"/"error -113" appears between ip prefix
+ // and mtu for throw/unreachable routes.
+ routeSubstrings.push_back("mtu " + mtu);
+ }
+
+ return routeSubstrings;
+}
+
+void expectNetworkRouteDoesNotExistWithMtu(const char* ipVersion, const std::string& ifName,
+ const std::string& dst, const std::string& nextHop,
+ const std::string& mtu, const char* table) {
+ std::vector<std::string> routeSubstrings = ipRouteSubstrings(ifName, dst, nextHop, mtu);
+ EXPECT_FALSE(ipRouteExists(ipVersion, table, routeSubstrings))
+ << "Found unexpected route [" << Join(routeSubstrings, ", ") << "] in table " << table;
+}
+
+void expectNetworkRouteExistsWithMtu(const char* ipVersion, const std::string& ifName,
+ const std::string& dst, const std::string& nextHop,
+ const std::string& mtu, const char* table) {
+ std::vector<std::string> routeSubstrings = ipRouteSubstrings(ifName, dst, nextHop, mtu);
+ EXPECT_TRUE(ipRouteExists(ipVersion, table, routeSubstrings))
+ << "Couldn't find route to " << dst << ": [" << Join(routeSubstrings, ", ")
+ << "] in table " << table;
+}
+
+void expectVpnLocalExclusionRuleExists(const std::string& ifName, bool expectExists) {
+ std::string tableName = std::string(ifName + "_local");
+ // Check if rule exists
+ std::string vpnLocalExclusionRule =
+ StringPrintf("%d:\tfrom all fwmark 0x0/0x10000 iif lo lookup %s",
+ RULE_PRIORITY_LOCAL_ROUTES, tableName.c_str());
+ for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
+ EXPECT_EQ(expectExists, ipRuleExists(ipVersion, vpnLocalExclusionRule));
+ }
+}
+
+void expectNetworkRouteExists(const char* ipVersion, const std::string& ifName,
+ const std::string& dst, const std::string& nextHop,
+ const char* table) {
+ expectNetworkRouteExistsWithMtu(ipVersion, ifName, dst, nextHop, "", table);
+}
+
+void expectNetworkRouteDoesNotExist(const char* ipVersion, const std::string& ifName,
+ const std::string& dst, const std::string& nextHop,
+ const char* table) {
+ expectNetworkRouteDoesNotExistWithMtu(ipVersion, ifName, dst, nextHop, "", table);
+}
+
+void expectNetworkDefaultIpRuleExists(const char* ifName) {
+ std::string networkDefaultRule =
+ StringPrintf("%u:\tfrom all fwmark 0x0/0xffff iif lo lookup %s",
+ RULE_PRIORITY_DEFAULT_NETWORK, ifName);
+
+ for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
+ EXPECT_TRUE(ipRuleExists(ipVersion, networkDefaultRule));
+ }
+}
+
+void expectNetworkDefaultIpRuleDoesNotExist() {
+ std::string networkDefaultRule =
+ StringPrintf("%u:\tfrom all fwmark 0x0/0xffff iif lo", RULE_PRIORITY_DEFAULT_NETWORK);
+
+ for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
+ EXPECT_FALSE(ipRuleExists(ipVersion, networkDefaultRule));
+ }
+}
+
+void expectNetworkPermissionIpRuleExists(const char* ifName, int permission) {
+ std::string networkPermissionRule = "";
+ switch (permission) {
+ case INetd::PERMISSION_NONE:
+ networkPermissionRule =
+ StringPrintf("%u:\tfrom all fwmark 0x1ffdd/0x1ffff iif lo lookup %s",
+ RULE_PRIORITY_EXPLICIT_NETWORK, ifName);
+ break;
+ case INetd::PERMISSION_NETWORK:
+ networkPermissionRule =
+ StringPrintf("%u:\tfrom all fwmark 0x5ffdd/0x5ffff iif lo lookup %s",
+ RULE_PRIORITY_EXPLICIT_NETWORK, ifName);
+ break;
+ case INetd::PERMISSION_SYSTEM:
+ networkPermissionRule =
+ StringPrintf("%u:\tfrom all fwmark 0xdffdd/0xdffff iif lo lookup %s",
+ RULE_PRIORITY_EXPLICIT_NETWORK, ifName);
+ break;
+ }
+
+ for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
+ EXPECT_TRUE(ipRuleExists(ipVersion, networkPermissionRule));
+ }
+}
+
+// TODO: It is a duplicate function, need to remove it
+bool iptablesNetworkPermissionIptablesRuleExists(const char* binary, const char* chainName,
+ const std::string& expectedInterface,
+ const std::string& expectedRule,
+ const char* table) {
+ std::vector<std::string> rules = listIptablesRuleByTable(binary, table, chainName);
+ for (const auto& rule : rules) {
+ if (rule.find(expectedInterface) != std::string::npos) {
+ if (rule.find(expectedRule) != std::string::npos) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+void expectNetworkPermissionIptablesRuleExists(const char* ifName, int permission) {
+ static const char ROUTECTRL_INPUT[] = "routectrl_mangle_INPUT";
+ std::string networkIncomingPacketMarkRule = "";
+ switch (permission) {
+ case INetd::PERMISSION_NONE:
+ networkIncomingPacketMarkRule = "MARK xset 0x3ffdd/0xffefffff";
+ break;
+ case INetd::PERMISSION_NETWORK:
+ networkIncomingPacketMarkRule = "MARK xset 0x7ffdd/0xffefffff";
+ break;
+ case INetd::PERMISSION_SYSTEM:
+ networkIncomingPacketMarkRule = "MARK xset 0xfffdd/0xffefffff";
+ break;
+ }
+
+ for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
+ EXPECT_TRUE(iptablesNetworkPermissionIptablesRuleExists(
+ binary, ROUTECTRL_INPUT, ifName, networkIncomingPacketMarkRule, MANGLE_TABLE));
+ }
+}
+
} // namespace
TEST_F(NetdBinderTest, StrictSetUidCleartextPenalty) {
@@ -1395,75 +1626,6 @@
} // namespace
-TEST_F(NetdBinderTest, ClatdStartStop) {
- binder::Status status;
-
- const std::string clatdName = StringPrintf("clatd-%s", sTun.name().c_str());
- std::string clatAddress;
- std::string nat64Prefix = "2001:db8:cafe:f00d:1:2::/96";
-
- // Can't start clatd on an interface that's not part of any network...
- status = mNetd->clatdStart(sTun.name(), nat64Prefix, &clatAddress);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(ENODEV, status.serviceSpecificErrorCode());
-
- // ... so create a test physical network and add our tun to it.
- const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
- EXPECT_TRUE(mNetd->networkCreate(config).isOk());
- EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
-
- // Prefix must be 96 bits long.
- status = mNetd->clatdStart(sTun.name(), "2001:db8:cafe:f00d::/64", &clatAddress);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
-
- // Can't start clatd unless there's a default route...
- status = mNetd->clatdStart(sTun.name(), nat64Prefix, &clatAddress);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EADDRNOTAVAIL, status.serviceSpecificErrorCode());
-
- // so add a default route.
- EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
-
- // Can't start clatd unless there's a global address...
- status = mNetd->clatdStart(sTun.name(), nat64Prefix, &clatAddress);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EADDRNOTAVAIL, status.serviceSpecificErrorCode());
-
- // ... so add a global address.
- const std::string v6 = "2001:db8:1:2:f076:ae99:124e:aa99";
- EXPECT_EQ(0, sTun.addAddress(v6.c_str(), 64));
-
- // Now expect clatd to start successfully.
- status = mNetd->clatdStart(sTun.name(), nat64Prefix, &clatAddress);
- EXPECT_TRUE(status.isOk());
- EXPECT_EQ(0, status.serviceSpecificErrorCode());
-
- // Starting it again returns EBUSY.
- status = mNetd->clatdStart(sTun.name(), nat64Prefix, &clatAddress);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EBUSY, status.serviceSpecificErrorCode());
-
- expectProcessExists(clatdName);
-
- // Expect clatd to stop successfully.
- status = mNetd->clatdStop(sTun.name());
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
- expectProcessDoesNotExist(clatdName);
-
- // Stopping a clatd that doesn't exist returns ENODEV.
- status = mNetd->clatdStop(sTun.name());
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(ENODEV, status.serviceSpecificErrorCode());
- expectProcessDoesNotExist(clatdName);
-
- // Clean up.
- EXPECT_TRUE(mNetd->networkRemoveRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
- EXPECT_EQ(0, ifc_del_address(sTun.name().c_str(), v6.c_str(), 64));
- EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
-}
-
namespace {
bool getIpfwdV4Enable() {
@@ -1575,7 +1737,7 @@
TEST_F(NetdBinderTest, TestIpfwdAddRemoveInterfaceForward) {
// Add test physical network
auto config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -1697,7 +1859,7 @@
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -1717,7 +1879,7 @@
long testAlertBytes = 373;
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
// Need to have a prior interface quota set to set an alert
@@ -1752,150 +1914,6 @@
expectBandwidthGlobalAlertRuleExists(testAlertBytes);
}
-namespace {
-
-std::string ipRouteString(const std::string& ifName, const std::string& dst,
- const std::string& nextHop, const std::string& mtu) {
- std::string dstString = (dst == "0.0.0.0/0" || dst == "::/0") ? "default" : dst;
-
- if (!nextHop.empty()) {
- dstString += " via " + nextHop;
- }
-
- dstString += " dev " + ifName;
-
- if (!mtu.empty()) {
- dstString += " proto static";
- // IPv6 routes report the metric, IPv4 routes report the scope.
- // TODO: move away from specifying the entire string and use a regexp instead.
- if (dst.find(':') != std::string::npos) {
- dstString += " metric 1024";
- } else {
- if (nextHop.empty()) {
- dstString += " scope link";
- }
- }
- dstString += " mtu " + mtu;
- }
-
- return dstString;
-}
-
-void expectNetworkRouteExistsWithMtu(const char* ipVersion, const std::string& ifName,
- const std::string& dst, const std::string& nextHop,
- const std::string& mtu, const char* table) {
- std::string routeString = ipRouteString(ifName, dst, nextHop, mtu);
- EXPECT_TRUE(ipRouteExists(ipVersion, table, ipRouteString(ifName, dst, nextHop, mtu)))
- << "Couldn't find route to " << dst << ": '" << routeString << "' in table " << table;
-}
-
-void expectNetworkRouteExists(const char* ipVersion, const std::string& ifName,
- const std::string& dst, const std::string& nextHop,
- const char* table) {
- expectNetworkRouteExistsWithMtu(ipVersion, ifName, dst, nextHop, "", table);
-}
-
-void expectNetworkRouteDoesNotExist(const char* ipVersion, const std::string& ifName,
- const std::string& dst, const std::string& nextHop,
- const char* table) {
- std::string routeString = ipRouteString(ifName, dst, nextHop, "");
- EXPECT_FALSE(ipRouteExists(ipVersion, table, ipRouteString(ifName, dst, nextHop, "")))
- << "Found unexpected route " << routeString << " in table " << table;
-}
-
-bool ipRuleExists(const char* ipVersion, const std::string& ipRule) {
- std::vector<std::string> rules = listIpRules(ipVersion);
- for (const auto& rule : rules) {
- if (rule.find(ipRule) != std::string::npos) {
- return true;
- }
- }
- return false;
-}
-
-void expectNetworkDefaultIpRuleExists(const char* ifName) {
- std::string networkDefaultRule =
- StringPrintf("%u:\tfrom all fwmark 0x0/0xffff iif lo lookup %s",
- RULE_PRIORITY_DEFAULT_NETWORK, ifName);
-
- for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
- EXPECT_TRUE(ipRuleExists(ipVersion, networkDefaultRule));
- }
-}
-
-void expectNetworkDefaultIpRuleDoesNotExist() {
- std::string networkDefaultRule =
- StringPrintf("%u:\tfrom all fwmark 0x0/0xffff iif lo", RULE_PRIORITY_DEFAULT_NETWORK);
-
- for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
- EXPECT_FALSE(ipRuleExists(ipVersion, networkDefaultRule));
- }
-}
-
-void expectNetworkPermissionIpRuleExists(const char* ifName, int permission) {
- std::string networkPermissionRule = "";
- switch (permission) {
- case INetd::PERMISSION_NONE:
- networkPermissionRule =
- StringPrintf("%u:\tfrom all fwmark 0x1ffdd/0x1ffff iif lo lookup %s",
- RULE_PRIORITY_EXPLICIT_NETWORK, ifName);
- break;
- case INetd::PERMISSION_NETWORK:
- networkPermissionRule =
- StringPrintf("%u:\tfrom all fwmark 0x5ffdd/0x5ffff iif lo lookup %s",
- RULE_PRIORITY_EXPLICIT_NETWORK, ifName);
- break;
- case INetd::PERMISSION_SYSTEM:
- networkPermissionRule =
- StringPrintf("%u:\tfrom all fwmark 0xdffdd/0xdffff iif lo lookup %s",
- RULE_PRIORITY_EXPLICIT_NETWORK, ifName);
- break;
- }
-
- for (const auto& ipVersion : {IP_RULE_V4, IP_RULE_V6}) {
- EXPECT_TRUE(ipRuleExists(ipVersion, networkPermissionRule));
- }
-}
-
-// TODO: It is a duplicate function, need to remove it
-bool iptablesNetworkPermissionIptablesRuleExists(const char* binary, const char* chainName,
- const std::string& expectedInterface,
- const std::string& expectedRule,
- const char* table) {
- std::vector<std::string> rules = listIptablesRuleByTable(binary, table, chainName);
- for (const auto& rule : rules) {
- if (rule.find(expectedInterface) != std::string::npos) {
- if (rule.find(expectedRule) != std::string::npos) {
- return true;
- }
- }
- }
- return false;
-}
-
-void expectNetworkPermissionIptablesRuleExists(const char* ifName, int permission) {
- static const char ROUTECTRL_INPUT[] = "routectrl_mangle_INPUT";
- std::string networkIncomingPacketMarkRule = "";
- switch (permission) {
- case INetd::PERMISSION_NONE:
- networkIncomingPacketMarkRule = "MARK xset 0x3ffdd/0xffefffff";
- break;
- case INetd::PERMISSION_NETWORK:
- networkIncomingPacketMarkRule = "MARK xset 0x7ffdd/0xffefffff";
- break;
- case INetd::PERMISSION_SYSTEM:
- networkIncomingPacketMarkRule = "MARK xset 0xfffdd/0xffefffff";
- break;
- }
-
- for (const auto& binary : {IPTABLES_PATH, IP6TABLES_PATH}) {
- EXPECT_TRUE(iptablesNetworkPermissionIptablesRuleExists(
- binary, ROUTECTRL_INPUT, ifName, networkIncomingPacketMarkRule, MANGLE_TABLE));
- }
-}
-
-} // namespace
-
TEST_F(NetdBinderTest, NetworkAddRemoveRouteUserPermission) {
static const struct {
const char* ipVersion;
@@ -1912,6 +1930,14 @@
{IP_RULE_V6, "::/0", "2001:db8::", true},
{IP_RULE_V6, "2001:db8:cafe::/64", "2001:db8::", true},
{IP_RULE_V4, "fe80::/64", "0.0.0.0", false},
+ {IP_RULE_V4, "10.251.10.2/31", "throw", true},
+ {IP_RULE_V4, "10.251.10.2/31", "unreachable", true},
+ {IP_RULE_V4, "0.0.0.0/0", "throw", true},
+ {IP_RULE_V4, "0.0.0.0/0", "unreachable", true},
+ {IP_RULE_V6, "::/0", "throw", true},
+ {IP_RULE_V6, "::/0", "unreachable", true},
+ {IP_RULE_V6, "2001:db8:cafe::/64", "throw", true},
+ {IP_RULE_V6, "2001:db8:cafe::/64", "unreachable", true},
};
static const struct {
@@ -1930,7 +1956,7 @@
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -2039,6 +2065,12 @@
}
}
+ /*
+ * Test networkUpdateRouteParcel behavior in case of route MTU change.
+ *
+ * Change of route MTU should be treated as an update of the route:
+ * - networkUpdateRouteParcel should succeed and update route MTU.
+ */
for (size_t i = 0; i < std::size(kTestData); i++) {
const auto& td = kTestData[i];
int mtu = (i % 2) ? 1480 : 1280;
@@ -2079,6 +2111,61 @@
EXPECT_NE(0, status.serviceSpecificErrorCode());
}
}
+
+ /*
+ * Test network[Update|Add]RouteParcel behavior in case of route type change.
+ *
+ * Change of route type should be treated as an update of the route:
+ * - networkUpdateRouteParcel should succeed and update route type.
+ * - networkAddRouteParcel should silently fail, because the route already exists. Route type
+ * should not be changed in this case.
+ */
+ for (size_t i = 0; i < std::size(kTestData); i++) {
+ const auto& td = kTestData[i];
+
+ if (!td.expectSuccess) {
+ continue;
+ }
+
+ android::net::RouteInfoParcel parcel;
+ parcel.ifName = sTun.name();
+ parcel.destination = td.testDest;
+ parcel.nextHop = td.testNextHop;
+ parcel.mtu = 1280;
+ binder::Status status = mNetd->networkAddRouteParcel(TEST_NETID1, parcel);
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+ expectNetworkRouteExistsWithMtu(td.ipVersion, sTun.name(), td.testDest, td.testNextHop,
+ std::to_string(parcel.mtu), sTun.name().c_str());
+
+ parcel.nextHop = parcel.nextHop == "throw" ? "unreachable" : "throw";
+ const char* oldNextHop = td.testNextHop;
+ const char* newNextHop = parcel.nextHop.c_str();
+
+ // Trying to add same route with changed type, this should silently fail.
+ status = mNetd->networkAddRouteParcel(TEST_NETID1, parcel);
+ // No error reported.
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+ // Old route still exists.
+ expectNetworkRouteExistsWithMtu(td.ipVersion, sTun.name(), td.testDest, oldNextHop,
+ std::to_string(parcel.mtu), sTun.name().c_str());
+ // New route was not actually added.
+ expectNetworkRouteDoesNotExistWithMtu(td.ipVersion, sTun.name(), td.testDest, newNextHop,
+ std::to_string(parcel.mtu), sTun.name().c_str());
+
+ // Update should succeed.
+ status = mNetd->networkUpdateRouteParcel(TEST_NETID1, parcel);
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+ expectNetworkRouteExistsWithMtu(td.ipVersion, sTun.name(), td.testDest, newNextHop,
+ std::to_string(parcel.mtu), sTun.name().c_str());
+ expectNetworkRouteDoesNotExistWithMtu(td.ipVersion, sTun.name(), td.testDest, oldNextHop,
+ std::to_string(parcel.mtu), sTun.name().c_str());
+
+ status = mNetd->networkRemoveRouteParcel(TEST_NETID1, parcel);
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+ expectNetworkRouteDoesNotExistWithMtu(td.ipVersion, sTun.name(), td.testDest, newNextHop,
+ std::to_string(parcel.mtu), sTun.name().c_str());
+ }
+
// Remove test physical network
EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}
@@ -2086,7 +2173,7 @@
TEST_F(NetdBinderTest, NetworkPermissionDefault) {
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -2627,7 +2714,7 @@
}
bool compareListInterface(const std::vector<std::string>& interfaceList) {
- const auto& res = InterfaceController::getIfaceNames();
+ const auto& res = getIfaceNames();
EXPECT_TRUE(isOk(res));
std::vector<std::string> resIfList;
@@ -2740,7 +2827,7 @@
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -2761,7 +2848,7 @@
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -2801,7 +2888,7 @@
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -2821,7 +2908,7 @@
TEST_F(NetdBinderTest, InterfaceSetEnableIPv6) {
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -2844,7 +2931,7 @@
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -2992,35 +3079,6 @@
updateAndCheckTcpBuffer(mNetd, rmemValue, wmemValue);
}
-namespace {
-
-void checkUidsInPermissionMap(std::vector<int32_t>& uids, bool exist) {
- android::bpf::BpfMap<uint32_t, uint8_t> uidPermissionMap(UID_PERMISSION_MAP_PATH);
- for (int32_t uid : uids) {
- android::base::Result<uint8_t> permission = uidPermissionMap.readValue(uid);
- if (exist) {
- ASSERT_RESULT_OK(permission);
- EXPECT_EQ(INetd::PERMISSION_NONE, permission.value());
- } else {
- ASSERT_FALSE(permission.ok());
- EXPECT_EQ(ENOENT, permission.error().code());
- }
- }
-}
-
-} // namespace
-
-TEST_F(NetdBinderTest, TestInternetPermission) {
- std::vector<int32_t> appUids = {TEST_UID1, TEST_UID2};
-
- mNetd->trafficSetNetPermForUids(INetd::PERMISSION_INTERNET, appUids);
- checkUidsInPermissionMap(appUids, false);
- mNetd->trafficSetNetPermForUids(INetd::PERMISSION_NONE, appUids);
- checkUidsInPermissionMap(appUids, true);
- mNetd->trafficSetNetPermForUids(INetd::PERMISSION_UNINSTALLED, appUids);
- checkUidsInPermissionMap(appUids, false);
-}
-
TEST_F(NetdBinderTest, UnsolEvents) {
auto testUnsolService = android::net::TestUnsolService::start();
std::string oldTunName = sTun.name();
@@ -3132,7 +3190,7 @@
// Add test physical network
const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
@@ -3215,18 +3273,26 @@
}
void NetdBinderTest::createVpnNetworkWithUid(bool secure, uid_t uid, int vpnNetId,
- int fallthroughNetId) {
+ int fallthroughNetId, int nonDefaultNetId) {
// Re-init sTun* to ensure route rule exists.
sTun.destroy();
sTun.init();
sTun2.destroy();
sTun2.init();
+ sTun3.destroy();
+ sTun3.init();
// Create physical network with fallthroughNetId but not set it as default network
auto config = makeNativeNetworkConfig(fallthroughNetId, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(fallthroughNetId, sTun.name()).isOk());
+ // Create a physical network to test that local network access does not include the non-default
+ // networks.
+ auto nonDefaultNetworkConfig = makeNativeNetworkConfig(
+ nonDefaultNetId, NativeNetworkType::PHYSICAL, INetd::PERMISSION_NONE, false, false);
+ EXPECT_TRUE(mNetd->networkCreate(nonDefaultNetworkConfig).isOk());
+ EXPECT_TRUE(mNetd->networkAddInterface(nonDefaultNetId, sTun3.name()).isOk());
// Create VPN with vpnNetId
config.netId = vpnNetId;
@@ -3250,7 +3316,7 @@
ASSERT_TRUE(mNetd->networkGetDefault(&mStoredDefaultNetwork).isOk());
const auto& config =
- makeNativeNetworkConfig(netId, NativeNetworkType::PHYSICAL, permission, false);
+ makeNativeNetworkConfig(netId, NativeNetworkType::PHYSICAL, permission, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(netId, interface).isOk());
EXPECT_TRUE(mNetd->networkSetDefault(netId).isOk());
@@ -3259,7 +3325,7 @@
void NetdBinderTest::createPhysicalNetwork(int netId, const std::string& interface,
int permission) {
const auto& config =
- makeNativeNetworkConfig(netId, NativeNetworkType::PHYSICAL, permission, false);
+ makeNativeNetworkConfig(netId, NativeNetworkType::PHYSICAL, permission, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(netId, interface).isOk());
}
@@ -3281,7 +3347,7 @@
createDefaultAndOtherPhysicalNetwork(systemDefaultNetId, otherNetId);
auto config = makeNativeNetworkConfig(vpnNetId, NativeNetworkType::VIRTUAL,
- INetd::PERMISSION_NONE, secure);
+ INetd::PERMISSION_NONE, secure, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(vpnNetId, sTun3.name()).isOk());
EXPECT_TRUE(mNetd->networkAddRoute(vpnNetId, sTun3.name(), "2001:db8::/32", "").isOk());
@@ -3407,7 +3473,8 @@
void expectVpnFallthroughWorks(android::net::INetd* netdService, bool bypassable, uid_t uid,
const TunInterface& fallthroughNetwork,
- const TunInterface& vpnNetwork, int vpnNetId = TEST_NETID2,
+ const TunInterface& vpnNetwork,
+ const TunInterface& nonDefaultNetwork, int vpnNetId = TEST_NETID2,
int fallthroughNetId = TEST_NETID1) {
// Set default network to NETID_UNSET
EXPECT_TRUE(netdService->networkSetDefault(NETID_UNSET).isOk());
@@ -3442,6 +3509,11 @@
// Check if fallthrough rule exists
expectVpnFallthroughRuleExists(fallthroughNetwork.name(), vpnNetId);
+ // Check if local exclusion rule exists for default network
+ expectVpnLocalExclusionRuleExists(fallthroughNetwork.name(), true);
+ // No local exclusion rule for non-default network
+ expectVpnLocalExclusionRuleExists(nonDefaultNetwork.name(), false);
+
// Expect fallthrough to default network
// The fwmark differs depending on whether the VPN is bypassable or not.
EXPECT_TRUE(sendIPv6PacketFromUid(uid, outsideVpnAddr, &fwmark, fallthroughFd));
@@ -3488,14 +3560,14 @@
createVpnNetworkWithUid(true /* secure */, TEST_UID1);
// Get current default network NetId
ASSERT_TRUE(mNetd->networkGetDefault(&mStoredDefaultNetwork).isOk());
- expectVpnFallthroughWorks(mNetd.get(), false /* bypassable */, TEST_UID1, sTun, sTun2);
+ expectVpnFallthroughWorks(mNetd.get(), false /* bypassable */, TEST_UID1, sTun, sTun2, sTun3);
}
TEST_F(NetdBinderTest, BypassableVPNFallthrough) {
createVpnNetworkWithUid(false /* secure */, TEST_UID1);
// Get current default network NetId
ASSERT_TRUE(mNetd->networkGetDefault(&mStoredDefaultNetwork).isOk());
- expectVpnFallthroughWorks(mNetd.get(), true /* bypassable */, TEST_UID1, sTun, sTun2);
+ expectVpnFallthroughWorks(mNetd.get(), true /* bypassable */, TEST_UID1, sTun, sTun2, sTun3);
}
namespace {
@@ -3527,7 +3599,7 @@
// Add test physical network 1 and set as default network.
auto config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "2001:db8::/32", "").isOk());
@@ -3557,307 +3629,6 @@
EXPECT_TRUE(mNetd->networkDestroy(TEST_NETID1).isOk());
}
-namespace {
-
-TetherOffloadRuleParcel makeTetherOffloadRule(int inputInterfaceIndex, int outputInterfaceIndex,
- const std::vector<uint8_t>& destination,
- int prefixLength,
- const std::vector<uint8_t>& srcL2Address,
- const std::vector<uint8_t>& dstL2Address, int pmtu) {
- android::net::TetherOffloadRuleParcel parcel;
- parcel.inputInterfaceIndex = inputInterfaceIndex;
- parcel.outputInterfaceIndex = outputInterfaceIndex;
- parcel.destination = destination;
- parcel.prefixLength = prefixLength;
- parcel.srcL2Address = srcL2Address;
- parcel.dstL2Address = dstL2Address;
- parcel.pmtu = pmtu;
- return parcel;
-}
-
-} // namespace
-
-// TODO: probably remove the test because TetherOffload* binder calls are deprecated.
-TEST_F(NetdBinderTest, DISABLED_TetherOffloadRule) {
- // TODO: Perhaps verify invalid interface index once the netd handle the error in methods.
- constexpr uint32_t kIfaceInt = 101;
- constexpr uint32_t kIfaceExt = 102;
- constexpr uint32_t kIfaceNonExistent = 103;
-
- const std::vector<uint8_t> kAddr6 = {0x20, 0x01, 0x0d, 0xb8, 0xca, 0xfe, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88};
- const std::vector<uint8_t> kSrcMac = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0a};
- const std::vector<uint8_t> kDstMac = {0x00, 0x00, 0x00, 0x00, 0x00, 0x0b};
-
- const std::vector<uint8_t> kInvalidAddr4 = {0xac, 0x0a, 0x0d, 0xb8}; // should be IPv6 address
- const std::vector<uint8_t> kInvalidMac = {0xde, 0xad, 0xbe, 0xef}; // should be 6-byte length
-
- // Invalid IP address, add rule
- TetherOffloadRuleParcel rule = makeTetherOffloadRule(
- kIfaceExt, kIfaceInt, kInvalidAddr4 /*bad*/, 128, kSrcMac, kDstMac, 1500);
- auto status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EAFNOSUPPORT, status.serviceSpecificErrorCode());
-
- // Invalid source L2 address, add rule
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kInvalidMac /*bad*/, kDstMac,
- 1500);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(ENXIO, status.serviceSpecificErrorCode());
-
- // Invalid destination L2 address, add rule
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kInvalidMac /*bad*/,
- 1500);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(ENXIO, status.serviceSpecificErrorCode());
-
- // Invalid IP address, remove rule
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kInvalidAddr4 /*bad*/, 128, kSrcMac, kDstMac,
- 1500);
- status = mNetd->tetherOffloadRuleRemove(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EAFNOSUPPORT, status.serviceSpecificErrorCode());
-
- // Invalid prefix length
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 64 /*bad*/, kSrcMac, kDstMac, 1500);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
- status = mNetd->tetherOffloadRuleRemove(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
-
- // Invalid interface index
- rule = makeTetherOffloadRule(kIfaceExt, 0, kAddr6, 128, kSrcMac, kDstMac, 1500);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(ENODEV, status.serviceSpecificErrorCode());
- rule = makeTetherOffloadRule(0, kIfaceInt, kAddr6, 64, kSrcMac, kDstMac, 1500);
- status = mNetd->tetherOffloadRuleRemove(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(ENODEV, status.serviceSpecificErrorCode());
-
- // Invalid pmtu (too low)
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 1279);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
-
- // Invalid pmtu (too high)
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 65536);
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_FALSE(status.isOk());
- EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
-
- // Remove non existent rule. Expect that silently return success if the rule did not exist.
- rule = makeTetherOffloadRule(kIfaceNonExistent, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 1500);
- EXPECT_TRUE(mNetd->tetherOffloadRuleRemove(rule).isOk());
-
- // Add and remove rule normally.
- rule = makeTetherOffloadRule(kIfaceExt, kIfaceInt, kAddr6, 128, kSrcMac, kDstMac, 1500);
- EXPECT_TRUE(mNetd->tetherOffloadRuleAdd(rule).isOk());
- EXPECT_TRUE(mNetd->tetherOffloadRuleRemove(rule).isOk());
-}
-
-static bool expectPacket(int fd, uint8_t* ipPacket, ssize_t ipLen) {
- constexpr bool kDebug = false;
-
- uint8_t buf[ETHER_HDR_LEN + 1500];
-
- // Wait a bit to ensure that the packet we're interested in has arrived.
- // TODO: speed this up.
- usleep(100 * 1000);
-
- ssize_t bytesRead;
- ssize_t expectedLen = ipLen + ETHER_HDR_LEN;
- while ((bytesRead = read(fd, buf, sizeof(buf))) >= 0) {
- if (kDebug) {
- std::cerr << fmt::format(
- "Expected: {:02x}\n Actual: {:02x}\n",
- fmt::join(ipPacket, ipPacket + ipLen, " "),
- fmt::join(buf + ETHER_HDR_LEN, buf + ETHER_HDR_LEN + ipLen, " "));
- }
-
- if (bytesRead != expectedLen) {
- continue;
- }
-
- if (!memcmp(ipPacket, buf + ETHER_HDR_LEN, ipLen)) {
- return true;
- }
- }
-
- return false;
-}
-
-static bool tcQdiscExists(const std::string& interface) {
- std::string command = StringPrintf("tc qdisc show dev %s", interface.c_str());
- std::vector<std::string> lines = runCommand(command);
- for (const auto& line : lines) {
- if (StartsWith(line, "qdisc clsact ffff:")) return true;
- }
- return false;
-}
-
-static bool tcFilterExists(const std::string& interface) {
- std::string command = StringPrintf("tc filter show dev %s ingress", interface.c_str());
- std::vector<std::string> lines = runCommand(command);
- const std::basic_regex regex("^filter .* bpf .* prog_offload_schedcls_tether_.*$");
- for (const auto& line : lines) {
- if (std::regex_match(Trim(line), regex)) return true;
- }
- return false;
-}
-
-// TODO: probably remove the test because TetherOffload* binder calls are deprecated.
-TEST_F(NetdBinderTest, DISABLED_TetherOffloadForwarding) {
- SKIP_IF_EXTENDED_BPF_NOT_SUPPORTED;
-
- constexpr const char* kDownstreamPrefix = "2001:db8:2::/64";
-
- // 1500-byte packet.
- constexpr unsigned short kPayloadLen = 1500 - sizeof(ipv6hdr);
- struct packet {
- ipv6hdr hdr;
- char data[kPayloadLen];
- } __attribute__((packed)) pkt = {
- .hdr =
- {
- .version = 6,
- .payload_len = htons(kPayloadLen),
- .nexthdr = 59, // No next header.
- .hop_limit = 64,
- .saddr = {{{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}}},
- .daddr = {{{0x20, 0x01, 0x0d, 0xb8, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x0f, 0x00, 0xca, 0xfe}}},
- },
- };
- ASSERT_EQ(1500U, sizeof(pkt));
-
- // Use one of the test's tun interfaces as upstream.
- // It must be part of a network or it will not have the clsact attached.
- const auto& config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
- EXPECT_TRUE(mNetd->networkCreate(config).isOk());
- EXPECT_TRUE(mNetd->networkAddInterface(TEST_NETID1, sTun.name()).isOk());
- int fd1 = sTun.getFdForTesting();
- EXPECT_TRUE(tcQdiscExists(sTun.name()));
-
- // Create our own tap as a downstream.
- TunInterface tap;
- ASSERT_EQ(0, tap.init(true /* isTap */));
- ASSERT_LE(tap.name().size(), static_cast<size_t>(IFNAMSIZ));
- int fd2 = tap.getFdForTesting();
-
- // Set it to nonblocking so that expectPacket can work.
- int flags = fcntl(fd2, F_GETFL, 0);
- fcntl(fd2, F_SETFL, flags | O_NONBLOCK);
-
- // Downstream interface setup. Add to local network, add directly-connected route, etc.
- binder::Status status = mNetd->networkAddInterface(INetd::LOCAL_NET_ID, tap.name());
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
- status = mNetd->tetherInterfaceAdd(tap.name());
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
- expectTetherInterfaceConfigureForIPv6Router(tap.name());
- EXPECT_TRUE(tcQdiscExists(tap.name()));
-
- // Can't easily use INetd::NEXTHOP_NONE because it is a String16 constant. Use "" instead.
- status = mNetd->networkAddRoute(INetd::LOCAL_NET_ID, tap.name(), kDownstreamPrefix, "");
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-
- // Set up forwarding. All methods take intIface first and extIface second.
- status = mNetd->tetherAddForward(tap.name(), sTun.name());
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
- status = mNetd->ipfwdAddInterfaceForward(tap.name(), sTun.name());
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
- EXPECT_TRUE(tcFilterExists(sTun.name()));
-
- std::vector<uint8_t> kDummyMac = {02, 00, 00, 00, 00, 00};
- uint8_t* daddr = reinterpret_cast<uint8_t*>(&pkt.hdr.daddr);
- std::vector<uint8_t> dstAddr(daddr, daddr + sizeof(pkt.hdr.daddr));
-
- TetherOffloadRuleParcel rule = makeTetherOffloadRule(sTun.ifindex(), tap.ifindex(), dstAddr,
- 128, kDummyMac, kDummyMac, sizeof(pkt));
- status = mNetd->tetherOffloadRuleAdd(rule);
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-
- // Set data limit to one byte less than two packets.
- // If you get rid of the '- 1' then the second packet will get forwarded
- // and the EXPECT_FALSE(expectPacket(...)) a dozen lines down will fail.
- status = mNetd->tetherOffloadSetInterfaceQuota(sTun.ifindex(), sizeof(pkt) * 2 - 1);
- EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
-
- // Receive a packet on sTun.
- EXPECT_EQ((ssize_t)sizeof(pkt), write(fd1, &pkt, sizeof(pkt)));
-
- // Expect a packet identical to pkt, except with a TTL of 63.
- struct packet pkt2 = pkt;
- ASSERT_EQ(1500U, sizeof(pkt2));
- pkt2.hdr.hop_limit = pkt.hdr.hop_limit - 1;
- EXPECT_TRUE(expectPacket(fd2, (uint8_t*)&pkt2, sizeof(pkt2)));
-
- // Receive a second packet on sTun.
- EXPECT_EQ((ssize_t)sizeof(pkt), write(fd1, &pkt, sizeof(pkt)));
-
- // Should fail to forward due to quota limit.
- EXPECT_FALSE(expectPacket(fd2, (uint8_t*)&pkt2, sizeof(pkt2)));
-
- // Clean up.
- EXPECT_TRUE(mNetd->tetherOffloadRuleRemove(rule).isOk());
-
- TetherStatsParcel tetherStats;
- EXPECT_TRUE(mNetd->tetherOffloadGetAndClearStats(sTun.ifindex(), &tetherStats).isOk());
- EXPECT_EQ("", tetherStats.iface);
- EXPECT_EQ(static_cast<int64_t>(sizeof(pkt)), tetherStats.rxBytes);
- EXPECT_EQ(1, tetherStats.rxPackets);
- EXPECT_EQ(0, tetherStats.txBytes);
- EXPECT_EQ(0, tetherStats.txPackets);
- EXPECT_EQ(sTun.ifindex(), tetherStats.ifIndex);
-
- EXPECT_TRUE(mNetd->ipfwdRemoveInterfaceForward(tap.name(), sTun.name()).isOk());
- EXPECT_TRUE(mNetd->tetherRemoveForward(tap.name(), sTun.name()).isOk());
- EXPECT_TRUE(mNetd->networkRemoveRoute(INetd::LOCAL_NET_ID, tap.name(), kDownstreamPrefix, "")
- .isOk());
- EXPECT_TRUE(mNetd->tetherInterfaceRemove(tap.name()).isOk());
- EXPECT_TRUE(mNetd->networkRemoveInterface(INetd::LOCAL_NET_ID, tap.name()).isOk());
- EXPECT_TRUE(mNetd->networkRemoveInterface(TEST_NETID1, sTun.name()).isOk());
-}
-
-namespace {
-
-std::vector<std::string> dumpService(const sp<IBinder>& binder) {
- unique_fd localFd, remoteFd;
- bool success = Pipe(&localFd, &remoteFd);
- EXPECT_TRUE(success) << "Failed to open pipe for dumping: " << strerror(errno);
- if (!success) return {};
-
- // dump() blocks until another thread has consumed all its output.
- std::thread dumpThread = std::thread([binder, remoteFd{std::move(remoteFd)}]() {
- android::status_t ret = binder->dump(remoteFd, {});
- EXPECT_EQ(android::OK, ret) << "Error dumping service: " << android::statusToString(ret);
- });
-
- std::string dumpContent;
-
- EXPECT_TRUE(ReadFdToString(localFd.get(), &dumpContent))
- << "Error during dump: " << strerror(errno);
- dumpThread.join();
-
- std::stringstream dumpStream(std::move(dumpContent));
- std::vector<std::string> lines;
- std::string line;
- while (std::getline(dumpStream, line)) {
- lines.push_back(line);
- }
-
- return lines;
-}
-
-} // namespace
-
TEST_F(NetdBinderTest, TestServiceDump) {
sp<IBinder> binder = INetd::asBinder(mNetd);
ASSERT_NE(nullptr, binder);
@@ -3873,17 +3644,17 @@
// Send some IPCs and for each one add an element to testData telling us what to expect.
const auto& config = makeNativeNetworkConfig(TEST_DUMP_NETID, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
testData.push_back(
{"networkCreate(NativeNetworkConfig{netId: 65123, networkType: PHYSICAL, "
- "permission: 0, secure: false, vpnType: PLATFORM})",
+ "permission: 0, secure: false, vpnType: PLATFORM, excludeLocalRoutes: false})",
"networkCreate.*65123"});
EXPECT_EQ(EEXIST, mNetd->networkCreate(config).serviceSpecificErrorCode());
testData.push_back(
{"networkCreate(NativeNetworkConfig{netId: 65123, networkType: PHYSICAL, "
- "permission: 0, secure: false, vpnType: PLATFORM}) "
+ "permission: 0, secure: false, vpnType: PLATFORM, excludeLocalRoutes: false}) "
"-> ServiceSpecificException(17, \"File exists\")",
"networkCreate.*65123.*17"});
@@ -3908,7 +3679,9 @@
testData.push_back({"networkDestroy(65123)", "networkDestroy.*65123"});
// Send the service dump request to netd.
- std::vector<std::string> lines = dumpService(binder);
+ std::vector<std::string> lines = {};
+ android::status_t ret = dumpService(binder, {}, lines);
+ ASSERT_EQ(android::OK, ret) << "Error dumping service: " << android::statusToString(ret);
// Basic regexp to match dump output lines. Matches the beginning and end of the line, and
// puts the output of the command itself into the first match group.
@@ -3937,40 +3710,6 @@
}
}
-TEST_F(NetdBinderTest, DeprecatedTetherOffloadRuleAdd) {
- TetherOffloadRuleParcel emptyRule;
- auto status = mNetd->tetherOffloadRuleAdd(emptyRule);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
-}
-
-TEST_F(NetdBinderTest, DeprecatedTetherOffloadRuleRemove) {
- TetherOffloadRuleParcel emptyRule;
- auto status = mNetd->tetherOffloadRuleRemove(emptyRule);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
-}
-
-TEST_F(NetdBinderTest, DeprecatedTetherOffloadGetStats) {
- std::vector<TetherStatsParcel> tetherStatsList;
- auto status = mNetd->tetherOffloadGetStats(&tetherStatsList);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
-}
-
-TEST_F(NetdBinderTest, DeprecatedTetherOffloadSetInterfaceQuota) {
- auto status = mNetd->tetherOffloadSetInterfaceQuota(0 /* ifIndex */, 0 /* quotaBytes */);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
-}
-
-TEST_F(NetdBinderTest, DeprecatedTetherOffloadGetAndClearStats) {
- TetherStatsParcel tetherStats;
- auto status = mNetd->tetherOffloadGetAndClearStats(0 /* ifIndex */, &tetherStats);
- ASSERT_FALSE(status.isOk());
- ASSERT_EQ(status.exceptionCode(), binder::Status::EX_UNSUPPORTED_OPERATION);
-}
-
namespace {
// aliases for better reading
@@ -3979,7 +3718,7 @@
#define VPN_NETID TEST_NETID3
void verifyAppUidRules(std::vector<bool>&& expectedResults, std::vector<UidRangeParcel>& uidRanges,
- const std::string& iface, uint32_t subPriority) {
+ const std::string& iface, int32_t subPriority) {
ASSERT_EQ(expectedResults.size(), uidRanges.size());
if (iface.size()) {
std::string action = StringPrintf("lookup %s ", iface.c_str());
@@ -4017,15 +3756,17 @@
}
void verifyVpnUidRules(std::vector<bool>&& expectedResults, NativeUidRangeConfig& uidRangeConfig,
- const std::string& iface, bool secure) {
+ const std::string& iface, bool secure, bool excludeLocalRoutes) {
ASSERT_EQ(expectedResults.size(), uidRangeConfig.uidRanges.size());
std::string action = StringPrintf("lookup %s ", iface.c_str());
- uint32_t priority;
+ int32_t priority;
if (secure) {
priority = RULE_PRIORITY_SECURE_VPN;
} else {
- priority = RULE_PRIORITY_BYPASSABLE_VPN;
+ // Set to no local exclusion here to reflect the default value of local exclusion.
+ priority = excludeLocalRoutes ? RULE_PRIORITY_BYPASSABLE_VPN_LOCAL_EXCLUSION
+ : RULE_PRIORITY_BYPASSABLE_VPN_NO_LOCAL_EXCLUSION;
}
for (unsigned long i = 0; i < uidRangeConfig.uidRanges.size(); i++) {
EXPECT_EQ(expectedResults[i], ipRuleExistsForRange(priority + uidRangeConfig.subPriority,
@@ -4039,8 +3780,8 @@
}
}
-constexpr int SUB_PRIORITY_1 = UidRanges::DEFAULT_SUB_PRIORITY + 1;
-constexpr int SUB_PRIORITY_2 = UidRanges::DEFAULT_SUB_PRIORITY + 2;
+constexpr int SUB_PRIORITY_1 = UidRanges::SUB_PRIORITY_HIGHEST + 1;
+constexpr int SUB_PRIORITY_2 = UidRanges::SUB_PRIORITY_HIGHEST + 2;
constexpr int IMPLICITLY_SELECT = 0;
constexpr int EXPLICITLY_SELECT = 1;
@@ -4102,7 +3843,7 @@
// Verify whether API reject overlapped UID ranges
TEST_F(NetdBinderTest, PerAppDefaultNetwork_OverlappedUidRanges) {
const auto& config = makeNativeNetworkConfig(APP_DEFAULT_NETID, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(APP_DEFAULT_NETID, sTun.name()).isOk());
@@ -4147,7 +3888,7 @@
// Verify whether IP rules for app default network are correctly configured.
TEST_F(NetdBinderTest, PerAppDefaultNetwork_VerifyIpRules) {
const auto& config = makeNativeNetworkConfig(APP_DEFAULT_NETID, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(APP_DEFAULT_NETID, sTun.name()).isOk());
@@ -4156,23 +3897,23 @@
EXPECT_TRUE(mNetd->networkAddUidRanges(APP_DEFAULT_NETID, uidRanges).isOk());
verifyAppUidRules({true, true} /*expectedResults*/, uidRanges, sTun.name(),
- UidRanges::DEFAULT_SUB_PRIORITY);
+ UidRanges::SUB_PRIORITY_HIGHEST);
EXPECT_TRUE(mNetd->networkRemoveUidRanges(APP_DEFAULT_NETID, {uidRanges.at(0)}).isOk());
verifyAppUidRules({false, true} /*expectedResults*/, uidRanges, sTun.name(),
- UidRanges::DEFAULT_SUB_PRIORITY);
+ UidRanges::SUB_PRIORITY_HIGHEST);
EXPECT_TRUE(mNetd->networkRemoveUidRanges(APP_DEFAULT_NETID, {uidRanges.at(1)}).isOk());
verifyAppUidRules({false, false} /*expectedResults*/, uidRanges, sTun.name(),
- UidRanges::DEFAULT_SUB_PRIORITY);
+ UidRanges::SUB_PRIORITY_HIGHEST);
EXPECT_TRUE(mNetd->networkAddUidRanges(INetd::UNREACHABLE_NET_ID, uidRanges).isOk());
verifyAppUidRules({true, true} /*expectedResults*/, uidRanges, "",
- UidRanges::DEFAULT_SUB_PRIORITY);
+ UidRanges::SUB_PRIORITY_HIGHEST);
EXPECT_TRUE(mNetd->networkRemoveUidRanges(INetd::UNREACHABLE_NET_ID, {uidRanges.at(0)}).isOk());
verifyAppUidRules({false, true} /*expectedResults*/, uidRanges, "",
- UidRanges::DEFAULT_SUB_PRIORITY);
+ UidRanges::SUB_PRIORITY_HIGHEST);
EXPECT_TRUE(mNetd->networkRemoveUidRanges(INetd::UNREACHABLE_NET_ID, {uidRanges.at(1)}).isOk());
verifyAppUidRules({false, false} /*expectedResults*/, uidRanges, "",
- UidRanges::DEFAULT_SUB_PRIORITY);
+ UidRanges::SUB_PRIORITY_HIGHEST);
}
// Verify whether packets go through the right network with and without per-app default network.
@@ -4475,7 +4216,7 @@
TEST_F(NetdBinderTest, NetworkCreate) {
auto config = makeNativeNetworkConfig(TEST_NETID1, NativeNetworkType::PHYSICAL,
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkDestroy(config.netId).isOk());
@@ -4486,7 +4227,7 @@
// invalid network type
auto wrongConfig = makeNativeNetworkConfig(TEST_NETID2, static_cast<NativeNetworkType>(-1),
- INetd::PERMISSION_NONE, false);
+ INetd::PERMISSION_NONE, false, false);
EXPECT_EQ(EINVAL, mNetd->networkCreate(wrongConfig).serviceSpecificErrorCode());
// invalid VPN type
@@ -4499,16 +4240,16 @@
TEST_F(NetdBinderTest, UidRangeSubPriority_ValidateInputs) {
createVpnAndOtherPhysicalNetwork(SYSTEM_DEFAULT_NETID, APP_DEFAULT_NETID, VPN_NETID,
/*isSecureVPN=*/true);
- // Invalid priority -1 on a physical network.
+ // Invalid priority -10 on a physical network.
NativeUidRangeConfig uidRangeConfig =
makeNativeUidRangeConfig(APP_DEFAULT_NETID, {makeUidRangeParcel(BASE_UID, BASE_UID)},
- UidRanges::DEFAULT_SUB_PRIORITY - 1);
+ UidRanges::SUB_PRIORITY_HIGHEST - 10);
binder::Status status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
EXPECT_FALSE(status.isOk());
EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
// Invalid priority 1000 on a physical network.
- uidRangeConfig.subPriority = UidRanges::LOWEST_SUB_PRIORITY + 1;
+ uidRangeConfig.subPriority = UidRanges::SUB_PRIORITY_NO_DEFAULT + 1;
status = mNetd->networkAddUidRangesParcel(uidRangeConfig);
EXPECT_FALSE(status.isOk());
EXPECT_EQ(EINVAL, status.serviceSpecificErrorCode());
@@ -4587,34 +4328,54 @@
// Create 2 VPNs, using sTun and sTun2.
auto config = makeNativeNetworkConfig(VPN_NETID, NativeNetworkType::VIRTUAL,
- INetd::PERMISSION_NONE, isSecureVPN);
+ INetd::PERMISSION_NONE, isSecureVPN, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(VPN_NETID, sTun.name()).isOk());
config = makeNativeNetworkConfig(VPN_NETID2, NativeNetworkType::VIRTUAL, INetd::PERMISSION_NONE,
- isSecureVPN);
+ isSecureVPN, false);
EXPECT_TRUE(mNetd->networkCreate(config).isOk());
EXPECT_TRUE(mNetd->networkAddInterface(VPN_NETID2, sTun2.name()).isOk());
// Assign uid ranges to different VPNs. Check if rules match.
NativeUidRangeConfig uidRangeConfig1 = makeNativeUidRangeConfig(
- VPN_NETID, {makeUidRangeParcel(BASE_UID, BASE_UID)}, UidRanges::DEFAULT_SUB_PRIORITY);
+ VPN_NETID, {makeUidRangeParcel(BASE_UID, BASE_UID)}, UidRanges::SUB_PRIORITY_HIGHEST);
EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
- verifyVpnUidRules({true}, uidRangeConfig1, sTun.name(), isSecureVPN);
+ verifyVpnUidRules({true}, uidRangeConfig1, sTun.name(), isSecureVPN, false);
NativeUidRangeConfig uidRangeConfig2 =
makeNativeUidRangeConfig(VPN_NETID2, {makeUidRangeParcel(BASE_UID + 1, BASE_UID + 1)},
- UidRanges::DEFAULT_SUB_PRIORITY);
+ UidRanges::SUB_PRIORITY_HIGHEST);
EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());
- verifyVpnUidRules({true}, uidRangeConfig2, sTun2.name(), isSecureVPN);
+ verifyVpnUidRules({true}, uidRangeConfig2, sTun2.name(), isSecureVPN, false);
// Remove uid configs one-by-one. Check if rules match.
EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig1).isOk());
- verifyVpnUidRules({false}, uidRangeConfig1, sTun.name(), isSecureVPN);
- verifyVpnUidRules({true}, uidRangeConfig2, sTun2.name(), isSecureVPN);
+ verifyVpnUidRules({false}, uidRangeConfig1, sTun.name(), isSecureVPN, false);
+ verifyVpnUidRules({true}, uidRangeConfig2, sTun2.name(), isSecureVPN, false);
EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig2).isOk());
- verifyVpnUidRules({false}, uidRangeConfig1, sTun.name(), isSecureVPN);
- verifyVpnUidRules({false}, uidRangeConfig2, sTun2.name(), isSecureVPN);
+ verifyVpnUidRules({false}, uidRangeConfig1, sTun.name(), isSecureVPN, false);
+ verifyVpnUidRules({false}, uidRangeConfig2, sTun2.name(), isSecureVPN, false);
+}
+
+// Verify VPN ip rule on bypassable/secureVPN virtual network with local routes excluded
+TEST_P(VpnParameterizedTest, VerifyVpnIpRules_excludeLocalRoutes) {
+ const bool isSecureVPN = GetParam();
+ // Create VPN with local route excluded
+ auto config = makeNativeNetworkConfig(VPN_NETID, NativeNetworkType::VIRTUAL,
+ INetd::PERMISSION_NONE, isSecureVPN, true);
+ EXPECT_TRUE(mNetd->networkCreate(config).isOk());
+ EXPECT_TRUE(mNetd->networkAddInterface(VPN_NETID, sTun.name()).isOk());
+
+ // Assign uid ranges to VPN. Check if rules match.
+ NativeUidRangeConfig uidRangeConfig1 = makeNativeUidRangeConfig(
+ VPN_NETID, {makeUidRangeParcel(BASE_UID, BASE_UID)}, UidRanges::SUB_PRIORITY_HIGHEST);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
+ verifyVpnUidRules({true}, uidRangeConfig1, sTun.name(), isSecureVPN, true);
+
+ // Remove uid configs. Check if rules match.
+ EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig1).isOk());
+ verifyVpnUidRules({false}, uidRangeConfig1, sTun.name(), isSecureVPN, true);
}
// Verify if packets go through the right network when subsidiary priority and VPN works together.
@@ -4654,38 +4415,34 @@
constexpr int APP_DEFAULT_1_NETID = TEST_NETID2;
constexpr int APP_DEFAULT_2_NETID = TEST_NETID4;
+ static const struct TestData {
+ uint32_t subPriority;
+ std::vector<UidRangeParcel> uidRanges;
+ unsigned int netId;
+ } kTestData[] = {
+ {UidRanges::SUB_PRIORITY_HIGHEST, {makeUidRangeParcel(TEST_UID1)}, VPN_NETID},
+ {SUB_PRIORITY_1,
+ {makeUidRangeParcel(TEST_UID1), makeUidRangeParcel(TEST_UID2)},
+ APP_DEFAULT_1_NETID},
+ {SUB_PRIORITY_1, {makeUidRangeParcel(TEST_UID3)}, APP_DEFAULT_2_NETID},
+ {SUB_PRIORITY_1, {makeUidRangeParcel(TEST_UID5)}, INetd::UNREACHABLE_NET_ID},
+ {SUB_PRIORITY_2, {makeUidRangeParcel(TEST_UID3)}, APP_DEFAULT_1_NETID},
+ {SUB_PRIORITY_2,
+ {makeUidRangeParcel(TEST_UID4), makeUidRangeParcel(TEST_UID5)},
+ APP_DEFAULT_2_NETID},
+ };
+
// Creates 4 networks.
createVpnAndOtherPhysicalNetwork(SYSTEM_DEFAULT_NETID, APP_DEFAULT_1_NETID, VPN_NETID,
/*isSecureVPN=*/false);
createPhysicalNetwork(APP_DEFAULT_2_NETID, sTun4.name());
EXPECT_TRUE(mNetd->networkAddRoute(APP_DEFAULT_2_NETID, sTun4.name(), "::/0", "").isOk());
- // Adds VPN setting.
- NativeUidRangeConfig uidRangeConfigVpn = makeNativeUidRangeConfig(
- VPN_NETID, {makeUidRangeParcel(TEST_UID1, TEST_UID1)}, UidRanges::DEFAULT_SUB_PRIORITY);
- EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfigVpn).isOk());
-
- // Adds uidRangeConfig1 setting.
- NativeUidRangeConfig uidRangeConfig1 = makeNativeUidRangeConfig(
- APP_DEFAULT_1_NETID,
- {makeUidRangeParcel(TEST_UID1, TEST_UID1), makeUidRangeParcel(TEST_UID2, TEST_UID2)},
- SUB_PRIORITY_1);
- EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
- uidRangeConfig1.netId = APP_DEFAULT_2_NETID;
- uidRangeConfig1.uidRanges = {makeUidRangeParcel(TEST_UID3, TEST_UID3)};
- EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
- uidRangeConfig1.netId = INetd::UNREACHABLE_NET_ID;
- uidRangeConfig1.uidRanges = {makeUidRangeParcel(TEST_UID5, TEST_UID5)};
- EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig1).isOk());
-
- // Adds uidRangeConfig2 setting.
- NativeUidRangeConfig uidRangeConfig2 = makeNativeUidRangeConfig(
- APP_DEFAULT_1_NETID, {makeUidRangeParcel(TEST_UID3, TEST_UID3)}, SUB_PRIORITY_2);
- EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());
- uidRangeConfig2.netId = APP_DEFAULT_2_NETID;
- uidRangeConfig2.uidRanges = {makeUidRangeParcel(TEST_UID4, TEST_UID4),
- makeUidRangeParcel(TEST_UID5, TEST_UID5)};
- EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig2).isOk());
+ for (const auto& td : kTestData) {
+ NativeUidRangeConfig uidRangeConfig =
+ makeNativeUidRangeConfig(td.netId, td.uidRanges, td.subPriority);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(uidRangeConfig).isOk());
+ }
int systemDefaultFd = sTun.getFdForTesting();
int appDefault_1_Fd = sTun2.getFdForTesting();
@@ -4700,5 +4457,252 @@
expectPacketSentOnNetId(TEST_UID6, SYSTEM_DEFAULT_NETID, systemDefaultFd, IMPLICITLY_SELECT);
// Remove test rules from the unreachable network.
- EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig1).isOk());
-}
\ No newline at end of file
+ for (const auto& td : kTestData) {
+ if (td.netId == INetd::UNREACHABLE_NET_ID) {
+ NativeUidRangeConfig uidRangeConfig =
+ makeNativeUidRangeConfig(td.netId, td.uidRanges, td.subPriority);
+ EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(uidRangeConfig).isOk());
+ }
+ }
+}
+
+class PerAppNetworkPermissionsTest : public NetdBinderTest {
+ public:
+ int bindSocketToNetwork(int sock, int netId, bool explicitlySelected) {
+ ScopedUidChange uidChange(AID_ROOT);
+ Fwmark fwmark;
+ fwmark.explicitlySelected = explicitlySelected;
+ fwmark.netId = netId;
+ return setsockopt(sock, SOL_SOCKET, SO_MARK, &(fwmark.intValue), sizeof(fwmark.intValue));
+ }
+
+ void changeNetworkPermissionForUid(int netId, int uid, bool add) {
+ auto nativeUidRangeConfig = makeNativeUidRangeConfig(netId, {makeUidRangeParcel(uid, uid)},
+ UidRanges::SUB_PRIORITY_NO_DEFAULT);
+ ScopedUidChange rootUid(AID_ROOT);
+ if (add) {
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(nativeUidRangeConfig).isOk());
+ } else {
+ EXPECT_TRUE(mNetd->networkRemoveUidRangesParcel(nativeUidRangeConfig).isOk());
+ }
+ }
+
+ protected:
+ static inline const sockaddr_in6 TEST_SOCKADDR_IN6 = {
+ .sin6_family = AF_INET6,
+ .sin6_port = 42,
+ .sin6_addr = V6_ADDR,
+ };
+ std::array<char, 4096> mTestBuf;
+};
+
+TEST_F(PerAppNetworkPermissionsTest, HasExplicitAccess) {
+ // TEST_NETID1 -> restricted network
+ createPhysicalNetwork(TEST_NETID1, sTun.name(), INetd::PERMISSION_SYSTEM);
+ EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
+
+ // Change uid to uid without PERMISSION_SYSTEM
+ ScopedUidChange testUid(TEST_UID1);
+ unique_fd sock(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+ EXPECT_EQ(bindSocketToNetwork(sock, TEST_NETID1, true /*explicitlySelected*/), 0);
+
+ // Test without permissions should fail
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), -1);
+
+ // Test access with permission succeeds and packet is routed correctly
+ changeNetworkPermissionForUid(TEST_NETID1, TEST_UID1, true /*add*/);
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), 0);
+ EXPECT_EQ(send(sock, "foo", sizeof("foo"), 0), (int)sizeof("foo"));
+ EXPECT_GT(read(sTun.getFdForTesting(), mTestBuf.data(), mTestBuf.size()), 0);
+
+ // Test removing permissions.
+ // Note: Send will still succeed as the destination is cached in
+ // sock.sk_dest_cache. Try another connect instead.
+ changeNetworkPermissionForUid(TEST_NETID1, TEST_UID1, false /*add*/);
+ EXPECT_EQ(-1, connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)));
+}
+
+TEST_F(PerAppNetworkPermissionsTest, HasImplicitAccess) {
+ // TEST_NETID1 -> restricted network
+ createPhysicalNetwork(TEST_NETID1, sTun.name(), INetd::PERMISSION_SYSTEM);
+ EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
+
+ // Change uid to uid without PERMISSION_SYSTEM
+ ScopedUidChange testUid(TEST_UID1);
+ unique_fd sock(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+ EXPECT_EQ(bindSocketToNetwork(sock, TEST_NETID1, false /*explicitlySelected*/), 0);
+
+ // Note: we cannot call connect() when implicitly selecting the network as
+ // the fwmark would get reset to the default network.
+ // Call connect which should bind socket to default network
+ EXPECT_EQ(sendto(sock, "foo", sizeof("foo"), 0, (sockaddr*)&TEST_SOCKADDR_IN6,
+ sizeof(TEST_SOCKADDR_IN6)),
+ -1);
+
+ // Test access with permission succeeds and packet is routed correctly
+ changeNetworkPermissionForUid(TEST_NETID1, TEST_UID1, true /*add*/);
+ EXPECT_EQ(sendto(sock, "foo", sizeof("foo"), 0, (sockaddr*)&TEST_SOCKADDR_IN6,
+ sizeof(TEST_SOCKADDR_IN6)),
+ (int)sizeof("foo"));
+ EXPECT_GT(read(sTun.getFdForTesting(), mTestBuf.data(), mTestBuf.size()), 0);
+}
+
+TEST_F(PerAppNetworkPermissionsTest, DoesNotAffectDefaultNetworkSelection) {
+ // TEST_NETID1 -> default network
+ // TEST_NETID2 -> restricted network
+ createPhysicalNetwork(TEST_NETID1, sTun.name(), INetd::PERMISSION_NONE);
+ createPhysicalNetwork(TEST_NETID2, sTun2.name(), INetd::PERMISSION_SYSTEM);
+ EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
+ EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID2, sTun2.name(), "::/0", "").isOk());
+ mNetd->networkSetDefault(TEST_NETID1);
+
+ changeNetworkPermissionForUid(TEST_NETID2, TEST_UID1, true /*add*/);
+
+ // Change uid to uid without PERMISSION_SYSTEM
+ ScopedUidChange testUid(TEST_UID1);
+ unique_fd sock(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+
+ // Connect should select default network
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), 0);
+ EXPECT_EQ(send(sock, "foo", sizeof("foo"), 0), (int)sizeof("foo"));
+ EXPECT_GT(read(sTun.getFdForTesting(), mTestBuf.data(), mTestBuf.size()), 0);
+}
+
+TEST_F(PerAppNetworkPermissionsTest, PermissionDoesNotAffectPerAppDefaultNetworkSelection) {
+ // TEST_NETID1 -> restricted app default network
+ // TEST_NETID2 -> restricted network
+ createPhysicalNetwork(TEST_NETID1, sTun.name(), INetd::PERMISSION_SYSTEM);
+ createPhysicalNetwork(TEST_NETID2, sTun2.name(), INetd::PERMISSION_SYSTEM);
+ EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
+ EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID2, sTun2.name(), "::/0", "").isOk());
+
+ auto nativeUidRangeConfig = makeNativeUidRangeConfig(
+ TEST_NETID1, {makeUidRangeParcel(TEST_UID1, TEST_UID1)}, 0 /*subPriority*/);
+ EXPECT_TRUE(mNetd->networkAddUidRangesParcel(nativeUidRangeConfig).isOk());
+ changeNetworkPermissionForUid(TEST_NETID2, TEST_UID1, true /*add*/);
+
+ // Change uid to uid without PERMISSION_SYSTEM
+ ScopedUidChange testUid(TEST_UID1);
+ unique_fd sock(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+
+ // Connect should select app default network
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), 0);
+ EXPECT_EQ(send(sock, "foo", sizeof("foo"), 0), (int)sizeof("foo"));
+ EXPECT_GT(read(sTun.getFdForTesting(), mTestBuf.data(), mTestBuf.size()), 0);
+}
+
+TEST_F(PerAppNetworkPermissionsTest, PermissionOnlyAffectsUid) {
+ // TEST_NETID1 -> restricted network
+ // TEST_NETID2 -> restricted network
+ createPhysicalNetwork(TEST_NETID1, sTun.name(), INetd::PERMISSION_SYSTEM);
+ createPhysicalNetwork(TEST_NETID2, sTun2.name(), INetd::PERMISSION_SYSTEM);
+ EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID1, sTun.name(), "::/0", "").isOk());
+ EXPECT_TRUE(mNetd->networkAddRoute(TEST_NETID2, sTun2.name(), "::/0", "").isOk());
+
+ // test that neither TEST_UID1, nor TEST_UID2 have access without permission
+ {
+ // TEST_UID1
+ ScopedUidChange testUid(TEST_UID1);
+ unique_fd sock(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+ // TEST_NETID1
+ EXPECT_EQ(bindSocketToNetwork(sock, TEST_NETID1, true /*explicitlySelected*/), 0);
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), -1);
+ // TEST_NETID2
+ EXPECT_EQ(bindSocketToNetwork(sock, TEST_NETID2, true /*explicitlySelected*/), 0);
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), -1);
+ }
+ {
+ // TEST_UID2
+ ScopedUidChange testUid(TEST_UID2);
+ unique_fd sock(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+ // TEST_NETID1
+ EXPECT_EQ(bindSocketToNetwork(sock, TEST_NETID1, true /*explicitlySelected*/), 0);
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), -1);
+ // TEST_NETID2
+ EXPECT_EQ(bindSocketToNetwork(sock, TEST_NETID2, true /*explicitlySelected*/), 0);
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), -1);
+ }
+
+ changeNetworkPermissionForUid(TEST_NETID1, TEST_UID1, true);
+
+ // test that TEST_UID1 has access to TEST_UID1
+ {
+ // TEST_UID1
+ ScopedUidChange testUid(TEST_UID1);
+ unique_fd sock(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+ // TEST_NETID1
+ EXPECT_EQ(bindSocketToNetwork(sock, TEST_NETID1, true /*explicitlySelected*/), 0);
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), 0);
+ // TEST_NETID2
+ EXPECT_EQ(bindSocketToNetwork(sock, TEST_NETID2, true /*explicitlySelected*/), 0);
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), -1);
+ }
+ {
+ // TEST_UID2
+ ScopedUidChange testUid(TEST_UID2);
+ unique_fd sock(socket(AF_INET6, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+ // TEST_NETID1
+ EXPECT_EQ(bindSocketToNetwork(sock, TEST_NETID1, true /*explicitlySelected*/), 0);
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), -1);
+ // TEST_NETID2
+ EXPECT_EQ(bindSocketToNetwork(sock, TEST_NETID2, true /*explicitlySelected*/), 0);
+ EXPECT_EQ(connect(sock, (sockaddr*)&TEST_SOCKADDR_IN6, sizeof(TEST_SOCKADDR_IN6)), -1);
+ }
+}
+
+class MDnsBinderTest : public ::testing::Test {
+ public:
+ MDnsBinderTest() {
+ sp<IServiceManager> sm = android::defaultServiceManager();
+ sp<IBinder> binder = sm->getService(String16("mdns"));
+ if (binder != nullptr) {
+ mMDns = android::interface_cast<IMDns>(binder);
+ }
+ }
+
+ void SetUp() override { ASSERT_NE(nullptr, mMDns.get()); }
+
+ void TearDown() override {}
+
+ protected:
+ sp<IMDns> mMDns;
+};
+
+class TestMDnsListener : public android::net::mdns::aidl::BnMDnsEventListener {
+ public:
+ Status onServiceRegistrationStatus(const RegistrationInfo& /* status */) override {
+ return Status::ok();
+ }
+ Status onServiceDiscoveryStatus(const DiscoveryInfo& /* status */) override {
+ return Status::ok();
+ }
+ Status onServiceResolutionStatus(const ResolutionInfo& /* status */) override {
+ return Status::ok();
+ }
+ Status onGettingServiceAddressStatus(const GetAddressInfo& /* status */) override {
+ return Status::ok();
+ }
+};
+
+TEST_F(MDnsBinderTest, EventListenerTest) {
+ // Register a null listener.
+ binder::Status status = mMDns->registerEventListener(nullptr);
+ EXPECT_FALSE(status.isOk());
+
+ // Unregister a null listener.
+ status = mMDns->unregisterEventListener(nullptr);
+ EXPECT_FALSE(status.isOk());
+
+ // Register the test listener.
+ android::sp<TestMDnsListener> testListener = new TestMDnsListener();
+ status = mMDns->registerEventListener(testListener);
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+
+ // Register the duplicated listener
+ status = mMDns->registerEventListener(testListener);
+ EXPECT_FALSE(status.isOk());
+
+ // Unregister the test listener
+ status = mMDns->unregisterEventListener(testListener);
+ EXPECT_TRUE(status.isOk()) << status.exceptionMessage();
+}
diff --git a/tests/bpf_base_test.cpp b/tests/bpf_base_test.cpp
index 7ab4290..e402e08 100644
--- a/tests/bpf_base_test.cpp
+++ b/tests/bpf_base_test.cpp
@@ -36,7 +36,7 @@
#include "bpf/BpfMap.h"
#include "bpf/BpfUtils.h"
-#include "netdbpf/bpf_shared.h"
+#include "bpf_shared.h"
using android::base::Result;
@@ -47,8 +47,6 @@
// it's -1, which is INVALID_UID.
constexpr uid_t TEST_UID = UID_MAX - 1;
constexpr uint32_t TEST_TAG = 42;
-constexpr int TEST_COUNTERSET = 1;
-constexpr int DEFAULT_COUNTERSET = 0;
class BpfBasicTest : public testing::Test {
protected:
@@ -127,47 +125,5 @@
FAIL() << "socket tag still exist after 50ms";
}
-TEST_F(BpfBasicTest, TestChangeCounterSet) {
- BpfMap<uint32_t, uint8_t> uidCounterSetMap(UID_COUNTERSET_MAP_PATH);
- ASSERT_LE(0, uidCounterSetMap.getMap());
- ASSERT_EQ(0, qtaguid_setCounterSet(TEST_COUNTERSET, TEST_UID));
- uid_t uid = TEST_UID;
- Result<uint8_t> counterSetResult = uidCounterSetMap.readValue(uid);
- ASSERT_RESULT_OK(counterSetResult);
- ASSERT_EQ(TEST_COUNTERSET, counterSetResult.value());
- ASSERT_EQ(0, qtaguid_setCounterSet(DEFAULT_COUNTERSET, TEST_UID));
- counterSetResult = uidCounterSetMap.readValue(uid);
- ASSERT_FALSE(counterSetResult.ok());
- ASSERT_EQ(ENOENT, counterSetResult.error().code());
-}
-
-TEST_F(BpfBasicTest, TestDeleteTagData) {
- BpfMap<StatsKey, StatsValue> statsMapA(STATS_MAP_A_PATH);
- ASSERT_LE(0, statsMapA.getMap());
- BpfMap<StatsKey, StatsValue> statsMapB(STATS_MAP_B_PATH);
- ASSERT_LE(0, statsMapB.getMap());
- BpfMap<uint32_t, StatsValue> appUidStatsMap(APP_UID_STATS_MAP_PATH);
- ASSERT_LE(0, appUidStatsMap.getMap());
-
- StatsKey key = {.uid = TEST_UID, .tag = TEST_TAG, .counterSet = TEST_COUNTERSET,
- .ifaceIndex = 1};
- StatsValue statsMapValue = {.rxPackets = 1, .rxBytes = 100};
- EXPECT_RESULT_OK(statsMapB.writeValue(key, statsMapValue, BPF_ANY));
- key.tag = 0;
- EXPECT_RESULT_OK(statsMapA.writeValue(key, statsMapValue, BPF_ANY));
- EXPECT_RESULT_OK(appUidStatsMap.writeValue(TEST_UID, statsMapValue, BPF_ANY));
- ASSERT_EQ(0, qtaguid_deleteTagData(0, TEST_UID));
- Result<StatsValue> statsResult = statsMapA.readValue(key);
- ASSERT_FALSE(statsResult.ok());
- ASSERT_EQ(ENOENT, statsResult.error().code());
- statsResult = appUidStatsMap.readValue(TEST_UID);
- ASSERT_FALSE(statsResult.ok());
- ASSERT_EQ(ENOENT, statsResult.error().code());
- key.tag = TEST_TAG;
- statsResult = statsMapB.readValue(key);
- ASSERT_FALSE(statsResult.ok());
- ASSERT_EQ(ENOENT, statsResult.error().code());
-}
-
}
}
diff --git a/tests/kernel_test.cpp b/tests/kernel_test.cpp
new file mode 100644
index 0000000..2cc5c99
--- /dev/null
+++ b/tests/kernel_test.cpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 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.
+ *
+ */
+
+#include <gtest/gtest.h>
+#include <vintf/VintfObject.h>
+
+#include <fstream>
+#include <string>
+
+namespace android {
+namespace net {
+
+namespace {
+
+using ::android::vintf::RuntimeInfo;
+using ::android::vintf::VintfObject;
+
+class KernelConfigVerifier final {
+ public:
+ KernelConfigVerifier() : mRuntimeInfo(VintfObject::GetRuntimeInfo()) {}
+
+ bool hasOption(const std::string& option) const {
+ const auto& configMap = mRuntimeInfo->kernelConfigs();
+ auto it = configMap.find(option);
+ if (it != configMap.cend()) {
+ return it->second == "y";
+ }
+ return false;
+ }
+
+ private:
+ std::shared_ptr<const RuntimeInfo> mRuntimeInfo;
+};
+
+bool isGsiImage() {
+ std::ifstream ifs("/system/system_ext/etc/init/init.gsi.rc");
+ return ifs.good();
+}
+
+} // namespace
+
+/**
+ * If this test fails, enable the following kernel modules in your kernel config:
+ * CONFIG_NET_CLS_MATCHALL=y
+ * CONFIG_NET_ACT_POLICE=y
+ * CONFIG_NET_ACT_BPF=y
+ */
+TEST(KernelTest, TestRateLimitingSupport) {
+ if (isGsiImage()) {
+ // skip test on gsi images
+ GTEST_SKIP() << "GSI Image";
+ }
+ KernelConfigVerifier configVerifier;
+ ASSERT_TRUE(configVerifier.hasOption("CONFIG_NET_CLS_MATCHALL"));
+ ASSERT_TRUE(configVerifier.hasOption("CONFIG_NET_ACT_POLICE"));
+ ASSERT_TRUE(configVerifier.hasOption("CONFIG_NET_ACT_BPF"));
+}
+
+} // namespace net
+} // namespace android
diff --git a/tests/netd_client_test.cpp b/tests/netd_client_test.cpp
index c8af408..844616b 100644
--- a/tests/netd_client_test.cpp
+++ b/tests/netd_client_test.cpp
@@ -25,12 +25,9 @@
#include "NetdClient.h"
-#define SKIP_IF_NO_NETWORK_CONNECTIVITY \
- do { \
- if (!checkNetworkConnectivity()) { \
- GTEST_LOG_(INFO) << "Skip. Required Network Connectivity. \n"; \
- return; \
- } \
+#define SKIP_IF_NO_NETWORK_CONNECTIVITY \
+ do { \
+ if (!checkNetworkConnectivity()) GTEST_SKIP() << "Skip. Requires Network Connectivity."; \
} while (0)
namespace {
diff --git a/tests/netd_test.cpp b/tests/netd_test.cpp
index fcd538e..8d5d8bc 100644
--- a/tests/netd_test.cpp
+++ b/tests/netd_test.cpp
@@ -32,10 +32,8 @@
#include <android-base/unique_fd.h>
#define LOG_TAG "NetdTest"
-#include "bpf/BpfMap.h"
-#include "netdbpf/bpf_shared.h"
-#include "OffloadUtils.h"
+#include "TcUtils.h"
namespace android {
namespace net {
diff --git a/tests/netlink_listener_test.cpp b/tests/netlink_listener_test.cpp
deleted file mode 100644
index 249bdfb..0000000
--- a/tests/netlink_listener_test.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-//
-// Copyright (C) 2018 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.
-//
-
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <linux/inet_diag.h>
-#include <linux/netlink.h>
-#include <linux/sock_diag.h>
-#include <linux/unistd.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-
-#include <gtest/gtest.h>
-
-#include <cutils/qtaguid.h>
-
-#include <netdutils/Misc.h>
-#include <netdutils/Syscalls.h>
-#include "NetlinkListener.h"
-#include "TrafficController.h"
-#include "bpf/BpfMap.h"
-#include "bpf/BpfUtils.h"
-#include "netdutils/Netlink.h"
-
-// A test uid that is large enough so normal apps are not likely to take,
-constexpr uid_t TEST_UID = UID_MAX - 2;
-// A test tag arbitrarily selected.
-constexpr uint32_t TEST_TAG = 0xFF0F0F0F;
-
-constexpr uint32_t SOCK_CLOSE_WAIT_US = 30 * 1000;
-constexpr uint32_t ENOBUFS_POLL_WAIT_US = 10 * 1000;
-
-using android::base::Result;
-using android::base::ResultError;
-
-// This test set up a SkDestroyListener that is runing parallel with the production
-// SkDestroyListener. The test will create thousands of sockets and tag them on the
-// production cookieUidTagMap and close them in a short time. When the number of
-// sockets get closed exceeds the buffer size, it will start to return ENOBUFF
-// error. The error will be ignored by the production SkDestroyListener and the
-// test will clean up the tags in tearDown if there is any remains.
-
-// TODO: Instead of test the ENOBUFF error, we can test the production
-// SkDestroyListener to see if it failed to delete a tagged socket when ENOBUFF
-// triggerred.
-class NetlinkListenerTest : public testing::Test {
- protected:
- NetlinkListenerTest() {}
- BpfMap<uint64_t, UidTagValue> mCookieTagMap;
-
- void SetUp() {
- mCookieTagMap.reset(android::bpf::mapRetrieveRW(COOKIE_TAG_MAP_PATH));
- ASSERT_TRUE(mCookieTagMap.isValid());
- }
-
- void TearDown() {
- const auto deleteTestCookieEntries = [](const uint64_t& key, const UidTagValue& value,
- BpfMap<uint64_t, UidTagValue>& map) {
- if ((value.uid == TEST_UID) && (value.tag == TEST_TAG)) {
- Result<void> res = map.deleteValue(key);
- if (res.ok() || (res.error().code() == ENOENT)) {
- return Result<void>();
- }
- ALOGE("Failed to delete data(cookie = %" PRIu64 "): %s\n", key,
- strerror(res.error().code()));
- }
- // Move forward to next cookie in the map.
- return Result<void>();
- };
- EXPECT_RESULT_OK(mCookieTagMap.iterateWithValue(deleteTestCookieEntries));
- }
-
- Result<void> checkNoGarbageTagsExist() {
- const auto checkGarbageTags = [](const uint64_t&, const UidTagValue& value,
- const BpfMap<uint64_t, UidTagValue>&) -> Result<void> {
- if ((TEST_UID == value.uid) && (TEST_TAG == value.tag)) {
- return ResultError("Closed socket is not untagged", EUCLEAN);
- }
- return Result<void>();
- };
- return mCookieTagMap.iterateWithValue(checkGarbageTags);
- }
-
- bool checkMassiveSocketDestroy(int totalNumber, bool expectError) {
- std::unique_ptr<android::net::NetlinkListenerInterface> skDestroyListener;
- auto result = android::net::TrafficController::makeSkDestroyListener();
- if (!isOk(result)) {
- ALOGE("Unable to create SkDestroyListener: %s", toString(result).c_str());
- } else {
- skDestroyListener = std::move(result.value());
- }
- int rxErrorCount = 0;
- // Rx handler extracts nfgenmsg looks up and invokes registered dispatch function.
- const auto rxErrorHandler = [&rxErrorCount](const int, const int) { rxErrorCount++; };
- skDestroyListener->registerSkErrorHandler(rxErrorHandler);
- int fds[totalNumber];
- for (int i = 0; i < totalNumber; i++) {
- fds[i] = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0);
- // The likely reason for a failure is running out of available file descriptors.
- EXPECT_LE(0, fds[i]) << i << " of " << totalNumber;
- if (fds[i] < 0) {
- // EXPECT_LE already failed above, so test case is a failure, but we don't
- // want potentially tens of thousands of extra failures creating and then
- // closing all these fds cluttering up the logs.
- totalNumber = i;
- break;
- };
- qtaguid_tagSocket(fds[i], TEST_TAG, TEST_UID);
- }
-
- // TODO: Use a separate thread that has it's own fd table so we can
- // close sockets even faster simply by terminating that thread.
- for (int i = 0; i < totalNumber; i++) {
- EXPECT_EQ(0, close(fds[i]));
- }
- // wait a bit for netlink listener to handle all the messages.
- usleep(SOCK_CLOSE_WAIT_US);
- if (expectError) {
- // If ENOBUFS triggered, check it only called into the handler once, ie.
- // that the netlink handler is not spinning.
- int currentErrorCount = rxErrorCount;
- // 0 error count is acceptable because the system has chances to close all sockets
- // normally.
- EXPECT_LE(0, rxErrorCount);
- if (!rxErrorCount) return true;
-
- usleep(ENOBUFS_POLL_WAIT_US);
- EXPECT_EQ(currentErrorCount, rxErrorCount);
- } else {
- EXPECT_RESULT_OK(checkNoGarbageTagsExist());
- EXPECT_EQ(0, rxErrorCount);
- }
- return false;
- }
-};
-
-TEST_F(NetlinkListenerTest, TestAllSocketUntagged) {
- checkMassiveSocketDestroy(10, false);
- checkMassiveSocketDestroy(100, false);
-}
-
-// Disabled because flaky on blueline-userdebug; this test relies on the main thread
-// winning a race against the NetlinkListener::run() thread. There's no way to ensure
-// things will be scheduled the same way across all architectures and test environments.
-TEST_F(NetlinkListenerTest, DISABLED_TestSkDestroyError) {
- bool needRetry = false;
- int retryCount = 0;
- do {
- needRetry = checkMassiveSocketDestroy(32500, true);
- if (needRetry) retryCount++;
- } while (needRetry && retryCount < 3);
- // Should review test if it can always close all sockets correctly.
- EXPECT_GT(3, retryCount);
-}
diff --git a/tests/test_utils.cpp b/tests/test_utils.cpp
index 27b17c5..93c7dd8 100644
--- a/tests/test_utils.cpp
+++ b/tests/test_utils.cpp
@@ -88,10 +88,19 @@
return runCommand(command);
}
-bool ipRouteExists(const char* ipVersion, const char* table, const std::string& ipRoute) {
+bool ipRouteExists(const char* ipVersion, const char* table,
+ const std::vector<std::string>& ipRouteSubstrings) {
std::vector<std::string> routes = listIpRoutes(ipVersion, table);
for (const auto& route : routes) {
- if (route.find(ipRoute) != std::string::npos) {
+ bool matched = true;
+ for (const auto& substring : ipRouteSubstrings) {
+ if (route.find(substring) == std::string::npos) {
+ matched = false;
+ break;
+ }
+ }
+
+ if (matched) {
return true;
}
}
diff --git a/tests/test_utils.h b/tests/test_utils.h
index c8cd6ce..de6c221 100644
--- a/tests/test_utils.h
+++ b/tests/test_utils.h
@@ -35,4 +35,5 @@
std::vector<std::string> listIpRoutes(const char* ipVersion, const char* table);
-bool ipRouteExists(const char* ipVersion, const char* table, const std::string& ipRoute);
+bool ipRouteExists(const char* ipVersion, const char* table,
+ const std::vector<std::string>& ipRouteSubstrings);