dpdk学习记录一

1.搭建dpdk环境

(1).检测虚拟机是否支持多队列,使用ifconfig命令查看网卡信息,如果是ens33,需要将ens33转为eth0。

为什么需要多队列网卡,因为dpdk需要多队列网卡,单网卡只有一个中断,多队列网卡有多个中断,dpdk可以同时处理多个中断,增加吞吐量

(2).修改完成后查看网卡中断,命令cat /proc/interrupts | grep eth0,如果不是下图这种情况,需要进行第三步修改vmx文件

(3).如果不支持修改对应的vmx文件,修改前关闭虚拟机

(4).上述完成以后,接下来配置巨页,使用命令vim /etc/default/grub,添加这三句

default_hugepagesz=1G hugepagesz=2M hugepages=1024

物理机和虚拟机存在差异

(5).下载dpdk : https://core.dpdk.org/download/

下载完成以后进入dpdk目录使用命令

根据机器选择编译类型,我是本机编译然后本机运行选择带native的,如果不修改dpdk源码选择36,否则选39.

(6).接下来执行43,44,45,46,47,49,46和47设置巨页时选择512,选择49时eth0如果还是活跃状态需要关掉ifconfig eth0 down,执行完毕后,环境配置完成。每次重启系统需要重新执行一遍上述设置

(7).设置dpdk环境变量,根据自己的具体目录修改/home/dpdk,每次重启需要重新设置

# export RTE_SDK=/home/dpdk

# export RTE_TARGET=x86_64-native-linux-gcc

2.dpdk使用UDP接收数据

(1).编译方式,使用makefile文件编译,Makefile复制于cp ../dpdk-stable-19.08.2/examples/helloworld/Makefile ./

# binary name
APP = helloworld

# all source are stored in SRCS-y
SRCS-y := main.c

(2).代码

#include <stdio.h>
#include <unistd.h>
#include <rte_eal.h>
#include <rte_ethdev.h>
#include <rte_mbuf.h>
#include <arpa/inet.h>

#define NUM_MBUFS 4096
#define BURST_SIZE 128

int global_portid = 0;

static const struct rte_eth_conf port_conf_default = {
    .rxmode = { .max_rx_pkt_len = RTE_ETHER_MAX_LEN}
};

static int ustack_init_port(struct rte_mempool *mbuf_pool)
{
    uint16_t nb_sys_ports = rte_eth_dev_count_avail();
    if(nb_sys_ports == 0)
    {
        rte_exit(EXIT_FAILURE, "No Support eth found\n");
    }

    const int num_rx_queues = 1;
    const int num_tx_queues = 0;
    rte_eth_dev_configure(global_portid, num_rx_queues, num_tx_queues, &port_conf_default);

    //创建一个global_portid网卡,0位置的128的mbuf队列
    if(rte_eth_rx_queue_setup(global_portid, 0, 128, rte_eth_dev_socket_id(global_portid), NULL, mbuf_pool) < 0)
    {
        rte_exit(EXIT_FAILURE, "Could not setup RX queue\n");
    }

    if(rte_eth_dev_start(global_portid) < 0)
    {
        rte_exit(EXIT_FAILURE, "Could not start\n");
    }

    return 0;
}

int main(int argc, char* argv[])
{
    //检测网卡信息
    if(rte_eal_init(argc, argv) < 0)
        rte_exit(EXIT_FAILURE, "Error with EAL init\n");

    //创建一个mbuf用于接收
    struct rte_mempool *mbuf_pool = rte_pktmbuf_pool_create("mbuf pool", NUM_MBUFS, 0, 0,
        RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());   //rte_socket_id()为内存id
    if(!mbuf_pool)
    {
        rte_exit(EXIT_FAILURE, "Could not create mbuf pool\n");
    }
    
    ustack_init_port(mbuf_pool);

    while(1)
    {
        //解析收到的数据
        struct rte_mbuf *mbufs[BURST_SIZE] = {0};
        uint16_t nb_recvd = rte_eth_rx_burst(global_portid, 0, mbufs, BURST_SIZE);
        if(nb_recvd > BURST_SIZE)
        {
            rte_exit(EXIT_FAILURE, "ERRor receiving from eth\n");
        }

        int i = 0;
        for(i = 0; i < nb_recvd; i++)
        {
            //获取以太网头
            struct rte_ether_hdr *ethhdr = rte_pktmbuf_mtod(mbufs[i], struct rte_ether_hdr *);
            if(ethhdr->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4))
            {
                continue;  
            }

            //获取ip头
            struct rte_ipv4_hdr *iphdr = rte_pktmbuf_mtod_offset(mbufs[i], struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr));
            if(iphdr->next_proto_id == IPPROTO_UDP)
            {
                struct rte_udp_hdr *udphdr = (struct rte_udp_hdr*)(iphdr+1);
                printf("udp:%s\n", (char*)(udphdr+1));
            }
            
        }
    }
    printf("hello dpdk!\n");
    
    return 0;
}

(3).设置静态arp,在windows命令行输入命令

netsh -c i i add neighbors 16 192.168.2.66 00-0c-29-18-ef-9d

ip地址为dpdk网卡的ip,后面的是对应的mark地址 

然后就可以测试dpdk接收数据了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值