1. 用 tc 加载 BPF 程序

给定一个为 tc 编译的 BPF 对象文件 prog.o, 可以通过 tc 命令将其加载到一个网 络设备(netdevice)。但与 XDP 不同,设备是否支持 attach BPF 程序并不依赖驱动 (即任何网络设备都支持 tc BPF)。下面的命令可以将程序 attach 到 em1 的ingress 网络:

$ tc qdisc add dev em1 clsact

$ tc filter add dev em1 ingress bpf da obj prog.o

第一步创建了一个 clsact qdisc (Linux 排队规则,Linux queueing discipline)。

clsact 是一个 dummy qdisc,和 ingress qdisc 类似,可以持有(hold)分类器和 动作(classifier and actions),但不执行真正的排队(queueing)。后面 attach bpf 分类器需要用到它。clsact qdisc 提供了两个特殊的 hook:ingress and egress,分类器可以 attach 到这两个 hook 点。这两个 hook 都位于 datapath 的 关键收发路径上,设备 em1 的每个包都会经过这两个点。这两个 hook 分别会被下面的内 核函数调用:

  • ingress hook:__netif_receive_skb_core() -> sch_handle_ingress()
  • egress hook:__dev_queue_xmit() -> sch_handle_egress()

类似地,将程序 attach 到 egress hook:

$ tc filter add dev em1 egress bpf da obj prog.o

第二条命令,tc filter 选择了在 da(direct-action)模式中使用 bpfda 是 推荐的模式,并且应该永远指定这个参数。粗略地说,da 模式表示 bpf 分类器不需 要调用外部的 tc action 模块。事实上 bpf 分类器也完全不需要调用外部模块,因 为所有的 packet mangling、转发或其他类型的 action 都可以在这单个 BPF 程序内完成 ,因此执行会明显更快。

配置了这两条命令之后,程序就 attach 完成了,接下来只要有包经过这个设备,就会触发 这个程序执行。和 XDP 类似,如果没有使用默认 section 名字,那可以在加载时指定,例 如指定 section 为 foobar

$ tc filter add dev em1 egress bpf da obj prog.o sec foobar

查看已经 attach 的程序:

$ tc filter show dev em1 ingress

filter protocol all pref 49152 bpf

filter protocol all pref 49152 bpf handle 0x1 prog.o:[ingress] direct-action id 1 tag c5f7825e5dac396f

$ tc filter show dev em1 egress

filter protocol all pref 49152 bpf

filter protocol all pref 49152 bpf handle 0x1 prog.o:[egress] direct-action id 2 tag b2fd5adc0f262714

输出中的 prog.o:[ingress] 表示 section ingress 中的程序是从 文件 prog.o 加 载的,而且 bpf 工作在 direct-action 模式。上面还打印了程序的 id 和 tag, 其中 tag 是指令流(instruction stream)的哈希,可以关联到对应的对象文件或用perf 查看调用栈信息。id 是一个操作系统层唯一的 BPF 程序标识符,可以用 bpftool 进一步查看或 dump 相关的程序信息。

