put tethering bpf maps & programs in /sys/fs/bpf/tethering/...
This makes it harder for system and mainline bpf programs to conflict with each other, thus enabling easier mainline module updates. Test: builds and boots, atest, TreeHugger Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: Ic1b69bb1ddc4a10bd4861dadbd6b97e2520c532d
This commit is contained in:
parent
da5d7ec6a7
commit
d8a4578f30
3 changed files with 52 additions and 17 deletions
|
@ -51,10 +51,23 @@
|
||||||
using android::base::EndsWith;
|
using android::base::EndsWith;
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
#define BPF_PROG_PATH_MAINLINE_TETHERING "/apex/com.android.tethering/etc/bpf/"
|
struct {
|
||||||
#define BPF_PROG_PATH_SYSTEM "/system/etc/bpf/"
|
const char* const dir;
|
||||||
|
const char* const prefix;
|
||||||
|
} locations[] = {
|
||||||
|
// Tethering mainline module
|
||||||
|
{
|
||||||
|
.dir = "/apex/com.android.tethering/etc/bpf/",
|
||||||
|
.prefix = "tethering/",
|
||||||
|
},
|
||||||
|
// Core operating system
|
||||||
|
{
|
||||||
|
.dir = "/system/etc/bpf/",
|
||||||
|
.prefix = "",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
int loadAllElfObjects(const char* progDir) {
|
int loadAllElfObjects(const char* const progDir, const char* const prefix) {
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
DIR* dir;
|
DIR* dir;
|
||||||
struct dirent* ent;
|
struct dirent* ent;
|
||||||
|
@ -68,7 +81,7 @@ int loadAllElfObjects(const char* progDir) {
|
||||||
progPath += s;
|
progPath += s;
|
||||||
|
|
||||||
bool critical;
|
bool critical;
|
||||||
int ret = android::bpf::loadProg(progPath.c_str(), &critical);
|
int ret = android::bpf::loadProg(progPath.c_str(), &critical, prefix);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (critical) retVal = ret;
|
if (critical) retVal = ret;
|
||||||
ALOGE("Failed to load object: %s, ret: %s", progPath.c_str(), std::strerror(-ret));
|
ALOGE("Failed to load object: %s, ret: %s", progPath.c_str(), std::strerror(-ret));
|
||||||
|
@ -81,11 +94,29 @@ int loadAllElfObjects(const char* progDir) {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void createSysFsBpfSubDir(const char* const prefix) {
|
||||||
|
if (*prefix) {
|
||||||
|
mode_t prevUmask = umask(0);
|
||||||
|
|
||||||
|
string s = "/sys/fs/bpf/";
|
||||||
|
s += prefix;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
|
int ret = mkdir(s.c_str(), S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO);
|
||||||
|
if (ret && errno != EEXIST) {
|
||||||
|
ALOGW("Failed to create directory: %s, ret: %s", s.c_str(), std::strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
umask(prevUmask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// Load all ELF objects, create programs and maps, and pin them
|
// Load all ELF objects, create programs and maps, and pin them
|
||||||
for (const auto dir : {BPF_PROG_PATH_MAINLINE_TETHERING, BPF_PROG_PATH_SYSTEM}) {
|
for (const auto location : locations) {
|
||||||
if (loadAllElfObjects(dir) != 0) {
|
createSysFsBpfSubDir(location.prefix);
|
||||||
ALOGE("=== CRITICAL FAILURE LOADING BPF PROGRAMS FROM %s ===", dir);
|
if (loadAllElfObjects(location.dir, location.prefix) != 0) {
|
||||||
|
ALOGE("=== CRITICAL FAILURE LOADING BPF PROGRAMS FROM %s ===", location.dir);
|
||||||
ALOGE("If this triggers reliably, you're probably missing kernel options or patches.");
|
ALOGE("If this triggers reliably, you're probably missing kernel options or patches.");
|
||||||
ALOGE("If this triggers randomly, you might be hitting some memory allocation "
|
ALOGE("If this triggers randomly, you might be hitting some memory allocation "
|
||||||
"problems or startup script race.");
|
"problems or startup script race.");
|
||||||
|
|
|
@ -403,7 +403,8 @@ static int getSymNameByIdx(ifstream& elfFile, int index, string& name) {
|
||||||
return getSymName(elfFile, symtab[index].st_name, name);
|
return getSymName(elfFile, symtab[index].st_name, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>& mapFds) {
|
static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>& mapFds,
|
||||||
|
const char* prefix) {
|
||||||
int ret;
|
int ret;
|
||||||
vector<char> mdData;
|
vector<char> mdData;
|
||||||
vector<struct bpf_map_def> md;
|
vector<struct bpf_map_def> md;
|
||||||
|
@ -421,11 +422,11 @@ static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>&
|
||||||
|
|
||||||
for (int i = 0; i < (int)mapNames.size(); i++) {
|
for (int i = 0; i < (int)mapNames.size(); i++) {
|
||||||
unique_fd fd;
|
unique_fd fd;
|
||||||
// Format of pin location is /sys/fs/bpf/map_<filename>_<mapname>
|
// Format of pin location is /sys/fs/bpf/<prefix>map_<filename>_<mapname>
|
||||||
string mapPinLoc;
|
string mapPinLoc;
|
||||||
bool reuse = false;
|
bool reuse = false;
|
||||||
|
|
||||||
mapPinLoc = string(BPF_FS_PATH) + "map_" + fname + "_" + string(mapNames[i]);
|
mapPinLoc = string(BPF_FS_PATH) + prefix + "map_" + fname + "_" + string(mapNames[i]);
|
||||||
if (access(mapPinLoc.c_str(), F_OK) == 0) {
|
if (access(mapPinLoc.c_str(), F_OK) == 0) {
|
||||||
fd.reset(bpf_obj_get(mapPinLoc.c_str()));
|
fd.reset(bpf_obj_get(mapPinLoc.c_str()));
|
||||||
ALOGD("bpf_create_map reusing map %s, ret: %d\n", mapNames[i].c_str(), fd.get());
|
ALOGD("bpf_create_map reusing map %s, ret: %d\n", mapNames[i].c_str(), fd.get());
|
||||||
|
@ -527,7 +528,8 @@ static void applyMapRelo(ifstream& elfFile, vector<unique_fd> &mapFds, vector<co
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int loadCodeSections(const char* elfPath, vector<codeSection>& cs, const string& license) {
|
static int loadCodeSections(const char* elfPath, vector<codeSection>& cs, const string& license,
|
||||||
|
const char* prefix) {
|
||||||
unsigned kvers = kernelVersion();
|
unsigned kvers = kernelVersion();
|
||||||
int ret, fd;
|
int ret, fd;
|
||||||
|
|
||||||
|
@ -554,8 +556,10 @@ static int loadCodeSections(const char* elfPath, vector<codeSection>& cs, const
|
||||||
|
|
||||||
bool reuse = false;
|
bool reuse = false;
|
||||||
// Format of pin location is
|
// Format of pin location is
|
||||||
// /sys/fs/bpf/prog_<filename>_<mapname>
|
// /sys/fs/bpf/<prefix>prog_<filename>_<mapname>
|
||||||
string progPinLoc = BPF_FS_PATH "prog_";
|
string progPinLoc = BPF_FS_PATH;
|
||||||
|
progPinLoc += prefix;
|
||||||
|
progPinLoc += "prog_";
|
||||||
progPinLoc += fname;
|
progPinLoc += fname;
|
||||||
progPinLoc += '_';
|
progPinLoc += '_';
|
||||||
progPinLoc += name;
|
progPinLoc += name;
|
||||||
|
@ -609,7 +613,7 @@ static int loadCodeSections(const char* elfPath, vector<codeSection>& cs, const
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int loadProg(const char* elfPath, bool* isCritical) {
|
int loadProg(const char* elfPath, bool* isCritical, const char* prefix) {
|
||||||
vector<char> license;
|
vector<char> license;
|
||||||
vector<char> critical;
|
vector<char> critical;
|
||||||
vector<codeSection> cs;
|
vector<codeSection> cs;
|
||||||
|
@ -644,7 +648,7 @@ int loadProg(const char* elfPath, bool* isCritical) {
|
||||||
/* Just for future debugging */
|
/* Just for future debugging */
|
||||||
if (0) dumpAllCs(cs);
|
if (0) dumpAllCs(cs);
|
||||||
|
|
||||||
ret = createMaps(elfPath, elfFile, mapFds);
|
ret = createMaps(elfPath, elfFile, mapFds, prefix);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ALOGE("Failed to create maps: (ret=%d) in %s\n", ret, elfPath);
|
ALOGE("Failed to create maps: (ret=%d) in %s\n", ret, elfPath);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -655,7 +659,7 @@ int loadProg(const char* elfPath, bool* isCritical) {
|
||||||
|
|
||||||
applyMapRelo(elfFile, mapFds, cs);
|
applyMapRelo(elfFile, mapFds, cs);
|
||||||
|
|
||||||
ret = loadCodeSections(elfPath, cs, string(license.data()));
|
ret = loadCodeSections(elfPath, cs, string(license.data()), prefix);
|
||||||
if (ret) ALOGE("Failed to load programs, loadCodeSections ret=%d\n", ret);
|
if (ret) ALOGE("Failed to load programs, loadCodeSections ret=%d\n", ret);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace android {
|
||||||
namespace bpf {
|
namespace bpf {
|
||||||
|
|
||||||
// BPF loader implementation. Loads an eBPF ELF object
|
// BPF loader implementation. Loads an eBPF ELF object
|
||||||
int loadProg(const char* elfPath, bool* isCritical);
|
int loadProg(const char* elfPath, bool* isCritical, const char* prefix = "");
|
||||||
|
|
||||||
// Wait for bpfloader to load BPF programs.
|
// Wait for bpfloader to load BPF programs.
|
||||||
void waitForProgsLoaded();
|
void waitForProgsLoaded();
|
||||||
|
|
Loading…
Reference in a new issue