2016-08-02 512 views
1

我想了解DPDK的basicfwd示例的转发机制。任何人都可以帮我初始化和编辑rte_mbuf的有效载荷吗? Here是班级。我打算使用tcpdump和查看数据包内容。DPDK - rte_mbuf负载/数据初始化或更新/修改

这里是rte_mbuf我想我自己的有效载荷添加到:

struct rte_mbuf *bufs[BURST_SIZE]; 

这是正在接收rte_mbuf

const uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE); 

这是rte_mbuf传输:

const uint16_t nb_tx = rte_eth_tx_burst(port^1, 0, 
            bufs, nb_rx); 

我修改了示例应用程序basicfwd.c在DPDK的例子在文件打印转发的数据包:

/* Get burst of RX packets, from first port of pair. */ 

const uint16_t nb_rx = rte_eth_rx_burst(port, 0, bufs, BURST_SIZE); 
FILE *fp; 

fp = fopen("dump.txt", "a"); 
fprintf(fp, "\n-----------------------\n fprintf... %d<->%d\n", count, port); 

rte_pktmbuf_dump(fp, bufs[0], 1000); 
fclose(fp); 
if (unlikely(nb_rx == 0)) 
     continue; 

/* Send burst of TX packets, to second port of pair. */ 
    const uint16_t nb_tx = rte_eth_tx_burst(port^1, 0,bufs, nb_rx); 

这些都是我在输出文件中看到的数据包: The dump for the first three iterations of the loop 我希望能够修改的内容进行更好的理解。我试过rte_pktmbuf_initbufs->userdata =*(unsigned short*) 0xAAAAAAAA,但它不适合我。

+0

用户数据不是有效载荷是私人区域的用户使用。有效载荷位于mbuf-> buf_addr处,它指向真实数据包中的第一个字节。 – roni

回答

2

我通过在内存池中创建自己的数据包解决了这个问题。

  1. 为程序创建一个内存池。
  2. 在内存池中分配一个数据包。
  3. 用数据,源地址,目标地址和初始化数据包字段填充数据包。

完整lcore_main功能:

/* 
* The main thread that does the work, reading from 
* an input port and writing to an output port. 
*/ 
struct message { 
    char data[DATA_SIZE]; 
}; 

static __attribute__(()) void 
lcore_main(void) 
{ 
    const uint8_t nb_ports = rte_eth_dev_count(); 
    uint8_t port; 

    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); 

    struct rte_mbuf *pkt; 
    struct ether_hdr *eth_hdr; 

    struct message obj; 
    struct message *msg; 
    int nb_rx = 0, nb_tx = 0, cnt = 0, pkt_size = 0; 
    int count = 0; 
    int k = 0; 
    for (count = 0; count < DATA_SIZE; count++){ 
     obj.data[count] = (char)(97 + (k++)); 
     if (k == 26) 
      k = 0; 
    } 
    time_t endtime = time(NULL) + 10; 
    port = 0; 
    while (time(NULL) < endtime) { 
     cnt = rte_eth_rx_burst(port, 0, &pkt, 1); 
     nb_rx += cnt; 

     if (cnt > 0) 
     { 
      eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *); 

      rte_eth_macaddr_get(port, &eth_hdr->s_addr); 

      pkt_size = sizeof(struct message) + sizeof(struct ether_hdr); 
      msg = (struct message *) (rte_pktmbuf_mtod(pkt, char*)) + sizeof(struct ether_hdr); 
      rte_pktmbuf_free(pkt); 
     } 

     msg = &obj; 
     pkt = rte_pktmbuf_alloc(mbuf_pool); 
     pkt_size = sizeof(struct message) + sizeof(struct ether_hdr); 
     pkt->data_len = pkt_size; 
     pkt->pkt_len = pkt_size; 
     eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *); 
     rte_eth_macaddr_get(port, &eth_hdr->d_addr); 
     rte_eth_macaddr_get(port^1, &eth_hdr->s_addr); 
     eth_hdr->ether_type = htons(PTP_PROTOCOL); 
     char* data; 

     data = rte_pktmbuf_append(pkt, sizeof(struct message)); 
     if (data != NULL) 
      rte_memcpy(data, msg, sizeof(struct message)); 

     nb_tx += rte_eth_tx_burst(port^1, 0, &pkt, 1); 
    } 
    printf("----\nData size: %d\nPacket size: %d\nRX : %d, TX : %d\n\n", DATA_SIZE, pkt_size, nb_rx, nb_tx); 
}