Can't create BPF_LPM_TRIE (1 EINVAL)
- Dominant language
- C
- Stars
- 22.7k
- Forks
- 4.1k
- Avg merge
- 10d 4h
- Merged PRs (30d)
- 3
Description
### System Info
**Distro**: Fedora 31 server
**Linux kernel**: 5.6.2
**LLVM**: 9.0.1 (Fedora 9.0.1-2.fc31)
**Python**: 3.7.6
**BCC**: 0.13.0-495a4a34 (from master, but same issue from Fedora 31 package)
Everything is run as root, SELinux is disabled, and ulimits (soft/hard) are set to unlimited.
### Problem
I cannot create a `BPF_MAP_TYPE_LPM_TRIE` map using BCC, but I can create it fine in-tree.
None of the following work with BCC.
```
BPF_LPM_TRIE(lpm_map);
BPF_F_TABLE("lpm_trie", long, long, lpm_map, 10240, BPF_F_NO_PREALLOC);
BPF_F_TABLE("lpm_trie", long, long, lpm_map, 8, BPF_F_NO_PREALLOC);
```
This works fine without BCC.
```
struct bpf_map_def SEC("maps") trie = {
.type = BPF_MAP_TYPE_LPM_TRIE,
.key_size = sizeof(long),
.value_size = sizeof(long),
.max_entries = 10000,
.map_flags = BPF_F_NO_PREALLOC
};
```
### Error output
This shows 2 successful (BPF_ARRAY) maps being created before failing (twice?) at creating a BPF_LPM_TRIE map.
```
Using BCC version 0.13.0-495a4a34
bpf(BPF_BTF_LOAD, {btf="\237\353\1\0\30\0\0\0\0\0\0\0\260\10\0\0\260\10\0\0j\f\0\0\1\0\0\0\2\0\0\4"..., btf_log_buf=NULL, btf_size=5426, btf_log_size=0, btf_log_level=0}, 120) = 3
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_ARRAY, key_size=4, value_size=4, max_entries=8, map_flags=0, inner_map_fd=0, map_name="test_map", map_ifindex=0, btf_fd=3, btf_key_type_id=7, btf_value_type_id=7}, 120) = 4
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_ARRAY, key_size=4, value_size=8, max_entries=256, map_flags=0, inner_map_fd=0, map_name="xdp_stats_map", map_ifindex=0, btf_fd=3, btf_key_type_id=7, btf_value_type_id=8}, 120) = 5
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_LPM_TRIE, key_size=8, value_size=8, max_entries=10240, map_flags=BPF_F_NO_PREALLOC, inner_map_fd=0, map_name="lpm_map", map_ifindex=0, btf_fd=3, btf_key_type_id=2, btf_value_type_id=2}, 120) = -1 EINVAL (Invalid argument)
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_LPM_TRIE, key_size=8, value_size=8, max_entries=10240, map_flags=BPF_F_NO_PREALLOC, inner_map_fd=0, map_name="", map_ifindex=0, btf_fd=3, btf_key_type_id=2, btf_value_type_id=2}, 120) = -1 EINVAL (Invalid argument)
could not open bpf map: lpm_map, error: Invalid argument
Traceback (most recent call last):
File "./src/examples/drop-icmp/user.py", line 110, in
main()
File "./src/examples/drop-icmp/user.py", line 73, in main
debug=args.debug)
File "./src/examples/drop-icmp/user.py", line 22, in load_xdp_program
debug=debug)
File "/usr/lib/python3.7/site-packages/bcc/__init__.py", line 356, in __init__
raise Exception("Failed to compile BPF module %s" % (src_file or ""))
Exception: Failed to compile BPF module b'/root/ebpf/src/examples/drop-icmp/kern.c'
+++ exited with 1 +++
```
Compared to a successful map create from in-tree BPF, I'm not seeing much difference in the syscall itself... Here's the working syscall without BCC.
```
bpf(BPF_MAP_CREATE, {map_type=BPF_MAP_TYPE_LPM_TRIE, key_size=8, value_size=8, max_entries=10000, map_flags=BPF_F_NO_PREALLOC, inner_map_fd=0, map_name="trie", map_ifindex=0, btf_fd=0, btf_key_type_id=0, btf_value_type_id=0}, 120) = 5
```
The in-tree sanity checks are being passed, but I'm not sure what BCC is doing differently. The in-tree checks are found here - https://elixir.bootlin.com/linux/v5.6.2/source/kernel/bpf/lpm_trie.c#L549 . Can someone point me to where the sanity checks for this map type happen in BCC source?
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with src/examples/drop-icmp/kern.c and src/examples/drop-icmp/user.py, then compare BCC's generated BPF_MAP_CREATE calls with the working in-tree syscall shown in the report. Inspect the BCC map creation path and the Linux v5.6.2 lpm_trie.c sanity checks linked in the issue. Done means identifying the BCC-specific incompatibility and making LPM_TRIE creation work without regressing the existing BPF_ARRAY maps.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, linux, python
- Domain
- devtools, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 30/100