Skip to content

Commit

Permalink
fix bpf map update
Browse files Browse the repository at this point in the history
Signed-off-by: Ric Li <[email protected]>
  • Loading branch information
ricmli committed Jan 29, 2024
1 parent e34f00b commit 462985b
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 27 deletions.
9 changes: 4 additions & 5 deletions manager/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ sudo ./build/MtlManager

This command will start the MTL Manager with root privileges, which are necessary for the advanced eBPF and network configurations and management tasks it performs.

## Run with our XDP program
## Run with another XDP program

We have a modified version of the original AF_XDP eBPF program which allows user to add or remove udp dest port in the eBPF program to act as a packet filter, please see [ebpf tool](../tools/ebpf) for how to build it.
We have a modified version of the original AF_XDP eBPF program which allows user to add or remove udp dest port in the eBPF program to act as a packet filter, this is built in the manager.

To run the MTL Manager with our XDP program, execute:
To run the MTL Manager with any other AF_XDP eBPF program, execute:

```bash
sudo MTL_XDP_PROG_PATH=/path/to/Media-Transport-Library/tools/ebpf/xsk.xdp.o ./build/MtlManager
sudo MTL_XDP_PROG_PATH=/path/to/xsk.xdp.o ./build/MtlManager
```

## Run in a Docker container
Expand All @@ -57,7 +57,6 @@ docker run -d \
--privileged --net=host \
-v /var/run/imtl:/var/run/imtl \
-v /sys/fs/bpf:/sys/fs/bpf \
-v "$(pwd)"/../tools/ebpf/xsk.xdp.o:/tmp/imtl/xdp_prog.o \
mtl-manager:latest
```

Expand Down
5 changes: 5 additions & 0 deletions manager/manager.xdp.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,8 @@ int xsk_def_prog(struct xdp_md* ctx) {

return bpf_redirect_map(&xsks_map, ctx->rx_queue_index, XDP_PASS);
}

#define XDP_METADATA_SECTION "xdp_metadata"
#define XSK_PROG_VERSION 1

__uint(xsk_prog_version, XSK_PROG_VERSION) SEC(XDP_METADATA_SECTION);
71 changes: 49 additions & 22 deletions manager/mtl_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class mtl_interface {
const int ifindex;
struct xdp_program* xdp_prog;
int xsks_map_fd;
int udp4_dp_filter_fd;
enum xdp_attach_mode xdp_mode;

private:
void log(const log_level& level, const std::string& message) const {
Expand All @@ -47,7 +49,11 @@ class mtl_interface {
};

mtl_interface::mtl_interface(int ifindex)
: ifindex(ifindex), xdp_prog(nullptr), xsks_map_fd(-1) {
: ifindex(ifindex),
xdp_prog(nullptr),
xsks_map_fd(-1),
udp4_dp_filter_fd(-1),
xdp_mode(XDP_MODE_UNSPEC) {
#ifdef MTL_HAS_XDP_BACKEND
if (load_xdp() < 0) throw std::runtime_error("Failed to load XDP program.");
#endif
Expand All @@ -71,15 +77,13 @@ int mtl_interface::update_udp_dp_filter(uint16_t dst_port, bool add) {
return -1;
}

int map_fd = bpf_map__fd(
bpf_object__find_map_by_name(xdp_program__bpf_obj(xdp_prog), "udp4_dp_filter"));
if (map_fd < 0) {
log(log_level::WARNING, "Failed to get udp4_dp_filter map fd");
if (udp4_dp_filter_fd < 0) {
log(log_level::WARNING, "No valid udp4_dp_filter map fd");
return -1;
}

int value = add ? 1 : 0;
if (bpf_map_update_elem(map_fd, &dst_port, &value, BPF_ANY) < 0) {
if (bpf_map_update_elem(udp4_dp_filter_fd, &dst_port, &value, BPF_ANY) < 0) {
log(log_level::WARNING, "Failed to update udp4_dp_filter map");
return -1;
}
Expand Down Expand Up @@ -139,29 +143,38 @@ int mtl_interface::clear_flow_rules() {
#ifdef MTL_HAS_XDP_BACKEND
int mtl_interface::load_xdp() {
/* get customized xdp prog path from env */
std::string xdp_prog_path = getenv("MTL_XDP_PROG_PATH");

if (!std::filesystem::is_regular_file(xdp_prog_path)) {
log(log_level::WARNING,
"Fallback to use built-in prog for " + xdp_prog_path + " is not valid.");
} else {
xdp_prog = xdp_program__open_file(xdp_prog_path.c_str(), NULL, NULL);
if (libxdp_get_error(xdp_prog)) {
log(log_level::WARNING, "Fallback to use built-in prog prog for " + xdp_prog_path +
" cannot be loaded.");
xdp_prog = nullptr;
std::string xdp_prog_path;
char* xdp_prog_path_env = getenv("MTL_XDP_PROG_PATH");
if (xdp_prog_path_env != nullptr) {
xdp_prog_path = xdp_prog_path_env;
if (!std::filesystem::is_regular_file(xdp_prog_path)) {
log(log_level::WARNING,
"Fallback to use built-in prog for " + xdp_prog_path + " is not valid.");
} else {
xdp_prog = xdp_program__open_file(xdp_prog_path.c_str(), NULL, NULL);
if (libxdp_get_error(xdp_prog)) {
log(log_level::WARNING, "Fallback to use built-in prog prog for " +
xdp_prog_path + " cannot be loaded.");
xdp_prog = nullptr;
}
}
} else {
xdp_prog_path = "<built-in>";
}

struct manager_xdp* skel = NULL;
if (xdp_prog == nullptr) {
/* load built-in xdp prog from skeleton */
xdp_prog_path = "<built-in>";
struct manager_xdp* skel = manager_xdp__open();
skel = manager_xdp__open_and_load();
if (!skel) {
log(log_level::ERROR, "Failed to open built-in xdp prog skeleton");
return -1;
}
xdp_prog = xdp_program__from_bpf_obj(skel->obj, "xdp");
xdp_prog = xdp_program__from_fd(bpf_program__fd(skel->progs.xsk_def_prog));
if (libxdp_get_error(xdp_prog)) {
log(log_level::ERROR, "Failed to load built-in xdp prog");
return -1;
}
}

if (xdp_program__attach(xdp_prog, ifindex, XDP_MODE_NATIVE, 0) < 0) {
Expand All @@ -172,11 +185,24 @@ int mtl_interface::load_xdp() {
xdp_program__close(xdp_prog);
return -1;
}
xdp_mode = XDP_MODE_SKB;
}
xdp_mode = XDP_MODE_NATIVE;

struct bpf_map* map = skel ? skel->maps.udp4_dp_filter
: bpf_object__find_map_by_name(
xdp_program__bpf_obj(xdp_prog), "udp4_dp_filter");
udp4_dp_filter_fd = bpf_map__fd(map);
if (udp4_dp_filter_fd < 0) {
log(log_level::ERROR, "Failed to get udp4_dp_filter fd");
xdp_program__detach(xdp_prog, ifindex, xdp_mode, 0);
xdp_program__close(xdp_prog);
return -1;
}

if (xsk_setup_xdp_prog(ifindex, &xsks_map_fd) < 0 || xsks_map_fd < 0) {
if (xdp_prog != nullptr) {
xdp_program__detach(xdp_prog, ifindex, XDP_MODE_NATIVE, 0);
xdp_program__detach(xdp_prog, ifindex, xdp_mode, 0);
xdp_program__close(xdp_prog);
}
/* unload all xdp programs for the interface */
Expand All @@ -196,7 +222,7 @@ int mtl_interface::load_xdp() {

void mtl_interface::unload_xdp() {
if (xdp_prog != nullptr) {
xdp_program__detach(xdp_prog, ifindex, XDP_MODE_NATIVE, 0);
xdp_program__detach(xdp_prog, ifindex, xdp_mode, 0);
xdp_program__close(xdp_prog);
xdp_prog = nullptr;
} else {
Expand All @@ -208,6 +234,7 @@ void mtl_interface::unload_xdp() {
xdp_multiprog__detach(multiprog);
xdp_multiprog__close(multiprog);
}

log(log_level::INFO, "Unloaded xdp prog");
}
#endif
Expand Down

0 comments on commit 462985b

Please sign in to comment.