Skip to content

Commit

Permalink
manager: use built-in xdp prog
Browse files Browse the repository at this point in the history
Signed-off-by: Ric Li <[email protected]>
  • Loading branch information
ricmli committed Jan 26, 2024
1 parent db51136 commit 2214635
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 25 deletions.
7 changes: 7 additions & 0 deletions manager/gen_skel.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/sh

cp $1/manager.xdp.c .

clang -g -O2 -target bpf -c manager.xdp.c -o manager.xdp.o
llvm-strip -g manager.xdp.o
bpftool gen skeleton manager.xdp.o > xdp.skel.h
70 changes: 70 additions & 0 deletions manager/manager.xdp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
* Copyright(c) 2023 Intel Corporation
*/

//clang-format off
#include <linux/bpf.h>
//clang-format off

#include <bpf/bpf_helpers.h>
#include <xdp/parsing_helpers.h>
#include <xdp/xdp_helpers.h>

char LICENSE[] SEC("license") = "Dual BSD/GPL";

struct {
__uint(type, BPF_MAP_TYPE_ARRAY);
__uint(max_entries, 65536);
__type(key, int);
__type(value, int);
} udp4_dp_filter SEC(".maps");

#define DEFAULT_QUEUE_IDS 64

struct {
__uint(type, BPF_MAP_TYPE_XSKMAP);
__uint(key_size, sizeof(int));
__uint(value_size, sizeof(int));
__uint(max_entries, DEFAULT_QUEUE_IDS);
} xsks_map SEC(".maps");

volatile int refcnt = 1;

static int __always_inline lookup_udp4_dp(int dp) {
int* value;

value = bpf_map_lookup_elem(&udp4_dp_filter, &dp);
if (value && *value != 0) return 1;
return 0;
}

SEC("xdp")
int xsk_def_prog(struct xdp_md* ctx) {
if (!refcnt) return XDP_PASS;

void* data_end = (void*)(long)ctx->data_end;
void* data = (void*)(long)ctx->data;

struct hdr_cursor nh;
struct ethhdr* eth;
int eth_type;

nh.pos = data;
eth_type = parse_ethhdr(&nh, data_end, &eth);
if (eth_type != bpf_htons(ETH_P_IP)) return XDP_PASS;

struct iphdr* iphdr;
int ip_type;
ip_type = parse_iphdr(&nh, data_end, &iphdr);
if (ip_type != IPPROTO_UDP) return XDP_PASS;

struct udphdr* udphdr;
int ret;
ret = parse_udphdr(&nh, data_end, &udphdr);
if (ret < 0) return XDP_PASS;

int dst_port = bpf_ntohs(udphdr->dest);
if (lookup_udp4_dp(dst_port) == 0) return XDP_PASS;

return bpf_redirect_map(&xsks_map, ctx->rx_queue_index, XDP_PASS);
}
13 changes: 10 additions & 3 deletions manager/meson.build
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright 2023 Intel Corporation

project('mtl_manager', 'cpp', default_options: ['buildtype=release', 'cpp_std=c++17'])
project('mtl_manager', 'cpp', default_options: ['buildtype=release', 'cpp_std=c++17'], version: '0.2.0')

exec_env = host_machine.system()
set_variable('is_windows', exec_env == 'windows')
Expand All @@ -15,8 +15,6 @@ message('BUILD Environment: ' + exec_env)

cpp_c = meson.get_compiler('cpp')

sources = ['mtl_manager.cpp']

cpp_args = ['-std=c++17', '-Wall']
link_cpp_args = ['-lstdc++fs']

Expand All @@ -41,6 +39,15 @@ else
message('libxdp and libbpf not found, no af_xdp backend')
endif

# Generate XDP prog code
gen_skel = find_program('gen_skel.sh')
sekl = custom_target('skeleton',
output : ['xdp.skel.h'],
input : ['manager.xdp.c'],
command : [gen_skel] + meson.current_source_dir())

sources = ['mtl_manager.cpp', sekl]

executable('MtlManager', sources,
cpp_args: cpp_args,
link_args: link_cpp_args,
Expand Down
50 changes: 28 additions & 22 deletions manager/mtl_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <bpf/libbpf.h>
#include <xdp/libxdp.h>
#include <xdp/xsk.h>

#include "xdp.skel.h"
#endif

#include <net/if.h>
Expand Down Expand Up @@ -136,34 +138,39 @@ int mtl_interface::clear_flow_rules() {

#ifdef MTL_HAS_XDP_BACKEND
int mtl_interface::load_xdp() {
/* get xdp prog path from env or use manager default path */
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;
} else {
xdp_prog_path = "/tmp/imtl/xdp_prog.o";
}
/* 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 libxdp default prog for " + xdp_prog_path + " is not valid.");
"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 libxdp default prog for " + xdp_prog_path + " cannot load.");
log(log_level::WARNING, "Fallback to use built-in prog prog for " + xdp_prog_path +
" cannot be loaded.");
xdp_prog = nullptr;
} else {
if (xdp_program__attach(xdp_prog, ifindex, XDP_MODE_NATIVE, 0) < 0) {
log(log_level::WARNING,
"Failed to attach XDP program with native mode, try skb mode.");
if (xdp_program__attach(xdp_prog, ifindex, XDP_MODE_SKB, 0) < 0) {
log(log_level::ERROR, "Failed to attach XDP program " + xdp_prog_path);
xdp_program__close(xdp_prog);
return -1;
}
}
}
}

if (xdp_prog == nullptr) {
/* load built-in xdp prog from skeleton */
xdp_prog_path = "<built-in>";
struct manager_xdp* skel = manager_xdp__open();
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");
}

if (xdp_program__attach(xdp_prog, ifindex, XDP_MODE_NATIVE, 0) < 0) {
log(log_level::WARNING,
"Failed to attach XDP program with native mode, try skb mode.");
if (xdp_program__attach(xdp_prog, ifindex, XDP_MODE_SKB, 0) < 0) {
log(log_level::ERROR, "Failed to attach XDP program " + xdp_prog_path);
xdp_program__close(xdp_prog);
return -1;
}
}

Expand All @@ -183,7 +190,6 @@ int mtl_interface::load_xdp() {
return -1;
}

if (xdp_prog == nullptr) xdp_prog_path = "<libxdp_default>";
log(log_level::INFO, "Loaded xdp prog " + xdp_prog_path);
return 0;
}
Expand Down

0 comments on commit 2214635

Please sign in to comment.