上一篇讲了xdp的hook点,我猜你肯定想到了xdp程序是如何与网卡驱动关联上的,也即如何在bpf_prog_run_xdp中被成功调用。

先看看bpf_prog_run_xdp函数的代码:

static __always_inline u32 bpf_prog_run_xdp(const struct bpf_prog *prog,struct xdp_buff *xdp)
{/* Caller needs to hold rcu_read_lock() (!), otherwise program* can be released while still running, or map elements could be* freed early while still having concurrent users. XDP fastpath* already takes rcu_read_lock() when fetching the program, so* it's not necessary here anymore.*/return BPF_PROG_RUN(prog, xdp);
}
#define BPF_PROG_RUN(filter, ctx)  (*(filter)->bpf_func)(ctx, (filter)->insnsi)

看到这个代码,可能会有疑问,xdp程序只能挂载一个功能函数 ?是的,确实是只能挂载一个,等你看到struct bpf_prog对象更新的逻辑就会明白的。

很明显,我们要跟踪struct bpf_prog *prog 对象来自哪里,下面我们看看bpf_prog_run_xdp的上级函数ixgbe_run_xdp,ixgbe_run_xdp是ixgbe网卡xdp最关键的函数了,贴出来大家看看。

static struct sk_buff *ixgbe_run_xdp(struct ixgbe_adapter *adapter,struct ixgbe_ring *rx_ring,struct xdp_buff *xdp)
{int err, result = IXGBE_XDP_PASS;struct bpf_prog *xdp_prog;struct xdp_frame *xdpf;u32 act;rcu_read_lock();xdp_prog = READ_ONCE(rx_ring->xdp_prog);if (!xdp_prog)goto xdp_out;prefetchw(xdp->data_hard_start); /* xdp_frame write */act = bpf_prog_run_xdp(xdp_prog, xdp);switch (act) {case XDP_PASS:break;case XDP_TX:xdpf = convert_to_xdp_frame(xdp);if (unlikely(!xdpf)) {result = IXGBE_XDP_CONSUMED;break;}result = ixgbe_xmit_xdp_ring(adapter, xdpf);break;case XDP_REDIRECT:err = xdp_do_redirect(adapter->netdev, xdp, xdp_prog);if (!err)result = IXGBE_XDP_REDIR;elseresult = IXGBE_XDP_CONSUMED;break;default:bpf_warn_invalid_xdp_action(act);/* fallthrough */case XDP_ABORTED:trace_xdp_exception(rx_ring->netdev, xdp_prog, act);/* fallthrough -- handle aborts by dropping packet */case XDP_DROP:result = IXGBE_XDP_CONSUMED;break;}
xdp_out:rcu_read_unlock();return ERR_PTR(-result);
}

你一定看过很多xdp的其他文章,对于XDP_PASS/XDP_TX/XDP_REDIRECT等字眼很熟,这个函数就是ixbge xdp最关键的函数,我们前面讲的bpf_prog_run_xdp也是在这个函数中被唯一调用。

当然这些都不是重点,重点是我们想跟踪bpf_prog_run_xdp的struct bpf_prog *xdp_prog对象是哪里来的,所以我们还要继续往下看。

xdp_prog = READ_ONCE(rx_ring->xdp_prog) 这行代码已经告诉你bpf_prog_run_xdp的struct bpf_prog *xdp_prog对象来自于struct ixgbe_ring *rx_ring对象的xdp_prog对象。

继续跟踪代码,发现struct ixgbe_ring *rx_ring对象的xdp_prog对象又来自于struct ixgbe_adapter *对象的xdp_prog。而struct ixgbe_adapter *对象xdp_prog实在函数 ixgbe_xdp_setup初始化的。

