• DPDK程序结合网络助手接收数据


    网络调试工具https://download.csdn.net/download/hdsHDS6/88390999?spm=1001.2014.3001.5503

    DPDK代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. #include
    14. #define NB_MBUF 512
    15. #define MAX_PKT_BURST 32
    16. #define SELF_PROTO_TYPE 0x0888
    17. static struct rte_eth_conf port_conf = {
    18. .rxmode = {
    19. .split_hdr_size = 0
    20. }
    21. };
    22. // cat /proc/interrupts
    23. void init_port(struct rte_mempool *mbuf_pool){
    24. uint16_t nb_ports = 0;
    25. int ret = 0;
    26. int portid = 0;
    27. struct rte_eth_dev_info dev_info;
    28. struct rte_ether_addr addr;
    29. const int num_rx_queues = 1;
    30. const int num_tx_queues = 0;
    31. nb_ports = rte_eth_dev_count_avail();
    32. if(nb_ports == 0){
    33. rte_exit(EXIT_FAILURE, "No support eth found\n");
    34. }
    35. for(portid = 0; portid < nb_ports; portid++){
    36. ret = rte_eth_macaddr_get(portid, &addr);
    37. if (ret != 0){
    38. rte_exit(EXIT_FAILURE, "macaddr get failed\n");
    39. }
    40. printf("Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
    41. " %02"PRIx8" %02"PRIx8" %02"PRIx8"\n",
    42. portid, RTE_ETHER_ADDR_BYTES(&addr));
    43. ret = rte_eth_dev_info_get(portid, &dev_info);
    44. ret = rte_eth_dev_configure(portid, num_rx_queues, num_tx_queues, &port_conf);
    45. ret = rte_eth_rx_queue_setup(portid, 0, 128, rte_eth_dev_socket_id(portid), NULL, mbuf_pool);
    46. ret = rte_eth_dev_start(portid);
    47. if (ret < 0) {
    48. rte_exit(EXIT_FAILURE, "rte_eth_dev_start:err=%d, port=%u\n", ret, portid);
    49. }
    50. }
    51. }
    52. /*
    53. 发送方注意设置LP信息
    54. */
    55. int
    56. main(int argc, char **argv)
    57. {
    58. int ret;
    59. unsigned lcore_id;
    60. int i = 0;
    61. int portid = 0;
    62. int nb_rx = 0;
    63. /* 初始化环境 */
    64. ret = rte_eal_init(argc, argv);
    65. if (ret < 0)
    66. rte_panic("Cannot init EAL\n");
    67. /* 创建内存池 */
    68. struct rte_mempool *mbuf_pool = rte_pktmbuf_pool_create("my pool", NB_MBUF, 32, 0,
    69. RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
    70. if (mbuf_pool == NULL){
    71. return -1;
    72. }
    73. init_port(mbuf_pool);
    74. while(1){
    75. struct rte_mbuf* pkts_burst[MAX_PKT_BURST];
    76. nb_rx = rte_eth_rx_burst(portid, 0, pkts_burst, MAX_PKT_BURST);
    77. if(nb_rx == 0){
    78. sleep(1);
    79. continue;
    80. }
    81. // printf("recv data start : %d \n", nb_rx);
    82. for(i = 0; i < nb_rx; i++){
    83. // ether
    84. struct rte_ether_hdr *hdr = rte_pktmbuf_mtod(pkts_burst[i], struct rte_ether_hdr *);
    85. // ip
    86. // printf("ether_type = %x \n", hdr->ether_type);
    87. if(hdr->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)){
    88. struct rte_ipv4_hdr *iphdr = rte_pktmbuf_mtod_offset(pkts_burst[i], struct rte_ipv4_hdr *, sizeof(struct rte_ether_hdr));
    89. // upd
    90. if(iphdr->next_proto_id == IPPROTO_UDP){
    91. // (struct rte_udp_hdr *)RTE_PTR_ADD(iphdr, sizeof(struct rte_ipv4_hdr));
    92. struct rte_udp_hdr* udphdr = (struct rte_udp_hdr*)(iphdr + 1);
    93. uint16_t length = ntohs(udphdr->dgram_len);
    94. *(char*)(udphdr + length) = '\0';
    95. struct in_addr addr;
    96. addr.s_addr = iphdr->src_addr;
    97. printf("src:%s:%d \n", inet_ntoa(addr), ntohs(udphdr->src_port));
    98. addr.s_addr = iphdr->dst_addr;
    99. printf("dst:%s:%d, %s \n", inet_ntoa(addr), ntohs(udphdr->dst_port), (char*)(udphdr+1));
    100. }else if(iphdr->next_proto_id == IPPROTO_TCP){
    101. struct rte_tcp_hdr* tcphdr = (struct rte_tcp_hdr*)(iphdr + 1);
    102. struct in_addr addr;
    103. addr.s_addr = iphdr->src_addr;
    104. printf("src:%s:%d \n", inet_ntoa(addr), ntohs(tcphdr->src_port));
    105. addr.s_addr = iphdr->dst_addr;
    106. printf("dst:%s:%d, date = %s \n", inet_ntoa(addr), ntohs(tcphdr->dst_port), (char*)(tcphdr+1));
    107. }
    108. }else if(hdr->ether_type == rte_cpu_to_be_16(SELF_PROTO_TYPE)){
    109. char *data = rte_pktmbuf_mtod_offset(pkts_burst[i], char *, sizeof(struct rte_ether_hdr));
    110. printf("recv data: %s \n", data);
    111. }
    112. rte_pktmbuf_free(pkts_burst[i]);
    113. }
    114. }
    115. return 0;
    116. }

    Makefile文件

    1. # SPDX-License-Identifier: BSD-3-Clause
    2. # Copyright(c) 2010-2014 Intel Corporation
    3. # binary name
    4. APP = recv
    5. # all source are stored in SRCS-y
    6. SRCS-y := main.c
    7. PKGCONF ?= pkg-config
    8. # Build using pkg-config variables if possible
    9. ifneq ($(shell $(PKGCONF) --exists libdpdk && echo 0),0)
    10. $(error "no installation of DPDK found")
    11. endif
    12. all: shared
    13. .PHONY: shared static
    14. shared: build/$(APP)-shared
    15. ln -sf $(APP)-shared build/$(APP)
    16. static: build/$(APP)-static
    17. ln -sf $(APP)-static build/$(APP)
    18. PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null)
    19. CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk)
    20. # Add flag to allow experimental API as l2fwd uses rte_ethdev_set_ptype API
    21. CFLAGS += -DALLOW_EXPERIMENTAL_API
    22. LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk)
    23. LDFLAGS_STATIC = $(shell $(PKGCONF) --static --libs libdpdk)
    24. ifeq ($(MAKECMDGOALS),static)
    25. # check for broken pkg-config
    26. ifeq ($(shell echo $(LDFLAGS_STATIC) | grep 'whole-archive.*l:lib.*no-whole-archive'),)
    27. $(warning "pkg-config output list does not contain drivers between 'whole-archive'/'no-whole-archive' flags.")
    28. $(error "Cannot generate statically-linked binaries with this version of pkg-config")
    29. endif
    30. endif
    31. build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build
    32. $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED)
    33. build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build
    34. $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC)
    35. build:
    36. @mkdir -p $@
    37. .PHONY: clean
    38. clean:
    39. rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared
    40. test -d build && rmdir -p build || true

    虚拟机设置

    网络适配器2和3用于DPDK的绑定,并设置为桥接模式,使两个网口与物理机处于同一局域网

    编译:

    加载驱动绑定网卡:

    1. #! /bin/bash
    2. eth1=$1
    3. eth2=$2
    4. DPDK_PATH=$3
    5. DPDK_KMOD_PATH=$4
    6. if [ -z "$DPDK_PATH" ];then
    7. DPDK_PATH="/root/dpdk-22.07/usertools"
    8. fi
    9. if [ -z "$DPDK_KMOD_PATH" ];then
    10. DPDK_KMOD_PATH="/root/dpdk-22.07/kmod"
    11. fi
    12. # 关闭网口
    13. ifconfig $eth1 down
    14. ifconfig $eth2 down
    15. # 大页
    16. echo 512 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
    17. # 加载uio驱动
    18. modprobe uio
    19. insmod $DPDK_KMOD_PATH/igb_uio.ko intr_mode=legacy
    20. # 加载kni驱动
    21. insmod $DPDK_KMOD_PATH/rte_kni.ko kthread_mode=multiple
    22. # 绑定网口
    23. $DPDK_PATH/dpdk-devbind.py -b igb_uio "$eth1" "$eth2"
    24. $DPDK_PATH/dpdk-devbind.py -s

    运行:

    可以获取到端口1的MAC地址,因为在代码中是端口1在接收数据

    windows上设置静态IP与MAC的映射

    命令:

    netsh i i show in

    添加静态IP与MAC的映射

    命令:

    netsh  -c  "i  i" add neighbors  16  "192.168.1.7" "00-0c-29-c3-b0-c0"

    arp -a

    利用网络调试工具发送UDP数据:

    本地主机地址要与DPDK绑定的网络适配器同属于一个局域网

  • 相关阅读:
    C语言-入门-语法-指针(十二)
    13、学习MySQL 分组
    Java编程学习-MySQL(函数)
    Redis学习笔记①基础篇_Redis快速入门
    HPC技术:MPICH源码分析
    数据库select语句基础
    【Dotnet 工具箱】跨平台图表库 LiveCharts2
    JavaSE——集合框架
    Java EE——线程(3)
    LeetCode 566. Reshape the Matrix
  • 原文地址:https://blog.csdn.net/hdsHDS6/article/details/133513804