[PATCH] Expose SLIRP attributes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



We allow users to use SLIRP stack. However, there are some knobs
which are not exposed to users, such as host network address, DNS
server, smb, and others.

Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx>
---
 docs/formatdomain.html.in                          |  7 +-
 docs/schemas/domaincommon.rng                      | 23 +++++-
 src/conf/domain_conf.c                             | 88 ++++++++++++++++++++++
 src/conf/domain_conf.h                             |  6 ++
 src/qemu/qemu_command.c                            | 19 +++++
 .../qemuxml2argvdata/qemuxml2argv-net-user-ip.args |  7 ++
 .../qemuxml2argvdata/qemuxml2argv-net-user-ip.xml  | 33 ++++++++
 tests/qemuxml2argvtest.c                           |  1 +
 8 files changed, 180 insertions(+), 4 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-user-ip.args
 create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-user-ip.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 7f90455..0a353ca 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3225,7 +3225,11 @@
       starting from <code>10.0.2.15</code>. The default router will be
       <code>10.0.2.2</code> and the DNS server will be <code>10.0.2.3</code>.
       This networking is the only option for unprivileged users who need their
-      VMs to have outgoing access.
+      VMs to have outgoing access. <span class="since">Since 1.2.3</span> the
+      user network can have the &lt;ip/&gt; element to override the default
+      network of <code>10.0.2.0/24</code>. For example it can be set to
+      <code>192.168.2.0/24</code>. The whole element and its attributes are
+      optional.
     </p>
 
 <pre>
@@ -3235,6 +3239,7 @@
     ...
     &lt;interface type='user'&gt;
       &lt;mac address="00:11:22:33:44:55"/&gt;
+      &lt;ip address="192.168.2.0" prefix="24" dns="192.168.2.3" dhcpstart="192.168.2.9"/&gt;
     &lt;/interface&gt;
   &lt;/devices&gt;
   ...</pre>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index bcd8142..5745ce7 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2152,9 +2152,26 @@
       </optional>
       <optional>
         <element name="ip">
-          <attribute name="address">
-            <ref name="ipv4Addr"/>
-          </attribute>
+          <optional>
+            <attribute name="address">
+              <ref name="ipv4Addr"/>
+            </attribute>
+          </optional>
+          <optional>
+            <attribute name="prefix">
+              <data type="integer"/>
+            </attribute>
+          </optional>
+          <optional>
+            <attribute name="dns">
+              <ref name="ipv4Addr"/>
+            </attribute>
+          </optional>
+          <optional>
+            <attribute name="dhcpstart">
+              <ref name="ipv4Addr"/>
+            </attribute>
+          </optional>
           <empty/>
         </element>
       </optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 6fb216e..aec14ed 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1539,6 +1539,11 @@ void virDomainNetDefFree(virDomainNetDefPtr def)
         break;
 
     case VIR_DOMAIN_NET_TYPE_USER:
+        VIR_FREE(def->data.user.ipaddr);
+        VIR_FREE(def->data.user.dns);
+        VIR_FREE(def->data.user.dhcpstart);
+        break;
+
     case VIR_DOMAIN_NET_TYPE_LAST:
         break;
     }
@@ -6669,6 +6674,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     char *mode = NULL;
     char *linkstate = NULL;
     char *addrtype = NULL;
+    char *prefix = NULL;
+    char *dns = NULL;
+    char *dhcpstart = NULL;
     virNWFilterHashTablePtr filterparams = NULL;
     virDomainActualNetDefPtr actual = NULL;
     xmlNodePtr oldnode = ctxt->node;
@@ -6750,6 +6758,13 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
                         def->type == VIR_DOMAIN_NET_TYPE_BRIDGE) &&
                        xmlStrEqual(cur->name, BAD_CAST "ip")) {
                 address = virXMLPropString(cur, "address");
+            } else if (!address &&
+                       def->type == VIR_DOMAIN_NET_TYPE_USER &&
+                       xmlStrEqual(cur->name, BAD_CAST "ip")) {
+                address = virXMLPropString(cur, "address");
+                prefix = virXMLPropString(cur, "prefix");
+                dns = virXMLPropString(cur, "dns");
+                dhcpstart = virXMLPropString(cur, "dhcpstart");
             } else if (!ifname &&
                        xmlStrEqual(cur->name, BAD_CAST "target")) {
                 ifname = virXMLPropString(cur, "dev");
@@ -6988,6 +7003,59 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
         break;
 
     case VIR_DOMAIN_NET_TYPE_USER:
+        if (prefix) {
+            if (!address) {
+                virReportError(VIR_ERR_XML_ERROR, "%s",
+                               _("can't use prefix without an address"));
+                goto error;
+            }
+
+            if (virStrToLong_i(prefix, NULL, 10, &def->data.user.prefix) < 0 ||
+                def->data.user.prefix < 0) {
+                virReportError(VIR_ERR_XML_ERROR,
+                               _("Invalid prefix: '%s'"), prefix);
+                goto error;
+            }
+        } else {
+            def->data.user.prefix = -1;
+        }
+
+        if (address) {
+            if (virSocketAddrParse(NULL, address, AF_UNSPEC) < 0) {
+                virReportError(VIR_ERR_XML_ERROR,
+                               _("Invalid address: '%s'"), address);
+                goto error;
+            }
+
+            def->data.user.ipaddr =  address;
+            address = NULL;
+        }
+
+        if (dns) {
+            if (virSocketAddrParse(NULL, dns, AF_UNSPEC) < 0) {
+                virReportError(VIR_ERR_XML_ERROR,
+                               _("Invalid dns address: '%s'"), dns);
+                goto error;
+            }
+
+            def->data.user.dns = dns;
+            dns = NULL;
+        }
+
+        if (dhcpstart) {
+            if (virSocketAddrParse(NULL, dhcpstart, AF_UNSPEC) < 0) {
+                virReportError(VIR_ERR_XML_ERROR,
+                               _("Invalid dhcpstart address: '%s'"),
+                               dhcpstart);
+                goto error;
+            }
+
+            def->data.user.dhcpstart = dhcpstart;
+            dhcpstart = NULL;
+        }
+
+        break;
+
     case VIR_DOMAIN_NET_TYPE_LAST:
         break;
     }
