[libvirt] [PATCH libvirt 2/2] qemu: implement user mode port <forward>
Hu Tao
hutao at cn.fujitsu.com
Thu May 10 10:15:36 UTC 2012
On Thu, May 10, 2012 at 02:10:45AM +0200, Marc-André Lureau wrote:
> Implement port forwarding for user mode networking with QEMU.
> ---
> src/libvirt_private.syms | 3 +
> src/qemu/qemu_command.c | 115 +++++++++++++++++++++
> tests/qemuargv2xmltest.c | 3 +-
> tests/qemuxml2argvdata/qemuxml2argv-net-user.args | 5 +-
> 4 files changed, 122 insertions(+), 4 deletions(-)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index afb308d..333284a 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -396,6 +396,9 @@ virDomainNetInsert;
> virDomainNetRemove;
> virDomainNetRemoveByMac;
> virDomainNetTypeToString;
> +virDomainNetForwardDefFree;
> +virDomainNetForwardTypeFromString;
> +virDomainNetForwardTypeToString;
> virDomainNostateReasonTypeFromString;
> virDomainNostateReasonTypeToString;
> virDomainNumatuneMemModeTypeFromString;
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 720f5b4..82c041c 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -2837,6 +2837,22 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
> virBufferAsprintf(&buf, ",sndbuf=%lu", net->tune.sndbuf);
> }
>
> + if (netType == VIR_DOMAIN_NET_TYPE_USER) {
> + int i;
> + for (i = 0; i < net->data.user.nforward; ++i) {
> + virDomainNetForwardDefPtr fwd = net->data.user.forwards[i];
> + const char *type = virDomainNetForwardTypeToString(fwd->type);
> + if (!type) {
> + qemuReportError(VIR_ERR_INTERNAL_ERROR,
> + "%s", _("Invalid forward type"));
> + return NULL;
> + }
> + virBufferAsprintf(&buf, ",hostfwd=%s:%s:%d-%s:%d", type,
> + fwd->host_addr ? fwd->host_addr : "", fwd->host_port,
> + fwd->guest_addr ? fwd->guest_addr : "", fwd->guest_port);
> + }
> + }
> +
> if (virBufferError(&buf)) {
> virBufferFreeAndReset(&buf);
> virReportOOMError();
> @@ -6704,6 +6720,82 @@ qemuFindNICForVLAN(int nnics,
> }
>
>
> +static virDomainNetForwardDefPtr
> +qemuParseNetForward(char *val)
> +{
> + char *type, *host, *guest, *port;
> + virDomainNetForwardDefPtr def;
> +
> + if (VIR_ALLOC(def) < 0) {
> + virReportOOMError();
> + return NULL;
> + }
> +
> + type = val;
> + host = strchr(type, ':');
> + if (!host) {
> + qemuReportError(VIR_ERR_INTERNAL_ERROR,
> + _("cannot parse hostfwd host '%s'"), val);
> + goto error;
> + }
> + *host = '\0';
> + host++;
> + guest = strchr(host, '-');
> + if (!guest) {
> + qemuReportError(VIR_ERR_INTERNAL_ERROR,
> + _("cannot parse hostfwd guest '%s'"), val);
> + goto error;
> + }
> + *guest = '\0';
> + guest++;
> +
> + if (STREQ(type, "")) {
> + def->type = VIR_DOMAIN_NET_FORWARD_TYPE_TCP;
> + } else if ((def->type = virDomainNetForwardTypeFromString(type)) < 0) {
> + qemuReportError(VIR_ERR_INTERNAL_ERROR,
> + _("unknown forward type '%s'"), type);
> + goto error;
> + }
> +
> + port = strchr(host, ':');
> + if (!port) {
> + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Missing host port"));
> + goto error;
> + }
> + *port = '\0';
> + port++;
> + if (!STREQ(host, ""))
> + def->host_addr = strdup(host);
> + if (virStrToLong_i(port, NULL, 10, &def->host_port) < 0) {
> + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Cannot parse host port"));
> + goto error;
> + }
> +
> + port = strchr(guest, ':');
> + if (!port) {
> + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Missing guest port"));
> + goto error;
> + }
> + *port = '\0';
> + port++;
> + if (!STREQ(guest, ""))
> + def->guest_addr = strdup(guest);
> + if (virStrToLong_i(port, NULL, 10, &def->guest_port) < 0) {
> + qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("Cannot parse guest port"));
> + goto error;
> + }
> +
> + return def;
> +
> +error:
> + virDomainNetForwardDefFree(def);
> + return NULL;
> +}
> +
> /*
> * Tries to parse a QEMU -net backend argument. Gets given
> * a list of all known -net frontend arguments to try and
> @@ -6723,6 +6815,7 @@ qemuParseCommandLineNet(virCapsPtr caps,
> int wantvlan = 0;
> const char *tmp;
> int genmac = 1;
> + int nforward = 0;
> int i;
>
> tmp = strchr(val, ',');
> @@ -6769,9 +6862,31 @@ qemuParseCommandLineNet(virCapsPtr caps,
> STREQ(keywords[i], "ifname")) {
> def->ifname = values[i];
> values[i] = NULL;
> + } else if (def->type == VIR_DOMAIN_NET_TYPE_USER &&
> + STREQ(keywords[i], "hostfwd")) {
> + nforward++;
> }
> }
>
> + if (nforward > 0) {
> + if (VIR_ALLOC_N(def->data.user.forwards, nforward) < 0) {
> + virReportOOMError();
> + goto cleanup;
> + }
> +
> + for (i = 0 ; i < nkeywords ; i++) {
> + virDomainNetForwardDefPtr fwd;
> + if (def->type != VIR_DOMAIN_NET_TYPE_USER ||
> + !STREQ(keywords[i], "hostfwd"))
> + continue;
> +
> + if ((fwd = qemuParseNetForward(values[i])) == NULL)
> + goto cleanup;
> +
> + def->data.user.forwards[def->data.user.nforward] = fwd;
> + def->data.user.nforward++;
> + }
> + }
>
> /* Done parsing the nic backend. Now to try and find corresponding
> * frontend, based off vlan number. NB this assumes a 1-1 mapping
> diff --git a/tests/qemuargv2xmltest.c b/tests/qemuargv2xmltest.c
> index cf2862b..439218e 100644
> --- a/tests/qemuargv2xmltest.c
> +++ b/tests/qemuargv2xmltest.c
> @@ -207,8 +207,7 @@ mymain(void)
> DO_TEST("misc-acpi");
> DO_TEST("misc-no-reboot");
> DO_TEST("misc-uuid");
> - /* Fixed in following commit */
> - /* DO_TEST("net-user"); */
> + DO_TEST("net-user");
> DO_TEST("net-virtio");
> DO_TEST("net-eth");
> DO_TEST("net-eth-ifname");
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-user.args b/tests/qemuxml2argvdata/qemuxml2argv-net-user.args
> index 093ff01..db31e95 100644
> --- a/tests/qemuxml2argvdata/qemuxml2argv-net-user.args
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-net-user.args
> @@ -1,5 +1,6 @@
> LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
> pc -m 214 -smp 1 -nographic -monitor unix:/tmp/test-monitor,server,nowait \
> -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net nic,\
> -macaddr=00:11:22:33:44:55,vlan=0 -net user,vlan=0 -serial none -parallel none \
> --usb
> +macaddr=00:11:22:33:44:55,vlan=0 \
> +-net user,vlan=0,hostfwd=tcp::2222-:22,hostfwd=udp:127.0.0.1:2242-10.0.2.15:42 \
> +-serial none -parallel none -usb
> --
> 1.7.10.1
>
> --
> libvir-list mailing list
> libvir-list at redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
Reviewed-By: Hu Tao <hutao at cn.fujitsu.com>
--
Thanks,
Hu Tao
More information about the libvir-list
mailing list