首页 > 其他分享 >dpdk官方转发例子分析

dpdk官方转发例子分析

时间:2023-10-01 17:22:52浏览次数:45  
标签:rte addr nb 例子 转发 eth retval port dpdk

例子源码
http://dpdk.org/browse/dpdk/tree/examples/skeleton/basicfwd.c

main函数主流程

1. 初始化环境抽象层EAL

int ret = rte_eal_init(argc, argv);
if (ret < 0)
    rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");

2. 分配mempool

dpdk使用mbuf保存packet,mempool用于操作mbuf。

mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
        MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
if (mbuf_pool == NULL)
    rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");

3. 初始化所有网卡port

for (portid = 0; portid < nb_ports; portid++) {
    if (port_init(portid, mbuf_pool) != 0)
        rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n", portid);
}
static inline int
port_init(uint8_t port, struct rte_mempool *mbuf_pool)
{
    struct rte_eth_conf port_conf = port_conf_default;
    const uint16_t rx_rings = 1, tx_rings = 1;
    int retval;
    uint16_t q;

    // rte_eth_dev_count() 获取可用 eth 的个数
    if (port >= rte_eth_dev_count())
        return -1;

    /* 配置网卡设备 */
    retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
    if (retval != 0)
        return retval;

    /* 每个 port 1 个 rx 队列 */
    for (q = 0; q < rx_rings; q++) {
        retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE,
                rte_eth_dev_socket_id(port), NULL, mbuf_pool);
        if (retval < 0)
            return retval;
    }

    /* 每个 port 1 个 tx 队列 */
    for (q = 0; q < tx_rings; q++) {
        retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE,
                rte_eth_dev_socket_id(port), NULL);
        if (retval < 0)
            return retval;
    }

    /* 启用网卡设备 */
    retval = rte_eth_dev_start(port);
    if (retval < 0)
        return retval;

    struct ether_addr addr;
    rte_eth_macaddr_get(port, &addr);
    printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
               " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
            (unsigned)port,
            addr.addr_bytes[0], addr.addr_bytes[1],
            addr.addr_bytes[2], addr.addr_bytes[3],
            addr.addr_bytes[4], addr.addr_bytes[5]);

    /* 设置网卡混杂模式 */
    rte_eth_promiscuous_enable(port);

    return 0;
}

4. 为每个核调用线程

/*
 * 从 input 网卡读包,转发写入 output 网卡
 */
static __attribute__((noreturn)) void
lcore_main(void)
{
    const uint8_t nb_ports = rte_eth_dev_count();
    uint8_t port;

    /* 为了更好的性能,检查收发网卡是否在同一 NUMA 节点 */
    for (port = 0; port < nb_ports; port++)
        if (rte_eth_dev_socket_id(port) > 0 &&
                rte_eth_dev_socket_id(port) != (int)rte_socket_id())
            printf("WARNING, port %u is on remote NUMA node to "
                    "polling thread.\n\tPerformance will "
                    "not be optimal.\n", port);

    printf("\nCore %u forwarding packets. [Ctrl+C to quit]\n", rte_lcore_id());

    /* 死循环收包,Ctrl+C 退出 */
    for (;;) {
        for (port = 0; port < nb_ports; port++) {
            struct rte_mbuf *bufs[BURST_SIZE];

            /* 从网卡读包 */
            const uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE);
            if (unlikely(nb_rx == 0))  // 没有读到包就继续下一个 port
                continue;

            /* 发送到网卡 */
            const uint16_t nb_tx = rte_eth_tx_burst(port ^ 1, 0, bufs, nb_rx);
            if (unlikely(nb_tx < nb_rx)) {  // 手动释放没有发送出去的 mbuf
                uint16_t buf;
                for (buf = nb_tx; buf < nb_rx; buf++)
                    rte_pktmbuf_free(bufs[buf]);
            }
        }
    }
}

rte_eth_tx_burst发送成功后会自动释放mbuf,失败时需要代码手动释放。

参考资料

https://blog.csdn.net/fengfengdiandia/article/details/70821968

