vendorBpfLoader: kernel is guaranteed to be 5.4+
(even 5.10+) Test: TreeHugger Flag: EXEMPT cleanup Signed-off-by: Maciej Żenczykowski <maze@google.com> Change-Id: I4c9a2a222071095559b1605d4417f93eecf4667f
This commit is contained in:
parent
d29bd0b4ca
commit
174cddec91
1 changed files with 8 additions and 20 deletions
|
|
@ -432,7 +432,7 @@ static int getSymNameByIdx(ifstream& elfFile, int index, string& name) {
|
|||
}
|
||||
|
||||
static bool mapMatchesExpectations(const unique_fd& fd, const string& mapName,
|
||||
const struct bpf_map_def& mapDef, const enum bpf_map_type type) {
|
||||
const struct bpf_map_def& mapDef) {
|
||||
// Assuming fd is a valid Bpf Map file descriptor then
|
||||
// all the following should always succeed on a 4.14+ kernel.
|
||||
// If they somehow do fail, they'll return -1 (and set errno),
|
||||
|
|
@ -446,14 +446,14 @@ static bool mapMatchesExpectations(const unique_fd& fd, const string& mapName,
|
|||
// DEVMAPs are readonly from the bpf program side's point of view, as such
|
||||
// the kernel in kernel/bpf/devmap.c dev_map_init_map() will set the flag
|
||||
int desired_map_flags = (int)mapDef.map_flags;
|
||||
if (type == BPF_MAP_TYPE_DEVMAP || type == BPF_MAP_TYPE_DEVMAP_HASH)
|
||||
if (mapDef.type == BPF_MAP_TYPE_DEVMAP || mapDef.type == BPF_MAP_TYPE_DEVMAP_HASH)
|
||||
desired_map_flags |= BPF_F_RDONLY_PROG;
|
||||
|
||||
// The .h file enforces that this is a power of two, and page size will
|
||||
// also always be a power of two, so this logic is actually enough to
|
||||
// force it to be a multiple of the page size, as required by the kernel.
|
||||
unsigned int desired_max_entries = mapDef.max_entries;
|
||||
if (type == BPF_MAP_TYPE_RINGBUF) {
|
||||
if (mapDef.type == BPF_MAP_TYPE_RINGBUF) {
|
||||
if (desired_max_entries < page_size) desired_max_entries = page_size;
|
||||
}
|
||||
|
||||
|
|
@ -464,7 +464,7 @@ static bool mapMatchesExpectations(const unique_fd& fd, const string& mapName,
|
|||
// Another possibility is that something is misconfigured in the code:
|
||||
// most likely a shared map is declared twice differently.
|
||||
// But such a change should never be checked into the source tree...
|
||||
if ((fd_type == type) &&
|
||||
if ((fd_type == mapDef.type) &&
|
||||
(fd_key_size == (int)mapDef.key_size) &&
|
||||
(fd_value_size == (int)mapDef.value_size) &&
|
||||
(fd_max_entries == (int)desired_max_entries) &&
|
||||
|
|
@ -474,7 +474,7 @@ static bool mapMatchesExpectations(const unique_fd& fd, const string& mapName,
|
|||
|
||||
ALOGE("bpf map name %s mismatch: desired/found: "
|
||||
"type:%d/%d key:%u/%d value:%u/%d entries:%u/%d flags:%u/%d",
|
||||
mapName.c_str(), type, fd_type, mapDef.key_size, fd_key_size, mapDef.value_size,
|
||||
mapName.c_str(), mapDef.type, fd_type, mapDef.key_size, fd_key_size, mapDef.value_size,
|
||||
fd_value_size, mapDef.max_entries, fd_max_entries, desired_map_flags, fd_map_flags);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -520,23 +520,11 @@ static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>&
|
|||
continue;
|
||||
}
|
||||
|
||||
enum bpf_map_type type = md[i].type;
|
||||
if (type == BPF_MAP_TYPE_DEVMAP_HASH && !isAtLeastKernelVersion(5, 4, 0)) {
|
||||
// On Linux Kernels older than 5.4 this map type doesn't exist, but it can kind
|
||||
// of be approximated: HASH has the same userspace visible api.
|
||||
// However it cannot be used by ebpf programs in the same way.
|
||||
// Since bpf_redirect_map() only requires 4.14, a program using a DEVMAP_HASH map
|
||||
// would fail to load (due to trying to redirect to a HASH instead of DEVMAP_HASH).
|
||||
// One must thus tag any BPF_MAP_TYPE_DEVMAP_HASH + bpf_redirect_map() using
|
||||
// programs as being 5.4+...
|
||||
type = BPF_MAP_TYPE_HASH;
|
||||
}
|
||||
|
||||
// The .h file enforces that this is a power of two, and page size will
|
||||
// also always be a power of two, so this logic is actually enough to
|
||||
// force it to be a multiple of the page size, as required by the kernel.
|
||||
unsigned int max_entries = md[i].max_entries;
|
||||
if (type == BPF_MAP_TYPE_RINGBUF) {
|
||||
if (md[i].type == BPF_MAP_TYPE_RINGBUF) {
|
||||
if (max_entries < page_size) max_entries = page_size;
|
||||
}
|
||||
|
||||
|
|
@ -556,7 +544,7 @@ static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>&
|
|||
reuse = true;
|
||||
} else {
|
||||
union bpf_attr req = {
|
||||
.map_type = type,
|
||||
.map_type = md[i].type,
|
||||
.key_size = md[i].key_size,
|
||||
.value_size = md[i].value_size,
|
||||
.max_entries = max_entries,
|
||||
|
|
@ -573,7 +561,7 @@ static int createMaps(const char* elfPath, ifstream& elfFile, vector<unique_fd>&
|
|||
// When reusing a pinned map, we need to check the map type/sizes/etc match, but for
|
||||
// safety (since reuse code path is rare) run these checks even if we just created it.
|
||||
// We assume failure is due to pinned map mismatch, hence the 'NOT UNIQUE' return code.
|
||||
if (!mapMatchesExpectations(fd, mapNames[i], md[i], type)) return -ENOTUNIQ;
|
||||
if (!mapMatchesExpectations(fd, mapNames[i], md[i])) return -ENOTUNIQ;
|
||||
|
||||
if (!reuse) {
|
||||
ret = bpfFdPin(fd, mapPinLoc.c_str());
|
||||
|
|
|
|||
Loading…
Reference in a new issue