//packetsend_withSequence is the function where I am trying to generate the packets. #include #include #include #include #include #include uint64_t temp1; uint64_t temp2; int temp3; int test_type; double sec; time_t start_t,end_t; double diff_t; #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #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,ð_hdr.d_addr); rte_ether_addr_copy(&my_addr, ð_hdr.s_addr); eth_hdr.ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4); memset(temppacketdata,0x0,sizeof(temppacketdata)); memcpy(temppacketdata, ð_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(); return(0); }