gpt4 book ai didi

c - 如何在DPDK中生成增量数据值

转载 作者:行者123 更新时间:2023-11-30 19:25:29 25 4
gpt4 key购买 nike

Code image

您好DPDK用户,我试图通过DPDK生成UDP数据包的增量数据值。但是当我传输它时,我在 Wireshark 中验证了相同的帧。数据包的数据部分发生不合逻辑的变化。数据中看不到序列。它优化了我写的数据值。我尝试写入的最后一个值存在于有效负载的所有字节中,而不是按增量顺序预期。任何人都可以帮助我,为什么会发生这种情况以及生成增量 DPDK 数据包的最简单方法是什么?代码在上面的图像文件中给出。

最佳答案

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <unistd.h>

#include <inttypes.h>
#include<assert.h>
uint64_t temp1;
uint64_t temp2;
int temp3;
int test_type;
double sec;
time_t start_t,end_t;
double diff_t;

#include<time.h>
#include<signal.h>
#include<linux/kernel.h>


#include <rte_memory.h>
#include <rte_launch.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_ethdev.h>
#include <rte_udp.h>
#include <rte_tcp.h>
#include <rte_ip.h>
#include <rte_arp.h>
#include <rte_icmp.h>
#include <rte_cycles.h>
#include <rte_lcore.h>
#include <rte_mbuf.h>


#define RX_RING_SIZE 2028
#define TX_RING_SIZE 2048

#define NUM_MBUFS 8191
#define MBUF_CACHE_SIZE 250
#define BURST_SIZE 32

#define UDP_SRC_PORT 6666
#define UDP_DST_PORT 6666
#define TCP_SRC_PORT 6666
#define TCP_DST_PORT 6666
#define IP_DEFTTL 64
#define IP_VERSION 0x40
#define IP_HDRLEN 0x05
#define IP_VHL_DEF (IP_VERSION | IP_HDRLEN)

#define TX_PACKET_LENGTH 64
#define ETHER_MAX_LEN 1518
#if RTE_BYTE_ORDER == RTE_BIG_ENDIAN
#define RTE_BE_TO_CPU_16(be_16_v) (be_16_v)
#define RTE_CPU_TO_BE_16(cpu_16_v) (cpu_16_v)
#else
#define RTE_BE_TO_CPU_16(be_16_v) \
(uint16_t) ((((be_16_v) & 0xFF) << 8) | ((be_16_v) >> 8))
#define RTE_CPU_TO_BE_16(cpu_16_v) \
(uint16_t) ((((cpu_16_v) & 0xFF) << 8) | ((cpu_16_v) >> 8))
#endif
#define rte_ctrlmbuf_data(m) ((char *)((m)->buf_addr)+(m)->data_off)

// convert a quad-dot IP string to uint32_t IP address
uint32_t string_to_ip(char *s) {
unsigned char a[4];
int rc = sscanf(s, "%d.%d.%d.%d",a+0,a+1,a+2,a+3);
if(rc != 4){
fprintf(stderr, "bad source IP address format. Use like: -s 198.19.111.179\n");
exit(1);
}

return
(uint32_t)(a[0]) << 24 |
(uint32_t)(a[1]) << 16 |
(uint32_t)(a[2]) << 8 |
(uint32_t)(a[3]);

}

// convert six colon separated hex bytes string to uint64_t Ethernet MAC address
uint64_t string_to_mac(char *s) {
unsigned char a[6];
int rc = sscanf(s, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
a + 0, a + 1, a + 2, a + 3, a + 4, a + 5);
if(rc !=6 ){
fprintf(stderr, "bad MAC address format. Use like: -m 0a:38:ca:f6:f3:20\n");
exit(1);
}

return
(uint64_t)(a[0]) << 40 |
(uint64_t)(a[1]) << 32 |
(uint64_t)(a[2]) << 24 |
(uint64_t)(a[3]) << 16 |
(uint64_t)(a[4]) << 8 |
(uint64_t)(a[5]);
}

uint64_t DST_MAC;
uint32_t IP_SRC_ADDR,IP_DST_ADDR;


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

static struct rte_ipv4_hdr pkt_ip_hdr;
static struct rte_udp_hdr pkt_udp_hdr;

struct rte_ether_addr my_addr;
struct rte_mempool *mbuf_pool;
struct rte_data_hdr pkt_data_hdr;



