On Mon, Jan 12, 2015 at 01:15:31PM +0000, Bala wrote:
> 
> On Thursday 08 January 2015 09:39 PM, Stuart Haslam 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");
> > +
> > +           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]));
> We need to call _odp_packet_parse() function here.
> Since the packet received from Loopback queue are identical to the 
> packet received on the interface.

Yes you're right, forgot to parse it.

-- 
Stuart.


_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to