mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-22 11:22:23 +00:00
Add -netdev bridge support
This patch adds the support to run the QEMU network helper under unprivileged user. It also adds the support for attach-interface option in virsh to run under unprivileged user. Signed-off-by: Richa Marwaha <rmarwah@linux.vnet.ibm.com> Signed-off-by: Corey Bryant<coreyb@linux.vnet.ibm.com>
This commit is contained in:
parent
756fe7868b
commit
e060f86495
@ -2964,6 +2964,8 @@ error:
|
|||||||
|
|
||||||
char *
|
char *
|
||||||
qemuBuildHostNetStr(virDomainNetDefPtr net,
|
qemuBuildHostNetStr(virDomainNetDefPtr net,
|
||||||
|
struct qemud_driver *driver,
|
||||||
|
virBitmapPtr qemuCaps,
|
||||||
char type_sep,
|
char type_sep,
|
||||||
int vlan,
|
int vlan,
|
||||||
const char *tapfd,
|
const char *tapfd,
|
||||||
@ -2972,6 +2974,7 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
|
|||||||
bool is_tap = false;
|
bool is_tap = false;
|
||||||
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||||
enum virDomainNetType netType = virDomainNetGetActualType(net);
|
enum virDomainNetType netType = virDomainNetGetActualType(net);
|
||||||
|
const char *brname = NULL;
|
||||||
|
|
||||||
if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
|
if (net->script && netType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
@ -2981,8 +2984,21 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (netType) {
|
switch (netType) {
|
||||||
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
/*
|
||||||
|
* If type='bridge', and we're running as privileged user
|
||||||
|
* or -netdev bridge is not supported then it will fall
|
||||||
|
* through, -net tap,fd
|
||||||
|
*/
|
||||||
case VIR_DOMAIN_NET_TYPE_BRIDGE:
|
case VIR_DOMAIN_NET_TYPE_BRIDGE:
|
||||||
|
if (!driver->privileged &&
|
||||||
|
qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE)) {
|
||||||
|
brname = virDomainNetGetActualBridgeName(net);
|
||||||
|
virBufferAsprintf(&buf, "bridge%cbr=%s", type_sep, brname);
|
||||||
|
type_sep = ',';
|
||||||
|
is_tap = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VIR_DOMAIN_NET_TYPE_NETWORK:
|
||||||
case VIR_DOMAIN_NET_TYPE_DIRECT:
|
case VIR_DOMAIN_NET_TYPE_DIRECT:
|
||||||
virBufferAsprintf(&buf, "tap%cfd=%s", type_sep, tapfd);
|
virBufferAsprintf(&buf, "tap%cfd=%s", type_sep, tapfd);
|
||||||
type_sep = ',';
|
type_sep = ',';
|
||||||
@ -5125,7 +5141,7 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
for (i = 0 ; i < def->nnets ; i++) {
|
for (i = 0 ; i < def->nnets ; i++) {
|
||||||
virDomainNetDefPtr net = def->nets[i];
|
virDomainNetDefPtr net = def->nets[i];
|
||||||
char *nic, *host;
|
char *nic, *host;
|
||||||
char tapfd_name[50];
|
char tapfd_name[50] = "";
|
||||||
char vhostfd_name[50] = "";
|
char vhostfd_name[50] = "";
|
||||||
int vlan;
|
int vlan;
|
||||||
int bootindex = bootNet;
|
int bootindex = bootNet;
|
||||||
@ -5162,17 +5178,26 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
|
|
||||||
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
|
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
|
||||||
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
|
actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
|
||||||
int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net,
|
/*
|
||||||
qemuCaps);
|
* If type='bridge' then we attempt to allocate the tap fd here only if
|
||||||
if (tapfd < 0)
|
* running under a privilged user or -netdev bridge option is not
|
||||||
goto error;
|
* supported.
|
||||||
|
*/
|
||||||
|
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
|
||||||
|
driver->privileged ||
|
||||||
|
(!qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV_BRIDGE))) {
|
||||||
|
int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net,
|
||||||
|
qemuCaps);
|
||||||
|
if (tapfd < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
last_good_net = i;
|
last_good_net = i;
|
||||||
virCommandTransferFD(cmd, tapfd);
|
virCommandTransferFD(cmd, tapfd);
|
||||||
|
|
||||||
if (snprintf(tapfd_name, sizeof(tapfd_name), "%d",
|
if (snprintf(tapfd_name, sizeof(tapfd_name), "%d",
|
||||||
tapfd) >= sizeof(tapfd_name))
|
tapfd) >= sizeof(tapfd_name))
|
||||||
goto no_memory;
|
goto no_memory;
|
||||||
|
}
|
||||||
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
|
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
|
||||||
int tapfd = qemuPhysIfaceConnect(def, driver, net,
|
int tapfd = qemuPhysIfaceConnect(def, driver, net,
|
||||||
qemuCaps, vmop);
|
qemuCaps, vmop);
|
||||||
@ -5215,8 +5240,9 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
|
if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
|
||||||
qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
|
qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
|
||||||
virCommandAddArg(cmd, "-netdev");
|
virCommandAddArg(cmd, "-netdev");
|
||||||
if (!(host = qemuBuildHostNetStr(net, ',', vlan,
|
if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps,
|
||||||
tapfd_name, vhostfd_name)))
|
',', vlan, tapfd_name,
|
||||||
|
vhostfd_name)))
|
||||||
goto error;
|
goto error;
|
||||||
virCommandAddArg(cmd, host);
|
virCommandAddArg(cmd, host);
|
||||||
VIR_FREE(host);
|
VIR_FREE(host);
|
||||||
@ -5238,8 +5264,9 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
if (!(qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
|
if (!(qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) &&
|
||||||
qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {
|
qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE))) {
|
||||||
virCommandAddArg(cmd, "-net");
|
virCommandAddArg(cmd, "-net");
|
||||||
if (!(host = qemuBuildHostNetStr(net, ',', vlan,
|
if (!(host = qemuBuildHostNetStr(net, driver, qemuCaps,
|
||||||
tapfd_name, vhostfd_name)))
|
',', vlan, tapfd_name,
|
||||||
|
vhostfd_name)))
|
||||||
goto error;
|
goto error;
|
||||||
virCommandAddArg(cmd, host);
|
virCommandAddArg(cmd, host);
|
||||||
VIR_FREE(host);
|
VIR_FREE(host);
|
||||||
|
@ -62,6 +62,8 @@ qemuBuildChrDeviceStr (virDomainChrDefPtr serial,
|
|||||||
|
|
||||||
/* With vlan == -1, use netdev syntax, else old hostnet */
|
/* With vlan == -1, use netdev syntax, else old hostnet */
|
||||||
char * qemuBuildHostNetStr(virDomainNetDefPtr net,
|
char * qemuBuildHostNetStr(virDomainNetDefPtr net,
|
||||||
|
struct qemud_driver *driver,
|
||||||
|
virBitmapPtr qemuCaps,
|
||||||
char type_sep,
|
char type_sep,
|
||||||
int vlan,
|
int vlan,
|
||||||
const char *tapfd,
|
const char *tapfd,
|
||||||
|
@ -695,12 +695,21 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
|
|||||||
|
|
||||||
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
|
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
|
||||||
actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
|
actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
|
||||||
if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net,
|
/*
|
||||||
priv->qemuCaps)) < 0)
|
* If type=bridge then we attempt to allocate the tap fd here only if
|
||||||
goto cleanup;
|
* running under a privilged user or -netdev bridge option is not
|
||||||
iface_connected = true;
|
* supported.
|
||||||
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0)
|
*/
|
||||||
goto cleanup;
|
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
|
||||||
|
driver->privileged ||
|
||||||
|
(!qemuCapsGet (priv->qemuCaps, QEMU_CAPS_NETDEV_BRIDGE))) {
|
||||||
|
if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net,
|
||||||
|
priv->qemuCaps)) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
iface_connected = true;
|
||||||
|
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, &vhostfd) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
|
} else if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
|
||||||
if ((tapfd = qemuPhysIfaceConnect(vm->def, driver, net,
|
if ((tapfd = qemuPhysIfaceConnect(vm->def, driver, net,
|
||||||
priv->qemuCaps,
|
priv->qemuCaps,
|
||||||
@ -748,12 +757,14 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
|
|||||||
|
|
||||||
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
|
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_NETDEV) &&
|
||||||
qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
|
||||||
if (!(netstr = qemuBuildHostNetStr(net, ',',
|
if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps,
|
||||||
-1, tapfd_name, vhostfd_name)))
|
',', -1, tapfd_name,
|
||||||
|
vhostfd_name)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
if (!(netstr = qemuBuildHostNetStr(net, ' ',
|
if (!(netstr = qemuBuildHostNetStr(net, driver, priv->qemuCaps,
|
||||||
vlan, tapfd_name, vhostfd_name)))
|
' ', vlan, tapfd_name,
|
||||||
|
vhostfd_name)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user