程序优先级(pref)和句柄(handle

在上面的 show 命令中,tc 还打印出了 pref 49152 和 handle 0x1。如果之前没有 通过命令行显式指定,这两个数据就会自动生成。pref 表示优先级,如果指定了多个分 类器,它们会按照优先级从高到低依次执行;handle 是一个标识符,在加载了同一分类器的多 个实例并且它们的优先级(pref)都一样的情况下会用到这个标识符。因为 在 BPF 的场景下,单个程序就足够了,因此 pref 和 handle 通常情况下都可以忽略。

除非打算后面原子地替换 attached BPF 程序,否则不建议在加载时显式指定 pref 和 handle。显式指定这两个参数的好处是,后面执行 replace 操作时,就不需要再去动 态地查询这两个值。显式指定 pref 和 handle 时的加载命令:

$ tc filter add dev em1 ingress pref 1 handle 1 bpf da obj prog.o sec foobar$ tc filter show dev em1 ingress
filter protocol all pref 1 bpf
filter protocol all pref 1 bpf handle 0x1 prog.o:[foobar] direct-action id 1 tag c5f7825e5dac396f

对应的原子 replace 命令:将 ingress hook 处的已有程序替换为 prog.o 文件中 foobar section 中的新 BPF 程序

$ tc filter replace dev em1 ingress pref 1 handle 1 bpf da obj prog.o sec foobar

2. 用 tc 删除 BPF 程序

要分别从 ingress 和 egress 删除所有 attach 的程序

$ tc filter del dev em1 ingress
$ tc filter del dev em1 egress

要从 netdevice 删除整个 clsact qdisc(会隐式地删除 attach 到 ingress 和 egress hook 上面的所有程序),执行


$ tc qdisc del dev em1 clsact

3. offload 到网卡

如果网卡驱动支持 tc BPF 程序,那也可以将它们 offload 到网卡 。Netronome 的 nfp 网卡对 XDP 和 tc BPF 程序都支持 offload。

$ tc qdisc add dev em1 clsact
$ tc filter replace dev em1 ingress pref 1 handle 1 bpf skip_sw da obj prog.o
Error: TC offload is disabled on net device.
We have an error talking to the kernel

如果显式以上错误,那需要先启用网卡的 hw-tc-offload 功能:

$ ethtool -K em1 hw-tc-offload on$ tc qdisc add dev em1 clsact
$ tc filter replace dev em1 ingress pref 1 handle 1 bpf skip_sw da obj prog.o
$ tc filter show dev em1 ingress
filter protocol all pref 1 bpf
filter protocol all pref 1 bpf handle 0x1 prog.o:[classifier] direct-action skip_sw in_hw id 19 tag 57cd311f2e27366b

其中的 in_hw 标志表示这个程序已经被 offload 到网卡了。

注意,tc 和 XDP offload 无法同时加载,因此必须要指明是 tc 还是 XDP offload 选项 。

tc ebpf 实践相关推荐

  1. tc ebpf sample - tethering offload on linux pc

    引用 BpfCoordinator.java - OpenGrok cross reference for /packages/modules/Connectivity/Tethering/src/c ...

  2. eBPF技术应用云原生网络实践系列之基于socket的service | 龙蜥技术

    简介:如何使用 socket eBPF进一步提升Service 网络的转发性能? 背景介绍 Kubernetes 中的网络功能,主要包括 POD 网络,service 网络和网络策略组成.其中 POD ...

  3. 深入浅出 eBPF: (Linux/Kernel/XDP/BCC/BPFTrace/Cillium)

    [BPF入门系列-1]eBPF 技术简介 | 深入浅出 eBPF[BPF入门系列-1]eBPF 技术简介https://www.ebpf.top/post/bpf_intro_blog/ 目录 eBP ...

  4. eBPF学习仓库bpf_study-996station GitHub鉴赏官

    推荐理由:eBPF学习参考资料,Linux内核观测技术BPF免费下载(英文) "eBPF 是我见过的 Linux 中最神奇的技术,没有之一,已成为 Linux 内核中顶级子模块,从 tcpd ...

  5. 【BPF入门系列-1】eBPF 技术简介

    由范老师和我一起翻译的图书 <Linux内核观测技术BPF> 已经在 JD 上有现货,欢迎感兴趣 BPF 技术的同学选购.链接地址 https://item.jd.com/72110825 ...

  6. 大规模微服务利器:eBPF 与 Kubernetes

    Daniel 是 eBPF 两位 maintainer 之一,目前在 eBPF commits 榜单上排名第一,也是 Cilium 的核心开发者之一. 本文内容的时间跨度有 8 年,覆盖了 eBPF ...

  7. 大规模微服务利器:eBPF + Kubernetes

    hi, 大家好,微服务,云原生近来大热,在企业积极进行数字化转型,全面提升效率的今天,几乎无人否认云原生代表着云计算的"下一个时代",IT大厂们都不约而同的将其视为未来云应用的发展 ...

  8. 深入理解 Cilium 的 eBPF(XDP)收发包路径:数据包在Linux网络协议栈中的路径

    Table of Contents 1 为什么要关注 eBPF? 1.1 网络成为瓶颈 1.2 eBPF 无处不在 1.3 性能就是金钱 2 eBPF 是什么? 3 为什么 eBPF 如此强大? 3. ...

  9. eBPF 的发展历史和核心设计

    前言 本文翻译自 2016 年 Daniel Borkman 在 NetdevConf 大会上的一篇文章:On getting tc classifier fully programmable wit ...

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

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

最新文章

  1. linux 编译zbar
  2. 【网寻】mui - 点击事件
  3. SpringBoot自动装配源码解析
  4. CGLIB 实现代理对象API
  5. UE4 多线程使用tip
  6. AOP原理解析及Castle、Autofac、Unity框架使用
  7. hdu--5135--贪心
  8. 该设备或资源(Web代理)未设置为接受端口“7890“上的连接解决方案
  9. oracle 数据库安装与使用说明(简略版)
  10. java正则匹配下划线_java验证,”支持6-20个字母、数字、下划线或减号,以字母开头“这个的正则表达式怎么写?...
  11. UE4 下载4.11.2的时候:当前遇到连接问题,正在重试
  12. JMeter proxy server
  13. 批量将 xlsx 文件 转换 为 csv文件
  14. 统计学考研笔记:正态分布概率计算题
  15. ios中Date.prase()兼容问题
  16. kali为一加三(oneplus3)编译lineage15.1(安卓8.1)
  17. Python开发培训哪里好
  18. 沉浸式状态栏实现,完美适配Android刘海屏,终极兼容
  19. java如何优雅的判空
  20. 万字长文回顾智能驾驶进化史

热门文章

  1. Chartboost 广告添加使用
  2. 安装SQL 2000挂起的解决办法
  3. Zynga和StarLark庆祝《Golf Rival》面世四周年
  4. 小牛叔讲Python第11章:函数的高级用法以及匿名函数
  5. python获取小数部分
  6. GCC 优化选项 -O -O0 -O1 -O2 -O3 -Os 简单介绍
  7. 【Mapreduce】利用job嵌套,多重Mapreduce,求解二度人脉
  8. nyoj-234-吃土豆(动态规划)
  9. 华为交换机5720常用命令
  10. openpose handpose 人体关键点识别 关键点检测