1b1b8bc3fSopenharmony_ci/* 2b1b8bc3fSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 3b1b8bc3fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4b1b8bc3fSopenharmony_ci * you may not use this file except in compliance with the License. 5b1b8bc3fSopenharmony_ci * You may obtain a copy of the License at 6b1b8bc3fSopenharmony_ci * 7b1b8bc3fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8b1b8bc3fSopenharmony_ci * 9b1b8bc3fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10b1b8bc3fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11b1b8bc3fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b1b8bc3fSopenharmony_ci * See the License for the specific language governing permissions and 13b1b8bc3fSopenharmony_ci * limitations under the License. 14b1b8bc3fSopenharmony_ci */ 15b1b8bc3fSopenharmony_ci 16b1b8bc3fSopenharmony_ci#include <stdint.h> 17b1b8bc3fSopenharmony_ci#include <linux/bpf.h> 18b1b8bc3fSopenharmony_ci 19b1b8bc3fSopenharmony_ci#define SEC(NAME) __attribute__((section(NAME), used)) 20b1b8bc3fSopenharmony_ci 21b1b8bc3fSopenharmony_cistatic const int APP_STATS_MAP_SIZE = 5000; 22b1b8bc3fSopenharmony_cistatic const int IFACE_STATS_MAP_SIZE = 1000; 23b1b8bc3fSopenharmony_cistatic const int IFACE_NAM_MAP_SIZE = 1000; 24b1b8bc3fSopenharmony_cistatic const int IFNAM_SIZE = 16; 25b1b8bc3fSopenharmony_ci 26b1b8bc3fSopenharmony_citypedef struct { 27b1b8bc3fSopenharmony_ci unsigned int type; // actual bpf_map_type 28b1b8bc3fSopenharmony_ci unsigned int key_size; 29b1b8bc3fSopenharmony_ci unsigned int value_size; 30b1b8bc3fSopenharmony_ci unsigned int max_entries; 31b1b8bc3fSopenharmony_ci unsigned int map_flags; 32b1b8bc3fSopenharmony_ci unsigned int inner_map_idx; 33b1b8bc3fSopenharmony_ci unsigned int numa_node; 34b1b8bc3fSopenharmony_ci} bpf_map_def; 35b1b8bc3fSopenharmony_ci 36b1b8bc3fSopenharmony_citypedef struct { 37b1b8bc3fSopenharmony_ci uint64_t rx_packets; 38b1b8bc3fSopenharmony_ci uint64_t rx_bytes; 39b1b8bc3fSopenharmony_ci uint64_t tx_packets; 40b1b8bc3fSopenharmony_ci uint64_t tx_bytes; 41b1b8bc3fSopenharmony_ci} stats_value; 42b1b8bc3fSopenharmony_ci 43b1b8bc3fSopenharmony_citypedef struct { 44b1b8bc3fSopenharmony_ci char name[IFNAM_SIZE]; 45b1b8bc3fSopenharmony_ci} iface_name; 46b1b8bc3fSopenharmony_ci 47b1b8bc3fSopenharmony_cibpf_map_def SEC("maps") iface_stats_map = { 48b1b8bc3fSopenharmony_ci .type = BPF_MAP_TYPE_HASH, 49b1b8bc3fSopenharmony_ci .key_size = sizeof(uint32_t), 50b1b8bc3fSopenharmony_ci .value_size = sizeof(stats_value), 51b1b8bc3fSopenharmony_ci .max_entries = IFACE_STATS_MAP_SIZE, 52b1b8bc3fSopenharmony_ci .map_flags = 0, 53b1b8bc3fSopenharmony_ci .inner_map_idx = 0, 54b1b8bc3fSopenharmony_ci .numa_node = 0, 55b1b8bc3fSopenharmony_ci}; 56b1b8bc3fSopenharmony_ci 57b1b8bc3fSopenharmony_cibpf_map_def SEC("maps") iface_name_map = { 58b1b8bc3fSopenharmony_ci .type = BPF_MAP_TYPE_HASH, 59b1b8bc3fSopenharmony_ci .key_size = sizeof(uint32_t), 60b1b8bc3fSopenharmony_ci .value_size = sizeof(iface_name), 61b1b8bc3fSopenharmony_ci .max_entries = IFACE_NAM_MAP_SIZE, 62b1b8bc3fSopenharmony_ci .map_flags = 0, 63b1b8bc3fSopenharmony_ci .inner_map_idx = 0, 64b1b8bc3fSopenharmony_ci .numa_node = 0, 65b1b8bc3fSopenharmony_ci}; 66b1b8bc3fSopenharmony_ci 67b1b8bc3fSopenharmony_cibpf_map_def SEC("maps") app_uid_stats_map = { 68b1b8bc3fSopenharmony_ci .type = BPF_MAP_TYPE_HASH, 69b1b8bc3fSopenharmony_ci .key_size = sizeof(uint32_t), 70b1b8bc3fSopenharmony_ci .value_size = sizeof(stats_value), 71b1b8bc3fSopenharmony_ci .max_entries = APP_STATS_MAP_SIZE, 72b1b8bc3fSopenharmony_ci .map_flags = 0, 73b1b8bc3fSopenharmony_ci .inner_map_idx = 0, 74b1b8bc3fSopenharmony_ci .numa_node = 0, 75b1b8bc3fSopenharmony_ci}; 76b1b8bc3fSopenharmony_ci 77b1b8bc3fSopenharmony_cistatic SEC("cgroup_skb/uid/ingress") int bpf_cgroup_skb_uid_ingress(struct __sk_buff *skb) 78b1b8bc3fSopenharmony_ci{ 79b1b8bc3fSopenharmony_ci uint32_t sock_uid = bpf_get_socket_uid(skb); 80b1b8bc3fSopenharmony_ci 81b1b8bc3fSopenharmony_ci stats_value *value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid); 82b1b8bc3fSopenharmony_ci if (!value) { 83b1b8bc3fSopenharmony_ci stats_value newValue = {}; 84b1b8bc3fSopenharmony_ci bpf_map_update_elem(&app_uid_stats_map, &sock_uid, &newValue, BPF_NOEXIST); 85b1b8bc3fSopenharmony_ci value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid); 86b1b8bc3fSopenharmony_ci } 87b1b8bc3fSopenharmony_ci 88b1b8bc3fSopenharmony_ci if (value) { 89b1b8bc3fSopenharmony_ci __sync_fetch_and_add(&value->rx_packets, 1); 90b1b8bc3fSopenharmony_ci __sync_fetch_and_add(&value->rx_bytes, skb->len); 91b1b8bc3fSopenharmony_ci 92b1b8bc3fSopenharmony_ci const char log[] = "[Uid ingress] sock_uid = %d, value->rx_packets = %d, value->rx_bytes = %d"; 93b1b8bc3fSopenharmony_ci bpf_trace_printk(log, sizeof(log), sock_uid, value->rx_packets, value->rx_bytes); 94b1b8bc3fSopenharmony_ci } 95b1b8bc3fSopenharmony_ci return 1; 96b1b8bc3fSopenharmony_ci} 97b1b8bc3fSopenharmony_ci 98b1b8bc3fSopenharmony_cistatic SEC("cgroup_skb/uid/egress") int bpf_cgroup_skb_uid_egress(struct __sk_buff *skb) 99b1b8bc3fSopenharmony_ci{ 100b1b8bc3fSopenharmony_ci uint32_t sock_uid = bpf_get_socket_uid(skb); 101b1b8bc3fSopenharmony_ci 102b1b8bc3fSopenharmony_ci stats_value *value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid); 103b1b8bc3fSopenharmony_ci if (!value) { 104b1b8bc3fSopenharmony_ci stats_value newValue = {}; 105b1b8bc3fSopenharmony_ci bpf_map_update_elem(&app_uid_stats_map, &sock_uid, &newValue, BPF_NOEXIST); 106b1b8bc3fSopenharmony_ci value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid); 107b1b8bc3fSopenharmony_ci } 108b1b8bc3fSopenharmony_ci 109b1b8bc3fSopenharmony_ci if (value) { 110b1b8bc3fSopenharmony_ci __sync_fetch_and_add(&value->tx_packets, 1); 111b1b8bc3fSopenharmony_ci __sync_fetch_and_add(&value->tx_bytes, skb->len); 112b1b8bc3fSopenharmony_ci 113b1b8bc3fSopenharmony_ci const char log[] = "[Uid egress] sock_uid = %d, value->tx_packets = %d, value->tx_bytes = %d"; 114b1b8bc3fSopenharmony_ci bpf_trace_printk(log, sizeof(log), sock_uid, value->tx_packets, value->tx_bytes); 115b1b8bc3fSopenharmony_ci } 116b1b8bc3fSopenharmony_ci return 1; 117b1b8bc3fSopenharmony_ci} 118b1b8bc3fSopenharmony_ci 119b1b8bc3fSopenharmony_cistatic SEC("socket/iface/ingress") void bpf_socket_iface_ingress(struct __sk_buff *skb) 120b1b8bc3fSopenharmony_ci{ 121b1b8bc3fSopenharmony_ci uint32_t key = skb->ifindex; 122b1b8bc3fSopenharmony_ci 123b1b8bc3fSopenharmony_ci stats_value *value = bpf_map_lookup_elem(&iface_stats_map, &key); 124b1b8bc3fSopenharmony_ci if (!value) { 125b1b8bc3fSopenharmony_ci stats_value newValue = {}; 126b1b8bc3fSopenharmony_ci bpf_map_update_elem(&iface_stats_map, &key, &newValue, BPF_NOEXIST); 127b1b8bc3fSopenharmony_ci value = bpf_map_lookup_elem(&iface_stats_map, &key); 128b1b8bc3fSopenharmony_ci } 129b1b8bc3fSopenharmony_ci 130b1b8bc3fSopenharmony_ci if (value) { 131b1b8bc3fSopenharmony_ci __sync_fetch_and_add(&value->rx_packets, 1); 132b1b8bc3fSopenharmony_ci __sync_fetch_and_add(&value->rx_bytes, skb->len); 133b1b8bc3fSopenharmony_ci 134b1b8bc3fSopenharmony_ci const char log[] = "[Iface ingress] ifindex = %d, value->rx_packets = %d, value->rx_bytes = %d"; 135b1b8bc3fSopenharmony_ci bpf_trace_printk(log, sizeof(log), key, value->rx_packets, value->rx_bytes); 136b1b8bc3fSopenharmony_ci } 137b1b8bc3fSopenharmony_ci} 138b1b8bc3fSopenharmony_ci 139b1b8bc3fSopenharmony_cistatic SEC("socket/iface/egress") void bpf_socket_iface_egress(struct __sk_buff *skb) 140b1b8bc3fSopenharmony_ci{ 141b1b8bc3fSopenharmony_ci uint32_t key = skb->ifindex; 142b1b8bc3fSopenharmony_ci 143b1b8bc3fSopenharmony_ci stats_value *value = bpf_map_lookup_elem(&iface_stats_map, &key); 144b1b8bc3fSopenharmony_ci if (!value) { 145b1b8bc3fSopenharmony_ci stats_value newValue = {}; 146b1b8bc3fSopenharmony_ci bpf_map_update_elem(&iface_stats_map, &key, &newValue, BPF_NOEXIST); 147b1b8bc3fSopenharmony_ci value = bpf_map_lookup_elem(&iface_stats_map, &key); 148b1b8bc3fSopenharmony_ci } 149b1b8bc3fSopenharmony_ci 150b1b8bc3fSopenharmony_ci if (value) { 151b1b8bc3fSopenharmony_ci __sync_fetch_and_add(&value->tx_packets, 1); 152b1b8bc3fSopenharmony_ci __sync_fetch_and_add(&value->tx_bytes, skb->len); 153b1b8bc3fSopenharmony_ci 154b1b8bc3fSopenharmony_ci const char log[] = "[Iface egress] ifindex = %d, value->tx_packets = %d, value->tx_bytes = %d"; 155b1b8bc3fSopenharmony_ci bpf_trace_printk(log, sizeof(log), key, value->tx_packets, value->tx_bytes); 156b1b8bc3fSopenharmony_ci } 157b1b8bc3fSopenharmony_ci} 158b1b8bc3fSopenharmony_ci 159b1b8bc3fSopenharmony_cichar _license[] SEC("license") = "GPL";