static int ixgbe_xdp_setup(struct net_device *dev, struct bpf_prog *prog)
{int i, frame_size = dev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;struct ixgbe_adapter *adapter = netdev_priv(dev);struct bpf_prog *old_prog;if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)return -EINVAL;if (adapter->flags & IXGBE_FLAG_DCB_ENABLED)return -EINVAL;/* verify ixgbe ring attributes are sufficient for XDP */for (i = 0; i < adapter->num_rx_queues; i++) {struct ixgbe_ring *ring = adapter->rx_ring[i];if (ring_is_rsc_enabled(ring))return -EINVAL;if (frame_size > ixgbe_rx_bufsz(ring))return -EINVAL;}if (nr_cpu_ids > MAX_XDP_QUEUES)return -ENOMEM;old_prog = xchg(&adapter->xdp_prog, prog);/* If transitioning XDP modes reconfigure rings */if (!!prog != !!old_prog) {int err = ixgbe_setup_tc(dev, adapter->hw_tcs);if (err) {rcu_assign_pointer(adapter->xdp_prog, old_prog);return -EINVAL;}} else {for (i = 0; i < adapter->num_rx_queues; i++)(void)xchg(&adapter->rx_ring[i]->xdp_prog,adapter->xdp_prog);}if (old_prog)bpf_prog_put(old_prog);return 0;
}

而struct ixgbe_adapter *对象xdp_prog实在函数 ixgbe_xdp_setup中初始化的,所以我们的问题就变成了ixgbe_xdp_setup在什么时候调用。当日前面也提过了xdp只能挂载一个功能性函数,也在上面的ixgbe_xdp_setup函数中得到了印证。

继续ixgbe_xdp_setup函数的调用用关系:

ixgbe_xdp_setup

ixgbe_xdp(.ndo_bpf = ixgbe_xdp)

dev_xdp_install

dev_change_xdp_fd

do_setlink

--------------

bpf_set_link_xdp_fd

main (samples/bpf/xdp1_user.c)

好了,到这里,你肯定知道怎么回事了。

很明显在xdp的用户态程序中(比如samples/bpf/xdp1_user.c),一定会调用bpf_set_link_xdp_fd这个用户态函数,这个函数 通过netlink方式实现了网卡的xdp功能函数设置和替换。

这个函数中真正调用了.ndo_bpf = ixgbe_xdp,实现了网卡的prog对象切换。

static int dev_xdp_install(struct net_device *dev, bpf_op_t bpf_op,struct netlink_ext_ack *extack, u32 flags,struct bpf_prog *prog)
{struct netdev_bpf xdp;memset(&xdp, 0, sizeof(xdp));if (flags & XDP_FLAGS_HW_MODE)xdp.command = XDP_SETUP_PROG_HW;elsexdp.command = XDP_SETUP_PROG;xdp.extack = extack;xdp.flags = flags;xdp.prog = prog;return bpf_op(dev, &xdp);
}

好了,讲到这里就结束了,估计你还有疑问,xdp的功能程序存储在哪里,它又是怎么被找到的。

下一篇文章再讲。

