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 45namespace OHOS { 46namespace Bpf { 47static 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 52static 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 61enum 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 75struct 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 85struct BpfMapData { 86 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 96class BpfLoader { 97public: 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 110private: 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