On Fri, Jan 09, 2015 at 02:41:54PM +0000, Bill Fischofer wrote:
> 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

This patch would need a bit of tidy up before being committable, at
least to fix the typo and the @todo. I'd rather the other series go in
first, and I'll rebase this one and send again next week as a non-RFC
patch.

--
Stuart.

> 
> On Fri, Jan 9, 2015 at 8:26 AM, Ciprian Barbu 
> <[email protected]<mailto:[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]<mailto:[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]<mailto:[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<http://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<http://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<http://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

Reply via email to