if (!dryRun) {
if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
- def->uuid, NULL, 0,
+ def->uuid, NULL, NULL, 0,
virDomainNetGetActualVirtPortProfile(net),
virDomainNetGetActualVlan(net),
VIR_NETDEV_TAP_CREATE_IFUP | VIR_NETDEV_TAP_CREATE_PERSIST) < 0) {
ignore_value(virNetDevBridgeRemovePort(
virDomainNetGetActualBridgeName(net),
net->ifname));
- ignore_value(virNetDevTapDelete(net->ifname));
+ ignore_value(virNetDevTapDelete(net->ifname, NULL));
}
}
}
/* Keep tun fd open and interface up to allow for IPv6 DAD to happen */
if (virNetDevTapCreateInBridgePort(network->def->bridge,
&macTapIfName, &network->def->mac,
- NULL, &tapfd, 1, NULL, NULL,
+ NULL, NULL, &tapfd, 1, NULL, NULL,
VIR_NETDEV_TAP_CREATE_USE_MAC_FOR_BRIDGE |
VIR_NETDEV_TAP_CREATE_IFUP |
VIR_NETDEV_TAP_CREATE_PERSIST) < 0) {
if (macTapIfName) {
VIR_FORCE_CLOSE(tapfd);
- ignore_value(virNetDevTapDelete(macTapIfName));
+ ignore_value(virNetDevTapDelete(macTapIfName, NULL));
VIR_FREE(macTapIfName);
}
if (network->def->mac_specified) {
char *macTapIfName = networkBridgeDummyNicName(network->def->bridge);
if (macTapIfName) {
- ignore_value(virNetDevTapDelete(macTapIfName));
+ ignore_value(virNetDevTapDelete(macTapIfName, NULL));
VIR_FREE(macTapIfName);
}
}
bool template_ifname = false;
int actualType = virDomainNetGetActualType(net);
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+ const char *tunpath = "/dev/net/tun";
+
+ if (net->backend.tap)
+ tunpath = net->backend.tap;
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
bool fail = false;
if (cfg->privileged) {
if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
- def->uuid, tapfd, *tapfdSize,
+ def->uuid, tunpath, tapfd, *tapfdSize,
virDomainNetGetActualVirtPortProfile(net),
virDomainNetGetActualVlan(net),
tap_create_flags) < 0) {
- virDomainAuditNetDevice(def, net, "/dev/net/tun", false);
+ virDomainAuditNetDevice(def, net, tunpath, false);
goto cleanup;
}
} else {
if (qemuCreateInBridgePortWithHelper(cfg, brname,
&net->ifname,
tapfd, tap_create_flags) < 0) {
- virDomainAuditNetDevice(def, net, "/dev/net/tun", false);
+ virDomainAuditNetDevice(def, net, tunpath, false);
goto cleanup;
}
/* qemuCreateInBridgePortWithHelper can only create a single FD */
}
}
- virDomainAuditNetDevice(def, net, "/dev/net/tun", true);
+ virDomainAuditNetDevice(def, net, tunpath, true);
if (cfg->macFilter &&
ebtablesAddForwardAllowIn(driver->ebtables,
int *vhostfdSize)
{
size_t i;
+ const char *vhostnet_path = net->backend.vhost;
+
+ if (!vhostnet_path)
+ vhostnet_path = "/dev/vhost-net";
/* If running a plain QEMU guest, or
* if the config says explicitly to not use vhost, return now*/
}
for (i = 0; i < *vhostfdSize; i++) {
- vhostfd[i] = open("/dev/vhost-net", O_RDWR);
+ vhostfd[i] = open(vhostnet_path, O_RDWR);
/* If the config says explicitly to use vhost and we couldn't open it,
* report an error.
*/
if (vhostfd[i] < 0) {
- virDomainAuditNetDevice(def, net, "/dev/vhost-net", false);
+ virDomainAuditNetDevice(def, net, vhostnet_path, false);
if (net->driver.virtio.name == VIR_DOMAIN_NET_BACKEND_TYPE_VHOST) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("vhost-net was requested for an interface, "
break;
}
}
- virDomainAuditNetDevice(def, net, "/dev/vhost-net", *vhostfdSize);
+ virDomainAuditNetDevice(def, net, vhostnet_path, *vhostfdSize);
return 0;
error:
case VIR_DOMAIN_NET_TYPE_NETWORK:
#ifdef VIR_NETDEV_TAP_REQUIRE_MANUAL_CLEANUP
if (!(vport && vport->virtPortType == VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH))
- ignore_value(virNetDevTapDelete(net->ifname));
+ ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
#endif
break;
}
}
if (virNetDevTapCreateInBridgePort(bridge, &net->ifname, &net->mac,
- vm->uuid, &tapfd, 1,
+ vm->uuid, net->backend.tap, &tapfd, 1,
virDomainNetGetActualVirtPortProfile(net),
virDomainNetGetActualVlan(net),
VIR_NETDEV_TAP_CREATE_IFUP |
def->type != VIR_DOMAIN_NET_TYPE_NETWORK)
continue;
- ignore_value(virNetDevTapDelete(def->ifname));
+ ignore_value(virNetDevTapDelete(def->ifname,
+ def->backend.tap));
}
}
/**
* virNetDevTapCreate:
* @ifname: the interface name
+ * @tunpath: path to the tun device (if NULL, /dev/net/tun is used)
* @tapfds: array of file descriptors return value for the new tap device
* @tapfdSize: number of file descriptors in @tapfd
* @flags: OR of virNetDevTapCreateFlags. Only one flag is recognized:
* Returns 0 in case of success or -1 on failure.
*/
int virNetDevTapCreate(char **ifname,
+ const char *tunpath,
int *tapfd,
int tapfdSize,
unsigned int flags)
int ret = -1;
int fd;
+ if (!tunpath)
+ tunpath = "/dev/net/tun";
+
memset(&ifr, 0, sizeof(ifr));
for (i = 0; i < tapfdSize; i++) {
- if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
- virReportSystemError(errno, "%s",
- _("Unable to open /dev/net/tun, is tun module loaded?"));
+ if ((fd = open(tunpath, O_RDWR)) < 0) {
+ virReportSystemError(errno,
+ _("Unable to open %s, is tun module loaded?"),
+ tunpath);
goto cleanup;
}
}
-int virNetDevTapDelete(const char *ifname)
+int virNetDevTapDelete(const char *ifname,
+ const char *tunpath)
{
struct ifreq try;
int fd;
int ret = -1;
- if ((fd = open("/dev/net/tun", O_RDWR)) < 0) {
- virReportSystemError(errno, "%s",
- _("Unable to open /dev/net/tun, is tun module loaded?"));
+ if (!tunpath)
+ tunpath = "/dev/net/tun";
+
+ if ((fd = open(tunpath, O_RDWR)) < 0) {
+ virReportSystemError(errno,
+ _("Unable to open %s, is tun module loaded?"),
+ tunpath);
return -1;
}
}
#elif defined(SIOCIFCREATE2) && defined(SIOCIFDESTROY) && defined(IF_MAXUNIT)
int virNetDevTapCreate(char **ifname,
+ const char *tunpath ATTRIBUTE_UNUSED,
int *tapfd,
int tapfdSize,
unsigned int flags ATTRIBUTE_UNUSED)
return ret;
}
-int virNetDevTapDelete(const char *ifname)
+int virNetDevTapDelete(const char *ifname,
+ const char *tunpath ATTRIBUTE_UNUSED)
{
int s;
struct ifreq ifr;
#else
int virNetDevTapCreate(char **ifname ATTRIBUTE_UNUSED,
+ const char *tunpath ATTRIBUTE_UNUSED,
int *tapfd ATTRIBUTE_UNUSED,
int tapfdSize ATTRIBUTE_UNUSED,
unsigned int flags ATTRIBUTE_UNUSED)
_("Unable to create TAP devices on this platform"));
return -1;
}
-int virNetDevTapDelete(const char *ifname ATTRIBUTE_UNUSED)
+int virNetDevTapDelete(const char *ifname ATTRIBUTE_UNUSED,
+ const char *tunpath ATTRIBUTE_UNUSED)
{
virReportSystemError(ENOSYS, "%s",
_("Unable to delete TAP devices on this platform"));
* @brname: the bridge name
* @ifname: the interface name (or name template)
* @macaddr: desired MAC address
+ * @tunpath: path to the tun device (if NULL, /dev/net/tun is used)
* @tapfd: array of file descriptor return value for the new tap device
* @tapfdSize: number of file descriptors in @tapfd
* @virtPortProfile: bridge/port specific configuration
char **ifname,
const virMacAddr *macaddr,
const unsigned char *vmuuid,
+ const char *tunpath,
int *tapfd,
int tapfdSize,
virNetDevVPortProfilePtr virtPortProfile,
char macaddrstr[VIR_MAC_STRING_BUFLEN];
size_t i;
- if (virNetDevTapCreate(ifname, tapfd, tapfdSize, flags) < 0)
+ if (virNetDevTapCreate(ifname, tunpath, tapfd, tapfdSize, flags) < 0)
return -1;
/* We need to set the interface MAC before adding it
# endif
int virNetDevTapCreate(char **ifname,
+ const char *tunpath,
int *tapfd,
int tapfdSize,
unsigned int flags)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
-int virNetDevTapDelete(const char *ifname)
+int virNetDevTapDelete(const char *ifname,
+ const char *tunpath)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int virNetDevTapGetName(int tapfd, char **ifname)
char **ifname,
const virMacAddr *macaddr,
const unsigned char *vmuuid,
+ const char *tunpath,
int *tapfd,
int tapfdSize,
virNetDevVPortProfilePtr virtPortProfile,