ebpf教程(4.1):XDP程序的加载

news2024/12/22 19:28:13

文章目录

    • 前言
    • 环境准备
    • 加载XDP程序
      • 源码
      • 构建过程
      • 运行

前言

前置阅读要求:

  • ebpf教程(3):使用cmake构建ebpf项目-CSDN博客
  • [译] [论文] XDP (eXpress Data Path):在操作系统内核中实现快速、可编程包处理(ACM,2018)
  • xdp-tools/lib/libxdp/README.org at master · xdp-project/xdp-tools

在阅读完上面的文档后,我们大概知道XDP(eXpress Data Path)允许在数据包进入内核协议栈之前进行处理,这减少了不必要的开销。由于处理发生在内核的早期阶段,XDP 能够显著提高网络处理性能,特别是对于高流量的场景。

本文是XDP的hello world – 加载XDP程序。


环境准备

# 安装依赖
apt install libxdp-dev xdp-tools

# 当前的libxdp版本
pkg-config --modversion libxdp
1.4.2

# 当前的内核版本(ubuntu24的内核)
uname -r
6.8.0-31-generic

我当前的网络拓扑如下图所示。当然本文的示例对网络拓扑没有要求,把程序加载到网卡上即可。

在这里插入图片描述


加载XDP程序


源码

下面的示例代码修改自:

  • xdp-tutorial/basic01-xdp-pass/README.org at master · xdp-project/xdp-tutorial
  • xdp-tutorial/basic02-prog-by-name/README.org at master · xdp-project/xdp-tutorial

bpf程序的生命周期:open–create–attach–detach。

本文的 BPF ELF 文件中有两个XDP程序,可以选择按照名称加载。

首先是XDP程序。两个程序,分别是放行或者阻止数据包。

// xdp_kernel_prog.c
#include <linux/types.h>

#include <bpf/bpf_helpers.h>
#include <linux/bpf.h>

SEC("xdp")
int xdp_pass_func(struct xdp_md *ctx) {
  bpf_printk("%s", "Pkt pass...");
  return XDP_PASS;
}

SEC("xdp")
int xdp_drop_func(struct xdp_md *ctx) {
  bpf_printk("%s", "Pkt drop...");
  return XDP_DROP;
}

char _license[] SEC("license") = "GPL";

下面是加载XDP程序的用户层程序。

示例代码中,我使用了argp库,我喜欢用这个库来处理命令行参数。它的使用可见:一步步了解Argp-CSDN博客

#include <argp.h>
#include <net/if.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include <bpf/libbpf.h>
#include <xdp/libxdp.h>

#define PROG_NAME_MAXSIZE 32

static char ifname[IF_NAMESIZE] = {};
static const char *filename = "xdp_kernel_prog.o";
static char prog_name[PROG_NAME_MAXSIZE] = {};
static volatile bool exiting = false;

static int parse_opt(int key, char *arg, struct argp_state *state) {
  switch (key) {
  case 'd':
    snprintf(ifname, sizeof(ifname), "%s", arg);
    break;
  case 'p':
    snprintf(prog_name, sizeof(prog_name), "%s", arg);
    break;
  }
  return 0;
}

static void sig_handler(int sig) { exiting = true; }

int main(int argc, char *argv[]) {
  int ret = 0;
  struct bpf_object *obj;

  struct argp_option options[] = {
      {"dev", 'd', "DEV NAME", 0, "set the network card name"},
      {"prog", 'p', "program name", 0, "set the program"},
      {0},
  };

  struct argp argp = {
      .options = options,
      .parser = parse_opt,
  };

  argp_parse(&argp, argc, argv, 0, 0, 0);

  // check parameter
  printf("choice dev: %s\n", ifname);
  int ifindex = if_nametoindex(ifname);
  if (ifindex == 0) {
    perror("if_nametoindex failed");
    exit(EXIT_FAILURE);
  }
  printf("%s's index %d\n", ifname, ifindex);

  /* Cleaner handling of Ctrl-C */
  signal(SIGINT, sig_handler);
  signal(SIGTERM, sig_handler);

  obj = bpf_object__open(filename);
  if (obj == NULL) {
    perror("bpf_object__open failed");
    exit(EXIT_FAILURE);
  }

  struct xdp_program_opts prog_opts = {};
  prog_opts.sz = sizeof(struct xdp_program_opts);
  prog_opts.obj = obj;
  prog_opts.prog_name = prog_name;

  struct xdp_program *prog = xdp_program__create(&prog_opts);
  if (prog == NULL) {
    perror("xdp_program__create failed.");
    exit(EXIT_FAILURE);
  }

  ret = xdp_program__attach(prog, ifindex, XDP_MODE_UNSPEC, 0);
  if (ret != 0) {
    perror("xdp_program__attach failed.");
    exit(EXIT_FAILURE);
  }

  while (!exiting) {
    sleep(1);
  }

cleanup:
  struct xdp_multiprog *mp = xdp_multiprog__get_from_ifindex(ifindex);
  ret = xdp_multiprog__detach(mp);
  if (ret != 0) {
    perror("xdp_multiprog__detach failed.");
    exit(EXIT_FAILURE);
  }

  bpf_object__close(obj);
}

