On 10 November 2014 23:06, Maxim Uvarov <[email protected]> wrote:
> Generator is good example how to create packets and send them to wire. > Even if it's not really effective I think it's better to have it in code > for now. > I think its better to re-add if we want it. Cheers, Anders > > Maxim. > > On 11/11/2014 12:44 AM, Mike Holmes wrote: > >> I think I agree, it has been hard to have the bandwidth to progress the >> generator and we have started to use DPDK-pktgen for real tests such as >> L2FWD >> >> With the maturing of the ODP APIs for 1.0 I hope implementing a pktgen >> based tool will be easier than when the generator was created for 0.1 as a >> way to get any packets in and out. >> >> The only issue I see is a need to drive ODP without a pktio interface >> that directly put data into a queue. I assume pktgen will need a loopback >> interface if no real interface is involved - is that an issue ? >> >> >> On 10 November 2014 16:07, Anders Roxell <[email protected] >> <mailto:[email protected]>> wrote: >> >> The generator is deprecated and it will be replaced with pktgen and it >> has become a maintenance burden now when the API is changing so >> rapidly. >> >> Signed-off-by: Anders Roxell <[email protected] >> <mailto:[email protected]>> >> --- >> .gitignore | 1 - >> configure.ac <http://configure.ac> | 1 - >> doc/doxygen.cfg | 2 +- >> example/Makefile.am | 2 +- >> example/generator/Makefile.am | 6 - >> example/generator/odp_generator.c | 922 >> -------------------------------------- >> 6 files changed, 2 insertions(+), 932 deletions(-) >> delete mode 100644 example/generator/Makefile.am >> delete mode 100644 example/generator/odp_generator.c >> >> diff --git a/.gitignore b/.gitignore >> index 57b47ea..5f12d44 100644 >> --- a/.gitignore >> +++ b/.gitignore >> @@ -40,7 +40,6 @@ odp_ring >> odp_timer_ping >> odp_pktio >> odp_timer_test >> -odp_generator >> odp_l2fwd >> odp_ipsec >> odp_init >> diff --git a/configure.ac <http://configure.ac> b/configure.ac >> <http://configure.ac> >> index 1c061e9..5491bc9 100644 >> --- a/configure.ac <http://configure.ac> >> +++ b/configure.ac <http://configure.ac> >> >> @@ -168,7 +168,6 @@ AC_CONFIG_FILES([Makefile >> platform/Makefile >> platform/linux-generic/Makefile >> example/Makefile >> - example/generator/Makefile >> example/ipsec/Makefile >> example/l2fwd/Makefile >> example/odp_example/Makefile >> diff --git a/doc/doxygen.cfg b/doc/doxygen.cfg >> index 4b9d33c..b6fd644 100644 >> --- a/doc/doxygen.cfg >> +++ b/doc/doxygen.cfg >> @@ -9,7 +9,7 @@ TYPEDEF_HIDES_STRUCT = YES >> EXTRACT_STATIC = YES >> SORT_MEMBER_DOCS = NO >> WARN_NO_PARAMDOC = YES >> -INPUT = $(SRCDIR)/doc $(SRCDIR)/doc/users-guide >> $(DOCDIR)/api_headers $(SRCDIR)/helper/include >> $(SRCDIR)/example/packet $(SRCDIR)/example/l2fwd >> $(SRCDIR)/example/generator $(SRCDIR)/example/odp_example >> $(SRCDIR)/example/timer >> +INPUT = $(SRCDIR)/doc $(SRCDIR)/doc/users-guide >> $(DOCDIR)/api_headers $(SRCDIR)/helper/include >> $(SRCDIR)/example/packet $(SRCDIR)/example/l2fwd >> $(SRCDIR)/example/odp_example $(SRCDIR)/example/timer >> FILE_PATTERNS = odp*.h odp*.c *.dox >> RECURSIVE = YES >> SOURCE_BROWSER = YES >> diff --git a/example/Makefile.am b/example/Makefile.am >> index b2a22a3..a0e7c51 100644 >> --- a/example/Makefile.am >> +++ b/example/Makefile.am >> @@ -1 +1 @@ >> -SUBDIRS = generator ipsec l2fwd odp_example packet timer >> +SUBDIRS = ipsec l2fwd odp_example packet timer >> diff --git a/example/generator/Makefile.am >> b/example/generator/Makefile.am >> deleted file mode 100644 >> index 5b3d55a..0000000 >> --- a/example/generator/Makefile.am >> +++ /dev/null >> @@ -1,6 +0,0 @@ >> -include $(top_srcdir)/example/Makefile.inc >> - >> -bin_PROGRAMS = odp_generator >> -odp_generator_LDFLAGS = $(AM_LDFLAGS) -static >> - >> -dist_odp_generator_SOURCES = odp_generator.c >> diff --git a/example/generator/odp_generator.c >> b/example/generator/odp_generator.c >> deleted file mode 100644 >> index ffa5e62..0000000 >> --- a/example/generator/odp_generator.c >> +++ /dev/null >> @@ -1,922 +0,0 @@ >> -/* Copyright (c) 2014, Linaro Limited >> - * All rights reserved. >> - * >> - * SPDX-License-Identifier: BSD-3-Clause >> - */ >> - >> -/** >> - * @file >> - * >> - * @example odp_generator.c ODP loopback demo application >> - */ >> - >> -#include <stdlib.h> >> -#include <string.h> >> -#include <getopt.h> >> -#include <unistd.h> >> -#include <sys/time.h> >> - >> -#include <odp.h> >> - >> -#include <odph_linux.h> >> -#include <odph_packet.h> >> -#include <odph_eth.h> >> -#include <odph_ip.h> >> -#include <odph_udp.h> >> -#include <odph_icmp.h> >> - >> -#define MAX_WORKERS 32 /**< max number of >> works */ >> -#define SHM_PKT_POOL_SIZE (512*2048) /**< pkt pool size */ >> -#define SHM_PKT_POOL_BUF_SIZE 1856 /**< pkt pool buf >> size */ >> - >> -#define APPL_MODE_UDP 0 /**< UDP mode */ >> -#define APPL_MODE_PING 1 /**< ping mode */ >> -#define APPL_MODE_RCV 2 /**< receive mode */ >> - >> -/** print appl mode */ >> -#define PRINT_APPL_MODE(x) printf("%s(%i)\n", #x, (x)) >> - >> -/** Get rid of path in filename - only for unix-type paths using >> '/' */ >> -#define NO_PATH(file_name) (strrchr((file_name), '/') ? \ >> - strrchr((file_name), '/') + 1 : >> (file_name)) >> -/** >> - * Parsed command line application arguments >> - */ >> -typedef struct { >> - int core_count; /**< system core count */ >> - int if_count; /**< Number of interfaces to be >> used */ >> - char **if_names; /**< Array of pointers to >> interface names */ >> - odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ >> - odph_ethaddr_t srcmac; /**< src mac addr */ >> - odph_ethaddr_t dstmac; /**< dest mac addr */ >> - unsigned int srcip; /**< src ip addr */ >> - unsigned int dstip; /**< dest ip addr */ >> - int mode; /**< work mode */ >> - int number; /**< packets number to be sent */ >> - int payload; /**< data len */ >> - int timeout; /**< wait time */ >> - int interval; /**< wait interval ms between >> sending each packet */ >> -} appl_args_t; >> - >> -/** >> - * counters >> -*/ >> -static struct { >> - odp_atomic_u64_t seq; /**< ip seq to be send */ >> - odp_atomic_u64_t ip; /**< ip packets */ >> - odp_atomic_u64_t udp; /**< udp packets */ >> - odp_atomic_u64_t icmp; /**< icmp packets */ >> -} counters; >> - >> -/** * Thread specific arguments >> - */ >> -typedef struct { >> - char *pktio_dev; /**< Interface name to use */ >> - odp_buffer_pool_t pool; /**< Buffer pool for packet IO */ >> - int mode; /**< Thread mode */ >> -} thread_args_t; >> - >> -/** >> - * Grouping of both parsed CL args and thread specific args - >> alloc together >> - */ >> -typedef struct { >> - /** Application (parsed) arguments */ >> - appl_args_t appl; >> - /** Thread specific arguments */ >> - thread_args_t thread[MAX_WORKERS]; >> -} args_t; >> - >> -/** Global pointer to args */ >> -static args_t *args; >> - >> -/* helper funcs */ >> -static void parse_args(int argc, char *argv[], appl_args_t >> *appl_args); >> -static void print_info(char *progname, appl_args_t *appl_args); >> -static void usage(char *progname); >> -static int scan_ip(char *buf, unsigned int *paddr); >> -static int scan_mac(char *in, odph_ethaddr_t *des); >> -static void tv_sub(struct timeval *recvtime, struct timeval >> *sendtime); >> - >> -/** >> - * Scan ip >> - * Parse ip address. >> - * >> - * @param buf ip address string xxx.xxx.xxx.xx >> - * @param paddr ip address for odp_packet >> - * @return 1 success, 0 failed >> -*/ >> -static int scan_ip(char *buf, unsigned int *paddr) >> -{ >> - int part1, part2, part3, part4; >> - char tail = 0; >> - int field; >> - >> - if (buf == NULL) >> - return 0; >> - >> - field = sscanf(buf, "%d . %d . %d . %d %c", >> - &part1, &part2, &part3, &part4, &tail); >> - >> - if (field < 4 || field > 5) { >> - printf("expect 4 field,get %d/n", field); >> - return 0; >> - } >> - >> - if (tail != 0) { >> - printf("ip address mixed with non number/n"); >> - return 0; >> - } >> - >> - if ((part1 >= 0 && part1 <= 255) && (part2 >= 0 && part2 >> <= 255) && >> - (part3 >= 0 && part3 <= 255) && (part4 >= 0 && part4 >> <= 255)) { >> - if (paddr) >> - *paddr = part1 << 24 | part2 << 16 | part3 >> << 8 | part4; >> - return 1; >> - } else { >> - printf("not good ip %d:%d:%d:%d/n", part1, part2, >> part3, part4); >> - } >> - >> - return 0; >> -} >> - >> -/** >> - * Scan mac addr form string >> - * >> - * @param in mac string >> - * @param des mac for odp_packet >> - * @return 1 success, 0 failed >> - */ >> -static int scan_mac(char *in, odph_ethaddr_t *des) >> -{ >> - int field; >> - int i; >> - unsigned int mac[7]; >> - >> - field = sscanf(in, "%2x:%2x:%2x:%2x:%2x:%2x", >> - &mac[0], &mac[1], &mac[2], &mac[3], >> &mac[4], &mac[5]); >> - >> - for (i = 0; i < 6; i++) >> - des->addr[i] = mac[i]; >> - >> - if (field != 6) >> - return 0; >> - return 1; >> -} >> - >> -/** >> - * set up an udp packet >> - * >> - * @param obuf packet buffer >> -*/ >> -static void pack_udp_pkt(odp_buffer_t obuf) >> -{ >> - char *buf; >> - int max; >> - odp_packet_t pkt; >> - odph_ethhdr_t *eth; >> - odph_ipv4hdr_t *ip; >> - odph_udphdr_t *udp; >> - unsigned short seq; >> - >> - buf = odp_buffer_addr(obuf); >> - if (buf == NULL) >> - return; >> - max = odp_buffer_size(obuf); >> - if (max <= 0) >> - return; >> - >> - pkt = odp_packet_from_buffer(obuf); >> - /* ether */ >> - odp_packet_set_l2_offset(pkt, 0); >> - eth = (odph_ethhdr_t *)buf; >> - memcpy((char *)eth->src.addr, args->appl.srcmac.addr, >> ODPH_ETHADDR_LEN); >> - memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, >> ODPH_ETHADDR_LEN); >> - eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); >> - /* ip */ >> - odp_packet_set_l3_offset(pkt, ODPH_ETHHDR_LEN); >> - ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); >> - ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip); >> - ip->src_addr = odp_cpu_to_be_32(args->appl.srcip); >> - ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN; >> - ip->tot_len = odp_cpu_to_be_16(args->appl.payload + >> ODPH_UDPHDR_LEN + >> - ODPH_IPV4HDR_LEN); >> - ip->proto = ODPH_IPPROTO_UDP; >> - seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xFFFF; >> - ip->id = odp_cpu_to_be_16(seq); >> - ip->chksum = 0; >> - odph_ipv4_csum_update(pkt); >> - /* udp */ >> - odp_packet_set_l4_offset(pkt, ODPH_ETHHDR_LEN + >> ODPH_IPV4HDR_LEN); >> - udp = (odph_udphdr_t *)(buf + ODPH_ETHHDR_LEN + >> ODPH_IPV4HDR_LEN); >> - udp->src_port = 0; >> - udp->dst_port = 0; >> - udp->length = odp_cpu_to_be_16(args->appl.payload + >> ODPH_UDPHDR_LEN); >> - udp->chksum = 0; >> - udp->chksum = odp_cpu_to_be_16(odph_ipv4_udp_chksum(pkt)); >> - odp_packet_set_len(pkt, args->appl.payload + ODPH_UDPHDR_LEN + >> - ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); >> -} >> - >> -/** >> - * Set up an icmp packet >> - * >> - * @param obuf packet buffer >> -*/ >> -static void pack_icmp_pkt(odp_buffer_t obuf) >> -{ >> - char *buf; >> - int max; >> - odp_packet_t pkt; >> - odph_ethhdr_t *eth; >> - odph_ipv4hdr_t *ip; >> - odph_icmphdr_t *icmp; >> - struct timeval tval; >> - uint8_t *tval_d; >> - unsigned short seq; >> - >> - buf = odp_buffer_addr(obuf); >> - if (buf == NULL) >> - return; >> - max = odp_buffer_size(obuf); >> - if (max <= 0) >> - return; >> - >> - args->appl.payload = 56; >> - pkt = odp_packet_from_buffer(obuf); >> - /* ether */ >> - odp_packet_set_l2_offset(pkt, 0); >> - eth = (odph_ethhdr_t *)buf; >> - memcpy((char *)eth->src.addr, args->appl.srcmac.addr, >> ODPH_ETHADDR_LEN); >> - memcpy((char *)eth->dst.addr, args->appl.dstmac.addr, >> ODPH_ETHADDR_LEN); >> - eth->type = odp_cpu_to_be_16(ODPH_ETHTYPE_IPV4); >> - /* ip */ >> - odp_packet_set_l3_offset(pkt, ODPH_ETHHDR_LEN); >> - ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN); >> - ip->dst_addr = odp_cpu_to_be_32(args->appl.dstip); >> - ip->src_addr = odp_cpu_to_be_32(args->appl.srcip); >> - ip->ver_ihl = ODPH_IPV4 << 4 | ODPH_IPV4HDR_IHL_MIN; >> - ip->tot_len = odp_cpu_to_be_16(args->appl.payload + >> ODPH_ICMPHDR_LEN + >> - ODPH_IPV4HDR_LEN); >> - ip->proto = ODPH_IPPROTO_ICMP; >> - seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xffff; >> - ip->id = odp_cpu_to_be_16(seq); >> - ip->chksum = 0; >> - odph_ipv4_csum_update(pkt); >> - /* icmp */ >> - icmp = (odph_icmphdr_t *)(buf + ODPH_ETHHDR_LEN + >> ODPH_IPV4HDR_LEN); >> - icmp->type = ICMP_ECHO; >> - icmp->code = 0; >> - icmp->un.echo.id <http://un.echo.id> = 0; >> >> - icmp->un.echo.sequence = ip->id; >> - tval_d = (uint8_t *)(buf + ODPH_ETHHDR_LEN + >> ODPH_IPV4HDR_LEN + >> - ODPH_ICMPHDR_LEN); >> - /* TODO This should be changed to use an >> - * ODP timer API once one exists. */ >> - gettimeofday(&tval, NULL); >> - memcpy(tval_d, &tval, sizeof(struct timeval)); >> - icmp->chksum = 0; >> - icmp->chksum = odp_chksum(icmp, args->appl.payload + >> - ODPH_ICMPHDR_LEN); >> - >> - odp_packet_set_len(pkt, args->appl.payload + >> ODPH_ICMPHDR_LEN + >> - ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN); >> -} >> - >> -/** >> - * Packet IO loopback worker thread using ODP queues >> - * >> - * @param arg thread arguments of type 'thread_args_t *' >> - */ >> - >> -static void *gen_send_thread(void *arg) >> -{ >> - int thr; >> - odp_pktio_t pktio; >> - thread_args_t *thr_args; >> - odp_queue_t outq_def; >> - >> - odp_buffer_t buf; >> - >> - thr = odp_thread_id(); >> - thr_args = arg; >> - >> - /* Open a packet IO instance for this thread */ >> - pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool); >> - if (pktio == ODP_PKTIO_INVALID) { >> - ODP_ERR(" [%02i] Error: pktio create failed\n", thr); >> - return NULL; >> - } >> - >> - outq_def = odp_pktio_outq_getdef(pktio); >> - if (outq_def == ODP_QUEUE_INVALID) { >> - ODP_ERR(" [%02i] Error: def output-Q query\n", thr); >> - return NULL; >> - } >> - >> - printf(" [%02i] created mode: SEND\n", thr); >> - for (;;) { >> - int err; >> - buf = odp_buffer_alloc(thr_args->pool); >> - if (!odp_buffer_is_valid(buf)) { >> - ODP_ERR(" [%2i] alloc_single failed\n", thr); >> - return NULL; >> - } >> - >> - if (args->appl.mode == APPL_MODE_UDP) >> - pack_udp_pkt(buf); >> - else if (args->appl.mode == APPL_MODE_PING) >> - pack_icmp_pkt(buf); >> - >> - err = odp_queue_enq(outq_def, buf); >> - if (err != 0) { >> - ODP_ERR(" [%02i] send pkt err!\n", thr); >> - return NULL; >> - } >> - >> - if (args->appl.interval != 0) { >> - printf(" [%02i] send pkt no:%ju seq %ju\n", >> - thr, counters.seq, >> counters.seq%0xffff); >> - /* TODO use odp timer */ >> - usleep(args->appl.interval * 1000); >> - } >> - if (args->appl.number != -1 && counters.seq >> - >= (unsigned int)args->appl.number) { >> - break; >> - } >> - } >> - >> - /* receive number of reply pks until timeout */ >> - if (args->appl.mode == APPL_MODE_PING && args->appl.number >> > 0) { >> - while (args->appl.timeout >= 0) { >> - if (counters.icmp >= (unsigned >> int)args->appl.number) >> - break; >> - /* TODO use odp timer */ >> - sleep(1); >> - args->appl.timeout--; >> - } >> - } >> - >> - /* print info */ >> - if (args->appl.mode == APPL_MODE_UDP) { >> - printf(" [%02i] total send: %ju\n", thr, >> counters.seq); >> - } else if (args->appl.mode == APPL_MODE_PING) { >> - printf(" [%02i] total send: %ju total receive: >> %ju\n", >> - thr, counters.seq, counters.icmp); >> - } >> - return arg; >> -} >> - >> -/** >> - * Print odp packets >> - * >> - * @param thr worker id >> - * @param pkt_tbl packets to be print >> - * @param len packet number >> - */ >> -static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len) >> -{ >> - odp_packet_t pkt; >> - char *buf; >> - odph_ipv4hdr_t *ip; >> - odph_udphdr_t *udp; >> - odph_icmphdr_t *icmp; >> - struct timeval tvrecv; >> - struct timeval tvsend; >> - double rtt; >> - unsigned i; >> - size_t offset; >> - char msg[1024]; >> - int rlen; >> - for (i = 0; i < len; ++i) { >> - pkt = pkt_tbl[i]; >> - rlen = 0; >> - >> - /* only ip pkts */ >> - if (!odp_packet_inflag_ipv4(pkt)) >> - continue; >> - >> - odp_atomic_inc_u64(&counters.ip); >> - rlen += sprintf(msg, "receive Packet proto:IP "); >> - buf = odp_buffer_addr(odp_packet_to_buffer(pkt)); >> - ip = (odph_ipv4hdr_t *)(buf + >> odp_packet_l3_offset(pkt)); >> - rlen += sprintf(msg + rlen, "id %d ", >> - odp_be_to_cpu_16(ip->id)); >> - offset = odp_packet_l4_offset(pkt); >> - >> - /* udp */ >> - if (ip->proto == ODPH_IPPROTO_UDP) { >> - odp_atomic_inc_u64(&counters.udp); >> - udp = (odph_udphdr_t *)(buf + offset); >> - rlen += sprintf(msg + rlen, "UDP payload %d ", >> - odp_be_to_cpu_16(udp->length) - >> - ODPH_UDPHDR_LEN); >> - } >> - >> - /* icmp */ >> - if (ip->proto == ODPH_IPPROTO_ICMP) { >> - icmp = (odph_icmphdr_t *)(buf + offset); >> - /* echo reply */ >> - if (icmp->type == ICMP_ECHOREPLY) { >> - odp_atomic_inc_u64(&counters.icmp); >> - memcpy(&tvsend, buf + offset + >> ODPH_ICMPHDR_LEN, >> - sizeof(struct timeval)); >> - /* TODO This should be changed to >> use an >> - * ODP timer API once one exists. */ >> - gettimeofday(&tvrecv, NULL); >> - tv_sub(&tvrecv, &tvsend); >> - rtt = tvrecv.tv_sec*1000 + >> tvrecv.tv_usec/1000; >> - rlen += sprintf(msg + rlen, >> - "ICMP Echo Reply seq %d >> time %.1f ", >> - odp_be_to_cpu_16(icmp->un.echo.sequence) >> - , rtt); >> - } else if (icmp->type == ICMP_ECHO) { >> - rlen += sprintf(msg + rlen, >> - "Icmp Echo Request"); >> - } >> - } >> - >> - msg[rlen] = '\0'; >> - printf(" [%02i] %s\n", thr, msg); >> - } >> -} >> - >> -/** >> - * Main receive funtion >> - * >> - * @param arg thread arguments of type 'thread_args_t *' >> - */ >> -static void *gen_recv_thread(void *arg) >> -{ >> - int thr; >> - odp_pktio_t pktio; >> - thread_args_t *thr_args; >> - odp_queue_t inq_def; >> - char inq_name[ODP_QUEUE_NAME_LEN]; >> - odp_queue_param_t qparam; >> - >> - odp_packet_t pkt; >> - odp_buffer_t buf; >> - >> - thr = odp_thread_id(); >> - thr_args = arg; >> - >> - /* Open a packet IO instance for this thread */ >> - pktio = odp_pktio_open(thr_args->pktio_dev, thr_args->pool); >> - if (pktio == ODP_PKTIO_INVALID) { >> - ODP_ERR(" [%02i] Error: pktio create failed\n", thr); >> - return NULL; >> - } >> - >> - int ret; >> - qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; >> - qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; >> - qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; >> - snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", >> (int)pktio); >> - inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; >> - inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, >> &qparam); >> - if (inq_def == ODP_QUEUE_INVALID) { >> - ODP_ERR(" [%02i] Error: pktio queue creation >> failed\n", thr); >> - return NULL; >> - } >> - >> - ret = odp_pktio_inq_setdef(pktio, inq_def); >> - if (ret != 0) { >> - ODP_ERR(" [%02i] Error: default input-Q setup\n", >> thr); >> - return NULL; >> - } >> - >> - printf(" [%02i] created mode: RECEIVE\n", thr); >> - for (;;) { >> - /* Use schedule to get buf from any input queue */ >> - buf = odp_schedule(NULL, ODP_SCHED_WAIT); >> - >> - pkt = odp_packet_from_buffer(buf); >> - /* Drop packets with errors */ >> - if (odp_unlikely(odp_packet_error(pkt))) { >> - odph_packet_free(pkt); >> - continue; >> - } >> - >> - print_pkts(thr, &pkt, 1); >> - >> - odph_packet_free(pkt); >> - } >> - >> - return arg; >> -} >> -/** >> - * ODP packet example main function >> - */ >> -int main(int argc, char *argv[]) >> -{ >> - odph_linux_pthread_t thread_tbl[MAX_WORKERS]; >> - odp_buffer_pool_t pool; >> - int num_workers; >> - void *pool_base; >> - int i; >> - int first_core; >> - int core_count; >> - odp_shm_t shm; >> - >> - /* Init ODP before calling anything else */ >> - if (odp_init_global(NULL, NULL)) { >> - ODP_ERR("Error: ODP global init failed.\n"); >> - exit(EXIT_FAILURE); >> - } >> - >> - if (odp_init_local()) { >> - ODP_ERR("Error: ODP local init failed.\n"); >> - exit(EXIT_FAILURE); >> - } >> - >> - /* init counters */ >> - odp_atomic_init_u64(&counters.seq); >> - odp_atomic_init_u64(&counters.ip); >> - odp_atomic_init_u64(&counters.udp); >> - odp_atomic_init_u64(&counters.icmp); >> - >> - /* Reserve memory for args from shared mem */ >> - shm = odp_shm_reserve("shm_args", sizeof(args_t), >> - ODP_CACHE_LINE_SIZE, 0); >> - args = odp_shm_addr(shm); >> - >> - if (args == NULL) { >> - ODP_ERR("Error: shared mem alloc failed.\n"); >> - exit(EXIT_FAILURE); >> - } >> - memset(args, 0, sizeof(*args)); >> - >> - /* Parse and store the application arguments */ >> - parse_args(argc, argv, &args->appl); >> - >> - /* Print both system and application information */ >> - print_info(NO_PATH(argv[0]), &args->appl); >> - >> - core_count = odp_sys_core_count(); >> - num_workers = core_count; >> - >> - if (args->appl.core_count) >> - num_workers = args->appl.core_count; >> - >> - if (num_workers > MAX_WORKERS) >> - num_workers = MAX_WORKERS; >> - >> - /* ping mode need two worker */ >> - if (args->appl.mode == APPL_MODE_PING) >> - num_workers = 2; >> - >> - printf("Num worker threads: %i\n", num_workers); >> - >> - /* >> - * By default core #0 runs Linux kernel background tasks. >> - * Start mapping thread from core #1 >> - */ >> - first_core = 1; >> - >> - if (core_count == 1) >> - first_core = 0; >> - >> - printf("First core: %i\n\n", first_core); >> - >> - /* Create packet pool */ >> - shm = odp_shm_reserve("shm_packet_pool", >> - SHM_PKT_POOL_SIZE, >> ODP_CACHE_LINE_SIZE, 0); >> - pool_base = odp_shm_addr(shm); >> - >> - if (pool_base == NULL) { >> - ODP_ERR("Error: packet pool mem alloc failed.\n"); >> - exit(EXIT_FAILURE); >> - } >> - >> - pool = odp_buffer_pool_create("packet_pool", pool_base, >> - SHM_PKT_POOL_SIZE, >> - SHM_PKT_POOL_BUF_SIZE, >> - ODP_CACHE_LINE_SIZE, >> - ODP_BUFFER_TYPE_PACKET); >> - if (pool == ODP_BUFFER_POOL_INVALID) { >> - ODP_ERR("Error: packet pool create failed.\n"); >> - exit(EXIT_FAILURE); >> - } >> - odp_buffer_pool_print(pool); >> - >> - /* Create and init worker threads */ >> - memset(thread_tbl, 0, sizeof(thread_tbl)); >> - >> - if (args->appl.mode == APPL_MODE_PING) { >> - args->thread[1].pktio_dev = args->appl.if_names[0]; >> - args->thread[1].pool = pool; >> - args->thread[1].mode = args->appl.mode; >> - odph_linux_pthread_create(&thread_tbl[1], 1, 0, >> - gen_recv_thread, >> &args->thread[1]); >> - >> - args->thread[0].pktio_dev = args->appl.if_names[0]; >> - args->thread[0].pool = pool; >> - args->thread[0].mode = args->appl.mode; >> - odph_linux_pthread_create(&thread_tbl[0], 1, 0, >> - gen_send_thread, >> &args->thread[0]); >> - >> - /* only wait send thread to join */ >> - num_workers = 1; >> - } else { >> - for (i = 0; i < num_workers; ++i) { >> - void *(*thr_run_func) (void *); >> - int core; >> - int if_idx; >> - >> - core = (first_core + i) % core_count; >> - >> - if_idx = i % args->appl.if_count; >> - >> - args->thread[i].pktio_dev = >> args->appl.if_names[if_idx]; >> - args->thread[i].pool = pool; >> - args->thread[i].mode = args->appl.mode; >> - >> - if (args->appl.mode == APPL_MODE_UDP) { >> - thr_run_func = gen_send_thread; >> - } else if (args->appl.mode == APPL_MODE_RCV) { >> - thr_run_func = gen_recv_thread; >> - } else { >> - ODP_ERR("ERR MODE\n"); >> - exit(EXIT_FAILURE); >> - } >> - /* >> - * Create threads one-by-one instead of >> all-at-once, >> - * because each thread might get different >> arguments. >> - * Calls odp_thread_create(cpu) for each >> thread >> - */ >> - odph_linux_pthread_create(&thread_tbl[i], 1, >> - core, thr_run_func, >> - &args->thread[i]); >> - } >> - } >> - >> - /* Master thread waits for other threads to exit */ >> - odph_linux_pthread_join(thread_tbl, num_workers); >> - printf("Exit\n\n"); >> - >> - return 0; >> -} >> - >> - >> -/** >> - * Parse and store the command line arguments >> - * >> - * @param argc argument count >> - * @param argv[] argument vector >> - * @param appl_args Store application arguments here >> - */ >> -static void parse_args(int argc, char *argv[], appl_args_t >> *appl_args) >> -{ >> - int opt; >> - int long_index; >> - char *names, *str, *token, *save; >> - size_t len; >> - int i; >> - static struct option longopts[] = { >> - {"interface", required_argument, NULL, 'I'}, >> - {"workers", required_argument, NULL, 'w'}, >> - {"srcmac", required_argument, NULL, 'a'}, >> - {"dstmac", required_argument, NULL, 'b'}, >> - {"srcip", required_argument, NULL, 'c'}, >> - {"dstip", required_argument, NULL, 'd'}, >> - {"packetsize", required_argument, NULL, 's'}, >> - {"mode", required_argument, NULL, 'm'}, >> - {"count", required_argument, NULL, 'n'}, >> - {"timeout", required_argument, NULL, 't'}, >> - {"interval", required_argument, NULL, 'i'}, >> - {"help", no_argument, NULL, 'h'}, >> - {NULL, 0, NULL, 0} >> - }; >> - >> - appl_args->mode = -1; /* Invalid, must be changed by >> parsing */ >> - appl_args->number = -1; >> - appl_args->payload = 56; >> - appl_args->timeout = -1; >> - >> - while (1) { >> - opt = getopt_long(argc, argv, >> "+I:a:b:c:d:s:i:m:n:t:w:h", >> - longopts, &long_index); >> - if (opt == -1) >> - break; /* No more options */ >> - >> - switch (opt) { >> - case 'w': >> - appl_args->core_count = atoi(optarg); >> - break; >> - /* parse packet-io interface names */ >> - case 'I': >> - len = strlen(optarg); >> - if (len == 0) { >> - usage(argv[0]); >> - exit(EXIT_FAILURE); >> - } >> - len += 1; /* add room for '\0' */ >> - >> - names = malloc(len); >> - if (names == NULL) { >> - usage(argv[0]); >> - exit(EXIT_FAILURE); >> - } >> - >> - /* count the number of tokens separated by >> ',' */ >> - strcpy(names, optarg); >> - for (str = names, i = 0;; str = NULL, i++) { >> - token = strtok_r(str, ",", &save); >> - if (token == NULL) >> - break; >> - } >> - appl_args->if_count = i; >> - >> - if (appl_args->if_count == 0) { >> - usage(argv[0]); >> - exit(EXIT_FAILURE); >> - } >> - >> - /* allocate storage for the if names */ >> - appl_args->if_names = >> - calloc(appl_args->if_count, >> sizeof(char *)); >> - >> - /* store the if names (reset names string) */ >> - strcpy(names, optarg); >> - for (str = names, i = 0;; str = NULL, i++) { >> - token = strtok_r(str, ",", &save); >> - if (token == NULL) >> - break; >> - appl_args->if_names[i] = token; >> - } >> - break; >> - >> - case 'm': >> - if (optarg[0] == 'u') { >> - appl_args->mode = APPL_MODE_UDP; >> - } else if (optarg[0] == 'p') { >> - appl_args->mode = APPL_MODE_PING; >> - } else if (optarg[0] == 'r') { >> - appl_args->mode = APPL_MODE_RCV; >> - } else { >> - ODP_ERR("wrong mode!\n"); >> - exit(EXIT_FAILURE); >> - } >> - break; >> - >> - case 'a': >> - if (scan_mac(optarg, &appl_args->srcmac) >> != 1) { >> - ODP_ERR("wrong src mac:%s\n", optarg); >> - exit(EXIT_FAILURE); >> - } >> - break; >> - >> - case 'b': >> - if (scan_mac(optarg, &appl_args->dstmac) >> != 1) { >> - ODP_ERR("wrong dst mac:%s\n", optarg); >> - exit(EXIT_FAILURE); >> - } >> - break; >> - >> - case 'c': >> - if (scan_ip(optarg, &appl_args->srcip) != 1) { >> - ODP_ERR("wrong src ip:%s\n", optarg); >> - exit(EXIT_FAILURE); >> - } >> - break; >> - >> - case 'd': >> - if (scan_ip(optarg, &appl_args->dstip) != 1) { >> - ODP_ERR("wrong dst ip:%s\n", optarg); >> - exit(EXIT_FAILURE); >> - } >> - break; >> - >> - case 's': >> - appl_args->payload = atoi(optarg); >> - break; >> - >> - case 'n': >> - appl_args->number = atoi(optarg); >> - break; >> - >> - case 't': >> - appl_args->timeout = atoi(optarg); >> - break; >> - >> - case 'i': >> - appl_args->interval = atoi(optarg); >> - if (appl_args->interval <= 200 && >> geteuid() != 0) { >> - ODP_ERR("should be root user\n"); >> - exit(EXIT_FAILURE); >> - } >> - break; >> - >> - case 'h': >> - usage(argv[0]); >> - exit(EXIT_SUCCESS); >> - break; >> - >> - default: >> - break; >> - } >> - } >> - >> - if (appl_args->if_count == 0 || appl_args->mode == -1) { >> - usage(argv[0]); >> - exit(EXIT_FAILURE); >> - } >> - >> - optind = 1; /* reset 'extern optind' from the >> getopt lib */ >> -} >> - >> -/** >> - * Print system and application info >> - */ >> -static void print_info(char *progname, appl_args_t *appl_args) >> -{ >> - int i; >> - >> - printf("\n" >> - "ODP system info\n" >> - "---------------\n" >> - "ODP API version: %s\n" >> - "CPU model: %s\n" >> - "CPU freq (hz): %"PRIu64"\n" >> - "Cache line size: %i\n" >> - "Core count: %i\n" >> - "\n", >> - odp_version_api_str(), odp_sys_cpu_model_str(), >> odp_sys_cpu_hz(), >> - odp_sys_cache_line_size(), odp_sys_core_count()); >> - >> - printf("Running ODP appl: \"%s\"\n" >> - "-----------------\n" >> - "IF-count: %i\n" >> - "Using IFs: ", >> - progname, appl_args->if_count); >> - for (i = 0; i < appl_args->if_count; ++i) >> - printf(" %s", appl_args->if_names[i]); >> - printf("\n" >> - "Mode: "); >> - if (appl_args->mode == 0) >> - PRINT_APPL_MODE(0); >> - else >> - PRINT_APPL_MODE(0); >> - printf("\n\n"); >> - fflush(NULL); >> -} >> - >> -/** >> - * Prinf usage information >> - */ >> -static void usage(char *progname) >> -{ >> - printf("\n" >> - "Usage: %s OPTIONS\n" >> - " E.g. %s -I eth1 -r\n" >> - "\n" >> - "OpenDataPlane example application.\n" >> - "\n" >> - " Work mode:\n" >> - " 1.send udp packets\n" >> - " odp_generator -I eth0 --srcmac >> fe:0f:97:c9:e0:44 --dstmac 32:cb:9b:27:2f:1a --srcip 192.168.0.1 >> --dstip 192.168.0.2 -m u\n" >> - " 2.receive udp packets\n" >> - " odp_generator -I eth0 -m r\n" >> - " 3.work likes ping\n" >> - " odp_generator -I eth0 --srcmac >> fe:0f:97:c9:e0:44 --dstmac 32:cb:9b:27:2f:1a --srcip 192.168.0.1 >> --dstip 192.168.0.2 -m p\n" >> - "\n" >> - "Mandatory OPTIONS:\n" >> - " -I, --interface Eth interfaces (comma-separated, >> no spaces)\n" >> - " -a, --srcmac src mac address\n" >> - " -b, --dstmac dst mac address\n" >> - " -c, --srcip src ip address\n" >> - " -d, --dstip dst ip address\n" >> - " -s, --packetsize payload length of the packets\n" >> - " -m, --mode work mode: send udp(u), receive(r), >> send icmp(p)\n" >> - " -n, --count the number of packets to be send\n" >> - " -t, --timeout only for ping mode, wait ICMP >> reply timeout seconds\n" >> - " -i, --interval wait interval ms between sending >> each packet\n" >> - " default is 1000ms. 0 for flood >> mode\n" >> - "\n" >> - "Optional OPTIONS\n" >> - " -h, --help Display help and exit.\n" >> - " environment variables: >> ODP_PKTIO_DISABLE_SOCKET_MMAP\n" >> - " ODP_PKTIO_DISABLE_SOCKET_MMSG\n" >> - " ODP_PKTIO_DISABLE_SOCKET_BASIC\n" >> - " can be used to advanced pkt I/O selection for >> linux-generic\n" >> - "\n", NO_PATH(progname), NO_PATH(progname) >> - ); >> -} >> -/** >> - * calc time period >> - * >> - *@param recvtime start time >> - *@param sendtime end time >> -*/ >> -static void tv_sub(struct timeval *recvtime, struct timeval >> *sendtime) >> -{ >> - long sec = recvtime->tv_sec - sendtime->tv_sec; >> - long usec = recvtime->tv_usec - sendtime->tv_usec; >> - if (usec >= 0) { >> - recvtime->tv_sec = sec; >> - recvtime->tv_usec = usec; >> - } else { >> - recvtime->tv_sec = sec - 1; >> - recvtime->tv_usec = -usec; >> - } >> -} >> -- >> 2.1.0 >> >> >> _______________________________________________ >> lng-odp mailing list >> [email protected] <mailto:[email protected]> >> http://lists.linaro.org/mailman/listinfo/lng-odp >> >> >> >> >> -- >> *Mike Holmes* >> Linaro Sr Technical Manager >> LNG - ODP >> >> >> _______________________________________________ >> lng-odp mailing list >> [email protected] >> http://lists.linaro.org/mailman/listinfo/lng-odp >> > > > _______________________________________________ > lng-odp mailing list > [email protected] > http://lists.linaro.org/mailman/listinfo/lng-odp >
_______________________________________________ lng-odp mailing list [email protected] http://lists.linaro.org/mailman/listinfo/lng-odp
