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#ifndef NETMANAGER_BASE_BPF_LOADER_H
17b1b8bc3fSopenharmony_ci#define NETMANAGER_BASE_BPF_LOADER_H
18b1b8bc3fSopenharmony_ci
19b1b8bc3fSopenharmony_ci#include <cerrno>
20b1b8bc3fSopenharmony_ci#include <cstdio>
21b1b8bc3fSopenharmony_ci#include <cstdlib>
22b1b8bc3fSopenharmony_ci#include <fcntl.h>
23b1b8bc3fSopenharmony_ci#include <filesystem>
24b1b8bc3fSopenharmony_ci#include <fstream>
25b1b8bc3fSopenharmony_ci#include <functional>
26b1b8bc3fSopenharmony_ci#include <linux/bpf.h>
27b1b8bc3fSopenharmony_ci#include <linux/rtnetlink.h>
28b1b8bc3fSopenharmony_ci#include <linux/types.h>
29b1b8bc3fSopenharmony_ci#include <memory.h>
30b1b8bc3fSopenharmony_ci#include <net/if.h>
31b1b8bc3fSopenharmony_ci#include <string>
32b1b8bc3fSopenharmony_ci#include <sys/mount.h>
33b1b8bc3fSopenharmony_ci#include <sys/resource.h>
34b1b8bc3fSopenharmony_ci#include <sys/socket.h>
35b1b8bc3fSopenharmony_ci#include <sys/syscall.h>
36b1b8bc3fSopenharmony_ci#include <unistd.h>
37b1b8bc3fSopenharmony_ci#include <vector>
38b1b8bc3fSopenharmony_ci
39b1b8bc3fSopenharmony_ci#include "securec.h"
40b1b8bc3fSopenharmony_ci
41b1b8bc3fSopenharmony_ci#include "elf_types.hpp"
42b1b8bc3fSopenharmony_ci#include "elfio.hpp"
43b1b8bc3fSopenharmony_ci#include "elfio_relocation.hpp"
44b1b8bc3fSopenharmony_ci
45b1b8bc3fSopenharmony_cinamespace OHOS {
46b1b8bc3fSopenharmony_cinamespace Bpf {
47b1b8bc3fSopenharmony_cistatic constexpr const char *SECTION_NAMES[] = {
48b1b8bc3fSopenharmony_ci    "kprobe/", "kretprobe/", "tracepoint/", "raw_tracepoint/", "xdp",        "perf_event/",       "socket",
49b1b8bc3fSopenharmony_ci    "cgroup/", "sockops",    "sk_skb",      "sk_msg",          "cgroup_skb", "xdp_packet_parser",
50b1b8bc3fSopenharmony_ci};
51b1b8bc3fSopenharmony_ci
52b1b8bc3fSopenharmony_cistatic constexpr struct {
53b1b8bc3fSopenharmony_ci    const char *event;
54b1b8bc3fSopenharmony_ci    bpf_prog_type progType;
55b1b8bc3fSopenharmony_ci} PROG_TYPES[] = {
56b1b8bc3fSopenharmony_ci    {"socket", BPF_PROG_TYPE_SOCKET_FILTER},
57b1b8bc3fSopenharmony_ci    {"cgroup_skb", BPF_PROG_TYPE_CGROUP_SKB},
58b1b8bc3fSopenharmony_ci    {"xdp_packet_parser", BPF_PROG_TYPE_XDP},
59b1b8bc3fSopenharmony_ci};
60b1b8bc3fSopenharmony_ci
61b1b8bc3fSopenharmony_cienum ELfLoadError {
62b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_NONE = 0,
63b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_PATH_INVALID,
64b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_MOUNT_FAIL,
65b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_LOAD_FILE_FAIL,
66b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_GET_VERSION_FAIL,
67b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_SELECT_LICENSE_AND_VERSION_FAIL,
68b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_LOAD_MAP_SECTION_FAIL,
69b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_SET_RLIMIT_FAIL,
70b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_CREATE_MAP_FAIL,
71b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_PARSE_RELOCATION_FAIL,
72b1b8bc3fSopenharmony_ci    ELF_LOAD_ERR_LOAD_PROGS_FAIL,
73b1b8bc3fSopenharmony_ci};
74b1b8bc3fSopenharmony_ci
75b1b8bc3fSopenharmony_cistruct BpfLoadMapDef {
76b1b8bc3fSopenharmony_ci    unsigned int type; // actual type is bpf_map_type
77b1b8bc3fSopenharmony_ci    unsigned int keySize;
78b1b8bc3fSopenharmony_ci    unsigned int valueSize;
79b1b8bc3fSopenharmony_ci    unsigned int maxEntries;
80b1b8bc3fSopenharmony_ci    unsigned int mapFlags;
81b1b8bc3fSopenharmony_ci    unsigned int innerMapIdx;
82b1b8bc3fSopenharmony_ci    unsigned int numaNode;
83b1b8bc3fSopenharmony_ci};
84b1b8bc3fSopenharmony_ci
85b1b8bc3fSopenharmony_cistruct BpfMapData {
86b1b8bc3fSopenharmony_ci    BpfMapData() : fd(0)
87b1b8bc3fSopenharmony_ci    {
88b1b8bc3fSopenharmony_ci        (void)memset_s(&def, sizeof(def), 0, sizeof(def));
89b1b8bc3fSopenharmony_ci    }
90b1b8bc3fSopenharmony_ci
91b1b8bc3fSopenharmony_ci    int32_t fd;
92b1b8bc3fSopenharmony_ci    std::string name;
93b1b8bc3fSopenharmony_ci    BpfLoadMapDef def{};
94b1b8bc3fSopenharmony_ci};
95b1b8bc3fSopenharmony_ci
96b1b8bc3fSopenharmony_ciclass BpfLoader {
97b1b8bc3fSopenharmony_cipublic:
98b1b8bc3fSopenharmony_ci    /**
99b1b8bc3fSopenharmony_ci     * Construct a BpfLoader object
100b1b8bc3fSopenharmony_ci     * @param path the .o file which is need to be loaded
101b1b8bc3fSopenharmony_ci     */
102b1b8bc3fSopenharmony_ci    explicit BpfLoader(std::string path);
103b1b8bc3fSopenharmony_ci
104b1b8bc3fSopenharmony_ci    /**
105b1b8bc3fSopenharmony_ci     * Load the file specified in path_.
106b1b8bc3fSopenharmony_ci     * @return return ELF_LOAD_ERR_NONE if no error.
107b1b8bc3fSopenharmony_ci     */
108b1b8bc3fSopenharmony_ci    ELfLoadError Load();
109b1b8bc3fSopenharmony_ci
110b1b8bc3fSopenharmony_ciprivate:
111b1b8bc3fSopenharmony_ci    bool CheckPath();
112b1b8bc3fSopenharmony_ci
113b1b8bc3fSopenharmony_ci    bool IsPathValid();
114b1b8bc3fSopenharmony_ci
115b1b8bc3fSopenharmony_ci    bool LoadElfFile();
116b1b8bc3fSopenharmony_ci
117b1b8bc3fSopenharmony_ci    bool IsVersionValid();
118b1b8bc3fSopenharmony_ci
119b1b8bc3fSopenharmony_ci    bool SetRlimit();
120b1b8bc3fSopenharmony_ci
121b1b8bc3fSopenharmony_ci    bool IsMouted(const std::string &dir);
122b1b8bc3fSopenharmony_ci
123b1b8bc3fSopenharmony_ci    bool MountFs();
124b1b8bc3fSopenharmony_ci
125b1b8bc3fSopenharmony_ci    bool SetLicenseAndVersion();
126b1b8bc3fSopenharmony_ci
127b1b8bc3fSopenharmony_ci    bool LoadElfMapsSection();
128b1b8bc3fSopenharmony_ci
129b1b8bc3fSopenharmony_ci    bool CreateMaps();
130b1b8bc3fSopenharmony_ci
131b1b8bc3fSopenharmony_ci    bool ApplyRelocation(bpf_insn *insn, ELFIO::section *section);
132b1b8bc3fSopenharmony_ci
133b1b8bc3fSopenharmony_ci    bool LoadProg(const std::string &event, const bpf_insn *insn, size_t insnCnt);
134b1b8bc3fSopenharmony_ci
135b1b8bc3fSopenharmony_ci    bool ParseRelocation();
136b1b8bc3fSopenharmony_ci
137b1b8bc3fSopenharmony_ci    bool LoadProgs();
138b1b8bc3fSopenharmony_ci
139b1b8bc3fSopenharmony_ci    int32_t BpfCreateMapNode(const BpfMapData &map);
140b1b8bc3fSopenharmony_ci
141b1b8bc3fSopenharmony_ci    int32_t BpfLoadProgram(bpf_prog_type type, const bpf_insn *insns, size_t insnsCnt);
142b1b8bc3fSopenharmony_ci
143b1b8bc3fSopenharmony_ci    bpf_prog_type ConvertEventToProgType(const std::string &event);
144b1b8bc3fSopenharmony_ci
145b1b8bc3fSopenharmony_ci    std::string path_;
146b1b8bc3fSopenharmony_ci    ELFIO::elfio elfIo_;
147b1b8bc3fSopenharmony_ci    std::string license_;
148b1b8bc3fSopenharmony_ci    int32_t kernVersion_;
149b1b8bc3fSopenharmony_ci    std::vector<BpfMapData> maps_;
150b1b8bc3fSopenharmony_ci    std::function<ELfLoadError()> isPathValid_;
151b1b8bc3fSopenharmony_ci    std::function<ELfLoadError()> mountFs_;
152b1b8bc3fSopenharmony_ci    std::function<ELfLoadError()> loadElfFile_;
153b1b8bc3fSopenharmony_ci    std::function<ELfLoadError()> isVersionValid_;
154b1b8bc3fSopenharmony_ci    std::function<ELfLoadError()> setLicenseAndVersion_;
155b1b8bc3fSopenharmony_ci    std::function<ELfLoadError()> loadElfMapsSection_;
156b1b8bc3fSopenharmony_ci    std::function<ELfLoadError()> setRlimit_;
157b1b8bc3fSopenharmony_ci    std::function<ELfLoadError()> createMaps_;
158b1b8bc3fSopenharmony_ci    std::function<ELfLoadError()> parseRelocation_;
159b1b8bc3fSopenharmony_ci    std::function<ELfLoadError()> loadProgs_;
160b1b8bc3fSopenharmony_ci};
161b1b8bc3fSopenharmony_ci} // namespace Bpf
162b1b8bc3fSopenharmony_ci} // namespace OHOS
163b1b8bc3fSopenharmony_ci#endif /* NETMANAGER_BASE_BPF_LOADER_H */
164