summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChenbo Feng <fengc@google.com>2019-02-28 17:40:24 -0800
committerandroid-build-merger <android-build-merger@google.com>2019-02-28 17:40:24 -0800
commitd10841f90cfbc1946889425abe2101b48107c467 (patch)
tree89c07f7c94ceda2473f80ac58e130c5155892943
parentf4e1f13bbaa9702c16c269e80460e2d18c12347d (diff)
parentf8b9dee2d898183b0656cdfcd369ddb836ce20b6 (diff)
downloadandroid_system_bpf-d10841f90cfbc1946889425abe2101b48107c467.tar.gz
android_system_bpf-d10841f90cfbc1946889425abe2101b48107c467.tar.bz2
android_system_bpf-d10841f90cfbc1946889425abe2101b48107c467.zip
Move netd specific program back to netd am: 47e92158ca
am: f8b9dee2d8 Change-Id: I19483b663eaaa88aecc96db403e703d06c63bd73
-rw-r--r--progs/Android.bp31
-rw-r--r--progs/netd.c83
-rw-r--r--progs/netd.h282
3 files changed, 0 insertions, 396 deletions
diff --git a/progs/Android.bp b/progs/Android.bp
deleted file mode 100644
index 4302129..0000000
--- a/progs/Android.bp
+++ /dev/null
@@ -1,31 +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.
-//
-
-//
-// bpf kernel programs
-//
-bpf {
- name: "netd.o",
- srcs: ["netd.c"],
- cflags: [
- "-Wall",
- "-Werror",
- ],
- include_dirs: [
- "system/netd/libnetdbpf/include",
- "system/netd/libnetdutils/include",
- ],
-}
diff --git a/progs/netd.c b/progs/netd.c
deleted file mode 100644
index 1d47c73..0000000
--- a/progs/netd.c
+++ /dev/null
@@ -1,83 +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 "netd.h"
-#include <linux/bpf.h>
-
-SEC("cgroupskb/ingress/stats")
-int bpf_cgroup_ingress(struct __sk_buff* skb) {
- return bpf_traffic_account(skb, BPF_INGRESS);
-}
-
-SEC("cgroupskb/egress/stats")
-int bpf_cgroup_egress(struct __sk_buff* skb) {
- return bpf_traffic_account(skb, BPF_EGRESS);
-}
-
-SEC("skfilter/egress/xtbpf")
-int xt_bpf_egress_prog(struct __sk_buff* skb) {
- uint32_t key = skb->ifindex;
- bpf_update_stats(skb, &iface_stats_map, BPF_EGRESS, &key);
- return BPF_MATCH;
-}
-
-SEC("skfilter/ingress/xtbpf")
-int xt_bpf_ingress_prog(struct __sk_buff* skb) {
- uint32_t key = skb->ifindex;
- bpf_update_stats(skb, &iface_stats_map, BPF_INGRESS, &key);
- return BPF_MATCH;
-}
-
-SEC("skfilter/whitelist/xtbpf")
-int xt_bpf_whitelist_prog(struct __sk_buff* skb) {
- uint32_t sock_uid = bpf_get_socket_uid(skb);
- if (is_system_uid(sock_uid)) return BPF_MATCH;
- uint8_t* whitelistMatch = bpf_map_lookup_elem(&uid_owner_map, &sock_uid);
- if (whitelistMatch) return *whitelistMatch & HAPPY_BOX_MATCH;
- return BPF_NOMATCH;
-}
-
-SEC("skfilter/blacklist/xtbpf")
-int xt_bpf_blacklist_prog(struct __sk_buff* skb) {
- uint32_t sock_uid = bpf_get_socket_uid(skb);
- uint8_t* blacklistMatch = bpf_map_lookup_elem(&uid_owner_map, &sock_uid);
- if (blacklistMatch) return *blacklistMatch & PENALTY_BOX_MATCH;
- return BPF_NOMATCH;
-}
-
-struct bpf_map_def SEC("maps") uid_permission_map = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(uint32_t),
- .value_size = sizeof(uint8_t),
- .max_entries = UID_OWNER_MAP_SIZE,
-};
-
-SEC("cgroupsock/inet/creat")
-int inet_socket_create(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* internetPermission = bpf_map_lookup_elem(&uid_permission_map, &appId);
- if (internetPermission) return *internetPermission & ALLOW_SOCK_CREATE;
- return NO_PERMISSION;
-}
-
-char _license[] SEC("license") = "Apache 2.0";
diff --git a/progs/netd.h b/progs/netd.h
deleted file mode 100644
index fcf3a72..0000000
--- a/progs/netd.h
+++ /dev/null
@@ -1,282 +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 h file together with netd.c is used for compiling the eBPF kernel
- * program.
- */
-
-#include <bpf_helpers.h>
-#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 <stdbool.h>
-#include <stdint.h>
-#include "netdbpf/bpf_shared.h"
-
-struct uid_tag {
- uint32_t uid;
- uint32_t tag;
-};
-
-struct stats_key {
- uint32_t uid;
- uint32_t tag;
- uint32_t counterSet;
- uint32_t ifaceIndex;
-};
-
-struct stats_value {
- uint64_t rxPackets;
- uint64_t rxBytes;
- uint64_t txPackets;
- uint64_t txBytes;
-};
-
-struct IfaceValue {
- char name[IFNAMSIZ];
-};
-
-// This is defined for cgroup bpf filter only.
-#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
-
-struct bpf_map_def SEC("maps") cookie_tag_map = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(uint64_t),
- .value_size = sizeof(struct uid_tag),
- .max_entries = COOKIE_UID_MAP_SIZE,
-};
-
-struct bpf_map_def SEC("maps") uid_counterset_map = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(uint32_t),
- .value_size = sizeof(uint8_t),
- .max_entries = UID_COUNTERSET_MAP_SIZE,
-};
-
-struct bpf_map_def SEC("maps") app_uid_stats_map = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(uint32_t),
- .value_size = sizeof(struct stats_value),
- .max_entries = APP_STATS_MAP_SIZE,
-};
-
-struct bpf_map_def SEC("maps") stats_map_A = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(struct stats_key),
- .value_size = sizeof(struct stats_value),
- .max_entries = STATS_MAP_SIZE,
-};
-
-struct bpf_map_def SEC("maps") stats_map_B = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(struct stats_key),
- .value_size = sizeof(struct stats_value),
- .max_entries = STATS_MAP_SIZE,
-};
-
-struct bpf_map_def SEC("maps") iface_stats_map = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(uint32_t),
- .value_size = sizeof(struct stats_value),
- .max_entries = IFACE_STATS_MAP_SIZE,
-};
-
-struct bpf_map_def SEC("maps") configuration_map = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(uint32_t),
- .value_size = sizeof(uint8_t),
- .max_entries = CONFIGURATION_MAP_SIZE,
-};
-
-struct bpf_map_def SEC("maps") uid_owner_map = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(uint32_t),
- .value_size = sizeof(uint8_t),
- .max_entries = UID_OWNER_MAP_SIZE,
-};
-
-struct bpf_map_def SEC("maps") iface_index_name_map = {
- .type = BPF_MAP_TYPE_HASH,
- .key_size = sizeof(uint32_t),
- .value_size = sizeof(struct IfaceValue),
- .max_entries = IFACE_INDEX_NAME_MAP_SIZE,
-};
-
-static __always_inline int is_system_uid(uint32_t uid) {
- return (uid <= MAX_SYSTEM_UID) && (uid >= MIN_SYSTEM_UID);
-}
-
-static __always_inline inline void bpf_update_stats(struct __sk_buff* skb, struct bpf_map_def* map,
- int direction, void* key) {
- struct stats_value* value;
- value = bpf_map_lookup_elem(map, key);
- if (!value) {
- struct stats_value newValue = {};
- bpf_map_update_elem(map, key, &newValue, BPF_NOEXIST);
- value = bpf_map_lookup_elem(map, key);
- }
- if (value) {
- if (direction == BPF_EGRESS) {
- __sync_fetch_and_add(&value->txPackets, 1);
- __sync_fetch_and_add(&value->txBytes, skb->len);
- } else if (direction == BPF_INGRESS) {
- __sync_fetch_and_add(&value->rxPackets, 1);
- __sync_fetch_and_add(&value->rxBytes, skb->len);
- }
- }
-}
-
-static inline bool skip_owner_match(struct __sk_buff* skb) {
- int offset = -1;
- int ret = 0;
- if (skb->protocol == ETH_P_IP) {
- offset = IP_PROTO_OFF;
- uint8_t proto, ihl;
- uint16_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 == 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) {
- uint16_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_map_lookup_elem(&configuration_map, &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) {
- if (skip_owner_match(skb)) return BPF_PASS;
-
- if ((uid <= MAX_SYSTEM_UID) && (uid >= MIN_SYSTEM_UID)) return BPF_PASS;
-
- BpfConfig enabledRules = getConfig(UID_RULES_CONFIGURATION_KEY);
- if (!enabledRules) {
- return BPF_PASS;
- }
-
- uint8_t* uidEntry = bpf_map_lookup_elem(&uid_owner_map, &uid);
- uint8_t uidRules = uidEntry ? *uidEntry : 0;
- 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;
- }
- return BPF_PASS;
-}
-
-static __always_inline inline void update_stats_with_config(struct __sk_buff* skb, int direction,
- void* key, uint8_t selectedMap) {
- if (selectedMap == SELECT_MAP_A) {
- bpf_update_stats(skb, &stats_map_A, direction, key);
- } else if (selectedMap == SELECT_MAP_B) {
- bpf_update_stats(skb, &stats_map_B, 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);
- int match = bpf_owner_match(skb, sock_uid);
- 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);
- struct uid_tag* utag = bpf_map_lookup_elem(&cookie_tag_map, &cookie);
- uint32_t uid, tag;
- if (utag) {
- uid = utag->uid;
- tag = utag->tag;
- } else {
- uid = sock_uid;
- tag = 0;
- }
-
- struct stats_key key = {.uid = uid, .tag = tag, .counterSet = 0, .ifaceIndex = skb->ifindex};
-
- uint8_t* counterSet = bpf_map_lookup_elem(&uid_counterset_map, &uid);
- if (counterSet) key.counterSet = (uint32_t)*counterSet;
-
- uint32_t mapSettingKey = CURRENT_STATS_MAP_CONFIGURATION_KEY;
- uint8_t* selectedMap = bpf_map_lookup_elem(&configuration_map, &mapSettingKey);
- if (!selectedMap) {
- return match;
- }
-
- if (tag) {
- update_stats_with_config(skb, direction, &key, *selectedMap);
- }
-
- key.tag = 0;
- update_stats_with_config(skb, direction, &key, *selectedMap);
- bpf_update_stats(skb, &app_uid_stats_map, direction, &uid);
- return match;
-}