构建过程

构建过程还是稍微有点麻烦了。CMake文件修改自:libbpf-bootstrap/tools/cmake at master · libbpf/libbpf-bootstrap

cmake_minimum_required(VERSION 3.10)

project(xdp-load-prog)

find_package(PkgConfig)
pkg_check_modules(LIBBPF REQUIRED libbpf)
pkg_check_modules(LIBXDP REQUIRED libxdp)

# Get clang bpf system includes
execute_process(
  COMMAND bash -c "clang -v -E - < /dev/null 2>&1 |
          sed -n '/<...> search starts here:/,/End of search list./{ s| \\(/.*\\)|-idirafter \\1|p }'"
  OUTPUT_VARIABLE CLANG_SYSTEM_INCLUDES_output
  ERROR_VARIABLE CLANG_SYSTEM_INCLUDES_error
  RESULT_VARIABLE CLANG_SYSTEM_INCLUDES_result
  OUTPUT_STRIP_TRAILING_WHITESPACE)
if(${CLANG_SYSTEM_INCLUDES_result} EQUAL 0)
  separate_arguments(CLANG_SYSTEM_INCLUDES UNIX_COMMAND ${CLANG_SYSTEM_INCLUDES_output})
  message(STATUS "BPF system include flags: ${CLANG_SYSTEM_INCLUDES}")
else()
  message(FATAL_ERROR "Failed to determine BPF system includes: ${CLANG_SYSTEM_INCLUDES_error}")
endif()

set(BPF_C_FILE ${CMAKE_CURRENT_SOURCE_DIR}/xdp_kernel_prog.c)
set(BPF_O_FILE ${CMAKE_CURRENT_BINARY_DIR}/xdp_kernel_prog.o)
add_custom_command(OUTPUT ${BPF_O_FILE}
    COMMAND clang -g -O2 -target bpf ${CLANG_SYSTEM_INCLUDES} -c ${BPF_C_FILE} -o ${BPF_O_FILE}
    COMMAND_EXPAND_LISTS
    VERBATIM
    DEPENDS ${BPF_C_FILE}
    COMMENT "[clang] Building BPF file: ${BPF_C_FILE}")

add_custom_target(generate_bpf_obj ALL
    DEPENDS ${BPF_O_FILE}
)

add_executable(xdp_load xdp_loader.c)
target_link_libraries(xdp_load PRIVATE ${LIBBPF_LIBRARIES} ${LIBXDP_LIBRARIES})

运行

# 查看help信息
./xdp_load --help
Usage: xdp_load [OPTION...]

  -d, --dev=DEV NAME         set the network card name
  -p, --prog=program name    set the program
  -?, --help                 Give this help list
      --usage                Give a short usage message

Mandatory or optional arguments to long options are also mandatory or optional
for any corresponding short options.

放行指定网卡的所有数据包。

./xdp_load --dev=ens19 --prog=xdp_pass_func

# 查看是否附加成功
xdp-loader status ens19
CURRENT XDP PROGRAM STATUS:

Interface        Prio  Program name      Mode     ID   Tag               Chain actions
--------------------------------------------------------------------------------------
ens19                  xdp_dispatcher    native   403  4d7e87c0d30db711 
 =>              50     xdp_pass_func             412  2d69c152cb7a3b4b  XDP_PASS

# 向网卡发送数据后,查看trace信息
cat /sys/kernel/debug/tracing/trace_pipe
          <idle>-0       [004] ..s2. 24810.751471: bpf_trace_printk: Pkt pass...
          <idle>-0       [004] ..s2. 24811.768707: bpf_trace_printk: Pkt pass...
          <idle>-0       [004] ..s2. 24815.992664: bpf_trace_printk: Pkt pass...

丢弃指定网卡的所有数据包。

./xdp_load --dev=ens19 --prog=xdp_drop_func

xdp-loader status ens19
CURRENT XDP PROGRAM STATUS:

