I agree this looks useful. Stuart: This seems to apply to the tip but not after your other PktIO patch series is applied. What's the intended sequencing here?
Bill On Fri, Jan 9, 2015 at 8:26 AM, Ciprian Barbu <[email protected]> wrote: > This looks very useful, no more headaches figuring out what system > loopback device to use. > > On Thu, Jan 8, 2015 at 6:09 PM, Stuart Haslam <[email protected]> > wrote: > > Create a new linux-generic pktio type ODP_PKTIO_TYPE_LOOPBACK which > > will be used when the "loop" device is opened. A queue is used to > > connect the pktio output queue to the input queue. Packets sent to the > > loopback device are classified before making it to the input queue. > > A random MAC address is assigned when the device is opened, and the > > other control functions (MTU/promisc) are just dummies. > > > > As this doesn't need root access, the odp_pktio_run script is modified > > to use the "loop" device when not root. The veth method is still used > > when running as root (on linux-generic) so that the socket code > > actually gets tested. > > > > Signed-off-by: Stuart Haslam <[email protected]> > > --- > > (This code contribution is provided under the terms of agreement > LES-LTM-21309) > > > > .../linux-generic/include/odp_packet_io_internal.h | 3 + > > platform/linux-generic/odp_packet_io.c | 116 > ++++++++++++++++----- > > test/validation/odp_pktio_run | 11 +- > > 3 files changed, 99 insertions(+), 31 deletions(-) > > > > diff --git a/platform/linux-generic/include/odp_packet_io_internal.h > b/platform/linux-generic/include/odp_packet_io_internal.h > > index 465127b..ea97a88 100644 > > --- a/platform/linux-generic/include/odp_packet_io_internal.h > > +++ b/platform/linux-generic/include/odp_packet_io_internal.h > > @@ -34,6 +34,7 @@ typedef enum { > > ODP_PKTIO_TYPE_SOCKET_BASIC = 0x1, > > ODP_PKTIO_TYPE_SOCKET_MMSG, > > ODP_PKTIO_TYPE_SOCKET_MMAP, > > + ODP_PKTIO_TYPE_LOOPBACK, > > } odp_pktio_type_t; > > > > struct pktio_entry { > > @@ -41,12 +42,14 @@ struct pktio_entry { > > int taken; /**< is entry taken(1) or > free(0) */ > > odp_queue_t inq_default; /**< default input queue, if set > */ > > odp_queue_t outq_default; /**< default out queue */ > > + odp_queue_t loopq; /**< loopback queue */ > > odp_pktio_type_t type; /**< pktio type */ > > pkt_sock_t pkt_sock; /**< using socket API for IO */ > > pkt_sock_mmap_t pkt_sock_mmap; /**< using socket mmap API for > IO */ > > classifier_t cls; /**< classifier linked with this > pktio*/ > > char name[IFNAMSIZ]; /**< name of pktio provided to > > pktio_open() */ > > + odp_bool_t promisc; /**< promiscuous mode state */ > > }; > > > > typedef union { > > diff --git a/platform/linux-generic/odp_packet_io.c > b/platform/linux-generic/odp_packet_io.c > > index 59590d2..7335dd3 100644 > > --- a/platform/linux-generic/odp_packet_io.c > > +++ b/platform/linux-generic/odp_packet_io.c > > @@ -18,11 +18,13 @@ > > #include <odp_schedule_internal.h> > > #include <odp_classification_internal.h> > > #include <odp_debug_internal.h> > > +#include <odp_time.h> > > > > #include <string.h> > > #include <sys/ioctl.h> > > #include <linux/if_arp.h> > > #include <ifaddrs.h> > > +#include <stdlib.h> > > > > static pktio_table_t *pktio_tbl; > > > > @@ -160,14 +162,28 @@ static int free_pktio_entry(odp_pktio_t id) > > return 0; > > } > > > > +static int random_mac(void *mac_addr, size_t addr_size) > > +{ > > + uint32_t ethaddr_l, ethaddr_h; > > + > > + srand(odp_time_cycles()); > > + ethaddr_h = (rand() & 0xfeff) | 0x0200; > > + ethaddr_l = rand(); > > + > > + snprintf(mac_addr, addr_size, "%02x:%02x:%02x:%02x:%02x:%02x", > > + ethaddr_h >> 8, ethaddr_h & 0xff, > > + ethaddr_l >> 24, (ethaddr_l >> 16) & 0xff, > > + (ethaddr_l >> 8) & 0xff, ethaddr_l & 0xff); > > + > > + return 0; > > +} > > + > > odp_pktio_t odp_pktio_open(const char *dev, odp_buffer_pool_t pool) > > { > > odp_pktio_t id; > > pktio_entry_t *pktio_entry; > > int res; > > int fanout = 1; > > - char loop[IFNAMSIZ] = {0}; > > - char *loop_hint; > > > > if (strlen(dev) >= IFNAMSIZ) { > > /* ioctl names limitation */ > > @@ -176,28 +192,6 @@ odp_pktio_t odp_pktio_open(const char *dev, > odp_buffer_pool_t pool) > > return ODP_PKTIO_INVALID; > > } > > > > - if (!strcmp(dev, "loop")) { > > - /* If hint with ODP_PKTIO_LOOPDEV is provided, use hint, > > - * if not try to find usable device. > > - */ > > - loop_hint = getenv("ODP_PKTIO_LOOPDEV"); > > - if (!loop_hint || (strlen(loop_hint) == 0)) { > > - ODP_ERR("Set loop with > ODP_PKTIO_LOOPDEV=ethX\n"); > > - return ODP_PKTIO_INVALID; > > - } > > - > > - if (strlen(loop_hint) >= IFNAMSIZ) { > > - ODP_ERR("pktio name %s is too big, limit is %d > bytes\n", > > - loop_hint, IFNAMSIZ); > > - return ODP_PKTIO_INVALID; > > - } > > - > > - memset(loop, 0, IFNAMSIZ); > > - memcpy(loop, loop_hint, strlen(loop_hint)); > > - dev = loop; > > - ODP_DBG("pktio using %s as loopback device\n", > loop_hint); > > - } > > - > > id = alloc_lock_pktio_entry(); > > if (id == ODP_PKTIO_INVALID) { > > ODP_ERR("No resources available.\n"); > > @@ -209,6 +203,22 @@ odp_pktio_t odp_pktio_open(const char *dev, > odp_buffer_pool_t pool) > > if (!pktio_entry) > > return ODP_PKTIO_INVALID; > > > > + if (strcmp(dev, "loop") == 0) { > > + char loopq_name[ODP_QUEUE_NAME_LEN]; > > + ODP_DBG("pktio opening loop devive\n"); > > typo devive > > > + > > + pktio_entry->s.type = ODP_PKTIO_TYPE_LOOPBACK; > > + snprintf(loopq_name, sizeof(loopq_name), > "%i-pktio_loopq", > > + (int)id); > > + pktio_entry->s.loopq = odp_queue_create(loopq_name, > > + > ODP_QUEUE_TYPE_POLL, > > + NULL); > > + random_mac(pktio_entry->s.pkt_sock.if_mac, > > + sizeof(pktio_entry->s.pkt_sock.if_mac)); > > + > > + goto done; > > + } > > + > > ODP_DBG("ODP_PKTIO_USE_FANOUT: %d\n", fanout); > > if (getenv("ODP_PKTIO_DISABLE_SOCKET_MMAP") == NULL) { > > pktio_entry->s.type = ODP_PKTIO_TYPE_SOCKET_MMAP; > > @@ -271,6 +281,10 @@ int odp_pktio_close(odp_pktio_t id) > > case ODP_PKTIO_TYPE_SOCKET_MMAP: > > res = > close_pkt_sock_mmap(&entry->s.pkt_sock_mmap); > > break; > > + case ODP_PKTIO_TYPE_LOOPBACK: > > + /* @todo: destroy loopback queue */ > > + res = 0; > > + break; > > default: > > break; > > } > > @@ -284,6 +298,22 @@ int odp_pktio_close(odp_pktio_t id) > > return 0; > > } > > > > +static int deq_loopback(pktio_entry_t *pktio_entry, odp_packet_t > pkt_tbl[], > > + unsigned len) > > +{ > > + int nbr, i; > > + odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX]; > > + queue_entry_t *qentry; > > + > > + qentry = queue_to_qentry(pktio_entry->s.loopq); > > + nbr = queue_deq_multi(qentry, hdr_tbl, len); > > + > > + for (i = 0; i < nbr; ++i) > > + pkt_tbl[i] = > odp_packet_from_buffer(odp_hdr_to_buf(hdr_tbl[i])); > > + > > + return nbr; > > +} > > + > > int odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned > len) > > { > > pktio_entry_t *pktio_entry = get_pktio_entry(id); > > @@ -307,6 +337,9 @@ int odp_pktio_recv(odp_pktio_t id, odp_packet_t > pkt_table[], unsigned len) > > pkts = recv_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > > pkt_table, len); > > break; > > + case ODP_PKTIO_TYPE_LOOPBACK: > > + pkts = deq_loopback(pktio_entry, pkt_table, len); > > + break; > > default: > > pkts = -1; > > break; > > @@ -322,6 +355,20 @@ int odp_pktio_recv(odp_pktio_t id, odp_packet_t > pkt_table[], unsigned len) > > return pkts; > > } > > > > +static int enq_loopback(pktio_entry_t *pktio_entry, odp_packet_t > pkt_tbl[], > > + unsigned len) > > +{ > > + odp_buffer_hdr_t *hdr_tbl[QUEUE_MULTI_MAX]; > > + queue_entry_t *qentry; > > + unsigned i; > > + > > + for (i = 0; i < len; ++i) > > + hdr_tbl[i] = > odp_buf_to_hdr(odp_packet_to_buffer(pkt_tbl[i])); > > + > > + qentry = queue_to_qentry(pktio_entry->s.loopq); > > + return queue_enq_multi(qentry, hdr_tbl, len) == 0 ? len : 0; > > +} > > + > > int odp_pktio_send(odp_pktio_t id, odp_packet_t pkt_table[], unsigned > len) > > { > > pktio_entry_t *pktio_entry = get_pktio_entry(id); > > @@ -344,6 +391,9 @@ int odp_pktio_send(odp_pktio_t id, odp_packet_t > pkt_table[], unsigned len) > > pkts = send_pkt_sock_mmap(&pktio_entry->s.pkt_sock_mmap, > > pkt_table, len); > > break; > > + case ODP_PKTIO_TYPE_LOOPBACK: > > + pkts = enq_loopback(pktio_entry, pkt_table, len); > > + break; > > default: > > pkts = -1; > > } > > @@ -559,6 +609,11 @@ int odp_pktio_mtu(odp_pktio_t id) > > return -1; > > } > > > > + if (entry->s.type == ODP_PKTIO_TYPE_LOOPBACK) { > > + unlock_entry(entry); > > + return 1500; > > + } > > + > > sockfd = sockfd_from_pktio_entry(entry); > > snprintf(ifr.ifr_name, IFNAMSIZ, "%s", entry->s.name); > > > > @@ -594,6 +649,13 @@ int odp_pktio_promisc_mode_set(odp_pktio_t id, > odp_bool_t enable) > > return -1; > > } > > > > + entry->s.promisc = enable; > > + > > + if (entry->s.type == ODP_PKTIO_TYPE_LOOPBACK) { > > + unlock_entry(entry); > > + return 0; > > + } > > + > > sockfd = sockfd_from_pktio_entry(entry); > > snprintf(ifr.ifr_name, IFNAMSIZ, "%s", entry->s.name); > > > > @@ -641,6 +703,11 @@ int odp_pktio_promisc_mode(odp_pktio_t id) > > return -1; > > } > > > > + if (entry->s.type == ODP_PKTIO_TYPE_LOOPBACK) { > > + unlock_entry(entry); > > + return entry->s.promisc ? 1 : 0; > > + } > > + > > sockfd = sockfd_from_pktio_entry(entry); > > snprintf(ifr.ifr_name, IFNAMSIZ, "%s", entry->s.name); > > > > @@ -683,6 +750,7 @@ size_t odp_pktio_mac_addr(odp_pktio_t id, void > *mac_addr, > > switch (entry->s.type) { > > case ODP_PKTIO_TYPE_SOCKET_BASIC: > > case ODP_PKTIO_TYPE_SOCKET_MMSG: > > + case ODP_PKTIO_TYPE_LOOPBACK: > > memcpy(mac_addr, entry->s.pkt_sock.if_mac, > > ETH_ALEN); > > break; > > diff --git a/test/validation/odp_pktio_run > b/test/validation/odp_pktio_run > > index d4d6b2c..08288e6 100755 > > --- a/test/validation/odp_pktio_run > > +++ b/test/validation/odp_pktio_run > > @@ -100,11 +100,13 @@ run_test() > > > > run() > > { > > - if [ "$ODP_PLATFORM" != "linux-generic" ]; then > > + if [ "$ODP_PLATFORM" != "linux-generic" -o "$(id -u)" != "0" ]; > then > > echo "pktio: using 'loop' device" > > $TEST_DIR/odp_pktio > > exit $? > > - elif [ "$ODP_PKTIO_IF0" = "" ]; then > > + fi > > + > > + if [ "$ODP_PKTIO_IF0" = "" ]; then > > # no interfaces specified on linux-generic, use defaults > > setup_env1 clean > > export ODP_PKTIO_IF0=$IF0 > > @@ -120,11 +122,6 @@ if [ "$ODP_PLATFORM" = "" ]; then > > exit 1 > > fi > > > > -if [ "$(id -u)" != "0" ]; then > > - echo "pktio: error: must be run as root" > > - exit $TEST_SKIPPED > > -fi > > - > > case "$1" in > > setup) setup_env1 ;; > > cleanup) cleanup_env1 ;; > > -- > > 2.1.1 > > > > > > > > _______________________________________________ > > lng-odp mailing list > > [email protected] > > http://lists.linaro.org/mailman/listinfo/lng-odp > > _______________________________________________ > lng-odp mailing list > [email protected] > http://lists.linaro.org/mailman/listinfo/lng-odp >
_______________________________________________ lng-odp mailing list [email protected] http://lists.linaro.org/mailman/listinfo/lng-odp
