Message ID | 1415653630-16999-2-git-send-email-anders.roxell@linaro.org |
---|---|
State | New |
Headers | show |
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 <anders.roxell@linaro.org> 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 <anders.roxell@linaro.org> > --- > .gitignore | 1 - > 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 b/configure.ac > index 1c061e9..5491bc9 100644 > --- a/configure.ac > +++ b/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 = 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 > lng-odp@lists.linaro.org > http://lists.linaro.org/mailman/listinfo/lng-odp >
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. 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 <anders.roxell@linaro.org > <mailto:anders.roxell@linaro.org>> 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 <anders.roxell@linaro.org > <mailto:anders.roxell@linaro.org>> > --- > .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 > lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org> > http://lists.linaro.org/mailman/listinfo/lng-odp > > > > > -- > *Mike Holmes* > Linaro Sr Technical Manager > LNG - ODP > > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > http://lists.linaro.org/mailman/listinfo/lng-odp
On 10 November 2014 23:06, Maxim Uvarov <maxim.uvarov@linaro.org> 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 <anders.roxell@linaro.org >> <mailto:anders.roxell@linaro.org>> 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 <anders.roxell@linaro.org >> <mailto:anders.roxell@linaro.org>> >> --- >> .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 >> lng-odp@lists.linaro.org <mailto:lng-odp@lists.linaro.org> >> http://lists.linaro.org/mailman/listinfo/lng-odp >> >> >> >> >> -- >> *Mike Holmes* >> Linaro Sr Technical Manager >> LNG - ODP >> >> >> _______________________________________________ >> lng-odp mailing list >> lng-odp@lists.linaro.org >> http://lists.linaro.org/mailman/listinfo/lng-odp >> > > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > http://lists.linaro.org/mailman/listinfo/lng-odp >
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 b/configure.ac index 1c061e9..5491bc9 100644 --- a/configure.ac +++ b/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 = 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; - } -}
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 <anders.roxell@linaro.org> --- .gitignore | 1 - 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