Interface        Prio  Program name      Mode     ID   Tag               Chain actions
--------------------------------------------------------------------------------------
ens19                  xdp_dispatcher    native   423  4d7e87c0d30db711 
 =>              50     xdp_drop_func             433  510776c6b1cf234d  XDP_PASS

cat /sys/kernel/debug/tracing/trace_pipe
          <idle>-0       [004] ..s2. 24902.015467: bpf_trace_printk: Pkt drop...
          <idle>-0       [004] ..s2. 24903.032696: bpf_trace_printk: Pkt drop...
          <idle>-0       [004] ..s2. 24907.128676: bpf_trace_printk: Pkt drop...
          <idle>-0       [004] ..s2. 24908.152674: bpf_trace_printk: Pkt drop...

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2056321.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Zabbix 中网络设备(交换机和防火墙)的报警信息配置指南

简述 本文介绍配置 Zabbix 以监控网络设备&#xff08;如交换机和防火墙&#xff09;并发送钉钉报警信息&#xff0c;我将提供一个详细的步骤指南。 请确保你已经完成了以下前提条件&#xff1a; 1. Zabbix 已经搭建完成。2. 网络设备&#xff08;交换机和防火墙&#xff09…

空状态设计教程:连接用户体验的桥梁

空状态设计是产品设计中常被忽视却又极其重要的一环。它不仅是用户旅程的起点&#xff0c;更是塑造第一印象的关键。本文将引导你如何使用强大的设计工具设计出既美观又实用的空状态&#xff0c;以提升用户体验。 空状态设计的意义 空状态作为用户与产品初次邂逅的界面&#…

PostgreSQL-04-入门篇-连接多张表

文章目录 1. 连接设置样例表PostgreSQL 左连接PostgreSQL 右连接PostgreSQL 全外连接 2. 表别名简介表别名的实际应用1) 对长表名使用表别名&#xff0c;使查询更具可读性2) 在连接子句中使用表别名3) 在自连接中使用表别名 3. INNER JOIN 内连接简介PostgreSQL INNER JOIN 示例…

【机器学习】正则化,欠拟合与过拟合(详细代码与图片演示!助你迅速拿下!!!)

目录 &#x1f354;欠拟合与过拟合 1.1 欠拟合与过拟合定义 1.2 通过代码认识过拟合和欠拟合 1.3 原因以及解决办法 &#x1f354;正则化 2.1 什么是正则化 2.2 正则化类别 &#x1f354;小结 学习目标 &#x1f340; 掌握过拟合、欠拟合的概念 &#x1f340; 掌握过…

黄山黄小徽光影乐园:思特科技打造沉浸式光影乐园解决方案,快乐指数拉满了!

01      「黄小徽儿童光影乐园」是由思特科技全力打造&#xff0c;依托行业领先的数字光影技术与交互科技&#xff0c;专为3-8岁儿童设计的全场景、全交互、全沉浸的沉浸式光影乐园解决方案。    沉浸式光影乐园解决方案-黄小徽儿童光影乐园      02      思特…

无人机之固定翼无人机的组成

固定翼无人机是根据空气动力学原理设计机翼的形状&#xff0c;靠动力装置产生推力或者拉力&#xff0c;使无人机获得一定速度后&#xff0c;会导致空气在飞机上下表面的压力不同&#xff0c;进而产生升力&#xff0c;其升力主要来源于固定的机翼。大多数都是由机翼、机身、尾翼…

ultralytics实例分割mask读取

在前面学习YOLOv8的实例分割过程中&#xff0c;需要使用实例分割的数据集&#xff0c;其标签的标注格式如下&#xff1a; 实例分割勾勒轮廓 其中&#xff0c;第一个数字代表的是类别编号&#xff0c;后面的数据代表的是标注的坐标&#xff08;转换到0-1之间&#xff09;每两个…

编程修炼之Hibernate--- springboot启动初始化ddl过程与如何自定义修改 table 字段长度

文章目录 springboot启动初始化ddl过程如何自定义修改 table springboot启动初始化ddl过程 跟踪Springboot整合hibernate的启动代码&#xff1a; SessionFactoryImpl 的初始化里做了非常多的事情&#xff0c;初始化各种资源&#xff0c;并调用 SchemaManagementToolCoordinat…

c语言基础--------字符串指针

在 C 语言中&#xff0c;字符串指针是一个指向字符类型的指针&#xff0c;通常用于指向字符串的第一个字符。字符串在 C 语言中通常表示为字符数组&#xff0c;而字符串指针则是用来存储这种字符数组首地址的变量。 定义字符串指针 字符串指针的定义方式如下&#xff1a; ch…

