地上一个猴 2022-10-12 16:30 采纳率: 66.7%
浏览 37
已结题

能够基于dpdk19.11进行L4处理的c程序

环境:dpdk19.11 ubuntu-18.04.5

两台ubuntu机器,一台基于dpdk进行L4处理(tcp/udp/icmp),另一台作为对端正常使用

求一套可以使用的基于dpdk19.11进行L4处理的c程序代码,
使用igb_uio或者vfio驱动,程序能够收发tcp/udp包、有自定义建立tcp/udp的套接字。
能够与未绑定dpdk驱动的对端电脑,互相进行tcp/udp连接、ping。

  • 写回答

1条回答 默认 最新

  • ilmss 2022-10-12 20:25
    关注

    send.c

    #include <stdio.h>
    #include <arpa/inet.h>
    #include <rte_eal.h>
    #include <rte_ethdev.h>
    #include <rte_mbuf.h>
    
    #define NUM_MBUFS        (4096-1)
    #define MBUFS_SIZE        32
    #define ENABLE_SEND        1
    
    uint16_t port_id = 0;
    
    
    
    #if ENABLE_SEND
    
    static uint32_t gSrcIp; 
    static uint32_t gDstIp;
    
    static uint8_t gSrcMac[RTE_ETHER_ADDR_LEN];
    static uint8_t gDstMac[RTE_ETHER_ADDR_LEN];
    
    static uint16_t gSrcPort;
    static uint16_t gDstPort;
    
    #endif
    
    
    
    static const struct rte_eth_conf port_conf_default = {
        .rxmode = {.max_rx_pkt_len = RTE_ETHER_MAX_LEN }
    };
    
    static void init_port(struct rte_mempool *mbufpool)
    {
        /*Get the number of ports which are usable for the application.*/
        uint16_t sys_port = rte_eth_dev_count_avail();
        if(sys_port == 0){
            rte_exit(EXIT_FAILURE, "Not available eth\n");
        }
    
        /*Get ethernet information*/
        struct rte_eth_dev_info dev_info;
        rte_eth_dev_info_get(port_id, &dev_info);
    
        /*Configure an Ethernet device*/
        uint16_t nb_rx_q = 1;
        uint16_t nb_tx_q = 1;
        struct rte_eth_conf dev_conf = port_conf_default;
        rte_eth_dev_configure(port_id, nb_rx_q, nb_tx_q, &dev_conf);
    
        /*Allocate and set up a receive queue for an Ethernet device*/
        uint16_t rx_queue_id = nb_rx_q - 1;
        unsigned int socket_id = rte_eth_dev_socket_id(port_id);
        if(rte_eth_rx_queue_setup(port_id, rx_queue_id, 1024, socket_id, NULL, mbufpool) < 0)
            rte_exit(EXIT_FAILURE, "Receive queue error\n");
            
    #if ENABLE_SEND
        /*Allocate and set up a transmit queue for an Ethernet device*/
        struct rte_eth_txconf txq_conf = dev_info.default_txconf;
        txq_conf.offloads = dev_conf.rxmode.offloads;
        if (rte_eth_tx_queue_setup(port_id, 0 , 1024, socket_id, &txq_conf) < 0)
            rte_exit(EXIT_FAILURE, "Could not setup TX queue\n");
    
    #endif
    
        /*Start an Ethernet device*/
        if(rte_eth_dev_start(port_id) < 0)
            rte_exit(EXIT_FAILURE, "Start ethernet error\n");
    
    }
    
    
    
    int main(int argc, char **argv)
    {
        unsigned int i =0;
        //uint8_t   au8SendMsg[] = "hello misss";
        
        /*init*/
        if(rte_eal_init(argc, argv) < 0)
            rte_exit(EXIT_FAILURE, "EAL init Error\n");
    
        /*create a mbuf pool*/
        struct rte_mempool *mbufpool = rte_pktmbuf_pool_create("mbufpool", NUM_MBUFS, 0, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
        if(mbufpool == NULL)
            rte_exit(EXIT_FAILURE, "Create mbufpool Error\n");
    
        /*init port*/
        init_port(mbufpool);
    
    
        rte_eth_macaddr_get(port_id, (struct rte_ether_addr *)gSrcMac);
    
        while(1){
            struct rte_mbuf *rx_pkts[MBUFS_SIZE];
            /*Retrieve a burst of input packets from a receive queue of an Ethernet device*/
            unsigned num_recv = rte_eth_rx_burst(port_id, 0, rx_pkts, MBUFS_SIZE);
            if(num_recv > MBUFS_SIZE)
                rte_exit(EXIT_FAILURE, "Receive from eth error\n");
    
            for(i = 0; i < num_recv; i++){
                
                struct rte_ether_hdr *ehdr  = rte_pktmbuf_mtod(rx_pkts[i], struct rte_ether_hdr*);
                if (ehdr->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) {
                    rte_pktmbuf_free(rx_pkts[i]);
                    continue;
                }
                
                struct rte_ipv4_hdr *iphdr =  rte_pktmbuf_mtod_offset(rx_pkts[i], struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr));
                if (iphdr->next_proto_id == IPPROTO_UDP) {
                    /*IPPROTO_UDP is defined in kernel source code include/uapi/inux/in.h*/
    
                    struct rte_udp_hdr *udphdr = (struct rte_udp_hdr *)(iphdr + 1);
    
    #if ENABLE_SEND
    
                    //rte_eth_macaddr_get(port_id, (struct rte_ether_addr *)gSrcMac);
                    rte_memcpy(gDstMac, ehdr->s_addr.addr_bytes, RTE_ETHER_ADDR_LEN);
                                    
                    rte_memcpy(&gSrcIp, &iphdr->dst_addr, sizeof(uint32_t));
                    rte_memcpy(&gDstIp, &iphdr->src_addr, sizeof(uint32_t));
                    
                    rte_memcpy(&gSrcPort, &udphdr->dst_port, sizeof(uint16_t));
                    rte_memcpy(&gDstPort, &udphdr->src_port, sizeof(uint16_t));
                
    #endif
    
                    uint16_t length = ntohs(udphdr->dgram_len);
                    *((char*)udphdr + length) = '\0';
    
                    struct in_addr addr;
                    addr.s_addr = iphdr->src_addr;
                    printf("<- src: %s:%d, ", inet_ntoa(addr), udphdr->src_port);
                    addr.s_addr = iphdr->dst_addr;
                    printf("dst: %s:%d, %s\n", inet_ntoa(addr), udphdr->dst_port, (char *)(udphdr+1));
                    
    #if ENABLE_SEND
                    //20220926add
                    rte_memcpy(&iphdr->src_addr, &gSrcIp, sizeof(uint32_t));
                    rte_memcpy(&iphdr->dst_addr, &gDstIp, sizeof(uint32_t));
                    addr.s_addr = iphdr->src_addr;
                    printf("-> src: %s:%d, ", inet_ntoa(addr), udphdr->src_port);
                    addr.s_addr = iphdr->dst_addr;
                    printf("dst: %s:%d, %s\n", inet_ntoa(addr), udphdr->dst_port, (char *)(udphdr+1));
    
                    rte_memcpy(ehdr->s_addr.addr_bytes, gSrcMac, RTE_ETHER_ADDR_LEN);
                    rte_memcpy(ehdr->d_addr.addr_bytes, gDstMac, RTE_ETHER_ADDR_LEN);
                    
                    //调测增加,实际使用可去掉端口限制
                    if (4369 == udphdr->src_port)
                    {
                        rte_eth_tx_burst(port_id , 0, rx_pkts, num_recv);
                                      
                    }
    #endif
                    rte_pktmbuf_free(rx_pkts[i]);
                }
            }
        }
    }
    
    
    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 10月17日
  • 修改了问题 10月12日
  • 修改了问题 10月12日
  • 创建了问题 10月12日

悬赏问题

  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配
  • ¥15 Power query添加列问题
  • ¥50 Kubernetes&Fission&Eleasticsearch
  • ¥15 報錯:Person is not mapped,如何解決?
  • ¥15 c++头文件不能识别CDialog