Topics

eBPF map - Control and Data plane concurrency #bcc

Simone Magnani
 

Hi everybody,

I am writing this email to ask for an opinion about how to address the following problem.

Lately, I have been trying to develop an eBPF program that extracts some per-flow values and stores them into an eBPF HASH_MAP, which is then read by the user-space that extracts the stored information.
When I start reading the map from user-space, all the entries should be deleted at the same time, and the data plane should keep storing the incoming data.
The solution that I have found is to use two maps (and programs) that are continuously swapped when the user-space read is triggered. In this way, when we read the 'old' map, the 'new' map keeps storing the new data.

At the same time, to speed up the lookup and delete operation, I could use the recently added "bpf_map_lookup_and_delete_batch" function to read and clear the map.

Do you think this could be an optimal solution, or are there other more efficient methods?

Thanks in advance for all the suggestions

Best Regards,
Simone

Yonghong Song
 

Your approach seems okay. You can use two maps or use map-in-map.
Using batch operation from user space should speedup the
deletion operation.

On Sat, May 9, 2020 at 5:31 AM <simonemagnani.96@...> wrote:

Hi everybody,

I am writing this email to ask for an opinion about how to address the following problem.

Lately, I have been trying to develop an eBPF program that extracts some per-flow values and stores them into an eBPF HASH_MAP, which is then read by the user-space that extracts the stored information.
When I start reading the map from user-space, all the entries should be deleted at the same time, and the data plane should keep storing the incoming data.
The solution that I have found is to use two maps (and programs) that are continuously swapped when the user-space read is triggered. In this way, when we read the 'old' map, the 'new' map keeps storing the new data.

At the same time, to speed up the lookup and delete operation, I could use the recently added "bpf_map_lookup_and_delete_batch" function to read and clear the map.

Do you think this could be an optimal solution, or are there other more efficient methods?

Thanks in advance for all the suggestions

Best Regards,
Simone

Simone Magnani
 

Thanks for the suggestion, now I feel more confident about this solution.

However, I have still problems with the map-in-map type: is it possible to use a map which has as key the 4 tcp-session identifier {srcIp, dstIp, srcPort, dstPort} and as value a BPF_ARRAY which is a list of some packets' headers belonging to that session?
As far as I undestood, a BPF_HASH_OF_MAPS key is coded as integer, and the value retrieved with lookup is the inner table fileDescriptor. Although, how do you initialize those inner arrays? I've tried to insert something, but what should I put as value? The inner map's fileDescriptor (how do I know it)?

Andrii Nakryiko
 

On Tue, May 12, 2020 at 2:19 AM <simonemagnani.96@...> wrote:

Thanks for the suggestion, now I feel more confident about this solution.

However, I have still problems with the map-in-map type: is it possible to use a map which has as key the 4 tcp-session identifier {srcIp, dstIp, srcPort, dstPort} and as value a BPF_ARRAY which is a list of some packets' headers belonging to that session?
As far as I undestood, a BPF_HASH_OF_MAPS key is coded as integer, and the value retrieved with lookup is the inner table fileDescriptor. Although, how do you initialize those inner arrays? I've tried to insert something, but what should I put as value? The inner map's fileDescriptor (how do I know it)?
No, HASH_OF_MAPS allows arbitrary-sized keys, just like normal
HASHMAP. Libbpf recently got a support for nicer map-in-map
declaration and initialization, you might want to check it out: [0].

[0] https://patchwork.ozlabs.org/project/netdev/patch/20200428064140.122796-4-andriin@.../