Android更改包名和签名

一、更改包名 1、包名——鼠标右键——Refactor——Rename 修改自己想更改的包名和选择更改范围后点击Refactor就可以了 2.手动修改app的build.gradle文件中的applicationId&#xff08;改成和我们之前修改的包名相同&#xff09; 3.修改AndroidManifest.xml文件中的packag…

“AI+Security”系列第2期(三):面向LLM(大语言模型)的漏洞挖掘与对齐防御研究

近日&#xff0c;由安全极客、Wisemodel 社区和 InForSec 网络安全研究国际学术论坛联合主办的“AISecurity”系列第 2 期——对抗&#xff01;大模型自身安全的攻防博弈线上活动如期举行。 在此次活动中&#xff0c;前阿里云高级安全专家郑瀚带来了以《通往LLM安全对齐的道路…

网易云音乐故障 2 小时,这次到底谁背锅?(今天记得领补偿)

大家好&#xff0c;我是程序员鱼皮&#xff0c;8 月 19 日下午&#xff0c;网易云音乐突发严重故障&#xff0c;并登顶微博热搜&#xff0c;跟黑神话悟空抢了热度。 根据用户的反馈&#xff0c;故障的具体表现为&#xff1a;用户无法登录、歌单加载失败、播放信息获取失败、无法…

SQL— DML语句学习【后端 10】

数据库操作-DML 详解 在数据库管理系统中&#xff0c;DML&#xff08;Data Manipulation Language&#xff0c;数据操作语言&#xff09;扮演着至关重要的角色&#xff0c;它负责对数据库中的数据进行增、删、改操作。掌握DML操作对于数据库的日常维护和管理至关重要。本文将详…

CSP 2023 普及组第一轮 - CSP/S 2023初试题 完善程序第二题解析

一、题目阅读 &#xff08;编辑距离&#xff09;给定两个字符串&#xff0c;每次操作可以选择删除&#xff08;Delete&#xff09;、插入&#xff08;Insert&#xff09;、替换&#xff08;Replace&#xff09;&#xff0c;一个字符&#xff0c;求将第一个字符串转换为第二个字…

时序预测|基于贝叶斯BO-卷积-双向门控单元-注意力机制的单变量时间序列预测模型BO-CNN-BiGRU-Attention

时序预测|基于贝叶斯BO-卷积-双向门控单元-注意力机制的单变量时间序列预测模型BO-CNN-BiGRU-Attention 文章目录 前言时序预测|基于贝叶斯BO-卷积-双向门控单元-注意力机制的单变量时间序列预测模型BO-CNN-BiGRU-Attention 一、BO-CNN-BiGRU-Attention模型1. 贝叶斯优化&#…

【C++ 第十二章】二叉搜索树

1.1 二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 左边小&#xff1a;若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值右边大&#xff1a;若它的右子树不为空&#xff0c;则右子树上…

并网式光伏气象站——科技百科

并网式光伏气象站的工作原理简洁而充满智慧&#xff0c;并网式光伏气象站巧妙地通过太阳能电池板将太阳能转化为电能&#xff0c;利用先进的气象监测设备&#xff0c;‌对风速、‌风向、‌温度、‌湿度、‌光照等关键气象要素进行实时监测和记录&#xff0c;不仅充分利用了太阳…

【初阶数据结构题目】32. 希尔排序

文章目录 希尔排序希尔排序的时间复杂度计算 希尔排序 希尔排序法又称缩小增量法。希尔排序法的基本思想是&#xff1a;先选定一个整数&#xff08;通常是gap n/31&#xff09;&#xff0c;把待排序文件所有记录分成各组&#xff0c;所有的距离相等的记录分在同一组内&#x…

全国10米分辨率逐年植被覆盖度(FVC)数据集

本数据集包括2017至2023年间&#xff0c;全国植被覆盖度数据&#xff0c;FVC范围值为0-1&#xff0c;数据为浮点型&#xff0c;GeoTIFF格式。GeoTIFF文件均可用ArcGIS软件和GDAL读取和打开。 植被覆盖度是指植被&#xff08;包括叶、茎、枝&#xff09;在地面的垂直投影面积占统…

系统编程-进程初步2

进程初步2 目录 进程初步2 1、进程等待清理函数&#xff08;wait&#xff09; 2、等待指定的子进程&#xff08;waitpid&#xff09; 3、新的开辟进程的函数&#xff08;vfork&#xff09; 4、在程序中运行系统下的指令&#xff08;system&#xff09; 5、exec 函数族 …