diff mbox

[PATCHv6,4/6] linux-generic: odp_pktio_open loop support

Message ID 1417796424-9909-5-git-send-email-maxim.uvarov@linaro.org
State New
Headers show

Commit Message

Maxim Uvarov Dec. 5, 2014, 4:20 p.m. UTC
Implement pktio device loop device suitable for testing.

Note: lo0 can not be used.  Instead of it we walking though
all devices and select one that can be used for cunit testing.
Filter criteria is: device has to support mac, promisc and mtu
changes. Device has to be wireless device.
Also hint variable is added to bind loop to specific device, example:
export ODP_PKTIO_LOOPDEV=eth0

Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
---
 platform/linux-generic/odp_packet_io.c | 64 ++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

Comments

Ola Liljedahl Dec. 8, 2014, 11:08 a.m. UTC | #1
On 5 December 2014 at 17:20, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:
> Implement pktio device loop device suitable for testing.
>
> Note: lo0 can not be used.  Instead of it we walking though
> all devices and select one that can be used for cunit testing.
> Filter criteria is: device has to support mac, promisc and mtu
> changes. Device has to be wireless device.
Why wireless? Why not e.g. Ethernet?

> Also hint variable is added to bind loop to specific device, example:
> export ODP_PKTIO_LOOPDEV=eth0
>
> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
> ---
>  platform/linux-generic/odp_packet_io.c | 64 ++++++++++++++++++++++++++++++++++
>  1 file changed, 64 insertions(+)
>
> diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
> index e8815cd..993f2ab 100644
> --- a/platform/linux-generic/odp_packet_io.c
> +++ b/platform/linux-generic/odp_packet_io.c
> @@ -22,6 +22,7 @@
>  #include <string.h>
>  #include <sys/ioctl.h>
>  #include <linux/if_arp.h>
> +#include <ifaddrs.h>
>
>  typedef struct {
>         pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES];
> @@ -154,12 +155,75 @@ static int free_pktio_entry(odp_pktio_t id)
>         return 0;
>  }
>
> +static int find_loop_dev(char loop[IFNAMSIZ])
> +{
> +       struct ifaddrs *ifap, *ifa;
> +
> +       getifaddrs(&ifap);
> +
> +       for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
> +               if (ifa->ifa_addr &&
> +                   ifa->ifa_addr->sa_family == AF_INET) {
> +                       if ((ifa->ifa_flags & (IFF_LOOPBACK |
> +                                             IFF_POINTOPOINT |
> +                                             IFF_NOARP)) ||
> +                           (!memcmp(ifa->ifa_name, "lxcbr", 5)) ||
> +                           (!memcmp(ifa->ifa_name, "wlan", 4)) ||
> +                           (!memcmp(ifa->ifa_name, "veth", 4)) ||
> +                           (!memcmp(ifa->ifa_name, "virbr", 5)))
I would use strncmp().
I don't think it is a good idea to compare against such names. E.g. on
my ChromeBook, the WiFi interface is called mlan0.
Do we care what kind of underlying link layer is used? What are the
observable characteristics you are looking for?


> +                               continue;
> +                       memcpy(loop, ifa->ifa_name, IFNAMSIZ);
> +                       freeifaddrs(ifap);
> +                       return 0;
> +               }
> +       }
> +
> +       freeifaddrs(ifap);
> +       return -1;
> +}
> +
>  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 */
> +               ODP_ERR("pktio name %s is too big, limit is %d bytes\n",
> +                       dev, IFNAMSIZ);
> +               return ODP_PKTIO_INVALID;
> +       }
> +
> +       /* If hint with ODP_PKTIO_LOOPDEV is provided, use hint,
> +        * if not try to find usable device.
> +        */
> +       loop_hint = getenv("ODP_PKTIO_LOOPDEV");
> +       if (!strcmp(dev, "loop")) {
> +               if (loop_hint && (strlen(loop_hint) > 0)) {
> +                       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);
> +               } else {
> +                       if (!find_loop_dev(loop)) {
> +                               ODP_DBG("pktio rename loop to %s\n", loop);
> +                               dev = loop;
> +                       } else {
> +                               ODP_DBG("pktio: No suitable netdev.\n");
> +                               return ODP_PKTIO_INVALID;
> +                       }
> +               }
> +       }
>
>         id = alloc_lock_pktio_entry();
>         if (id == ODP_PKTIO_INVALID) {
> --
> 1.8.5.1.163.gd7aced9
>
>
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp
Maxim Uvarov Dec. 8, 2014, 11:21 a.m. UTC | #2
On 12/08/2014 02:08 PM, Ola Liljedahl wrote:
> On 5 December 2014 at 17:20, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:
>> Implement pktio device loop device suitable for testing.
>>
>> Note: lo0 can not be used.  Instead of it we walking though
>> all devices and select one that can be used for cunit testing.
>> Filter criteria is: device has to support mac, promisc and mtu
>> changes. Device has to be wireless device.
> Why wireless? Why not e.g. Ethernet?

has not to be wireless. Somehow missed it. packet_parse() was bad with 
wireless.
But as I remember we fixed it in some time ago. But initially we were 
focused on
ethernet.

>
>> Also hint variable is added to bind loop to specific device, example:
>> export ODP_PKTIO_LOOPDEV=eth0
>>
>> Signed-off-by: Maxim Uvarov <maxim.uvarov@linaro.org>
>> ---
>>   platform/linux-generic/odp_packet_io.c | 64 ++++++++++++++++++++++++++++++++++
>>   1 file changed, 64 insertions(+)
>>
>> diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
>> index e8815cd..993f2ab 100644
>> --- a/platform/linux-generic/odp_packet_io.c
>> +++ b/platform/linux-generic/odp_packet_io.c
>> @@ -22,6 +22,7 @@
>>   #include <string.h>
>>   #include <sys/ioctl.h>
>>   #include <linux/if_arp.h>
>> +#include <ifaddrs.h>
>>
>>   typedef struct {
>>          pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES];
>> @@ -154,12 +155,75 @@ static int free_pktio_entry(odp_pktio_t id)
>>          return 0;
>>   }
>>
>> +static int find_loop_dev(char loop[IFNAMSIZ])
>> +{
>> +       struct ifaddrs *ifap, *ifa;
>> +
>> +       getifaddrs(&ifap);
>> +
>> +       for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
>> +               if (ifa->ifa_addr &&
>> +                   ifa->ifa_addr->sa_family == AF_INET) {
>> +                       if ((ifa->ifa_flags & (IFF_LOOPBACK |
>> +                                             IFF_POINTOPOINT |
>> +                                             IFF_NOARP)) ||
>> +                           (!memcmp(ifa->ifa_name, "lxcbr", 5)) ||
>> +                           (!memcmp(ifa->ifa_name, "wlan", 4)) ||
>> +                           (!memcmp(ifa->ifa_name, "veth", 4)) ||
>> +                           (!memcmp(ifa->ifa_name, "virbr", 5)))
> I would use strncmp().
ok.
> I don't think it is a good idea to compare against such names. E.g. on
> my ChromeBook, the WiFi interface is called mlan0.
> Do we care what kind of underlying link layer is used? What are the
> observable characteristics you are looking for?
So it has to be some ethernet device where it's possible to set/get mac, 
promisc mode,
change mtu. I printed ifa_flags and they are the same for ethernet eth0 
and wlan0 on
my machine. So I selected ethernet. That might be veth, so I'm not sure 
if we can select veth.
Any ideas of automatic loop device selection?

Maxim.

>
>
>> +                               continue;
>> +                       memcpy(loop, ifa->ifa_name, IFNAMSIZ);
>> +                       freeifaddrs(ifap);
>> +                       return 0;
>> +               }
>> +       }
>> +
>> +       freeifaddrs(ifap);
>> +       return -1;
>> +}
>> +
>>   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 */
>> +               ODP_ERR("pktio name %s is too big, limit is %d bytes\n",
>> +                       dev, IFNAMSIZ);
>> +               return ODP_PKTIO_INVALID;
>> +       }
>> +
>> +       /* If hint with ODP_PKTIO_LOOPDEV is provided, use hint,
>> +        * if not try to find usable device.
>> +        */
>> +       loop_hint = getenv("ODP_PKTIO_LOOPDEV");
>> +       if (!strcmp(dev, "loop")) {
>> +               if (loop_hint && (strlen(loop_hint) > 0)) {
>> +                       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);
>> +               } else {
>> +                       if (!find_loop_dev(loop)) {
>> +                               ODP_DBG("pktio rename loop to %s\n", loop);
>> +                               dev = loop;
>> +                       } else {
>> +                               ODP_DBG("pktio: No suitable netdev.\n");
>> +                               return ODP_PKTIO_INVALID;
>> +                       }
>> +               }
>> +       }
>>
>>          id = alloc_lock_pktio_entry();
>>          if (id == ODP_PKTIO_INVALID) {
>> --
>> 1.8.5.1.163.gd7aced9
>>
>>
>> _______________________________________________
>> lng-odp mailing list
>> lng-odp@lists.linaro.org
>> http://lists.linaro.org/mailman/listinfo/lng-odp
diff mbox

Patch

diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index e8815cd..993f2ab 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -22,6 +22,7 @@ 
 #include <string.h>
 #include <sys/ioctl.h>
 #include <linux/if_arp.h>
+#include <ifaddrs.h>
 
 typedef struct {
 	pktio_entry_t entries[ODP_CONFIG_PKTIO_ENTRIES];
@@ -154,12 +155,75 @@  static int free_pktio_entry(odp_pktio_t id)
 	return 0;
 }
 
+static int find_loop_dev(char loop[IFNAMSIZ])
+{
+	struct ifaddrs *ifap, *ifa;
+
+	getifaddrs(&ifap);
+
+	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+		if (ifa->ifa_addr &&
+		    ifa->ifa_addr->sa_family == AF_INET) {
+			if ((ifa->ifa_flags & (IFF_LOOPBACK |
+					      IFF_POINTOPOINT |
+					      IFF_NOARP)) ||
+			    (!memcmp(ifa->ifa_name, "lxcbr", 5)) ||
+			    (!memcmp(ifa->ifa_name, "wlan", 4)) ||
+			    (!memcmp(ifa->ifa_name, "veth", 4)) ||
+			    (!memcmp(ifa->ifa_name, "virbr", 5)))
+				continue;
+			memcpy(loop, ifa->ifa_name, IFNAMSIZ);
+			freeifaddrs(ifap);
+			return 0;
+		}
+	}
+
+	freeifaddrs(ifap);
+	return -1;
+}
+
 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 */
+		ODP_ERR("pktio name %s is too big, limit is %d bytes\n",
+			dev, IFNAMSIZ);
+		return ODP_PKTIO_INVALID;
+	}
+
+	/* If hint with ODP_PKTIO_LOOPDEV is provided, use hint,
+	 * if not try to find usable device.
+	 */
+	loop_hint = getenv("ODP_PKTIO_LOOPDEV");
+	if (!strcmp(dev, "loop")) {
+		if (loop_hint && (strlen(loop_hint) > 0)) {
+			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);
+		} else {
+			if (!find_loop_dev(loop)) {
+				ODP_DBG("pktio rename loop to %s\n", loop);
+				dev = loop;
+			} else {
+				ODP_DBG("pktio: No suitable netdev.\n");
+				return ODP_PKTIO_INVALID;
+			}
+		}
+	}
 
 	id = alloc_lock_pktio_entry();
 	if (id == ODP_PKTIO_INVALID) {