标签:rte,addr,nb,例子,转发,eth,retval,port,dpdk
From: https://www.cnblogs.com/WJQ2017/p/17739023.html

相关文章

  • 重定向和请求转发
    引言重定向(Redirect)和请求转发(Forward)都是在Web开发中用来处理页面跳转的方式。重定向重定向(Redirect)是通过发送特定的HTTP响应来告诉浏览器将请求重定向到另一个URL。当服务器收到一个请求后,如果需要将用户从当前页面导航到另一个页面,可以发送一个重定向响应给浏览器,浏览器会......
  • 1. weekly 发布及全网转发
 2. 各平台消息查看沟通及回复
 3. 中秋海报制作 公众
    作者:尚卓燃(PsiACE)澳门科技大学在读硕士,Databend研发工程师实习生ApacheOpenDAL(Incubating)Committerhttps://github.com/PsiACE对于Databend这样复杂的数据库服务端程序,往往需要支持大量的可配置选项,以帮助运维人员根据实际使用需要管理和调优系统。Databend目前支......
  • leptos 第一个例子
    leptos第一个例子下载安装rust下载安装后可通过下面的命令判断是否安装成功。rustup-V当提示不是内部命令时,需要自行设置环境变量,我默认安装的路径为C:\Users\{当前用户}\.cargo\bin成功显示当前版本安装trunk依赖包cargoinstalltrunk创建一个rust项目在特......
  • [JSON|序列化] fastjson自定义字段命名规则 (转发)
    1序言博主本人近期也遇到了基于fatsjson自定义命名字段规则的问题,为加强对此的学习和记忆,故转发这篇博文。博主本人最终采取的方法21.1前置知识fastjson在将对象转变为JSON字符串时,字段默认使用CamelCase规则命名。在1.2.15版本之后,fastjson支持配置Proper......
  • access口能转发其他tag报文
    Sundray-SW/#bcmshdumpport21filter_enableen_ifilter#"21"含义:从PORT.ipipe0[2]开始,总共1条excute:ovs-appctlplugin/bcmshdumpport21filter_enableen_ifilterPORT.ipipe0[2]:<FILTER_ENABLE=1,EN_IFILTER=0,>Sundray-SW/#bcmshdump......
  • 网络技术-数据转发过程
    前言TCP/IP协议簇喝底层协议配合,保证了数据能够实现端到端的传输。数据传输过程是一个非常复杂的过程,例如数据在转发的过程中会进行一系列的封装和解封装。对于网络工程师来说,只有深入地了解了数据再各种不同设备上的转发过程,才能对网络进行正确的分析和检测。 网关:网关(Gate......
  • 使用Cisco packet tracer验证交换机转发原理
    交换机的转发原理:交换机在收到数据帧后,记录帧的源MAC地址,在MAC地址表中查询目的MAC地址,进行转发。本文采用Ciscopackettracer验证交换机的转发原理模拟器:Ciscopackettracer8.2一、拓扑结构:二、设备基本配置设备IP:PC1为192.18.0.1;PC2为192.168.0.2;PC3为192.168.0.3设备MAC:PC1为......
  • 企业微信机器人Javascript调用例子
    constkey=""constoWX_URL='https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key='+key;constsent_msg={'msgtype':'text','text':{......
  • 重定向和请求转发
    servlet中请求转发(forword)与重定向(sendredirect)-断弯刀-博客园(cnblogs.com) 请求转发前后用的同一个request故可以传递一些session数据,地址栏不会发生变化,在jps页面也可以获取,而重定向不可以。 servlet传数据到jsp接受用请求转发,重定向用于表单提交,转到另一个jsp页面......
  • Win32编程之函数转发注入DLL(十五)
    一、创建目标DLL文件DLL名称:targetdll.dll头文件(targetdll.h):#pragmaonce__declspec(dllexport)void__stdcallhello();__declspec(dllexport)int__stdcalladd(inta,intb);源文件(targetdll.cpp)#include<stdio.h>#include"targetdll.h"void_......