ZBLOG

DPDK初始化rss的代码

以下是DPDK初始化RSS的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <errno.h>
#include <sys/queue.h>
#include <rte_common.h>
#include <rte_ethdev.h>

#define RX_RING_SIZE 1024
#define TX_RING_SIZE 1024

static const struct rte_eth_conf port_conf_default = {
    .rxmode = {
        .max_rx_pkt_len = ETHER_MAX_LEN,
        .split_hdr_size = 0,
        .header_split   = 0, /**< Header Split disabled */
        .hw_ip_checksum = 1, /**< IP checksum offload enabled */
        .hw_vlan_filter = 0, /**< VLAN filtering disabled */
        .jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
        .hw_strip_crc   = 1, /**< CRC stripped by hardware */
    },
    .txmode = {
        .mq_mode = ETH_MQ_TX_NONE,
    },
};

int main(int argc, char **argv)
{
    int ret;
    uint16_t nb_ports;
    uint16_t portid;

    // 初始化EAL环境
    ret = rte_eal_init(argc, argv);
    if (ret < 0) {
        rte_exit(EXIT_FAILURE, "Error: Failed to initialize EAL (%s)\n", strerror(-ret));
    }

    // 获取可用端口数
    nb_ports = rte_eth_dev_count_avail();
    if (nb_ports == 0) {
        rte_exit(EXIT_FAILURE, "Error: No available network ports\n");
     }

     // 配置每个端口
     for (portid = 0; portid < nb_ports; portid++) {

         struct rte_eth_conf port_conf;
         struct rte_eth_rxconf rxq_conf;
         struct rte_eth_txconf txq_conf;
         struct rte_eth_dev_info dev_info;

         // 获取端口设备信息
         memset(&dev_info, 0, sizeof(dev_info));
         rte_eth_dev_info_get(portid, &dev_info);

         // 设置rx和tx队列配置
         memset(&rxq_conf, 0, sizeof(rxq_conf));
         rxq_conf.rx_thresh.pthresh = 8;
         rxq_conf.rx_thresh.hthresh = 8;
         rxq_conf.rx_thresh.wthresh = 4;
         rxq_conf.rx_free_thresh = 32;

         memset(&txq_conf, 0, sizeof(txq_conf));
         txq_conf.tx_rs_thresh = 32;
         txq_conf.tx_free_thresh = 0;
         txq_conf.tx_thresh.pthresh = 36;
         txq_conf.tx_thresh.hthresh = 0;
         txq_conf.tx_thresh.wthresh = 0;

        // 初始化port configuration structure with default values
        port_conf = port_conf_default;

        // 配置rss功能
        if (dev_info.reta_size > RTE_ETH_RSS_RETA_SIZE_64) {
            uint8_t rss_key[] = {52,102,121,161,177};
            uint8_t rss_hash_func =
                    ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP |
                    ETH_RSS_SCTP | ETH_RSS_L2_PAYLOAD |
                    ETH_RSS_IPV6_EX | ETH_RSS_IPV6_TCP_EX |
                    ETH_RSS_IPV6_UDP_EX | ETH_RSS_IPV6_EX_L2_PAYLOAD |
                    ETH_RSS_NONFRAG_IPV4_OTHER | 
                    ETH_RSS_NONFRAG_IPV4_UDP | 
                    ETH_RSS_NONFRAG_IPV4_TCP |
                    ETH_RSS_NONFRAG_IPV6_OTHER | 
                    ETH_RSS_NONFRAG_IPV6_UDP | 
                    ETH_RSS_NONFRAG_IPV6_TCP;
            ret = rte_eth_dev_configure(portid, 1, 1, &port_conf);
            if (ret < 0) {
                rte_exit(EXIT_FAILURE, "Error: Failed to configure port %u (%s)\n", portid, strerror(-ret));
            }
            ret = rte_eth_dev_rss_hash_update(portid, rss_key,
                                              sizeof(rss_key),
                                              rss_hash_func);
            if (ret < 0) {
                rte_exit(EXIT_FAILURE, "Error: Failed to update RSS hash functions for port %u (%s)\n",
                         portid, strerror(-ret));
             }

             uint16_t i;
             struct ether_addr eth_addr;
             memset(&eth_addr.addr_bytes[0], 0x00, ETHER_ADDR_LEN);
             ret = rte_eth_macaddr_get(portid,&eth_addr);
             if(ret != 0){
                 printf("Faild to get MAC address of port :%d \n",portid);
                 return -1;
              }
              printf("MAC address of port:%d is %02X:%02X:%02X:%02X:%02X:%02X\n",
                      portid,
                      eth_addr.addr_bytes[0],
                      eth_addr.addr_bytes[1],
                      eth_addr.addr_bytes[2],
                      eth_addr.addr_bytes[3],
                      eth_addr.addr_bytes[4],
                      eth_addr.addr_bytes[5]);

        } else {
            ret = rte_eth_dev_configure(portid, 1, 1, &port_conf);
            if (ret < 0) {
                rte_exit(EXIT_FAILURE, "Error: Failed to configure port %u (%s)\n", portid,strerror(-ret));
            }
         }

         // 初始化rx和tx队列
         ret = rte_eth_rx_queue_setup(portid, 0, RX_RING_SIZE,
                                       rte_eth_dev_socket_id(portid),
                                       &rxq_conf,
                                       rte_eth_rx_burst);
         if (ret < 0) {
             rte_exit(EXIT_FAILURE, "Error: Failed to setup rx queue for port %u (%s)\n", portid,strerror(-ret));
          }

          ret = rte_eth_tx_queue_setup(portid, 0, TX_RING_SIZE,
                                        rte_eth_dev_socket_id(portid),
                                        &txq_conf);
          if (ret < 0) {
              rte_exit(EXIT_FAILURE, "Error: Failed to setup tx queue for port %u (%s)\n", portid,strerror(-ret));
           }

           // 启动端口
           ret = rte_eth_dev_start(portid);
           if (ret < 0) {
               rte_exit(EXIT_FAILURE, "Error: Failed to start port %u (%s)\n", portid,strerror(-ret));
            }
     }
}

此示例演示了如何初始化DPDK以使用RSS功能。在主函数中,我们首先调用rte_eal_init()来初始化EAL环境,然后获取可用端口数,并遍历每个端口以配置其rx和tx队列。

对于支持更大的RETAsize的设备,我们调用rte_eth_dev_rss_hash_update()函数来启用RSS哈希功能,并将所需的哈希键、哈希函数等参数传递给它。否则,我们只是简单地配置端口并启动它。

请注意,在此示例中未显示完整错误检查代码。实际应用程序中,您应该在每个函数调用后检查返回值以确保操作成功完成。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:http://sdn.0voice.com/?id=1226

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?