xdp 程序如何挂载相关推荐

  1. linux自己制作卸载u盘程序,linux挂载和卸载U盘

    挂载: mkdir /mnt/usb mount -t vfat /dev/sdb1 /mnt/usb ls /mnt/usb 这一句是查看/mnt/usb里面的文件 我们现在看到的1.txt跟2.t ...

  2. XDP/eBPF — 架构设计

    目录 文章目录 目录 XDP 的架构设计 XDP 的包处理 XDP 程序示例 XDP 的架构设计 XDP 总体设计包括以下几个部分: XDP 驱动:是网卡驱动中的一个 XDP 程序的挂载点,每当网卡接 ...

  3. ShareList 列表程序-挂载GD/OD/蓝奏云/天翼云/和彩云......

    标题是不是很牛皮,确实,作者的思路非常符合我的心意,把网盘集合起来,还能省域名,对不对i( •̀ ω •́ )✧ 搭建sharelist 简介 序 功能说明 准备 手动宝塔安装 docker安装 部署 ...

  4. 抖音seo源码混剪工具@小程序开发自主挂载

    原创文章禁止任何人抄袭,或者复用一经发现立即举报 抖音seo源码技术搭建,抖音 抖音seo源码搭建,抖音seo源码,抖音seo源码搭建的基础底层框架语言是后台语言PHP:python来编程开发的,抖音 ...

  5. CAD二次开发--像纬地与CASS程序一样双击桌面图标实现插件的自动挂载(不用netload也不用进入后输入挂载命令)

    先说一下我为什么要写这个文章,首先这一块我自己研究并查找了很久,始终没有很好的办法.二是网络上很多办法鱼龙混杂,要不很复杂,要不现在就已经过时了,总之不能解决问题.干脆自己写一下,防止遗忘! 要明白C ...

  6. Linux网络新技术基石 |​eBPF and XDP

    hi,大家好,欢迎来到极客重生的世界,今天给大家分享的是Linux 网络新技术,当前正流行网络技是什么?那就是eBPF和XDP技术,Cilium+eBPF超级火热,Google GCP也刚刚全面转过来 ...

  7. [译] Cilium:BPF 和 XDP 参考指南(2021)

    Cilium:BPF和XDP参考指南_RToax-CSDN博客Table of ContentsBPF体系结构指令系统辅助功能地图对象固定尾叫BPF到BPF呼叫准时制硬化减负工具链开发环境虚拟机本文档 ...

  8. Generic XDP Hook

    上一篇文章讲过bpf_prog_run_xdp是XDP 程序的最终调用函数,想要跟踪Generic XDP的代码可以从该函数入手.很显然你不应该从driver/,而是已改在net/目录下检索. jen ...

  9. 借助libbpf/libxdp使用AF_XDP,我们都需要做什么——以一个简单程序为例

    前言 AF_XDP是一种Linux提供的针对高性能数据包处理进行优化的地址族协议,为了进一步的理解和熟悉,我们以一个返回IPv4 ICMP Ping报文的程序为例,看看借助libbpf/libxdp使 ...

最新文章

  1. SPOJ MULTQ3 7299 Multiples of 3 (区间更新)
  2. 剑指offer 变态跳台阶
  3. android 摄像头预览左右镜像_OpenJDK镜像的tag说明
  4. 信息学奥赛一本通 1919:【02NOIP普及组】选数 | 洛谷 P1036 [NOIP2002 普及组] 选数
  5. 千兆网线8根线定义图_网线水晶头如何制作及怎么测试?
  6. outputStream
  7. Gnome Tweak Tool 3.0.5发布
  8. 智慧食堂项目策划书(商业计划书/立项计划)
  9. 《App违法违规收集使用个人信息自评估指南》
  10. 常见的USB接口类型
  11. dlna android电视,DLNA推送安卓手机投屏电视
  12. 计算机系统时间无法更改,Win7电脑无法修改系统时间如何解决?
  13. java poi 设置标题_java POI操作word2010简单实现多级标题结构
  14. 嵌入式软件工程师学习规划
  15. HTML5期末大作业:电影网站设计——电影泰坦尼克号(4页) HTML+CSS+JavaScript 学生HTML个人网页作业作品下载 个人网页设计制作 大学生个人网站作业模板 简单个人网页制作
  16. 微信PC版多开的方法
  17. mysql用户主机设置密码_MySQL用户账号管理(添加、删除、限制、设置密码、远程访问)...
  18. [hiho 14]并查集
  19. pycharm和Anaconda强强联手
  20. 音视频基础知识-时间戳的理解

热门文章

  1. 实用前端标注图片剪裁工具-AILabel.js
  2. 百度网盘加速无限试用_百度网盘上线 单日/单次 加速功能,最低仅需 2 块钱
  3. 微信小程序调用相册和相机
  4. Linux如何安装FTDI D2XX驱动
  5. echarts画折线图和数据excel导出
  6. LSwarm:复杂城市场景下覆盖受限的大集群高效避碰(Swarm-2019)
  7. mysql union update_MYSQL:union, 以及常用函数
  8. Python词云实现
  9. iOS 最新版9.3 disk image
  10. 【TB-02模组专题②】学习如何对接天猫精灵语音控制的过程;