diff mbox

[PATCHv4,07/11] linux-generic: odp_pktio_open loop support

Message ID 1417450537-7640-8-git-send-email-maxim.uvarov@linaro.org
State New
Headers show

Commit Message

Maxim Uvarov Dec. 1, 2014, 4:15 p.m. UTC
Implement pktio device loop device suitable for testing.
Note: lo0 can not be used. Instead of it first upped device
is used.

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

Patch

diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index d9c2425..8dc4fb1 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,71 @@  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) ||
+			    (!memcmp(ifa->ifa_name, "lxcbr", 5)) ||
+			    (!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 (!strncmp(dev, "loop", 4)) {
+		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 rename loop0 to %s\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) {