

ebpf 程序中常用的 load_byte/load_half/load_word 功能介绍
source link: https://mozillazg.com/2022/07/ebpf-libbpf-what-is-load_byte-load_half-load_word.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前言¶
大家在阅读一些网络相关的 ebpf 程序源码时可能会发现部分程序会使用 load_byte, load_half 以及 load_word 这几个函数来辅助解析网络数据包。
那么这几个函数的功能究竟是啥?以及它们各自的使用场景是啥,怎么知道究竟该用哪个函数? 本文将记录这几个函数各种的功能以及使用场景。
load_byte¶
函数定义¶
load_byte 函数的定义如下:
unsigned long long load_byte(void *skb,
unsigned long long off) asm("llvm.bpf.load.byte");
函数功能¶
它的功能是:从 skb 指向的数据包指针中读取 8-bits 的数据。 跟 gcc 里的 __builtin_bpf_load_byte 函数的功能是一样的。
使用场景¶
当想要从 struct __sk_buff *skb 中读取数据类型大小为 8-bits(1个字节) 的字段的值的时候, 可以使用 load_byte 直接从指针中读取对应的数据。
__u8 protocol = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));
load_half¶
函数定义¶
load_half 函数的定义如下:
unsigned long long load_half(void *skb,
unsigned long long off) asm("llvm.bpf.load.half");
函数功能¶
它的功能是:从 skb 指向的数据包指针中读取 16-bits 的数据。 跟 gcc 里的 __builtin_bpf_load_half 函数的功能是一样的。
使用场景¶
当想要从 struct __sk_buff *skb 中读取数据类型大小为 16-bits(2个字节)的字段的值的时候, 可以使用 load_byte 直接从指针中读取对应的数据。
__u16 h_proto = load_half(skb, offsetof(struct ethhdr, h_proto));
load_word¶
函数定义¶
load_word 函数的定义如下:
unsigned long long load_word(void *skb,
unsigned long long off) asm("llvm.bpf.load.word");
函数功能¶
它的功能是:从 skb 指向的数据包指针中读取 32-bits 的数据。 跟 gcc 里的 __builtin_bpf_load_word 函数的功能是一样的。
使用场景¶
当想要从 struct __sk_buff *skb 中读取数据类型大小为 32-bits(4个字节)的字段的值的时候, 可以使用 load_byte 直接从指针中读取对应的数据。
__u32 saddr = load_word(skb, ETH_HLEN + offsetof(struct iphdr, saddr));
替代函数¶
如果不想依赖 llvm 实现这几个函数所提供的功能的话,可以使用 bpf-helpers 中提供的 bpf_skb_load_bytes 函数实现类似的功能。
比如前面的那几个例子可以改写为:
// __u8 protocol = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));
struct iphdr ip_hdr;
if (bpf_skb_load_bytes(skb, ETH_HLEN, &ip_hdr, sizeof(ip_hdr)) < 0)
return 0;
__u8 protocol = ip_hdr.protocol;
// __u16 h_proto = load_half(skb, offsetof(struct ethhdr, h_proto));
struct ethhdr eth_hdr;
if (bpf_skb_load_bytes(skb, 0, ð_hdr, sizeof(eth_hdr)) < 0)
return 0;
__u16 h_proto = bpf_ntohs(eth_hdr.h_proto);
// __u32 saddr = load_word(skb, ETH_HLEN + offsetof(struct iphdr, saddr));
struct iphdr ip_hdr;
if (bpf_skb_load_bytes(skb, ETH_HLEN, &ip_hdr, sizeof(ip_hdr)) < 0)
return 0;
__u32 saddr = ip_hdr.saddr;
Recommend
-
11
第 1 部分: 在生产环境中使用 eBPF 调试 Go 程序 这是本系列文章的第一篇,讲述了我们如何在生产环境中使用 eBPF 调试应用程序而无需重新编译/重新部署。这篇文章介绍了如何使用 gobpf 和 uprobe 来为 Go 程序...
-
10
Android Studio 常用功能介绍 – Android开发中文站你的位置:Android开发中文站 > Android开发 >
-
5
一直想写(整理)一些关于 eBPF 的文章。在我眼中,它是 未来技术 之一。 最近零零碎碎看了一些,感觉信息太多,怕是永远也看不完,索性开始一遍看一边记笔记吧。这一篇是介绍。 eBPF 是什么 先介绍下 eBPF 的前身: BPF ->
-
7
eBPF原理介绍与C语言实现eBPF程序 发表于 2022-03-22...
-
6
By Shane Utt on October 19, 2022Writing an eBPF/XDP load-balancer in Rust
-
1
eBPF 介绍 eBPF 介绍 很早前就想写一篇关于eBPF的文章,但是迟迟没有动手,这两...
-
14
编写eBPF除了对eBPF的机制要要了解之外,还需要一些额外的辅助文件。基本上编写需要的文件已经全部打包在libbpf目录中。libpf对应的仓库是: https://github.com/libbpf/libbpf
-
7
BPF历史BPF是Berkeley Packet Filter(伯克利数据包过滤)的缩写,诞生于1992年。当时设计的BPF具有以下两个特性: 内核态引入一个新的虚拟机,所有的指令都在内核虚拟机中运行; 用户态使用BP...
-
9
针对 vArmor-ebpf 中的每个Hook函数进行分析。同时为了方便针对 vArmor-ebpf 项目进行测试,开发了...
-
4
vArmor-ebpf-loader 项目介绍和功能解读 2024年01月03日 2024年01月03日...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK