From 25d9c6cdaf82d3f627db92b69f3be3e2a68e06fa Mon Sep 17 00:00:00 2001 From: Dominique Martinet Date: Sun, 16 Apr 2023 16:14:49 +0900 Subject: 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 ` 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] --- src/shared/bpf-program.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'src/shared/bpf-program.c') diff --git a/src/shared/bpf-program.c b/src/shared/bpf-program.c index 531ae9b680..d5eb6f4ccb 100644 --- a/src/shared/bpf-program.c +++ b/src/shared/bpf-program.c @@ -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))); } -- cgit v1.2.1