eBPF Maps: How to update using bpftool from command line

I am using tc to attach my eBPF (C code compiled using clang), to network.

I am using eBPF Maps to store some data.

Specifically, I am using bpf_map_update_elem to update eBPF Maps from within the BPF Program, but I want to also change the contents of the map from outside the program.

Map structure:

struct rt_val { int ifaceno; int macaddr[6];
};
union key_4 { __u32 b32[2]; __u8 b8[8];
};
struct bpf_map_def SEC("maps") lpm_map_fwd = { .type = BPF_MAP_TYPE_LPM_TRIE, .key_size = 8, .value_size = sizeof(struct rt_val), .max_entries = 50, .map_flags = BPF_F_NO_PREALLOC,
};

Map updation, and lookup are fine.

But i want to dynamically change the contents of the eBPF Map, from outside the program execution.

Any comments/suggestion regarding the same would be much appreciated!

Resources:

System Specifics:

  • uname -r: 4.15.0-47-generic
  • OS: Ubuntu 18

1 Answer

You already found all the tools you need to update eBPF maps from user space.

bpf()

The bpf(cmd, attr, size) system call is used to perform the update. The cmd passed as first argument indicates what type of operation you want to perform: in your case, that would be BPF_MAP_UPDATE_ELEM. Then the manual page you linked explains how to build attr: in your case (for map updates), it should be:

struct { /* Used by BPF_MAP_*_ELEM and BPF_MAP_GET_NEXT_KEY commands */ __u32 map_fd; __aligned_u64 key; union { __aligned_u64 value; /* [...] */ }; __u64 flags;
};

Meaning you should build a union bpf_attr and pass it the file descriptor to the map, the key of the entry you want to update, the new value for that key, and possibly some flags.

The file descriptor for the map can be obtained:

  • from the path under the BPF virtual file system, if the map has been pinned beforehand,
  • from the id of the map, with another call to the bpf() system call, using the BPF_MAP_GET_FD_BY_ID command,
  • (or as a return value from the call to bpf() that created the map, but not in the case you used tc to load the program).

Note that libbpf (shipped with kernel or mirrored on GitHub) provides wrappers around the bpf() system call and can make things easier.

bpftool

In practice, you do not need to reimplement all of this. As you mentioned in the title, bpftool allows you to update maps from command line, without having to reimplement the whole process.

Get bpftool

Edit: On Ubuntu 19.10 (eoan), bpftool is packaged as part of the linux-tools-common package. Read below for instructions for older releases.

As of this writing, bpftool has not been packaged for Debian/Ubuntu, which means that you have to build it from source. It is shipped with the kernel, so it takes time to download, but building is actually very simple:

 $ git clone git:// $ cd linux $ cd tools/bpf/bpftool $ make
(# make install)
(# make doc doc-install)

Alternatively, there is an unofficial version packaged on this page (disclaimer: from my company). The packaged binary was statically built and should work on all x86_64 Linux machines.

Update maps

After that, you can use it to list the maps currently existing on your system:

# bpftool -f map show

The ids of each map will be displayed on the left. Find the id related to the map you want to update (or if the map was pinned, note its path, displayed with the -f option), and then use one of:

# bpftool map update id <id> key <key> value <new_value>
# bpftool map update pinned <path> key <key> value <new_value>

For example:

# bpftool map update id 17 key 0x1 0 0 0 0 0 0 0 value 0x1 0x2 0x3...

(Note: I would use an array of __u8s rather than ints for storing a MAC address in your struct rt_val. Your macaddr is likely to count for 24 bytes.)

In case you are unsure of how values are stored in the map, do not hesitate to dump it in the console:

# bpftool map dump id 17

More resources

I do not know of any existing bpftool tutorial, but you can find all the details in the manual pages for the tool. I also wrote some tips about it on Twitter.

6

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like