• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 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 #ifndef OHOS_NETMANAGERSTANDARD_BPFWRAPPER_H
17 #define OHOS_NETMANAGERSTANDARD_BPFWRAPPER_H
18 
19 #include <cerrno>
20 #include <linux/bpf.h>
21 #include <linux/unistd.h>
22 #include <stdint.h>
23 #include <string>
24 #include <unistd.h>
25 
26 #include "netnative_log_wrapper.h"
27 #include "securec.h"
28 
29 namespace OHOS {
30 namespace NetManagerStandard {
31 static constexpr int IFNAMESIZE = 16;
32 static constexpr int INVALID = -1;
33 
34 struct StatsValue {
35     uint64_t rxPackets;
36     uint64_t rxBytes;
37     uint64_t txPackets;
38     uint64_t txBytes;
39 
40     StatsValue &operator+=(const StatsValue &other)
41     {
42         rxPackets += other.rxPackets;
43         rxBytes += other.rxBytes;
44         txPackets += other.txPackets;
45         txBytes += other.txBytes;
46         return *this;
47     }
48 };
49 
50 typedef struct {
51     std::string name;
52 } IfaceName;
53 
54 template <class Key, class Value> class BpfWrappers {
55 public:
56     BpfWrappers<Key, Value>() = default;
57 
58     /**
59      * Bpf Syscall
60      *
61      * @param cmd which command need to execute
62      * @param attr union consists of various anonymous structures
63      * @return int return the result of executing the command
64      */
BpfSyscall(int cmd,const bpf_attr & attr)65     static inline int BpfSyscall(int cmd, const bpf_attr &attr)
66     {
67         int result = syscall(__NR_bpf, cmd, &attr, sizeof(attr));
68         NETNATIVE_LOGI("cmd = %{public}d,result = %{public}d", cmd, result);
69         if (result < 0) {
70             NETNATIVE_LOGE("BpfSyscall: errno = %{public}d,failed : %{public}s", errno, strerror(errno));
71             result = -errno;
72         }
73         return result;
74     }
75 
76     /**
77      * Create A Bpf Map but for test only
78      *
79      * @param mapType map type
80      * @param keySize key size in bytes
81      * @param valueSize value size in bytes
82      * @param maxEntries maximum number of elements
83      * @param mapFlags map flag
84      * @return int return a map file descriptor
85      */
CreateMap(bpf_map_type mapType,uint32_t keySize,uint32_t valueSize,uint32_t maxEntries,uint32_t mapFlags)86     static int CreateMap(bpf_map_type mapType, uint32_t keySize, uint32_t valueSize, uint32_t maxEntries,
87                          uint32_t mapFlags)
88     {
89         bpf_attr bpfAttr;
90         (void)memset_s(&bpfAttr, sizeof(bpfAttr), 0, sizeof(bpfAttr));
91         bpfAttr.map_type = mapType;
92         bpfAttr.key_size = keySize;
93         bpfAttr.value_size = valueSize;
94         bpfAttr.max_entries = maxEntries;
95         bpfAttr.map_flags = mapFlags;
96         return BpfSyscall(BPF_MAP_CREATE, bpfAttr);
97     }
98 
99     /**
100      * Write Value To Bpf Map
101      *
102      * @param mapFd map fd
103      * @param key the key of Bpf Map
104      * @param value the value of Bpf Map
105      * @param flags map flag
106      * @return int true:write success false:failure
107      */
WriteValueToMap(const int mapFd,const Key & key,const Value & value,uint64_t flags)108     static int WriteValueToMap(const int mapFd, const Key &key, const Value &value, uint64_t flags)
109     {
110         bpf_attr bpfAttr;
111         (void)memset_s(&bpfAttr, sizeof(bpfAttr), 0, sizeof(bpfAttr));
112         bpfAttr.map_fd = BpfFdToU32(mapFd);
113         bpfAttr.key = BpfMapKeyToU64(key);
114         bpfAttr.value = BpfMapValueToU64(value);
115         bpfAttr.flags = flags;
116         return BpfSyscall(BPF_MAP_UPDATE_ELEM, bpfAttr);
117     }
118 
119     /**
120      * LookUp Elem From Map
121      *
122      * @param mapFd map fd
123      * @param key the key of Bpf Map
124      * @param value the value of Bpf Map
125      * @return int true:find success false:failure
126      */
LookUpElem(const int mapFd,const Key & key,const Value & value)127     static int LookUpElem(const int mapFd, const Key &key, const Value &value)
128     {
129         bpf_attr bpfAttr;
130         (void)memset_s(&bpfAttr, sizeof(bpfAttr), 0, sizeof(bpfAttr));
131         bpfAttr.map_fd = BpfFdToU32(mapFd);
132         bpfAttr.key = BpfMapKeyToU64(key);
133         bpfAttr.value = BpfMapValueToU64(value);
134         return BpfSyscall(BPF_MAP_LOOKUP_ELEM, bpfAttr);
135     }
136 
137     /**
138      * Delete Elem From Map
139      *
140      * @param mapFd map fd
141      * @param key the key of Bpf Map
142      * @return int true:delete success false:failure
143      */
DeleteElem(const int mapFd,const Key & key)144     static int DeleteElem(const int mapFd, const Key &key)
145     {
146         bpf_attr bpfAttr;
147         (void)memset_s(&bpfAttr, sizeof(bpfAttr), 0, sizeof(bpfAttr));
148         bpfAttr.map_fd = BpfFdToU32(mapFd);
149         bpfAttr.key = BpfMapKeyToU64(key);
150         return BpfSyscall(BPF_MAP_DELETE_ELEM, bpfAttr);
151     }
152 
153     /**
154      * Get the Next Key From Map
155      *
156      * @param mapFd map fd
157      * @param key the key of Bpf Map
158      * @param next_key the key of Bpf Map
159      * @return int return next key
160      */
GetNextKey(const int mapFd,const Key & key,Key & next_key)161     static int GetNextKey(const int mapFd, const Key &key, Key &next_key)
162     {
163         bpf_attr bpfAttr;
164         (void)memset_s(&bpfAttr, sizeof(bpfAttr), 0, sizeof(bpfAttr));
165         bpfAttr.map_fd = BpfFdToU32(mapFd);
166         bpfAttr.key = BpfMapKeyToU64(key);
167         bpfAttr.next_key = BpfMapKeyToU64(next_key);
168         return BpfSyscall(BPF_MAP_GET_NEXT_KEY, bpfAttr);
169     }
170 
171     /**
172      * Get the First Key From Map
173      *
174      * @param mapFd map fd
175      * @param firstKey the first key of Bpf Map
176      * @return int return first key
177      */
GetFirstKey(const int mapFd,Key & key)178     static int GetFirstKey(const int mapFd, Key &key)
179     {
180         return GetNextKey(mapFd, INVALID, key);
181     }
182 
183     /**
184      * Attach Program To Map
185      *
186      * @param type bpf attach type
187      * @param progFd eBPF program to attach
188      * @param cgFd container object to attach to
189      * @return int true:attach success false:failure
190      */
AttachProgram(bpf_attach_type type,const int progFd,const int cgFd)191     static int AttachProgram(bpf_attach_type type, const int progFd, const int cgFd)
192     {
193         bpf_attr bpfAttr;
194         (void)memset_s(&bpfAttr, sizeof(bpfAttr), 0, sizeof(bpfAttr));
195         bpfAttr.target_fd = BpfFdToU32(cgFd);
196         bpfAttr.attach_bpf_fd = BpfFdToU32(progFd);
197         bpfAttr.attach_type = type;
198         return BpfSyscall(BPF_PROG_ATTACH, bpfAttr);
199     }
200 
201     /**
202      * Detach Program From Map
203      *
204      * @param type bpf detach type
205      * @param cgFd container object to detach to
206      * @return int true:detach success false:failure
207      */
DetachProgram(bpf_attach_type type,const int cgFd)208     static int DetachProgram(bpf_attach_type type, const int cgFd)
209     {
210         bpf_attr bpfAttr;
211         (void)memset_s(&bpfAttr, sizeof(bpfAttr), 0, sizeof(bpfAttr));
212         bpfAttr.target_fd = BpfFdToU32(cgFd);
213         bpfAttr.attach_type = type;
214         return BpfSyscall(BPF_PROG_DETACH, bpfAttr);
215     }
216 
217     /**
218      * Pin Bpf Object To File node
219      *
220      * @param pathName path the bpf map pinned
221      * @param bfdFd bfd fd
222      * @return int true:pin success false:failure
223      */
BpfObjPin(const std::string & pathName,int bfdFd)224     static int BpfObjPin(const std::string &pathName, int bfdFd)
225     {
226         bpf_attr bpfAttr;
227         (void)memset_s(&bpfAttr, sizeof(bpfAttr), 0, sizeof(bpfAttr));
228         bpfAttr.pathname = BpfMapPathNameToU64(pathName);
229         bpfAttr.bpf_fd = BpfFdToU32(bfdFd);
230         return BpfSyscall(BPF_OBJ_PIN, bpfAttr);
231     }
232 
233     /**
234      * Get Bpf Object By PathName
235      *
236      * @param pathName bpf map path
237      * @param fileFlags file flags
238      * @return int return map file descriptor
239      */
BpfObjGet(const std::string & pathName,uint32_t fileFlags)240     static int BpfObjGet(const std::string &pathName, uint32_t fileFlags)
241     {
242         bpf_attr bpfAttr;
243         (void)memset_s(&bpfAttr, sizeof(bpfAttr), 0, sizeof(bpfAttr));
244         bpfAttr.pathname = BpfMapPathNameToU64(pathName);
245         bpfAttr.file_flags = fileFlags;
246         return BpfSyscall(BPF_OBJ_GET, bpfAttr);
247     }
248 
249     /**
250      * Get the Map Fd
251      *
252      * @param pathName bpf map path
253      * @param objFlags obj flags
254      * @return int return map file descriptor
255      */
GetMap(const std::string & pathName,uint32_t objFlags)256     static int GetMap(const std::string &pathName, uint32_t objFlags)
257     {
258         return BpfObjGet(pathName, objFlags);
259     }
260 
261     /**
262      * Get the Map Fd
263      *
264      * @param pathName bpf map path
265      * @return int return map file descriptor
266      */
GetRWMap(const std::string & pathName)267     static int GetRWMap(const std::string &pathName)
268     {
269         return GetMap(pathName, 0);
270     }
271 
272     /**
273      * Get the Read—Only Map Fd
274      *
275      * @param pathName bpf map path
276      * @return int return map file descriptor
277      */
GetROMap(const std::string & pathName)278     static int GetROMap(const std::string &pathName)
279     {
280         return GetMap(pathName, BPF_F_RDONLY);
281     }
282 
283     /**
284      * Get the Write—Only Map Fd
285      *
286      * @param pathName bpf map path
287      * @return int return map file descriptor
288      */
GetWOMap(const std::string & pathName)289     static int GetWOMap(const std::string &pathName)
290     {
291         return GetMap(pathName, BPF_F_WRONLY);
292     }
293 
294 private:
BpfFdToU32(const int mapFd)295     static inline __u32 BpfFdToU32(const int mapFd)
296     {
297         return static_cast<__u32>(mapFd);
298     }
299 
BpfMapPathNameToU64(const std::string & pathName)300     static inline uint64_t BpfMapPathNameToU64(const std::string &pathName)
301     {
302         return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(pathName.c_str()));
303     }
304 
BpfMapKeyToU64(const Key & key)305     static inline uint64_t BpfMapKeyToU64(const Key &key)
306     {
307         return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&key));
308     }
309 
BpfMapValueToU64(const Value & value)310     static inline uint64_t BpfMapValueToU64(const Value &value)
311     {
312         return static_cast<uint64_t>(reinterpret_cast<uintptr_t>(&value));
313     }
314 };
315 } // namespace NetManagerStandard
316 } // namespace OHOS
317 #endif // OHOS_NETMANAGERSTANDARD_BPFWRAPPER_H
318