• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <linux/bpf.h>
17 #include <linux/if_packet.h>
18 #include <stddef.h>
19 #include <stdint.h>
20 
21 #include "bpf/bpf_helpers.h"
22 #include "bpf_def.h"
23 
24 #define SEC(NAME) __attribute__((section(NAME), used))
25 
26 // network stats begin
27 bpf_map_def SEC("maps") iface_stats_map = {
28     .type = BPF_MAP_TYPE_HASH,
29     .key_size = sizeof(uint64_t),
30     .value_size = sizeof(iface_stats_value),
31     .max_entries = IFACE_STATS_MAP_SIZE,
32     .map_flags = 0,
33     .inner_map_idx = 0,
34     .numa_node = 0,
35 };
36 
37 bpf_map_def SEC("maps") app_uid_stats_map = {
38     .type = BPF_MAP_TYPE_HASH,
39     .key_size = sizeof(uint64_t),
40     .value_size = sizeof(app_uid_stats_value),
41     .max_entries = APP_STATS_MAP_SIZE,
42     .map_flags = 0,
43     .inner_map_idx = 0,
44     .numa_node = 0,
45 };
46 
47 bpf_map_def SEC("maps") app_uid_if_stats_map = {
48     .type = BPF_MAP_TYPE_HASH,
49     .key_size = sizeof(app_uid_if_stats_key),
50     .value_size = sizeof(app_uid_if_stats_value),
51     .max_entries = IFACE_NAME_MAP_SIZE,
52     .map_flags = 0,
53     .inner_map_idx = 0,
54     .numa_node = 0,
55 };
56 
57 SEC("cgroup_skb/uid/ingress")
bpf_cgroup_skb_uid_ingress(struct __sk_buff * skb)58 int bpf_cgroup_skb_uid_ingress(struct __sk_buff *skb)
59 {
60     if (skb == NULL) {
61         return 1;
62     }
63     if (skb->pkt_type == PACKET_LOOPBACK) {
64         return 1;
65     }
66     uint64_t sock_uid = bpf_get_socket_uid(skb);
67     app_uid_stats_value *value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
68     if (value == NULL) {
69         app_uid_stats_value newValue = {};
70         bpf_map_update_elem(&app_uid_stats_map, &sock_uid, &newValue, BPF_NOEXIST);
71         value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
72     }
73     if (value != NULL) {
74         __sync_fetch_and_add(&value->rxPackets, 1);
75         __sync_fetch_and_add(&value->rxBytes, skb->len);
76     }
77     app_uid_if_stats_key key = {.uId = sock_uid, .ifIndex = skb->ifindex};
78     app_uid_if_stats_value *value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
79     if (value_uid_if == NULL) {
80         app_uid_if_stats_value newValue = {};
81         bpf_map_update_elem(&app_uid_if_stats_map, &key, &newValue, BPF_NOEXIST);
82         value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
83     }
84     if (value_uid_if != NULL) {
85         __sync_fetch_and_add(&value_uid_if->rxPackets, 1);
86         __sync_fetch_and_add(&value_uid_if->rxBytes, skb->len);
87     }
88     uint64_t ifindex = skb->ifindex;
89     iface_stats_value *value_if = bpf_map_lookup_elem(&iface_stats_map, &ifindex);
90     if (value_if == NULL) {
91         iface_stats_value newValue = {};
92         bpf_map_update_elem(&iface_stats_map, &ifindex, &newValue, BPF_NOEXIST);
93         value_if = bpf_map_lookup_elem(&iface_stats_map, &ifindex);
94     }
95     if (value_if != NULL) {
96         __sync_fetch_and_add(&value_if->rxPackets, 1);
97         __sync_fetch_and_add(&value_if->rxBytes, skb->len);
98     }
99     return 1;
100 }
101 
102 SEC("cgroup_skb/uid/egress")
bpf_cgroup_skb_uid_egress(struct __sk_buff * skb)103 int bpf_cgroup_skb_uid_egress(struct __sk_buff *skb)
104 {
105     if (skb == NULL) {
106         return 1;
107     }
108     if (skb->pkt_type == PACKET_LOOPBACK) {
109         return 1;
110     }
111     uint64_t sock_uid = bpf_get_socket_uid(skb);
112     app_uid_stats_value *value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
113     if (value == NULL) {
114         app_uid_stats_value newValue = {};
115         bpf_map_update_elem(&app_uid_stats_map, &sock_uid, &newValue, BPF_NOEXIST);
116         value = bpf_map_lookup_elem(&app_uid_stats_map, &sock_uid);
117     }
118     if (value != NULL) {
119         __sync_fetch_and_add(&value->txPackets, 1);
120         __sync_fetch_and_add(&value->txBytes, skb->len);
121     }
122     app_uid_if_stats_key key = {.uId = sock_uid, .ifIndex = skb->ifindex};
123     app_uid_if_stats_value *value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
124     if (value_uid_if == NULL) {
125         app_uid_if_stats_value newValue = {};
126         bpf_map_update_elem(&app_uid_if_stats_map, &key, &newValue, BPF_NOEXIST);
127         value_uid_if = bpf_map_lookup_elem(&app_uid_if_stats_map, &key);
128     }
129     if (value_uid_if != NULL) {
130         __sync_fetch_and_add(&value_uid_if->txPackets, 1);
131         __sync_fetch_and_add(&value_uid_if->txBytes, skb->len);
132     }
133     uint64_t ifindex = skb->ifindex;
134     iface_stats_value *value_if = bpf_map_lookup_elem(&iface_stats_map, &ifindex);
135     if (value_if == NULL) {
136         iface_stats_value newValue = {};
137         bpf_map_update_elem(&iface_stats_map, &ifindex, &newValue, BPF_NOEXIST);
138         value_if = bpf_map_lookup_elem(&iface_stats_map, &ifindex);
139     }
140     if (value_if != NULL) {
141         __sync_fetch_and_add(&value_if->txPackets, 1);
142         __sync_fetch_and_add(&value_if->txBytes, skb->len);
143     }
144     return 1;
145 }
146 // network stats end
147 
148 // internet permission begin
149 bpf_map_def SEC("maps") sock_permission_map = {
150     .type = BPF_MAP_TYPE_HASH,
151     .key_size = sizeof(sock_permission_key),
152     .value_size = sizeof(sock_permission_value),
153     .max_entries = 65536,
154 };
155 
156 SEC("cgroup_sock/inet_create_socket")
inet_create_socket(struct bpf_sock * sk)157 int inet_create_socket(struct bpf_sock *sk)
158 {
159     __u64 gid_uid = bpf_get_current_uid_gid();
160     __u32 uid = (__u32)(gid_uid & 0x00000000FFFFFFFF);
161     sock_permission_value *value = bpf_map_lookup_elem(&sock_permission_map, &uid);
162     // value == NULL means that the process attached to this uid is not a hap process which started by appspawn
163     // it is a native process, native process should have this permission
164     if (value == NULL) {
165         return 1;
166     }
167     // *value == 0 means no permission
168     if (*value == 0) {
169         return 0;
170     }
171     return 1;
172 }
173 // internet permission end
174 char g_license[] SEC("license") = "GPL";
175