@@ -7134,6 +7202,9 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     VIR_FREE(mode);
     VIR_FREE(linkstate);
     VIR_FREE(addrtype);
+    VIR_FREE(prefix);
+    VIR_FREE(dns);
+    VIR_FREE(dhcpstart);
     virNWFilterHashTableFree(filterparams);
 
     return def;
@@ -15766,6 +15837,23 @@ virDomainNetDefFormat(virBufferPtr buf,
             break;
 
         case VIR_DOMAIN_NET_TYPE_USER:
+            if (def->data.user.ipaddr ||
+                def->data.user.dns ||
+                def->data.user.dhcpstart) {
+                virBufferAddLit(buf, "<ip");
+
+                if (def->data.user.ipaddr) {
+                    virBufferAsprintf(buf, " address='%s'", def->data.user.ipaddr);
+                    if (def->data.user.prefix >= 0)
+                        virBufferAsprintf(buf, " prefix='%d'", def->data.user.prefix);
+                }
+
+                virBufferEscapeString(buf, " dns='%s'", def->data.user.dns);
+                virBufferEscapeString(buf, " dhcpstart='%s'", def->data.user.dhcpstart);
+                virBufferAddLit(buf, "/>\n");
+            }
+            break;
+
         case VIR_DOMAIN_NET_TYPE_LAST:
             break;
         }
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index f3f24c4..b5d52e9 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1046,6 +1046,12 @@ struct _virDomainNetDef {
         struct {
             virDomainHostdevDef def;
         } hostdev;
+        struct {
+            char *ipaddr;
+            int prefix;
+            char *dns;
+            char *dhcpstart;
+        } user;
     } data;
     /* virtPortProfile is used by network/bridge/direct/hostdev */
     virNetDevVPortProfilePtr virtPortProfile;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9a314bf..f17061e 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5156,6 +5156,25 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
        break;
 
     case VIR_DOMAIN_NET_TYPE_USER:
+       virBufferAddLit(&buf, "user");
+       if (net->data.user.ipaddr) {
+           virBufferAsprintf(&buf, "%cnet=%s", type_sep,
+                             net->data.user.ipaddr);
+           type_sep = ',';
+           if (net->data.user.prefix >= 0)
+               virBufferAsprintf(&buf, "/%d", net->data.user.prefix);
+       }
+       if (net->data.user.dns) {
+           virBufferAsprintf(&buf, "%cdns=%s", type_sep, net->data.user.dns);
+           type_sep = ',';
+       }
+       if (net->data.user.dhcpstart) {
+           virBufferAsprintf(&buf, "%cdhcpstart=%s", type_sep,
+                             net->data.user.dhcpstart);
+           type_sep = ',';
+       }
+       break;
+
     default:
         virBufferAddLit(&buf, "user");
         break;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-user-ip.args b/tests/qemuxml2argvdata/qemuxml2argv-net-user-ip.args
new file mode 100644
index 0000000..3e355f3
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-user-ip.args
@@ -0,0 +1,7 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
+/usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic \
+-monitor unix:/tmp/test-monitor,server,nowait \
+-no-acpi -boot c -usb -hda /dev/HostVG/QEMUGuest1 \
+-net nic,macaddr=00:11:22:33:44:55,vlan=0,model=rtl8139 \
+-net user,net=192.168.2.0/24,dns=192.168.2.3,dhcpstart=192.168.2.9,vlan=0 \
+-serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-net-user-ip.xml b/tests/qemuxml2argvdata/qemuxml2argv-net-user-ip.xml
new file mode 100644
index 0000000..5c36c77
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-net-user-ip.xml
@@ -0,0 +1,33 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219136</memory>
+  <currentMemory unit='KiB'>219136</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu</emulator>
+    <disk type='block' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <controller type='ide' index='0'/>
+    <controller type='pci' index='0' model='pci-root'/>
+    <interface type='user'>
+      <ip address='192.168.2.0' prefix='24' dns='192.168.2.3' dhcpstart='192.168.2.9'/>
+      <mac address='00:11:22:33:44:55'/>
+      <model type='rtl8139'/>
+    </interface>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 56854dc..02ed4ba 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -923,6 +923,7 @@ mymain(void)
     DO_TEST("misc-no-reboot", NONE);
     DO_TEST("misc-uuid", QEMU_CAPS_NAME, QEMU_CAPS_UUID);
     DO_TEST("net-user", NONE);
+    DO_TEST("net-user-ip", NONE);
     DO_TEST("net-virtio", NONE);
     DO_TEST("net-virtio-device",
             QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_VIRTIO_TX_ALG);
-- 
1.9.0

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]