1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
| #include <rte_eal.h> #include <rte_ethdev.h> #include <rte_mbuf.h>
#include <stdio.h> #include <arpa/inet.h>
#define NUM_MBUFS (4096-1)
#define BURST_SIZE 32 #define ENABLE_SEND 1
#if ENABLE_SEND
static uint32_t gSrcIp; static uint32_t gDstIp; static uint8_t gSrcMac[RTE_ETHER_ADDR_LEN]; static uint8_t gDstMac[RTE_ETHER_ADDR_LEN]; static uint16_t gSrcPort; static uint16_t gDstPort;
#endif
int gDpdkPortId = 0;
static const struct rte_eth_conf port_conf_default = { .rxmode = {.max_rx_pkt_len = RTE_ETHER_MAX_LEN } };
static void ng_init_port(struct rte_mempool *mbuf_pool) {
uint16_t nb_sys_ports= rte_eth_dev_count_avail(); if (nb_sys_ports == 0) { rte_exit(EXIT_FAILURE, "No Supported eth found\n"); }
struct rte_eth_dev_info dev_info; rte_eth_dev_info_get(gDpdkPortId, &dev_info); const int num_rx_queues = 1; const int num_tx_queues = 1; struct rte_eth_conf port_conf = port_conf_default; rte_eth_dev_configure(gDpdkPortId, num_rx_queues, num_tx_queues, &port_conf);
if (rte_eth_rx_queue_setup(gDpdkPortId, 0 , 128, rte_eth_dev_socket_id(gDpdkPortId),NULL, mbuf_pool) < 0) {
rte_exit(EXIT_FAILURE, "Could not setup RX queue\n"); }
#if ENABLE_SEND
struct rte_eth_txconf txq_conf = dev_info.default_txconf; txq_conf.offloads = port_conf.rxmode.offloads; if (rte_eth_tx_queue_setup(gDpdkPortId, 0 , 1024, rte_eth_dev_socket_id(gDpdkPortId) , &txq_conf) < 0) { rte_exit(EXIT_FAILURE, "Could not setup TX queue\n"); }
#endif
if (rte_eth_dev_start(gDpdkPortId) < 0 ) { rte_exit(EXIT_FAILURE, "Could not start\n"); } }
static int ng_encode_udp_pkt(uint8_t* msg , unsigned char* data , uint16_t total_len) {
struct rte_ether_hdr* eth = (struct rte_ether_hdr*)msg; rte_memcpy(ð->s_addr , &gSrcMac , RTE_ETHER_ADDR_LEN); rte_memcpy(ð->d_addr, &gDstMac, RTE_ETHER_ADDR_LEN); eth->ether_type = htons(RTE_ETHER_TYPE_IPV4); struct rte_ipv4_hdr* ip = (struct rte_ipv4_hdr*)(msg + sizeof(struct rte_ether_hdr)); ip->version_ihl = 0x45; ip->type_of_service = 0; ip->total_length = htonl(total_len - sizeof(struct rte_ether_hdr)); ip->packet_id = 0; ip->fragment_offset = 0; ip->time_to_live = 64; ip->next_proto_id = IPPROTO_UDP; ip->src_addr = gSrcIp; ip->dst_addr = gDstIp; ip->hdr_checksum = 0; ip->hdr_checksum = rte_ipv4_cksum(ip); struct rte_udp_hdr* udp = (struct rte_udp_hdr*)(ip + 1); udp->src_port = gSrcPort; udp->dst_port = gDstPort; udp->dgram_len = htons(total_len - sizeof(struct rte_ether_hdr) - sizeof(struct rte_ipv4_hdr)); uint16_t udp_len = total_len - sizeof(struct rte_ether_hdr) - sizeof(struct rte_ipv4_hdr); rte_memcpy(udp+1 , data , udp_len); udp->dgram_cksum= 0; udp->dgram_cksum = rte_ipv4_udptcp_cksum(ip ,udp);
return 0; }
static struct rte_mbuf* ng_send(struct rte_mempool* mbuf_pool, unsigned char* msg , uint16_t length) { const unsigned total_len = 14 + 20 + 8 + length;
struct rte_mbuf* mbuf = rte_pktmbuf_alloc(mbuf_pool); mbuf->pkt_len = total_len; mbuf->data_len = total_len;
uint8_t* pktdata = rte_pktmbuf_mtod(mbuf, uint8_t*); ng_encode_udp_pkt(pktdata , msg ,length);
return mbuf; }
int main(int argc, char *argv[]) {
if (rte_eal_init(argc, argv) < 0) { rte_exit(EXIT_FAILURE, "Error with EAL init\n"); } printf("init success!! \n");
struct rte_mempool *mbuf_pool = rte_pktmbuf_pool_create("mbuf pool", NUM_MBUFS, 0, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); if (mbuf_pool == NULL) { rte_exit(EXIT_FAILURE, "Could not create mbuf pool\n"); }
rte_eth_macaddr_get(gDpdkPortId , (struct rte_ether_addr*)gSrcMac);
ng_init_port(mbuf_pool); printf("mbuf_pool init success!! \n");
while(1) { struct rte_mbuf* mbufs[BUFSIZ]; unsigned num_recvd = rte_eth_rx_burst(gDpdkPortId , 0 , mbufs , BUFSIZ); if(num_recvd > BUFSIZ) { rte_exit(EXIT_FAILURE , "Error receiving from eth \n"); }
unsigned int i = 0; for(i=0 ; i<num_recvd ; ++i) { struct rte_ether_hdr* ehdr = rte_pktmbuf_mtod(mbufs[i] , struct rte_ether_hdr*); if(ehdr->ether_type != rte_cpu_to_be_16(RTE_ETHER_TYPE_IPV4)) { rte_pktmbuf_free(mbufs[i]); continue; } struct rte_ipv4_hdr* iphdr = rte_pktmbuf_mtod_offset(mbufs[i] , struct rte_ipv4_hdr* , sizeof(struct rte_ether_hdr)); if(iphdr->next_proto_id == IPPROTO_UDP) { struct rte_udp_hdr* udphdr = (struct rte_udp_hdr*)((char*)iphdr + sizeof(struct rte_ipv4_hdr)); #if ENABLE_SEND rte_memcpy(&gDstMac , &ehdr->d_addr , RTE_ETHER_ADDR_LEN); gSrcIp = iphdr->dst_addr; gDstIp = iphdr->src_addr; gSrcPort = udphdr->dst_port; gDstPort = udphdr->src_port; #endif
uint16_t length = htons(udphdr->dgram_len); *((char*)(udphdr + length)) = '\0';
struct in_addr addr; addr.s_addr = iphdr->src_addr; printf("src:%s %d " , inet_ntoa(addr) , ntohs(udphdr->src_port));
addr.s_addr = iphdr->dst_addr; printf("dst:%s %d length=%d:%s\n" , inet_ntoa(addr) , ntohs(udphdr->dst_port) , length , (char*)((char*)udphdr + sizeof(udphdr)));
#if ENABLE_SEND struct rte_mbuf* txbuf = ng_send(mbuf_pool , (unsigned char*)(udphdr + 1) , length); rte_eth_tx_burst(gDpdkPortId , 0 , &txbuf , 1); rte_pktmbuf_free(txbuf); #endif rte_pktmbuf_free(mbufs[i]); } } } }
|