fixed tap device setup (requires open/close for each call)
using more meaningful names for tap devices
This commit is contained in:
+2
-2
@@ -79,7 +79,7 @@ static iface_t* create_iface(private_guest_t *this, char *name)
|
||||
iterator = this->ifaces->create_iterator(this->ifaces, TRUE);
|
||||
while (iterator->iterate(iterator, (void**)&iface))
|
||||
{
|
||||
if (streq(name, iface->get_guest(iface)))
|
||||
if (streq(name, iface->get_guestif(iface)))
|
||||
{
|
||||
DBG1("guest '%s' already has an interface '%s'", this->name, name);
|
||||
iterator->destroy(iterator);
|
||||
@@ -88,7 +88,7 @@ static iface_t* create_iface(private_guest_t *this, char *name)
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
|
||||
iface = iface_create(name, this->mconsole);
|
||||
iface = iface_create(this->name, name, this->mconsole);
|
||||
if (iface)
|
||||
{
|
||||
this->ifaces->insert_last(this->ifaces, iface);
|
||||
|
||||
+52
-44
@@ -19,6 +19,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <net/if.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/if_tun.h>
|
||||
@@ -33,29 +34,27 @@ struct private_iface_t {
|
||||
/** public interface */
|
||||
iface_t public;
|
||||
/** device name in guest (eth0) */
|
||||
char *guest;
|
||||
char *guestif;
|
||||
/** device name at host (tap0) */
|
||||
char *host;
|
||||
/** tap device handle to manage taps */
|
||||
int tap;
|
||||
char *hostif;
|
||||
/** mconsole for guest */
|
||||
mconsole_t *mconsole;
|
||||
};
|
||||
|
||||
/**
|
||||
* Implementation of iface_t.get_guest.
|
||||
* Implementation of iface_t.get_guestif.
|
||||
*/
|
||||
static char* get_guest(private_iface_t *this)
|
||||
static char* get_guestif(private_iface_t *this)
|
||||
{
|
||||
return this->guest;
|
||||
return this->guestif;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of iface_t.get_host.
|
||||
* Implementation of iface_t.get_hostif.
|
||||
*/
|
||||
static char* get_host(private_iface_t *this)
|
||||
static char* get_hostif(private_iface_t *this)
|
||||
{
|
||||
return this->host;
|
||||
return this->hostif;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,37 +63,56 @@ static char* get_host(private_iface_t *this)
|
||||
static bool destroy_tap(private_iface_t *this)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int tap;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
strncpy(ifr.ifr_name, this->host, sizeof(ifr.ifr_name) - 1);
|
||||
strncpy(ifr.ifr_name, this->hostif, sizeof(ifr.ifr_name) - 1);
|
||||
|
||||
if (ioctl(this->tap, TUNSETIFF, &ifr) < 0 ||
|
||||
ioctl(this->tap, TUNSETPERSIST, 0) < 0)
|
||||
tap = open(TAP_DEVICE, O_RDWR);
|
||||
if (tap < 0)
|
||||
{
|
||||
DBG1("removing %s failed: %m", this->host);
|
||||
DBG1("unable to open tap device %s: %m", TAP_DEVICE);
|
||||
return FALSE;
|
||||
}
|
||||
if (ioctl(tap, TUNSETIFF, &ifr) < 0 ||
|
||||
ioctl(tap, TUNSETPERSIST, 0) < 0)
|
||||
{
|
||||
DBG1("removing %s failed: %m", this->hostif);
|
||||
close(tap);
|
||||
return FALSE;
|
||||
}
|
||||
close(tap);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* create the tap device
|
||||
*/
|
||||
static char* create_tap(private_iface_t *this)
|
||||
static char* create_tap(private_iface_t *this, char *guest)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int tap;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
|
||||
if (ioctl(this->tap, TUNSETIFF, &ifr) < 0 ||
|
||||
ioctl(this->tap, TUNSETPERSIST, 1) < 0 ||
|
||||
ioctl(this->tap, TUNSETOWNER, 0))
|
||||
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s-%s", guest, this->guestif);
|
||||
|
||||
tap = open(TAP_DEVICE, O_RDWR);
|
||||
if (tap < 0)
|
||||
{
|
||||
DBG1("unable to open tap device %s: %m", TAP_DEVICE);
|
||||
return NULL;
|
||||
}
|
||||
if (ioctl(tap, TUNSETIFF, &ifr) < 0 ||
|
||||
ioctl(tap, TUNSETPERSIST, 1) < 0 ||
|
||||
ioctl(tap, TUNSETOWNER, 0))
|
||||
{
|
||||
DBG1("creating new tap device failed: %m");
|
||||
close(tap);
|
||||
return NULL;
|
||||
}
|
||||
close(tap);
|
||||
return strdup(ifr.ifr_name);
|
||||
}
|
||||
|
||||
@@ -103,50 +121,40 @@ static char* create_tap(private_iface_t *this)
|
||||
*/
|
||||
static void destroy(private_iface_t *this)
|
||||
{
|
||||
this->mconsole->del_iface(this->mconsole, this->guest);
|
||||
this->mconsole->del_iface(this->mconsole, this->guestif);
|
||||
destroy_tap(this);
|
||||
close(this->tap);
|
||||
free(this->guest);
|
||||
free(this->host);
|
||||
free(this->guestif);
|
||||
free(this->hostif);
|
||||
free(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* create the iface instance
|
||||
*/
|
||||
iface_t *iface_create(char *guest, mconsole_t *mconsole)
|
||||
iface_t *iface_create(char *guest, char *guestif, mconsole_t *mconsole)
|
||||
{
|
||||
private_iface_t *this = malloc_thing(private_iface_t);
|
||||
|
||||
this->public.get_host = (char*(*)(iface_t*))get_host;
|
||||
this->public.get_guest = (char*(*)(iface_t*))get_guest;
|
||||
this->public.get_hostif = (char*(*)(iface_t*))get_hostif;
|
||||
this->public.get_guestif = (char*(*)(iface_t*))get_guestif;
|
||||
this->public.destroy = (void*)destroy;
|
||||
|
||||
this->mconsole = mconsole;
|
||||
this->tap = open(TAP_DEVICE, O_RDWR);
|
||||
if (this->tap < 0)
|
||||
this->guestif = strdup(guestif);
|
||||
this->hostif = create_tap(this, guest);
|
||||
if (this->hostif == NULL)
|
||||
{
|
||||
DBG1("unable to open tap device %s: %m", TAP_DEVICE);
|
||||
destroy_tap(this);
|
||||
free(this->guestif);
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
this->guest = strdup(guest);
|
||||
this->host = create_tap(this);
|
||||
if (this->host == NULL)
|
||||
if (!this->mconsole->add_iface(this->mconsole, this->guestif, this->hostif))
|
||||
{
|
||||
DBG1("creating interface '%s' in guest failed", this->guestif);
|
||||
destroy_tap(this);
|
||||
close(this->tap);
|
||||
free(this->guest);
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
if (!this->mconsole->add_iface(this->mconsole, this->guest, this->host))
|
||||
{
|
||||
DBG1("creating interface '%s' in guest failed", this->guest);
|
||||
destroy_tap(this);
|
||||
close(this->tap);
|
||||
free(this->guest);
|
||||
free(this->host);
|
||||
free(this->guestif);
|
||||
free(this->hostif);
|
||||
free(this);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+5
-4
@@ -35,14 +35,14 @@ struct iface_t {
|
||||
*
|
||||
* @return guest interface name
|
||||
*/
|
||||
char* (*get_guest)(iface_t *this);
|
||||
char* (*get_guestif)(iface_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the interface name at the host (e.g. tap0).
|
||||
*
|
||||
* @return host interface (tap device) name
|
||||
*/
|
||||
char* (*get_host)(iface_t *this);
|
||||
char* (*get_hostif)(iface_t *this);
|
||||
|
||||
/*
|
||||
bool (*up) (iface_t *this);
|
||||
@@ -61,10 +61,11 @@ struct iface_t {
|
||||
/**
|
||||
* @brief Create a new interface for a guest
|
||||
*
|
||||
* @param guest name of the interface in the guest
|
||||
* @param guest name of the guest for this interface
|
||||
* @param guestif name of the interface in the guest
|
||||
* @param mconsole mconsole of guest
|
||||
* @return interface descriptor, or NULL if failed
|
||||
*/
|
||||
iface_t *iface_create(char *guest, mconsole_t *mconsole);
|
||||
iface_t *iface_create(char *guest, char *guestif, mconsole_t *mconsole);
|
||||
|
||||
#endif /* IFACE_H */
|
||||
|
||||
+6
-5
@@ -151,7 +151,7 @@ static void add_if(guest_t *guest, char *name)
|
||||
if (iface)
|
||||
{
|
||||
printf("created guest interface '%s' connected to '%s'\n",
|
||||
iface->get_guest(iface), iface->get_host(iface));
|
||||
iface->get_guestif(iface), iface->get_hostif(iface));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -171,11 +171,11 @@ static void del_if(guest_t *guest, char *name)
|
||||
iterator = guest->create_iface_iterator(guest);
|
||||
while (iterator->iterate(iterator, (void**)&iface))
|
||||
{
|
||||
if (streq(name, iface->get_guest(iface)))
|
||||
if (streq(name, iface->get_guestif(iface)))
|
||||
{
|
||||
iterator->remove(iterator);
|
||||
printf("removing interface '%s' ('%s') from %s\n",
|
||||
iface->get_guest(iface), iface->get_host(iface),
|
||||
iface->get_guestif(iface), iface->get_hostif(iface),
|
||||
guest->get_name(guest));
|
||||
iface->destroy(iface);
|
||||
found = TRUE;
|
||||
@@ -201,7 +201,7 @@ static void list_if(guest_t *guest)
|
||||
iterator = guest->create_iface_iterator(guest);
|
||||
while (iterator->iterate(iterator, (void**)&iface))
|
||||
{
|
||||
printf("'%s' => '%s'\n", iface->get_guest(iface), iface->get_host(iface));
|
||||
printf("'%s' => '%s'\n", iface->get_guestif(iface), iface->get_hostif(iface));
|
||||
|
||||
}
|
||||
iterator->destroy(iterator);
|
||||
@@ -318,7 +318,8 @@ static void list(dumm_t *dumm)
|
||||
ifaces = guest->create_iface_iterator(guest);
|
||||
while (ifaces->iterate(ifaces, (void**)&iface))
|
||||
{
|
||||
printf(" '%s' => '%s'\n", iface->get_guest(iface), iface->get_host(iface));
|
||||
printf(" '%s' => '%s'\n",
|
||||
iface->get_guestif(iface), iface->get_hostif(iface));
|
||||
}
|
||||
ifaces->destroy(ifaces);
|
||||
}
|
||||
|
||||
+1
-1
@@ -154,7 +154,7 @@ mconsole_t *mconsole_create(char *sock)
|
||||
}
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sun_family = AF_UNIX;
|
||||
sprintf(&addr.sun_path[1], "%5d-%s", getpid(), sock);
|
||||
snprintf(&addr.sun_path[1], sizeof(addr.sun_path), "%5d-%s", getpid(), sock);
|
||||
if (bind(this->socket, (struct sockaddr*)&addr, sizeof(addr)) < 0)
|
||||
{
|
||||
DBG1("binding mconsole socket failed: %m");
|
||||
|
||||
Reference in New Issue
Block a user