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