XDP类型的BPF程序

目录

1. Loading via iproute2 ip

2 bpf程序绑定

3 bpf程序触发


经过上一节的内容,bpf程序和map已经加载到内核当中了。什么时候bpf程序才能发挥它的作用呢?
这就需要bpf的应用系统把其挂载到适当的钩子上,当钩子所在点的路径被执行,钩子被触发,BPF程序得以执行。

目前应用bpf的子系统分为两大类:

  • tracing:kprobe、tracepoint、perf_event
  • filter:sk_filter、sched_cls、sched_act、xdp、cg_skb

 接下来分析XDP类型的bpf程序的绑定和触发过程

1. Loading via iproute2 ip

It does seem overkill to write a C program to simply load and attach a specific BPF-program. However, we still include this in the tutorial since it will help you integrate BPF into other Open Source projects.

As an alternative to writing a new loader, the standard iproute2 tool also contains a BPF ELF loader. However, this loader is not based on libbpf, which unfortunately makes it incompatible when starting to use BPF maps.

The iproute2 loader can be used with the standard ip tool; so in this case you can actually load our ELF-file xdp_pass_kern.o (where we named our ELF section “xdp”) like this:

ip link set dev lo xdpgeneric obj xdp_pass_kern.o sec xdp

Listing the device via ip link show also shows the XDP info:

$ ip link show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 xdpgeneric qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    prog/xdp id 220 tag 3b185187f1855c4c jited

Removing the XDP program again from the device:

ip link set dev lo xdpgeneric off

2 bpf程序绑定

使用的是netlink消息跟内核通信,把fd和dev信息以及flag发送到内核,netlink使用的是NETLINK_ROUTE消息ID

int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)
{
    int sock, seq = 0, ret;
    struct nlattr *nla, *nla_xdp;
    struct {
        struct nlmsghdr  nh;
        struct ifinfomsg ifinfo;
        char             attrbuf[64];
    } req;
    __u32 nl_pid;
    sock = libbpf_netlink_open(&nl_pid);
    if (sock < 0)
        return sock;
    memset(&req, 0, sizeof(req));
    req.nh.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
    req.nh.nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
    req.nh.nlmsg_type = RTM_SETLINK;
    req.nh.nlmsg_pid = 0;
    req.nh.nlmsg_seq = ++seq;
    req.ifinfo.ifi_family = AF_UNSPEC;
    req.ifinfo.ifi_index = ifindex;
    /* started nested attribute for XDP */
    nla = (struct nlattr *)(((char *)&req)
                + NLMSG_ALIGN(req.nh.nlmsg_len));
    nla->nla_type = NLA_F_NESTED | IFLA_XDP;
    nla->nla_len = NLA_HDRLEN;
    /* add XDP fd */
    nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
    nla_xdp->nla_type = IFLA_XDP_FD;
    nla_xdp->nla_len = NLA_HDRLEN + sizeof(int);
    memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd));
    nla->nla_len += nla_xdp->nla_len;
    /* if user passed in any flags, add those too */
    if (flags) {
        nla_xdp = (struct nlattr *)((char *)nla + nla->nla_len);
        nla_xdp->nla_type = IFLA_XDP_FLAGS;
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值