Bcc

Bcc是ebpf的编译工具集合,前端提供python/lua调用,本身通过c语言实现,集成llvm/clang,将ebpf代码注入,提供一些更人性化的函数给用户使用,比如函数的注入等,里面提供了很多xdp的例子,本文将从bcc xdp例子为入口,研究整个xdp的工作流程

附:ebpf框架(map作为用户态和内核态注入代码的通信(目前upstream xdp支持devmap、cpumap、xskmap),通过verfier检查,通过JIT即时翻译,底层有各种静态探针点,比如xdp,tracepoint,perf,也有动态探针点,比如kprobe)

xdp注入流程

int xdp_redirect_map(struct xdp_md *ctx) {

void* data_end = (void*)(long)ctx->data_end;

void* data = (void*)(long)ctx->data;

struct ethhdr *eth = data;

uint32_t key = 0;

long *value;

uint64_t nh_off;

nh_off = sizeof(*eth);

if (data + nh_off > data_end)

return XDP_DROP;

value = rxcnt.lookup(&key);

if (value)

*value += 1;

swap_src_dst_mac(data);

return tx_port.redirect_map(0, 0);

}

int xdp_dummy(struct xdp_md *ctx) {

return XDP_PASS;

}

""", cflags=["-w"])

tx_port = b.get_table("tx_port")

tx_port[0] = ct.c_int(out_idx)

in_fn = b.load_func("xdp_redirect_map", BPF.XDP)

out_fn = b.load_func("xdp_dummy", BPF.XDP)

b.attach_xdp(in_if, in_fn, flags)

b.attach_xdp(out_if, out_fn, flags)

这个sample讲的是将in ifdev的包文redirect到out ifdev发出去(比如in为eth0,out为eth1),

in_fn = b.load_func(“xdp_redirect_map”, BPF.XDP) //加载xdp_redirect_map函数,返回prog_fd给in_fn

in_if就是eth0 dev设备

b.attach_xdp(in_if, in_fn, flags),//attach xdp

attach_xdp

调用逻辑

(bcc)/src/cc/libbpf.c bpf_attach_xdp(const char *dev_name, int progfd, uint32_t flags)

—(linux)/tools/lib/bpf/netlink.c bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags)

建立netlink socket,发送

req.nh.nlmsg_type = RTM_SETLINK

req.ifinfo.ifi_family = AF_UNSPEC

req.ifinfo.ifi_index = ifindex; //传入out ifindex

nla->nla_type = NLA_F_NESTED | IFLA_XDP

memcpy((char *)nla_xdp + NLA_HDRLEN, &fd, sizeof(fd)); //传入xdp_redirect_map的prog_fd

接受端:

(linux)/net/core/rtnetlink.c

rtnl_setlink

根据ifm->ifi_index查询本net namespace的dev(后面简称outdev)

-do_setlink

从xdp[IFLA_XDP_PROG_ID中获取到prog_fd

–dev_change_xdp_fd

dev_change_xdp_fd

调用dev_xdp_install安装xdp函数

这里会调用dev->netdev_ops->ndo_bpf(XDP_SETUP_PROG)

以i40e网卡驱动为例,调用:

i40e_xdp_setup

将vsi->xdp_prog赋值为prog_fd

将vsi->rx_rings[i]->xdp_prog赋值为prog_fd

这样后面调用vsi->rx_rings[i]->xdp_prog时,就会调用到用户注入的代码

xdp收包

以i40e为例,底层驱动收包流程如下

i40e_napi_poll

—i40e_clean_rx_irq_zc

——i40e_run_xdp

———bpf_prog_run_xdp

————BPF_PROG_RUN

—————(*(prog)->bpf_func)(ctx, (prog)->insnsi)//这里就是用户态注入的函数本例注入的xdp_redirect_map函数(vsi->rx_rings[i]->xdp_prog->bpf_func)

——————swap_src_dst_mac(data);//交换src dst的mac,这样src为eth0 mac,dst为原nc的mac

——————tx_port.redirect_map//tx_port的设置是通过map机制,为eth2的ifdex

———————bpf_xdp_redirect_map(这个怎么来的?xdp_verifier_ops->xdp_func_proto->BPF_FUNC_redirect_map->bpf_xdp_redirect_map_proto->bpf_xdp_redirect_map)

————————struct bpf_redirect_info *ri = this_cpu_ptr(&bpf_redirect_info);

————————ri->ifindex = ifindex;

————————WRITE_ONCE(ri->map, map);

————————返回XDP_REDIRECT

———xdp_do_redirect

————xdp_do_redirect_map

————— __xdp_map_lookup_elem//根据index和map获取到目标端口(eth1)的信息

—————__bpf_tx_xdp_map  //将xdp数据赋值到目标eth1 dev的xdp_bluk_quue(this_cpu_ptr(obj->bulkq)->q[blukq->count])里面,这里遗留个flag MEM_TYPE_ZERO_COPY用于零拷贝(这个feature引入的文章https://lwn.net/Articles/754659/)

—————ri->map_to_flush = map;//设置map_to_flush标志

—— i40e_finalize_xdp_rx(rx_ring, xdp_xmit);//将xdp_bluk_quue里面的

——— xdp_do_flush_map

————__dev_map_flush

————— bq_xmit_all

—————— ndo_xdp_xmit(dev, count,q) //调用目标eth1的xdp发包

xdp发包

ndo_xdp_xmit

i40e网卡对应i40e_xdp_xmit

调用i40e_xmit_xdp_ring往DMA发包,这样从eth0收到的包文,就直接通过eth1发出去啦。

参考文献

bcc钱包地址生成linux,从Bcc到xdp原理分析相关推荐

  1. Linux系统移植:menuconfig 原理分析

    文章目录 Linux系统移植:menuconfig 原理分析 一.make menuconfig 执行过程 二.Kconfig 语法 2.1 mainmenu 菜单 2.2 调用其他目录 Kconfi ...

  2. 调用uniswap在测试网Rinkeby上发起签名交易(批量钱包地址生成)

    1.交易数据的签名方式 部分展示: const myDexExec = require('../dex/myDexExec'); // 引入fs模块 const accounts = require( ...

  3. 嵌入式Linux——uevent机制:uevent原理分析

    简介: 本文主要介绍uevent机制是什么,并通过代码分析使用uevent机制生成设备节点的过程.而本文将分为两部分,第一部分我们介绍一些预备知识和uevent的原理,而第二部分--通过代码介绍使用u ...

  4. [Linux 基础] 嵌入式 Linux ---- uevent 机制:uevent 原理分析(深度好文)

    简介: 本文主要介绍 uevent 机制是什么,并通过代码分析使用 uevent 机制生成设备节点的过程.而本文将分为两部分,第一部分我们介绍一些预备知识和 uevent 的原理,而第二部分--通过代 ...

  5. linux代码工具tag,gcov-dump原理分析_Linux平台代码覆盖率测试

    第 16 页 LINES tag: tag_lines() 函数 3.4 LINES tag: tag_lines() 函数static void tag_lines ( const char * f ...

  6. linux keepalived 脚本,Linux下安装Keepalived及原理分析

    1.keepalived 原理 1.keepalived是什么 keepalived是集群管理中保证集群高可用的一个服务软件,其功能类似于heartbeat,用来防止单点故障. 2.keepalive ...

  7. Linux进程调度-CFS调度器原理分析及实现,懂了

    1. 概述 (1) Completely Fair Scheduler,完全公平调度器,用于Linux系统中普通进程的调度. (2) CFS采用了红黑树算法来管理所有的调度实体 sched_entit ...

  8. ad域与linux同步时间同步,AD时间同步原理分析

    首先我把我对AD环境时间同步理解描述:PDC服务器和Internet 外部时间源或本地硬件同步.所有域控制器按层次结构找PDC同步.所有成员服务器或客户端在登录时通过那台服务器验证,就与那台DC时间进 ...

  9. linux shellshock漏洞,shellshock漏洞原理分析(cve-2014-6271 bash漏洞)

    shellshock漏洞原理分析(cve-2014-6271 bash漏洞) 2014-09-26 10:04:16 阅读:0次 概述: 低于4.3版本的gnu bash存在漏洞,运行本地用户通过构造 ...

最新文章

  1. (6)javascript的程序控制结构及语句-----(1)条件判断
  2. Sharepoint中遭遇The Path specified cannot be used at this time.
  3. bootstrap 按钮样式单选效果_【自学C#】I 书 101 单选按钮
  4. 为什么要加上拉电阻和下拉电阻
  5. idea分支如何刷新显示最新
  6. java 线程池 资源回收_JAVA线程池资源回收的问题
  7. 机器学习必备:前20名Python人工智能和机器学习开源项目
  8. github的应用详解
  9. windows 本地搭建git仓库_Windows系统下搭建Git本地代码库
  10. php怎么访问到外部变量,从外部javascript fi访问PHP var
  11. postgresql查看表的创建者和表的权限
  12. 网络与社会导论之幂律与富者更富及其与长尾、齐普夫定律等的关系
  13. Dreamweaver网页作业——紫罗兰永恒花园动漫价绍网页 7页,含有table表格,js表单验证还有首页视频。以及列表页。浮动布局。div+css+js
  14. 按图搜索商品获取数据测试
  15. 学计算机高考英语听力考试时间,北京:2020年高考英语听力机考问答
  16. 【2022 CCPC 华为云计算挑战赛】1005 带权子集和 (NTT 优化dp)
  17. ZOJ 3557 (插板法+Lucas定理)
  18. MATLAB中画折线图:plot函数的简单用法
  19. ElasticSearch windows部署(避坑干货)
  20. 软件加密技术和注册机制加密基础(转)

热门文章

  1. 发送短信并存入短信库
  2. 【解决方案】雷电模拟器去桌面底部游戏和游戏中心
  3. python和易语言哪个容易胖_坐着长肉还是躺着长肉 哪个更容易胖
  4. vue3中播放视频和m3u8后缀的视频解决办法
  5. 定义一个点(point)类表示二维空间的点(x,y)
  6. 负电阻_三极管单管震荡电路
  7. 升级iOS CocoaPods 版本
  8. 世界各国劳动力总数数据集1990-2019年
  9. 2019牛客多校训练营第一场 H题 HOR 题解
  10. 10个Scratch热门作品(1)