static void setup_pkt_udp_ip_headers(struct rte_ipv4_hdr *ip_hdr,
struct rte_udp_hdr *pudp_hdr,
uint16_t pkt_data_len)
{
uint16_t *ptr16;
uint32_t ip_cksum;
uint16_t pkt_len;

int sizeof_=sizeof(struct rte_udp_hdr);
int sizeof__=sizeof(struct rte_ipv4_hdr);

//initialize udp headers
pkt_len = (uint16_t) (pkt_data_len + sizeof_);
pudp_hdr->src_port = rte_cpu_to_be_16(UDP_SRC_PORT);
pudp_hdr->dst_port = rte_cpu_to_be_16(UDP_DST_PORT);
pudp_hdr->dgram_len = RTE_CPU_TO_BE_16(pkt_len);
pudp_hdr->dgram_cksum = 32; // No udp checksum.

//Initialize IP header.
pkt_len = (uint16_t) (pkt_len + sizeof__);
ip_hdr->version_ihl = IP_VHL_DEF;
ip_hdr->type_of_service = 0;
ip_hdr->fragment_offset = 0;
ip_hdr->time_to_live = IP_DEFTTL;
ip_hdr->next_proto_id = IPPROTO_UDP;
ip_hdr->packet_id = 0;
ip_hdr->total_length = RTE_CPU_TO_BE_16(pkt_len);
ip_hdr->src_addr = rte_cpu_to_be_32(IP_SRC_ADDR);
ip_hdr->dst_addr = rte_cpu_to_be_32(IP_DST_ADDR);

//Compute IP header checksum.
ptr16 = (unaligned_uint16_t*) ip_hdr;
ip_cksum = 0;
ip_cksum += ptr16[0]; ip_cksum += ptr16[1];
ip_cksum += ptr16[2]; ip_cksum += ptr16[3];
ip_cksum += ptr16[4];
ip_cksum += ptr16[6]; ip_cksum += ptr16[7];
ip_cksum += ptr16[8]; ip_cksum += ptr16[9];

//Reduce 32 bit checksum to 16 bits and complement it.
ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) +
(ip_cksum & 0x0000FFFF);
if (ip_cksum > 65535)
ip_cksum -= 65535;
ip_cksum = (~ip_cksum) & 0x0000FFFF;
if (ip_cksum == 0)
ip_cksum = 0xFFFF;
ip_hdr->hdr_checksum = (uint16_t) ip_cksum;
}


union {
uint64_t as_int;
struct rte_ether_addr as_addr;
} dst_eth_addr;
static void packetsend_withSequence()
{
int counter=1;
int pkt_drop_counter=0;


struct rte_ether_hdr eth_hdr;
struct rte_mbuf *pkt=NULL;
struct rte_mbuf *pkts_burst[1];
struct rte_mbuf *m;
char *data;
char temppacketdata[100];

while(1){

pkt = rte_pktmbuf_alloc(mbuf_pool);
if(pkt == NULL) {printf("trouble at rte_mbuf_raw_alloc\n");}
data = rte_pktmbuf_append(pkt, TX_PACKET_LENGTH);
if(data == NULL ) {printf("trouble at data alloc\n");}

// set up addresses
printf("\n rte_pktmbuf_pkt_len is %d", rte_pktmbuf_pkt_len(pkt));
dst_eth_addr.as_int=rte_cpu_to_be_64(DST_MAC);
rte_ether_addr_copy(&dst_eth_addr,&eth_hdr.d_addr);
rte_ether_addr_copy(&my_addr, &eth_hdr.s_addr);
eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4);

memset(temppacketdata,0x0,sizeof(temppacketdata));

memcpy(temppacketdata, &eth_hdr,(size_t)sizeof(eth_hdr)); //copy eth header
memcpy(temppacketdata+(size_t)sizeof(eth_hdr), &pkt_ip_hdr,(size_t)sizeof(pkt_ip_hdr)); //copy IP header
memcpy(temppacketdata+(size_t)sizeof(eth_hdr)+(size_t)sizeof(pkt_ip_hdr), &pkt_udp_hdr,(size_t)sizeof(pkt_udp_hdr)); //copy UDP header

memcpy(temppacketdata+(size_t)sizeof(eth_hdr)+(size_t)sizeof(pkt_ip_hdr)+(size_t)sizeof(pkt_udp_hdr), &counter,(size_t)sizeof(counter)); //copy int data

memcpy(data,temppacketdata,rte_pktmbuf_pkt_len(pkt));


pkts_burst[0] = pkt;
const uint16_t nb_tx = rte_eth_tx_burst(0, 0, pkts_burst,1);

if (unlikely(nb_tx < 1))
{
pkt_drop_counter++;
rte_pktmbuf_free(pkt); // This frees chained segs
}
else{
counter++;
printf("%d",nb_tx);
}
if(counter > 1000)
break;

}
printf(" pkt_drop_counter = %d counter =%d",pkt_drop_counter,counter);
}

