DPDK - rte_mbuf payload/data 初始化或 updation/modification
DPDK - rte_mbuf payload/data initialization or updation/modification
我正在尝试了解DPDK的basicfwd示例的转发机制。谁能帮我初始化和编辑 rte_mbuf
的有效负载? Here 就是 class。
我计划使用 tcpdump
和 rte_pktmbuf_dump
查看数据包内容。
这里是 rte_mbuf
我想添加我自己的 payload 到:
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);
我修改了 DPDK 示例中的示例应用程序 basicfwd.c 以在文件中打印转发的数据包:
/* 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);
这些是我在输出文件中看到的数据包:
我希望能够修改内容以便更好地理解。我试过 rte_pktmbuf_init
和 bufs->userdata =*(unsigned short*) 0xAAAAAAAA
但它对我不起作用。
我通过在内存池中创建自己的数据包解决了这个问题。
- 为程序创建一个内存池。
- 在内存池中分配一个数据包。
- 用数据、源地址、目标地址填充数据包,并初始化数据包字段。
完整的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, ð_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, ð_hdr->d_addr);
rte_eth_macaddr_get(port ^ 1, ð_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);
}
我正在尝试了解DPDK的basicfwd示例的转发机制。谁能帮我初始化和编辑 rte_mbuf
的有效负载? Here 就是 class。
我计划使用 tcpdump
和 rte_pktmbuf_dump
查看数据包内容。
这里是 rte_mbuf
我想添加我自己的 payload 到:
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);
我修改了 DPDK 示例中的示例应用程序 basicfwd.c 以在文件中打印转发的数据包:
/* 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);
这些是我在输出文件中看到的数据包:
rte_pktmbuf_init
和 bufs->userdata =*(unsigned short*) 0xAAAAAAAA
但它对我不起作用。
我通过在内存池中创建自己的数据包解决了这个问题。
- 为程序创建一个内存池。
- 在内存池中分配一个数据包。
- 用数据、源地址、目标地址填充数据包,并初始化数据包字段。
完整的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, ð_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, ð_hdr->d_addr);
rte_eth_macaddr_get(port ^ 1, ð_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);
}