examples/ip_pipeline: add tap object
authorJasvinder Singh <jasvinder.singh@intel.com>
Thu, 29 Mar 2018 18:31:45 +0000 (19:31 +0100)
committerCristian Dumitrescu <cristian.dumitrescu@intel.com>
Thu, 5 Apr 2018 16:23:51 +0000 (18:23 +0200)
Add tap object implementation to the application

Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
examples/ip_pipeline/Makefile
examples/ip_pipeline/cli.c
examples/ip_pipeline/main.c
examples/ip_pipeline/meson.build
examples/ip_pipeline/tap.c [new file with mode: 0644]
examples/ip_pipeline/tap.h [new file with mode: 0644]

index 35e4302..0f6bb78 100644 (file)
@@ -12,6 +12,7 @@ SRCS-y += main.c
 SRCS-y += mempool.c
 SRCS-y += parser.c
 SRCS-y += swq.c
+SRCS-y += tap.c
 SRCS-y += tmgr.c
 #SRCS-y += thread.c
 
index 72ecbad..430b49d 100644 (file)
@@ -14,6 +14,7 @@
 #include "mempool.h"
 #include "parser.h"
 #include "swq.h"
+#include "tap.h"
 #include "tmgr.h"
 
 #ifndef CMD_MAX_TOKENS
@@ -603,6 +604,32 @@ cmd_tmgr_subport_pipe(char **tokens,
        }
 }
 
+/**
+ * tap <tap_name>
+ */
+static void
+cmd_tap(char **tokens,
+       uint32_t n_tokens,
+       char *out,
+       size_t out_size)
+{
+       char *name;
+       struct tap *tap;
+
+       if (n_tokens != 2) {
+               snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]);
+               return;
+       }
+
+       name = tokens[1];
+
+       tap = tap_create(name);
+       if (tap == NULL) {
+               snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]);
+               return;
+       }
+}
+
 void
 cli_process(char *in, char *out, size_t out_size)
 {
@@ -671,6 +698,11 @@ cli_process(char *in, char *out, size_t out_size)
                return;
        }
 
+       if (strcmp(tokens[0], "tap") == 0) {
+               cmd_tap(tokens, n_tokens, out, out_size);
+               return;
+       }
+
        snprintf(out, out_size, MSG_CMD_UNKNOWN, tokens[0]);
 }
 
index 490991f..33c3354 100644 (file)
@@ -15,6 +15,7 @@
 #include "link.h"
 #include "mempool.h"
 #include "swq.h"
+#include "tap.h"
 #include "tmgr.h"
 
 static const char usage[] =
@@ -191,6 +192,13 @@ main(int argc, char **argv)
                return status;
        }
 
+       /* TAP */
+       status = tap_init();
+       if (status) {
+               printf("Error: TAP initialization failed (%d)\n", status);
+               return status;
+       }
+
        /* Script */
        if (app.script_name)
                cli_script_process(app.script_name,
index cb2154c..e875811 100644 (file)
@@ -15,5 +15,6 @@ sources = files(
        'mempool.c',
        'parser.c',
        'swq.c',
+       'tap.c',
        'tmgr.c'
 )
diff --git a/examples/ip_pipeline/tap.c b/examples/ip_pipeline/tap.c
new file mode 100644 (file)
index 0000000..5b34032
--- /dev/null
@@ -0,0 +1,97 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#include <netinet/in.h>
+#ifdef RTE_EXEC_ENV_LINUXAPP
+#include <linux/if.h>
+#include <linux/if_tun.h>
+#endif
+#include <sys/ioctl.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "tap.h"
+
+#define TAP_DEV                                            "/dev/net/tun"
+
+static struct tap_list tap_list;
+
+int
+tap_init(void)
+{
+       TAILQ_INIT(&tap_list);
+
+       return 0;
+}
+
+struct tap *
+tap_find(const char *name)
+{
+       struct tap *tap;
+
+       if (name == NULL)
+               return NULL;
+
+       TAILQ_FOREACH(tap, &tap_list, node)
+               if (strcmp(tap->name, name) == 0)
+                       return tap;
+
+       return NULL;
+}
+
+#ifndef RTE_EXEC_ENV_LINUXAPP
+
+struct tap *
+tap_create(const char *name __rte_unused)
+{
+       return NULL;
+}
+
+#else
+
+struct tap *
+tap_create(const char *name)
+{
+       struct tap *tap;
+       struct ifreq ifr;
+       int fd, status;
+
+       /* Check input params */
+       if ((name == NULL) ||
+               tap_find(name))
+               return NULL;
+
+       /* Resource create */
+       fd = open(TAP_DEV, O_RDWR | O_NONBLOCK);
+       if (fd < 0)
+               return NULL;
+
+       memset(&ifr, 0, sizeof(ifr));
+       ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */
+       snprintf(ifr.ifr_name, IFNAMSIZ, "%s", name);
+
+       status = ioctl(fd, TUNSETIFF, (void *) &ifr);
+       if (status < 0)
+               return NULL;
+
+       /* Node allocation */
+       tap = calloc(1, sizeof(struct tap));
+       if (tap == NULL)
+               return NULL;
+
+       /* Node fill in */
+       strncpy(tap->name, name, sizeof(tap->name));
+       tap->fd = fd;
+
+       /* Node add to list */
+       TAILQ_INSERT_TAIL(&tap_list, tap, node);
+
+       return tap;
+}
+
+#endif
diff --git a/examples/ip_pipeline/tap.h b/examples/ip_pipeline/tap.h
new file mode 100644 (file)
index 0000000..0dce72f
--- /dev/null
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2018 Intel Corporation
+ */
+
+#ifndef _INCLUDE_TAP_H_
+#define _INCLUDE_TAP_H_
+
+#include <sys/queue.h>
+
+#include "common.h"
+
+struct tap {
+       TAILQ_ENTRY(tap) node;
+       char name[NAME_SIZE];
+       int fd;
+};
+
+TAILQ_HEAD(tap_list, tap);
+
+int
+tap_init(void);
+
+struct tap *
+tap_find(const char *name);
+
+struct tap *
+tap_create(const char *name);
+
+#endif /* _INCLUDE_TAP_H_ */