// Initialize Port
static inline int
port_init(uint16_t port, struct rte_mempool *mbuf_pool)
{
struct rte_eth_conf port_conf = port_conf_default;
const uint16_t rx_rings = 1, tx_rings = 1;
uint16_t nb_rxd = RX_RING_SIZE;
uint16_t nb_txd = TX_RING_SIZE;
int retval;
uint16_t q;
struct rte_eth_dev_info dev_info;
struct rte_eth_txconf txconf;

if (!rte_eth_dev_is_valid_port(port))
return -1;

rte_eth_dev_info_get(port, &dev_info);
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
port_conf.txmode.offloads |=
DEV_TX_OFFLOAD_MBUF_FAST_FREE;

/* Configure the Ethernet device. */
retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
if (retval != 0)
return retval;

retval = rte_eth_dev_adjust_nb_rx_tx_desc(port, &nb_rxd, &nb_txd);
if (retval != 0)
return retval;

txconf = dev_info.default_txconf;
txconf.offloads = port_conf.txmode.offloads;

//Allocate and set up 1 TX queue
for (q = 0; q < tx_rings; q++) {
retval = rte_eth_tx_queue_setup(port, q, nb_txd,
rte_eth_dev_socket_id(port), &txconf);
if (retval < 0)
return retval;
}
/* Allocate and set up 1 RX queue per Ethernet port. */
for (q = 0; q < rx_rings; q++) {
retval = rte_eth_rx_queue_setup(port, q, nb_rxd,
rte_eth_dev_socket_id(port), NULL, mbuf_pool);
if (retval < 0)
return retval;
}

/* Start the Ethernet port. */
retval = rte_eth_dev_start(port);
if (retval < 0)
return retval;

/* get the port MAC address. */
rte_eth_macaddr_get(port, &my_addr);
printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
" %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
port,
my_addr.addr_bytes[0], my_addr.addr_bytes[1],
my_addr.addr_bytes[2], my_addr.addr_bytes[3],
my_addr.addr_bytes[4], my_addr.addr_bytes[5]);

return 0;
}


int main(int argc, char **argv)
{
int ret,c;
uint16_t pkt_data_len;
int mac_flag=0,ip_src_flag=0,ip_dst_flag=0;

ret = rte_eal_init(argc, argv);
if (ret < 0)
rte_panic("Cannot init EAL\n");

argc -= ret;
argv += ret;




while ((c = getopt(argc, argv, "m:s:d:h")) != -1)
switch(c) {
case 'm':
// note, not quite sure why last two bytes are zero, but that is how DPDK likes it
DST_MAC=0ULL;
DST_MAC=string_to_mac(optarg)<<16;
mac_flag=1;
break;
case 's':
IP_SRC_ADDR=string_to_ip(optarg);
ip_src_flag=1;
break;
case 'd':
IP_DST_ADDR=string_to_ip(optarg);
ip_dst_flag=1;
break;
case 'h':
printf("usage -- -m [dst MAC] -s [src IP] -d [dst IP]\n");
exit(0);
break;
}

if(mac_flag==0) {
fprintf(stderr, "missing -m for destination MAC adress\n");
exit(1);
}
if(ip_src_flag==0) {
fprintf(stderr, "missing -s for IP source adress\n");
exit(1);
}
if(ip_dst_flag==0) {
fprintf(stderr, "missing -d for IP destination adress\n");
exit(1);
}

/* Creates a new mempool in memory to hold the mbufs. */
mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS,
MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());

if (mbuf_pool == NULL)
rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");

// initialize port 0
if (port_init(0,mbuf_pool) != 0)
rte_exit(EXIT_FAILURE, "Cannot init port 0\n");
/* Initialize all ports. */

if (port_init(1, mbuf_pool) != 0)
rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu16 "\n",
1);




pkt_data_len = (uint16_t) (TX_PACKET_LENGTH - (sizeof(struct rte_ether_hdr) +
sizeof(struct rte_ipv4_hdr) +
sizeof(struct rte_udp_hdr)));
setup_pkt_udp_ip_headers(&pkt_ip_hdr, &pkt_udp_hdr, pkt_data_len);

packetsend_withSequence();
// send_packet();
return(0);
}

关于c - 如何在DPDK中生成增量数据值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58710948/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com