mirror of
https://github.com/systemd/systemd.git
synced 2024-12-26 03:22:00 +03:00
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:
parent
38cdd08b22
commit
25d9c6cdaf
@ -451,7 +451,9 @@ static int bpf_firewall_prepare_access_maps(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n_ipv4 > 0) {
|
if (n_ipv4 > 0) {
|
||||||
|
char *name = strjoina("4_", u->id);
|
||||||
ipv4_map_fd = bpf_map_new(
|
ipv4_map_fd = bpf_map_new(
|
||||||
|
name,
|
||||||
BPF_MAP_TYPE_LPM_TRIE,
|
BPF_MAP_TYPE_LPM_TRIE,
|
||||||
offsetof(struct bpf_lpm_trie_key, data) + sizeof(uint32_t),
|
offsetof(struct bpf_lpm_trie_key, data) + sizeof(uint32_t),
|
||||||
sizeof(uint64_t),
|
sizeof(uint64_t),
|
||||||
@ -462,7 +464,9 @@ static int bpf_firewall_prepare_access_maps(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (n_ipv6 > 0) {
|
if (n_ipv6 > 0) {
|
||||||
|
char *name = strjoina("6_", u->id);
|
||||||
ipv6_map_fd = bpf_map_new(
|
ipv6_map_fd = bpf_map_new(
|
||||||
|
name,
|
||||||
BPF_MAP_TYPE_LPM_TRIE,
|
BPF_MAP_TYPE_LPM_TRIE,
|
||||||
offsetof(struct bpf_lpm_trie_key, data) + sizeof(uint32_t)*4,
|
offsetof(struct bpf_lpm_trie_key, data) + sizeof(uint32_t)*4,
|
||||||
sizeof(uint64_t),
|
sizeof(uint64_t),
|
||||||
@ -500,7 +504,8 @@ static int bpf_firewall_prepare_accounting_maps(Unit *u, bool enabled, int *fd_i
|
|||||||
|
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
if (*fd_ingress < 0) {
|
if (*fd_ingress < 0) {
|
||||||
r = bpf_map_new(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(uint64_t), 2, 0);
|
char *name = strjoina("I_", u->id);
|
||||||
|
r = bpf_map_new(name, BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(uint64_t), 2, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -508,8 +513,8 @@ static int bpf_firewall_prepare_accounting_maps(Unit *u, bool enabled, int *fd_i
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (*fd_egress < 0) {
|
if (*fd_egress < 0) {
|
||||||
|
char *name = strjoina("E_", u->id);
|
||||||
r = bpf_map_new(BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(uint64_t), 2, 0);
|
r = bpf_map_new(name, BPF_MAP_TYPE_ARRAY, sizeof(int), sizeof(uint64_t), 2, 0);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
@ -300,8 +300,16 @@ int bpf_program_cgroup_detach(BPFProgram *p) {
|
|||||||
return 0;
|
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;
|
union bpf_attr attr;
|
||||||
|
const char *n = name;
|
||||||
|
|
||||||
zero(attr);
|
zero(attr);
|
||||||
attr.map_type = type;
|
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.max_entries = max_entries;
|
||||||
attr.map_flags = flags;
|
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)));
|
return RET_NERRNO(bpf(BPF_MAP_CREATE, &attr, sizeof(attr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@ int bpf_program_deserialize_attachment_set(const char *v, FDSet *fds, Set **bpfs
|
|||||||
|
|
||||||
extern const struct hash_ops bpf_program_hash_ops;
|
extern const struct hash_ops bpf_program_hash_ops;
|
||||||
|
|
||||||
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);
|
||||||
int bpf_map_update_element(int fd, const void *key, void *value);
|
int bpf_map_update_element(int fd, const void *key, void *value);
|
||||||
int bpf_map_lookup_element(int fd, const void *key, void *value);
|
int bpf_map_lookup_element(int fd, const void *key, void *value);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user