bpf-firewall: give a name to maps used

Running systemd with IP accounting enabled generates many bpf maps (two
per unit for accounting, another two if IPAddressAllow/Deny are used).

Systemd itself knows which maps belong to what unit and commands like
`systemctl status <unit>` can be used to query what service has which
map, but monitoring these values all the time costs 4 dbus requests
(calling the .IP{E,I}gress{Bytes,Packets} method for each unit) and
makes services like the prometheus systemd_exporter[1] somewhat slow
when doing that for every units, while less precise information could
quickly be obtained by looking directly at the maps.

Unfortunately, bpf map names are rather limited:
- only 15 characters in length (16, but last byte must be 0)
- only allows isalnum(), _ and . characters

If it wasn't for the length limit we could use the normal unit escape
functions but I've opted to just make any forbidden character into
underscores for maximum brievty -- the map prefix is also rather short:
This isn't meant as a precise mapping, but as a hint for admins who want
to look at these.

(Note there is no problem if multiple maps have the same name)

Link: https://github.com/povilasv/systemd_exporter [1]
This commit is contained in:
Dominique Martinet
2023-04-18 08:23:55 +09:00
committed by Yu Watanabe
parent 38cdd08b22
commit 25d9c6cdaf
3 changed files with 26 additions and 5 deletions
+16 -1
View File
@@ -300,8 +300,16 @@ int bpf_program_cgroup_detach(BPFProgram *p) {
return 0;
}
int bpf_map_new(enum bpf_map_type type, size_t key_size, size_t value_size, size_t max_entries, uint32_t flags) {
int bpf_map_new(
const char *name,
enum bpf_map_type type,
size_t key_size,
size_t value_size,
size_t max_entries,
uint32_t flags) {
union bpf_attr attr;
const char *n = name;
zero(attr);
attr.map_type = type;
@@ -310,6 +318,13 @@ int bpf_map_new(enum bpf_map_type type, size_t key_size, size_t value_size, size
attr.max_entries = max_entries;
attr.map_flags = flags;
/* The map name is primarily informational for debugging purposes, and typically too short
* to carry the full unit name, hence we employ a trivial lossy escaping to make it fit
* (truncation + only alphanumerical, "." and "_" are allowed as per
* https://www.kernel.org/doc/html/next/bpf/maps.html#usage-notes) */
for (size_t i = 0; i < sizeof(attr.map_name) - 1 && *n; i++, n++)
attr.map_name[i] = strchr(ALPHANUMERICAL ".", *n) ? *n : '_';
return RET_NERRNO(bpf(BPF_MAP_CREATE, &attr, sizeof(attr)));
}