XDP入门--BPF程序如何转发报文到其它网卡

本文目录

  • 1、测试环境:
  • 2、实现的功能,使用bpf_redirect直接转发收到的报文到另外一张网卡
  • 3、测试步骤与测试结果

1、测试环境:

参照把树莓派改造成无线网卡(3)-----共享无线网络,无线网络转换成有线网络,让有线网络设备连上无线网络一文,形成如下测试网络:

                                                     +- RPi -------+          +- old pc1----+
                                                     |         Eth0+----------+ Eth0        |    
                 +- Router ----+                     |  DHCP server|          | 10.0.0.10   |
                 | Firewall    |                     |   10.0.0.1  |          |             |
(Internet)---WAN-+ DHCP server +-WLAN AP-+-)))   (((-+ WLAN        |          +-------------+
                 | 192.168.3.1 |                     |             |          
                 +-------------+                     |             |          +- old pc2----+
                                                     |         Eth1+----------+ Eth0        |   
                                                     |             |          | 10.0.0.4    |                                                       
                                                     +-------------+          |             |
                                                                              +-------------+

在这里插入图片描述

2、实现的功能,使用bpf_redirect直接转发收到的报文到另外一张网卡

在测试环境中,我们让

  • eth1把收到的IPv4的目标IP地址为10.0.0.10的直接从eth0转发出去
  • eth0把收到的IPv4的目标IP地址为10.0.0.4的直接从eth1转发出去
  • 其它报文上送内核TCP/IP协议栈处理

代码如下:

#include <stdio.h>
#include <linux/bpf.h>
#include <net/ethernet.h>
#include <linux/if_vlan.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <bpf/bpf_helpers.h>
#include <net/if.h>

#ifndef __section
# define __section(NAME)                  \
   __attribute__((section(NAME), used))
#endif

__section("prog")
int xdp_ip_filter(struct xdp_md *ctx)
{
    void *end = (void *)(long)ctx->data_end;
    void *data = (void *)(long)ctx->data;
    int ip_src;
    int ip_dst;
    long int offset;
    short int eth_type;
    char info_fmt1[] = "Dst Addr: xx.xx.%d.%d";
    char info_fmt2[] = "Src Addr: xx.xx.%d.%d";
    char info_fmt3[] = "------------------";

    static int i = 0;
    static int j = 0;
    unsigned char *saddrpoint = 0;
    unsigned char *daddrpoint = 0;

    struct ethhdr *eth = data;
    offset = sizeof(*eth);

    unsigned int indexofeth0 = 3;
    unsigned int indexofeth1 = 4;


    if (data + offset > end) {
    return XDP_ABORTED;
    }
    eth_type = eth->h_proto;
   
    /* 这里其实是有缺陷的,直接把收到的所有报文都当做不带VLAN的IPV4报文去解析,但因为测试环境简单,里面的报文也简单,所以这个处理基本上也问题不大 */

    struct iphdr *iph = data + offset;
    offset += sizeof(struct iphdr);
    /*在读取之前,确保你要读取的子节在数据包的长度范围内  */
    if (iph + 1 > end) {
        return XDP_ABORTED;
    }
    /*ip_src = iph->saddr;*/
    ip_dst = iph->daddr;

    /*saddrpoint = (unsigned char*)(&ip_src);
    daddrpoint =(unsigned char*)(&ip_dst);*/
    
    /* 发往10.0.0.10的直接通过eth0发送出去 */
    if(ip_dst == 0xa00000a)
    {
        return bpf_redirect(indexofeth0,0);
    }

    /* 发往10.0.0.4的直接通过eth1发送出去 */
    if(ip_dst == 0x400000a)
    {
        return bpf_redirect(indexofeth1,0);
    }
    /* 其它报文上送内核协议栈处理 */
    return XDP_PASS;
}

char __license[] __section("license") = "GPL";

如何获取: 网卡的index,可以用gcc编译如下程序,运行后得到eth0和eth1的网卡index:

#include <stdio.h>
#include <linux/bpf.h>
#include <net/ethernet.h>
#include <linux/if_vlan.h>
#include <netinet/in.h>
#include <linux/ip.h>
#include <bpf/bpf_helpers.h>
#include <net/if.h>

int main(struct xdp_md *ctx)
{
   unsigned int indexofeth0 = 0;
   unsigned int indexofeth1 = 0;
   
   indexofeth0 = if_nametoindex("eth0");
   indexofeth1 = if_nametoindex("eth1");

   printf("%d, %d", indexofeth0, indexofeth1);
   return 1;
}

3、测试步骤与测试结果

在没有加载XDP BPF程度时,从10.0.0.4往10.0.0.10用iperf3打流,数量流量约为65Mbps:
在这里插入图片描述
运行以下命令,在eth0和eth1都加载刚才编程的XDP BPF程序,两次用iperf3测试,发现数据流量约为70Mbps:

clang -O2 -Wall -target bpf -c xdp-example.c -o xdp-example.o
sudo ip link set dev eth0 xdp obj xdp-example.o
sudo ip link set dev eth1 xdp obj xdp-example.o

在这里插入图片描述

我们发现走XDP直接转发,比走Linux网桥的二层转发,性能还是稍有提高。

注意,系统重启后,eth0和eth1的网卡index是会变化的,需要每次重启后重新获取。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

插入排序、选择排序、冒泡排序小结(45)

小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 和猫妹学Python&#xff0c;一起趣味学编程。 今日主题 插入排序、选择排序、冒泡排序有什么区别&#xff1f; 原理不同 插入排序是将未排序的元素逐个插入到已排序序列中…

Unity之ASE从入门到精通 目录

前言 Amplify Shader Editor (ASE) 是受行业领先软件启发的基于节点着色器创建工具。它是一个开放且紧密集成的解决方案,提供了熟悉和连贯的开发环境,使 Unity 的 UI 约定和着色器的使用无缝地融合一起 目录 这里是ASE从入门到精通专栏的目录,不停更新中,有问题随时留…

入门JavaScript编程:上手实践四个常见操作和一个轮播图案例

部分数据来源&#xff1a;ChatGPT 简介 JavaScript是一门广泛应用于Web开发的脚本语言&#xff0c;它主要用于实现动态效果和客户端交互。下面我们将介绍几个例子&#xff0c;涵盖了JavaScript中一些常见的操作&#xff0c;包括&#xff1a;字符串、数组、对象、事件等。 例子…

rk3568 适配rk809音频

rk3568 适配rk809音频 RK809是一款集成了多种功能的电源管理芯片&#xff0c;主要用于笔记本电脑、平板电脑、工控机等设备的电源管理。以下是RK809的详细功能介绍&#xff1a; 电源管理&#xff1a;控制电源的开关、电压、电流等参数&#xff0c;保证设备的稳定运行。音频管…

Unity之使用Photon PUN开发多人游戏教程

前言 Photon是一个网络引擎和多人游戏平台,可以处理其服务器上的所有请求,我们可以在 Unity(或其他游戏引擎)中使用它,并快速把游戏接入Photon的网络中,而我们就可以专注于在项目中添加逻辑,专注于游戏玩法和功能了。 PUN(Photon Unity Networking)是一种开箱即用的解…

什么是DevOps?如何理解DevOps思想?

博文参考总结自&#xff1a;https://www.kuangstudy.com/course/play/1573900157572333569 仅供学习使用&#xff0c;若侵权&#xff0c;请联系我删除&#xff01; 1、什么是DevOps? DevOps是一种思想或方法论&#xff0c;它涵盖开发、测试、运维的整个过程。DevOps强调软件开…

Maven方式构建Spring Boot项目

文章目录 一&#xff0c;创建Maven项目二&#xff0c;添加依赖三&#xff0c;创建入口类四&#xff0c;创建控制器五&#xff0c;运行入口类六&#xff0c;访问Web页面七&#xff0c;修改访问映射路径八&#xff0c;定制启动标语1、创建标语文件2、生成标语字符串3、编辑标语文…

DNDC模型在土地利用变化、未来气候变化下的建模方法及温室气体时空动态模拟实践技术

DNDC模型讲解 1.1 碳循环模型简介 1.2 DNDC模型原理 1.3 DNDC下载与安装 1.4 DNDC注意事项 ​ DNDC初步操作 2.1 DNDC界面介绍 2.2 DNDC数据及格式 2.3 DNDC点尺度模拟 2.4 DNDC区域尺度模拟 2.5 DNDC结果分析 ​ DNDC气象数据制备 3.1 数据制备中的遥感和GIS技术 3…

Vue3 + TypeScript + Uniapp 开发小程序【医疗小程序完整案例·一篇文章精通系列】

当今的移动应用市场已经成为了一个日趋竞争激烈的领域&#xff0c;而开发一个既能在多个平台上运行&#xff0c;又能够高效、可维护的应用则成为了一个急需解决的问题。 在这个领域中&#xff0c;Vue3 TypeScript Uniapp 的组合已经成为了一种受欢迎的选择&#xff0c;特别…

ODB 2.4.0 使用延迟指针 lazy_shared_ptr 时遇到的问题

最近在学习使用C下的ORM库——ODB&#xff0c;来抽象对数据库的CURD&#xff0c;由于C的ORM实在是太冷门了&#xff0c;ODB除了官方英语文档&#xff0c;几乎找不到其他好用的资料&#xff0c;所以在使用过程中也是遇到很多疑惑&#xff0c;也解决很多问题。近期遇到的一个源码…

推荐系统系列之推荐系统概览(下)

在推荐系统概览的第一讲中&#xff0c;我们介绍了推荐系统的常见概念&#xff0c;常用的评价指标以及首页推荐场景的通用召回策略。本文我们将继续介绍推荐系统概览的其余内容&#xff0c;包括详情页推荐场景中的通用召回策略&#xff0c;排序阶段常用的排序模型&#xff0c;推…

Keil Debug 逻辑分析仪使用

Keil Debug 逻辑分析仪使用 基础配置 更改对应的bebug窗口参数 两边的 Dialog DLL 更改为&#xff1a;DARMSTM.DLL两边的 Parameter &#xff08;这里的根据单片机型号更改&#xff09;更改为&#xff1a;-pSTM32F103VE 选择左边的 Use Simulator 选项。 打开Debug和其中的逻…

数据全生命周期管理

数据存储 时代"海纳百川&#xff0c;有容乃大"意味结构化、半结构和非结构化多样化的海量的 &#xff0c;也意味着批数据和流数据多种数据形式的存储和计算。面对不同数据结构、数据形式、时效性与性能要求和存储与计算成本等因素考虑&#xff0c;应该使用适合的存储…

iptables防火墙(二)

iptables防火墙&#xff08;二&#xff09; 一、SNAT策略1、SNAT策略简述2、配置实验 二、DNAT策略1、DNAT策略简述2、配置实验 三、Linux抓包工具tcpdump四、防火墙规则保存 一、SNAT策略 1、SNAT策略简述 SNAT策略就是将从内网传给外网的数据包的源IP由私网IP转换成公网IP&…

四川省信创联盟2023年第一次理事会顺利召开,MIAOYUN荣获“信创企业优秀奖”!

5月18日&#xff0c;四川省技术创新促进会信创工委会&#xff08;四川省信创产业联盟&#xff09;在成都市高新区新川科技园成功召开《2023年第一次理事单位&#xff08;扩大&#xff09;会议》&#xff0c;四川省技术创新促进会专家组杜纯文副组长、四川省技术创新促进会任渝英…

EasyRecovery16适用于Windows和Mac的专业硬盘恢复软件

无论你对数据恢复了解多少&#xff0c; 我们将为您处理所有复杂的流程并简化恢复!适用于Windows和Mac的 专业硬盘恢复软件 硬盘数据无法保证绝对安全。有时会发生数据丢失&#xff0c;需要使用硬盘恢复工具。支持恢复不同存储介质数据&#xff1a;硬盘、光盘、U盘/移动硬盘、数…

AC规则-1

本文主要参考规范 GPD_Secure Element Access Control_vxxx.pdf OMA 架构 基本定义 GP(GlobalPlatform)定义了一套允许各应用提供方独立且安全地管理其在SE上的应用的安全框架&#xff0c;而AC(Access Control)&#xff0c;顾名思义&#xff0c;是对外部应用进行SE上应用访问…

网络知识点之-动态路由

动态路由是指路由器能够自动地建立自己的路由表&#xff0c;并且能够根据实际情况的变化适时地进行调整。 中文名&#xff1a;动态路由外文名&#xff1a;dynamic routing 简述 动态路由是与静态路由相对的一个概念&#xff0c;指路由器能够根据路由器之间的交换的特定路由信息…

【Python redis】零基础也能轻松掌握的学习路线与参考资料

Python redis是一种非常流行的缓存数据库&#xff0c;对于Python Web应用程序开发非常有用&#xff0c;能快速地处理大量的数据请求。Python redis的学习路线需要对Python语言有深刻的理解&#xff0c;并了解使用redis的API。在掌握了Python redis的基本知识后&#xff0c;就可…

Java设计模式-策略模式

简介 在软件开发中&#xff0c;设计模式是为了解决常见问题而提供的一套可重用的解决方案。策略模式&#xff08;Strategy Pattern&#xff09;是其中一种常见的设计模式&#xff0c;它属于行为型模式。该模式的核心思想是将不同的算法封装成独立的策略类&#xff0c;使得它们…