Tizen emulator specific logic is extracted to independent source file.
Tap interface prefix is changed to "tap-tizen".
Change-Id: I38e218936003e8bc8de51a4d0b3413872defe4c3
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
Signed-off-by: Munkyu Im <munkyu.im@samsung.com>
#define PATH_NET_TUN "/dev/net/tun"
-#if defined(CONFIG_MARU)
-#include "tizen/src/emul_state.h"
-
-static int launch_openvpn(bool ismake, const char *ifname)
-{
- int pid, status;
- const char* args[] = {
- "/usr/bin/sudo",
- "/usr/sbin/openvpn",
- "--mktun",
- "--dev",
- ifname,
- NULL
- };
- if (ismake) {
- fprintf(stdout, "launch_openvpn make tap: %s\n", ifname);
- } else {
- fprintf(stdout, "launch_openvpn remove tap: %s\n", ifname);
- args[2] = "--rmtun";
- }
- /* try to launch network script */
- pid = fork();
- if (pid == 0) {
- execv(args[0], (char**)args);
- _exit(1);
- } else if (pid > 0) {
- while (waitpid(pid, &status, 0) != pid) {
- /* loop */
- }
-
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- return 0;
- }
- }
- fprintf(stderr, "Could not launch openvpn\n");
- return -1;
-}
-
-static int tap_cleanup(void)
-{
- int fd, ret;
- struct ifreq ifr;
- char dname[100];
- int port = get_emul_vm_base_port() + 10;
-
- TFR(fd = open(PATH_NET_TUN, O_RDWR));
- if (fd < 0) {
- error_report("could not open %s: %m", PATH_NET_TUN);
- return -1;
- }
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
-
- for ( ; port < 26200; port += 10) {
- snprintf(dname, sizeof(dname), "tap%d", port);
- pstrcpy(ifr.ifr_name, IFNAMSIZ, dname);
- ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
- if (ret == 0) {
- close(fd);
- if (launch_openvpn(false, dname)) {
- fprintf(stderr, "Failed to remove %s device. It can be used on the other emulator\n", dname);
- }
- TFR(fd = open(PATH_NET_TUN, O_RDWR));
- if (fd < 0) {
- error_report("could not open %s: %m", PATH_NET_TUN);
- return -1;
- }
- } else {
- close(fd);
- }
- }
- return 0;
-}
-
-#endif
-
int tap_open(char *ifname, int ifname_size, int *vnet_hdr,
int vnet_hdr_required, int mq_required, Error **errp)
{
int fd, ret;
int len = sizeof(struct virtio_net_hdr);
unsigned int features;
-#if defined(CONFIG_MARU)
- if (tap_cleanup() < 0) {
- return -1;
- }
-#endif
+
TFR(fd = open(PATH_NET_TUN, O_RDWR));
if (fd < 0) {
error_setg_errno(errp, errno, "could not open %s", PATH_NET_TUN);
if (ifname[0] != '\0')
pstrcpy(ifr.ifr_name, IFNAMSIZ, ifname);
- else {
-#if defined(CONFIG_MARU)
- /* Create tap */
- char dname[100];
- snprintf(dname, sizeof dname, "tap%d", get_emul_vm_base_port());
- if (launch_openvpn(true, dname)) {
- close(fd);
- return -1;
- }
- pstrcpy(ifr.ifr_name, IFNAMSIZ, dname);
-#else
+ else
pstrcpy(ifr.ifr_name, IFNAMSIZ, "tap%d");
-#endif
- }
ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
if (ret != 0) {
if (ifname[0] != '\0') {
#include "net/vhost_net.h"
#if defined(CONFIG_MARU)
#include "tizen/src/emul_state.h"
+# if defined(CONFIG_LINUX)
+#include "tizen/src/util/tap_helper.h"
+# endif
#endif
typedef struct TAPState {
return s;
}
-#if !defined(CONFIG_WIN32) && defined(CONFIG_MARU)
+#if defined(CONFIG_MARU)
#include <arpa/inet.h>
#include <sys/socket.h>
#include <ifaddrs.h>
int fd, Error **errp)
{
int pid, status;
-#if !defined(CONFIG_WIN32) && defined(CONFIG_MARU)
+#if defined(CONFIG_MARU)
const char* sudo_path = "/usr/bin/sudo";
char *host_ifname = get_interface_name_from_ip();
fprintf(stdout, "host_ifname: %s\n", host_ifname);
}
}
parg = args;
-#if !defined(CONFIG_WIN32) && defined(CONFIG_MARU)
+#if defined(CONFIG_MARU)
*parg++ = (char *)sudo_path;
#endif
*parg++ = (char *)setup_script;
}
*parg = NULL;
-#if !defined(CONFIG_WIN32) && defined(CONFIG_MARU)
+#if defined(CONFIG_MARU)
execv(sudo_path, args);
#else
execv(setup_script, args);
if (tap->has_ifname) {
pstrcpy(ifname, sizeof ifname, tap->ifname);
} else {
+#if defined(CONFIG_LINUX) && defined(CONFIG_MARU)
+ /* Create tap */
+ tap_create(ifname);
+ if (ifname[0] == '\0') {
+ return -1;
+ }
+#else
ifname[0] = '\0';
+#endif
}
for (i = 0; i < queues; i++) {
obj-$(CONFIG_WIN32) += osutil-win32.o
obj-$(CONFIG_DARWIN) += osutil-darwin.o
+# tap helper
+obj-$(CONFIG_LINUX) += tap_helper.o
+
#sdb
obj-y += sdb.o
--- /dev/null
+/*
+ * TAP helper
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * MunKyu Im <munkyu.im@samsung.com>
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <linux/if_tun.h>
+
+#include "qemu-common.h"
+#include "qemu/error-report.h"
+
+#include "tap_helper.h"
+
+#define PATH_NET_TUN "/dev/net/tun"
+
+#include "util/new_debug_ch.h"
+DECLARE_DEBUG_CHANNEL(tap_helper);
+
+#define START_BASE_PORT 26100
+#define END_BASE_PORT 26200
+
+static bool launch_openvpn(bool ismake, const char *ifname)
+{
+ int pid, status;
+ const char* args[] = {
+ "/usr/bin/sudo",
+ "/usr/sbin/openvpn",
+ "",
+ "--dev",
+ ifname,
+ NULL
+ };
+ if (ismake) {
+ LOG_INFO("launch_openvpn make tap: %s\n", ifname);
+ args[2] = "--mktun";
+ } else {
+ LOG_INFO("launch_openvpn remove tap: %s\n", ifname);
+ args[2] = "--rmtun";
+ }
+ /* try to launch network script */
+ pid = fork();
+ if (pid == 0) {
+ execv(args[0], (char**)args);
+ _exit(1);
+ } else if (pid > 0) {
+ while (waitpid(pid, &status, 0) != pid) {
+ /* loop */
+ }
+
+ if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+ return true;
+ }
+ }
+
+ LOG_WARNING("Could not launch openvpn\n");
+ return false;
+}
+
+void tap_create(char *ifname)
+{
+ int fd, ret, i;
+ struct ifreq ifr;
+ char dname[128];
+ int cause;
+
+ ifname[0] = '\0';
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+
+ // clean-up legacy ifnames
+ for (i = START_BASE_PORT ; i < END_BASE_PORT; i += 10) {
+ g_snprintf(dname, sizeof(dname), "tap%d", i);
+ g_strlcpy(ifr.ifr_name, dname, IFNAMSIZ);
+
+ TFR(fd = open(PATH_NET_TUN, O_RDWR));
+ if (fd < 0) {
+ error_report("could not open %s: %m", PATH_NET_TUN);
+ return;
+ }
+
+ ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
+
+ close(fd);
+
+ if (ret == 0) {
+ if (!launch_openvpn(false, dname)) {
+ LOG_INFO("Failed to remove tap interface [%s]."
+ "The other emulator may be using this interface.\n", dname);
+ }
+ }
+ }
+
+ // clean-up and find first unused ifname
+ for (i = 0; i < 10; i++) {
+ g_snprintf(dname, sizeof(dname), "tap_tizen%d", i);
+ g_strlcpy(ifr.ifr_name, dname, IFNAMSIZ);
+
+ TFR(fd = open(PATH_NET_TUN, O_RDWR));
+ if (fd < 0) {
+ error_report("could not open %s: %m", PATH_NET_TUN);
+ return;
+ }
+
+ ret = ioctl(fd, TUNSETIFF, (void *) &ifr);
+ cause = errno;
+ close(fd);
+
+ // ret 0: exist but not used
+ // ret -1 and cause EPERM: not exist
+ if (ret == 0 || (ret == -1 && cause == EPERM)) {
+ if (ret == 0 && !launch_openvpn(false, dname)) {
+ LOG_INFO("Failed to remove tap interface [%s]."
+ "The other emulator may be using this interface.\n", dname);
+ continue;
+ }
+ if (ifname[0] == '\0') {
+ g_strlcpy(ifname, dname, 128);
+ }
+ }
+ }
+
+ // create tap
+ if (ifname == '\0' || !launch_openvpn(true, ifname)) {
+ LOG_INFO("Tap interface creattion failed.\n");
+ }
+
+ return;
+}
--- /dev/null
+/*
+ * TAP helper
+ *
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact:
+ * MunKyu Im <munkyu.im@samsung.com>
+ * SeokYeon Hwang <syeon.hwang@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+#ifndef __TAP_HELPER_H__
+#define __TAP_HELPER_H__
+
+void tap_create(char *);
+
+#endif //__TAP_HELPER_H__