bpf_xdp_attach
int bpf_xdp_attach(int ifindex, int prog_fd, __u32 flags, const struct bpf_xdp_attach_opts *opts)
{
int old_prog_fd, err;
//首先检查一下对应的flags是否合法
if (!OPTS_VALID(opts, bpf_xdp_attach_opts))
return libbpf_err(-EINVAL);
//从opts中获取fd值,
//如果old_prog_fd不为空,设置标志位位replace,替换掉原来的程序
//否则将old_prog_fd设置为-1
old_prog_fd = OPTS_GET(opts, old_prog_fd, 0);
if (old_prog_fd)
flags |= XDP_FLAGS_REPLACE;
else
old_prog_fd = -1;
//将BPF程序附加到指定的网络接口上
err = __bpf_set_link_xdp_fd_replace(ifindex, prog_fd, old_prog_fd, flags);
return libbpf_err(err);
}
首先我们来看一下对应的:
struct bpf_xdp_attach_opts {
size_t sz;
int old_prog_fd;
size_t :0;
};
我们看一下如何使用上面这个函数, 这个函数的第一个参数是ifindex, -1表示对应的
bpf_xdp_attach(ifindex, -1, flags, opts);
关闭对应的程序- 我们可以看一下对应的flags
#define XDP_FLAGS_UPDATE_IF_NOEXIST (1U << 0)
#define XDP_FLAGS_SKB_MODE (1U << 1)
#define XDP_FLAGS_DRV_MODE (1U << 2)
#define XDP_FLAGS_HW_MODE (1U << 3)
#define XDP_FLAGS_REPLACE (1U << 4)
XDP_FLAGS_UPDATE_IF_NOEXIST
:如果设置此标志,并且网络接口上没有已附加的XDP程序,则更新该接口的XDP程序。XDP_FLAGS_SKB_MODE
:设置此标志表示XDP程序将在skb(socket buffer)模式下运行,这是XDP的传统运行模式。XDP_FLAGS_DRV_MODE
:设置此标志表示XDP程序将在驱动模式下运行,这通常用于某些特定的硬件或驱动程序。XDP_FLAGS_HW_MODE
:设置此标志表示XDP程序将在硬件模式下运行,这要求硬件支持XDP。XDP_FLAGS_REPLACE
:设置此标志表示如果网络接口上已经有一个XDP程序,那么新的XDP程序将替换它。
然后是这个函数 __bpf_set_link_xdp_fd_replace(ifindex, prog_fd, old_prog_fd, flags)
挂载对应的程序
然后是下面这个函数,我们也来分析一下,函数参数我们在之前已经说的的比较清晰了, 下面这个函数最终会调用一个libbpf_netlink_send_recv
函数, 这个函数是通过netlink这个套接字来完成对应的功能的, 那么什么东西是net link呢, net link是一个提供用户空间进程与内核之间的通信方法, 这种方式是比ioctl要好很多的,
static int __bpf_set_link_xdp_fd_replace(
int ifindex, int fd, int old_fd, __u32 flags)
{
struct nlattr *nla;
int ret;
struct libbpf_nla_req req;
memset(