Re: Notification when an eBPF map is modified

Raffaele Sommese

I think that I need kprobe, map_update_elem and map_delete_elem are
defined in kernel space.
Thank You,
Il giorno gio 2 ago 2018 alle ore 17:39 Sunny Klair
<sunny@...> ha scritto:

You likely want uprobes if your function is defined in userspace, not kprobes (which are for functions defined in kernel space).

relevant link:

- Sunny

On Thu, Aug 2, 2018 at 11:36 AM, Raffaele Sommese <raffysommy@...> wrote:

I have tried to use kprobe but it fails when I try to attach a kprobe
on that function with this error: raise Exception("Failed to attach
BPF to kprobe")
I use b.attach_kprobe(event="map_update_elem", fn_name="hello") for
the attaching, and int hello(struct pt_regs *ctx,struct bpf_map *map)
as bpf function.
(I use basically the code of example right now).
Is this the right way? Or I can attach my ebpf program only to syscall?
Thank You,
Il giorno mer 1 ago 2018 alle ore 17:08 Y Song <ys114321@...> ha scritto:

On Wed, Aug 1, 2018 at 2:36 AM, Raffaele Sommese <raffysommy@...> wrote:
Hello everybody,
I was looking for a similar mechanism,
I need to trace an event on map update/delete, I have tried with
tracepoint but I can recover only the file descriptor of map and I
need the map id too (or the map name).
Is there some other solution to trace this event and recover this data?
bpf tracepoints have been removed from recent linux so the you need to
use kprobe to trace update/delete.

typical map_update_elem and map_delete_elem first argument is
'struct bpf_map *map', you can get name and id from there:

struct bpf_map {
/* The first two cachelines with read-mostly members of which some
* are also accessed in fast-path (e.g. ops, max_entries).
const struct bpf_map_ops *ops ____cacheline_aligned;
struct bpf_map *inner_map_meta;
void *security;
enum bpf_map_type map_type;
u32 key_size;
u32 value_size;
u32 max_entries;
u32 map_flags;
u32 pages;
u32 id;
int numa_node;
u32 btf_key_type_id;
u32 btf_value_type_id;
struct btf *btf;
bool unpriv_array;
/* 55 bytes hole */

/* The 3rd and 4th cacheline with misc members to avoid false sharing
* particularly with refcounting.
struct user_struct *user ____cacheline_aligned;
atomic_t refcnt;
atomic_t usercnt;
struct work_struct work;
char name[BPF_OBJ_NAME_LEN];

I prefer to avoid to modify the kernel code.
Thank You,
Best Regards
Il giorno sab 17 feb 2018 alle ore 18:41 Jesper Dangaard Brouer via
iovisor-dev <iovisor-dev@...> ha scritto:

On Sat, 17 Feb 2018 13:49:22 +0000 Teng Qin via iovisor-dev <iovisor-dev@...> wrote:

We were looking for a mechanism transparent to the eBPF program, though.
A possible rational is to have an hot-standby copy of the program
(including the state) in some other location, but I don't want my
dataplane to be aware of that.


You could also (use another BPF program or ftrace) to trace the
bpf_map_update_elem Tracepoint. But in that case you get all update calls
and would need to filter for the one you are interested on your own:)
That is a good idea.

Try it out via perf-record to see if it contains what you need:

$ perf record -e bpf:bpf_map_update_elem -a

$ perf script
xdp_redirect_ma 2273 [011] 261187.968223: bpf:bpf_map_update_elem: map type= ufd=4 key=[00 00 00 00] val=[07 00 00 00]

Looking at the above output and tracepoint kernel code, we should
extend that with a map_id to easily identify/filter what map you are
interested in.

See patch below signature (not even compile tested).

Example for attaching to tracepoints see:

Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat

tracepoint: add map id to bpf tracepoints

From: Jesper Dangaard Brouer <brouer@...>

include/trace/events/bpf.h | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/trace/events/bpf.h b/include/trace/events/bpf.h
index 150185647e6b..e6479ba45261 100644
--- a/include/trace/events/bpf.h
+++ b/include/trace/events/bpf.h
@@ -140,7 +140,7 @@ TRACE_EVENT(bpf_map_create,
__entry->flags = map->map_flags;
__entry->ufd = ufd;
+// TODO also add map_id here
TP_printk("map type=%s ufd=%d key=%u val=%u max=%u flags=%x",
__print_symbolic(__entry->type, __MAP_TYPE_SYM_TAB),
__entry->ufd, __entry->size_key, __entry->size_value,
@@ -199,15 +199,18 @@ DECLARE_EVENT_CLASS(bpf_obj_map,
__field(u32, type)
__field(int, ufd)
__string(path, pname->name)
+ __field(u32, map_id)

__assign_str(path, pname->name);
__entry->type = map->map_type;
__entry->ufd = ufd;
+ __entry->map_id = map->id;

- TP_printk("map type=%s ufd=%d path=%s",
+ TP_printk("map id=%u type=%s ufd=%d path=%s",
+ __entry->map_id,
__print_symbolic(__entry->type, __MAP_TYPE_SYM_TAB),
__entry->ufd, __get_str(path))
@@ -244,6 +247,7 @@ DECLARE_EVENT_CLASS(bpf_map_keyval,
__dynamic_array(u8, val, map->value_size)
__field(bool, val_trunc)
__field(int, ufd)
+ __field(u32, map_id)

@@ -255,9 +259,11 @@ DECLARE_EVENT_CLASS(bpf_map_keyval,
__entry->val_len = min(map->value_size, 16U);
__entry->val_trunc = map->value_size != __entry->val_len;
__entry->ufd = ufd;
+ __entry->map_id = map->id;

- TP_printk("map type=%s ufd=%d key=[%s%s] val=[%s%s]",
+ TP_printk("map id=%d type=%s ufd=%d key=[%s%s] val=[%s%s]",
+ __entry->map_id,
__print_symbolic(__entry->type, __MAP_TYPE_SYM_TAB),
__print_hex(__get_dynamic_array(key), __entry->key_len),
iovisor-dev mailing list

Raffaele Sommese
About me:
Gpg Key:
GPG key ID: 0x830b1428cf91db2a on

Raffaele Sommese
About me:
Gpg Key:
GPG key ID: 0x830b1428cf91db2a on

Raffaele Sommese
About me:
Gpg Key:
GPG key ID: 0x830b1428cf91db2a on

Join to automatically receive all group messages.