4

ebpf 程序中常用的 load_byte/load_half/load_word 功能介绍

 2 years ago
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.
neoserver,ios ssh client

前言

大家在阅读一些网络相关的 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, &eth_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
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    在生产环境中使用 eBPF 调试 GO 程序

    第 1 部分: 在生产环境中使用 eBPF 调试 Go 程序 这是本系列文章的第一篇,讲述了我们如何在生产环境中使用 eBPF 调试应用程序而无需重新编译/重新部署。这篇文章介绍了如何使用 gobpf 和 uprobe 来为 Go 程序...

  • 10
    • www.androidchina.net 3 years ago
    • Cache

    Android Studio 常用功能介绍

    Android Studio 常用功能介绍 – Android开发中文站你的位置:Android开发中文站 > Android开发 >

  • 5
    • yanhang.me 3 years ago
    • Cache

    eBPF系列1 - 介绍

    一直想写(整理)一些关于 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
    • coolshell.cn 2 years ago
    • Cache

    eBPF 介绍

    eBPF 介绍 eBPF 介绍 很早前就想写一篇关于eBPF的文章,但是迟迟没有动手,这两...

  • 14
    • blog.spoock.com 1 year ago
    • Cache

    eBPF常见文件介绍

    编写eBPF除了对eBPF的机制要要了解之外,还需要一些额外的辅助文件。基本上编写需要的文件已经全部打包在libbpf目录中。libpf对应的仓库是: https://github.com/libbpf/libbpf

  • 7
    • blog.spoock.com 1 year ago
    • Cache

    eBPF介绍

    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