[virt-tools-list] [virt-manager PATCH 4/4 v2] network: add support to create SR-IOV VF pool

Lin Ma lma at suse.com
Mon Mar 27 02:22:34 UTC 2017


Create a network with a device pool containing all the VFs of an SR-IOV
device.

Signed-off-by: Lin Ma <lma at suse.com>
---
 tests/xmlparse-xml/network-vf-pool-in.xml  |   5 +
 tests/xmlparse-xml/network-vf-pool-out.xml |   6 ++
 tests/xmlparse.py                          |  21 ++++
 ui/createnet.ui                            |  92 ++++++++++++++++-
 virtManager/createnet.py                   | 153 ++++++++++++++++++++---------
 virtinst/network.py                        |  12 +++
 6 files changed, 240 insertions(+), 49 deletions(-)
 create mode 100644 tests/xmlparse-xml/network-vf-pool-in.xml
 create mode 100644 tests/xmlparse-xml/network-vf-pool-out.xml

diff --git a/tests/xmlparse-xml/network-vf-pool-in.xml b/tests/xmlparse-xml/network-vf-pool-in.xml
new file mode 100644
index 0000000..821aa07
--- /dev/null
+++ b/tests/xmlparse-xml/network-vf-pool-in.xml
@@ -0,0 +1,5 @@
+<network>
+  <name>passthrough</name>
+    <forward mode="hostdev" managed="yes">
+    </forward>
+</network>
diff --git a/tests/xmlparse-xml/network-vf-pool-out.xml b/tests/xmlparse-xml/network-vf-pool-out.xml
new file mode 100644
index 0000000..62a7305
--- /dev/null
+++ b/tests/xmlparse-xml/network-vf-pool-out.xml
@@ -0,0 +1,6 @@
+<network>
+  <name>new-foo</name>
+    <forward mode="hostdev" managed="yes">
+      <pf dev="eth3"/>
+    </forward>
+</network>
diff --git a/tests/xmlparse.py b/tests/xmlparse.py
index a7fe5dd..b8beebf 100644
--- a/tests/xmlparse.py
+++ b/tests/xmlparse.py
@@ -1293,6 +1293,27 @@ class XMLParseTest(unittest.TestCase):
         utils.diff_compare(net.get_xml_config(), outfile)
         utils.test_create(conn, net.get_xml_config(), "networkDefineXML")
 
+    def testNetVfPool(self):
+        basename = "network-vf-pool"
+        infile = "tests/xmlparse-xml/%s-in.xml" % basename
+        outfile = "tests/xmlparse-xml/%s-out.xml" % basename
+        net = virtinst.Network(conn, parsexml=file(infile).read())
+
+        check = self._make_checker(net)
+        check("name", "passthrough", "new-foo")
+
+        check = self._make_checker(net.forward)
+        check("mode", "hostdev")
+        check("managed", "yes")
+
+        r = net.forward.add_pf()
+        r.dev = "eth3"
+        check = self._make_checker(r)
+        check("dev", "eth3")
+
+        utils.diff_compare(net.get_xml_config(), outfile)
+        utils.test_create(conn, net.get_xml_config(), "networkDefineXML")
+
 
     ##############
     # Misc tests #
diff --git a/ui/createnet.ui b/ui/createnet.ui
index 161056b..7bbd326 100644
--- a/ui/createnet.ui
+++ b/ui/createnet.ui
@@ -1091,6 +1091,94 @@
                     <property name="can_focus">False</property>
                     <property name="spacing">6</property>
                     <child>
+                      <object class="GtkAlignment" id="alignment5">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="left_padding">15</property>
+                        <child>
+                          <object class="GtkBox" id="box14">
+                            <property name="visible">True</property>
+                            <property name="can_focus">False</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">6</property>
+                            <child>
+                              <object class="GtkRadioButton" id="net-sriov-vfs-pool">
+                                <property name="label" translatable="yes">_Pool containing all of VFs of a SR-IOV device</property>
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="receives_default">False</property>
+                                <property name="valign">start</property>
+                                <property name="use_underline">True</property>
+                                <property name="draw_indicator">True</property>
+                                <property name="group">net-forward-dev</property>
+                                <signal name="toggled" handler="on_net_forward_toggled" swapped="no"/>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkAlignment" id="alignment8">
+                                <property name="visible">True</property>
+                                <property name="can_focus">False</property>
+                                <property name="left_padding">25</property>
+                                <child>
+                                  <object class="GtkGrid" id="table36">
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">False</property>
+                                    <property name="row_spacing">4</property>
+                                    <property name="column_spacing">6</property>
+                                    <child>
+                                      <object class="GtkLabel" id="label393">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                        <property name="halign">start</property>
+                                        <property name="xalign">1</property>
+                                        <property name="label" translatable="yes">Device _List:</property>
+                                        <property name="use_underline">True</property>
+                                        <property name="mnemonic_widget">net-forward</property>
+                                      </object>
+                                      <packing>
+                                        <property name="left_attach">0</property>
+                                        <property name="top_attach">0</property>
+                                      </packing>
+                                    </child>
+                                    <child>
+                                      <object class="GtkComboBox" id="pf-list">
+                                        <property name="visible">True</property>
+                                        <property name="can_focus">False</property>
+                                      </object>
+                                      <packing>
+                                        <property name="left_attach">1</property>
+                                        <property name="top_attach">0</property>
+                                      </packing>
+                                    </child>
+                                  </object>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="fill">True</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                          <packing>
+                            <property name="expand">False</property>
+                            <property name="fill">True</property>
+                            <property name="position">0</property>
+                          </packing>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
                       <object class="GtkLabel" id="label205">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
@@ -1103,7 +1191,7 @@
                       <packing>
                         <property name="expand">False</property>
                         <property name="fill">False</property>
-                        <property name="position">0</property>
+                        <property name="position">1</property>
                       </packing>
                     </child>
                     <child>
@@ -1354,7 +1442,7 @@
                       <packing>
                         <property name="expand">True</property>
                         <property name="fill">True</property>
-                        <property name="position">1</property>
+                        <property name="position">2</property>
                       </packing>
                     </child>
                   </object>
diff --git a/virtManager/createnet.py b/virtManager/createnet.py
index 9fdbc45..2154df1 100644
--- a/virtManager/createnet.py
+++ b/virtManager/createnet.py
@@ -120,6 +120,12 @@ class vmmCreateNetwork(vmmGObjectUI):
         self.widget("header").modify_bg(Gtk.StateType.NORMAL, blue)
 
         # [ label, dev name ]
+        pf_list = self.widget("pf-list")
+        pf_model = Gtk.ListStore(str, str)
+        pf_list.set_model(pf_model)
+        uiutil.init_combo_text_column(pf_list, 0)
+
+        # [ label, dev name ]
         fw_list = self.widget("net-forward")
         fw_model = Gtk.ListStore(str, str)
         fw_list.set_model(fw_model)
@@ -167,6 +173,9 @@ class vmmCreateNetwork(vmmGObjectUI):
 
         self.widget("net-enable-ipv6-networking").set_active(False)
 
+        pf_model = self.widget("pf-list").get_model()
+        pf_model.clear()
+
         fw_model = self.widget("net-forward").get_model()
         fw_model.clear()
         fw_model.append([_("Any physical device"), None])
@@ -181,6 +190,26 @@ class vmmCreateNetwork(vmmGObjectUI):
         for name in devnames:
             fw_model.append([_("Physical device %s") % name, name])
 
+        devprettynames = []
+        ifnames = []
+        for pcidev in self.conn.filter_nodedevs("pci"):
+            if pcidev.xmlobj.capability_type == "virt_functions":
+                devdesc = pcidev.xmlobj.pretty_name()
+                for netdev in self.conn.filter_nodedevs("net"):
+                        if pcidev.xmlobj.name == netdev.xmlobj.parent:
+                            ifname = netdev.xmlobj.interface
+                            devprettyname = "%s (%s)" % (ifname, devdesc)
+                            devprettynames.append(devprettyname)
+                            ifnames.append(ifname)
+                            break
+        if not devprettynames:
+            pf_model.append([_("No available device"), None])
+        else:
+            for devprettyname, ifname in zip(devprettynames, ifnames):
+                pf_model.append([_("%s") % devprettyname, ifname])
+
+        self.widget("pf-list").set_active(0)
+
         self.widget("net-forward").set_active(0)
         self.widget("net-forward-mode").set_active(0)
         self.widget("net-forward-none").set_active(True)
@@ -223,6 +252,11 @@ class vmmCreateNetwork(vmmGObjectUI):
         return self._get_network_helper("net-dhcpv6-end")
 
     def get_config_forwarding(self):
+        if self.widget("net-sriov-vfs-pool").get_active():
+            name = uiutil.get_list_selection(self.widget("pf-list"), column=1)
+            mode = "hostdev"
+            return [name, mode]
+
         if self.widget("net-forward-none").get_active():
             return [None, None]
 
@@ -481,10 +515,27 @@ class vmmCreateNetwork(vmmGObjectUI):
             self.widget("create-finish").grab_focus()
 
     def change_forward_type(self, ignore):
-        skip_fwd = self.widget("net-forward-none").get_active()
+        index = self.widget("pf-list").get_active()
+        model = self.widget("pf-list").get_model()
+        item = model[index]
+        if item[0] == "No available device":
+            sriov_capable = False
+        else:
+            sriov_capable = True
+        self.widget("net-sriov-vfs-pool").set_sensitive(sriov_capable)
+        vf_pool = self.widget("net-sriov-vfs-pool").get_active()
+        if not vf_pool:
+            skip_fwd = self.widget("net-forward-none").get_active()
+
+            self.widget("net-forward-mode").set_sensitive(not skip_fwd)
+            self.widget("net-forward").set_sensitive(not skip_fwd)
+        else:
+            self.widget("net-forward-mode").set_sensitive(False)
+            self.widget("net-forward").set_sensitive(False)
 
-        self.widget("net-forward-mode").set_sensitive(not skip_fwd)
-        self.widget("net-forward").set_sensitive(not skip_fwd)
+        self.widget("table36").set_sensitive(vf_pool)
+        self.widget("box13").set_sensitive(not vf_pool)
+        self.widget("hbox6").set_sensitive(not vf_pool)
 
     def change_ipv4_enable(self, ignore):
         enabled = self.get_config_ipv4_enable()
@@ -676,56 +727,64 @@ class vmmCreateNetwork(vmmGObjectUI):
         net = self._build_xmlstub()
 
         net.name = self.widget("net-name").get_text()
-        net.domain_name = self.widget("net-domain-name").get_text() or None
-
-        if self.widget("net-enable-ipv6-networking").get_active():
-            net.ipv6 = True
 
         dev, mode = self.get_config_forwarding()
         if mode:
             net.forward.mode = mode
             net.forward.dev = dev or None
 
-        if self.get_config_ipv4_enable():
-            ip = self.get_config_ip4()
-            ipobj = net.add_ip()
-            ipobj.address = str(ip.network + 1)
-            ipobj.netmask = str(ip.netmask)
-
-            if self.get_config_dhcpv4_enable():
-                dhcpobj = ipobj.add_range()
-                dhcpobj.start = str(self.get_config_dhcpv4_start().network)
-                dhcpobj.end = str(self.get_config_dhcpv4_end().network)
-
-        if self.get_config_ipv6_enable():
-            ip = self.get_config_ip6()
-            ipobj = net.add_ip()
-            ipobj.family = "ipv6"
-            ipobj.address = str(ip.network + 1)
-            ipobj.prefix = str(ip.prefixlen)
-
-            if self.get_config_dhcpv6_enable():
-                dhcpobj = ipobj.add_range()
-                dhcpobj.start = str(self.get_config_dhcpv6_start().network)
-                dhcpobj.end = str(self.get_config_dhcpv6_end().network)
-
-        netaddr = _make_ipaddr(self.get_config_routev4_network())
-        gwaddr = _make_ipaddr(self.get_config_routev4_gateway())
-        if netaddr and gwaddr:
-            route = net.add_route()
-            route.family = "ipv4"
-            route.address = netaddr.network
-            route.prefix = netaddr.prefixlen
-            route.gateway = gwaddr.network
-
-        netaddr = _make_ipaddr(self.get_config_routev6_network())
-        gwaddr = _make_ipaddr(self.get_config_routev6_gateway())
-        if netaddr and gwaddr:
-            route = net.add_route()
-            route.family = "ipv6"
-            route.address = netaddr.network
-            route.prefix = netaddr.prefixlen
-            route.gateway = gwaddr.network
+        if net.forward.mode == "hostdev":
+            net.forward.managed = "yes"
+            pfobj = net.forward.add_pf()
+            pfobj.dev = net.forward.dev
+            net.forward.dev = None
+            net.domain_name = None
+        else:
+            net.domain_name = self.widget("net-domain-name").get_text() or None
+
+            if self.widget("net-enable-ipv6-networking").get_active():
+                net.ipv6 = True
+
+            if self.get_config_ipv4_enable():
+                ip = self.get_config_ip4()
+                ipobj = net.add_ip()
+                ipobj.address = str(ip.network + 1)
+                ipobj.netmask = str(ip.netmask)
+
+                if self.get_config_dhcpv4_enable():
+                    dhcpobj = ipobj.add_range()
+                    dhcpobj.start = str(self.get_config_dhcpv4_start().network)
+                    dhcpobj.end = str(self.get_config_dhcpv4_end().network)
+
+            if self.get_config_ipv6_enable():
+                ip = self.get_config_ip6()
+                ipobj = net.add_ip()
+                ipobj.family = "ipv6"
+                ipobj.address = str(ip.network + 1)
+                ipobj.prefix = str(ip.prefixlen)
+
+                if self.get_config_dhcpv6_enable():
+                    dhcpobj = ipobj.add_range()
+                    dhcpobj.start = str(self.get_config_dhcpv6_start().network)
+                    dhcpobj.end = str(self.get_config_dhcpv6_end().network)
+
+            netaddr = _make_ipaddr(self.get_config_routev4_network())
+            gwaddr = _make_ipaddr(self.get_config_routev4_gateway())
+            if netaddr and gwaddr:
+                route = net.add_route()
+                route.family = "ipv4"
+                route.address = netaddr.network
+                route.prefix = netaddr.prefixlen
+                route.gateway = gwaddr.network
+
+            netaddr = _make_ipaddr(self.get_config_routev6_network())
+            gwaddr = _make_ipaddr(self.get_config_routev6_gateway())
+            if netaddr and gwaddr:
+                route = net.add_route()
+                route.family = "ipv6"
+                route.address = netaddr.network
+                route.prefix = netaddr.prefixlen
+                route.gateway = gwaddr.network
 
         return net
 
diff --git a/virtinst/network.py b/virtinst/network.py
index 457afa0..dfc1436 100644
--- a/virtinst/network.py
+++ b/virtinst/network.py
@@ -72,11 +72,23 @@ class _NetworkRoute(XMLBuilder):
     netmask = XMLProperty("./@netmask")
 
 
+class _NetworkForwardPf(XMLBuilder):
+    _XML_ROOT_NAME = "pf"
+    dev = XMLProperty("./@dev")
+
+
 class _NetworkForward(XMLBuilder):
     _XML_ROOT_NAME = "forward"
 
     mode = XMLProperty("./@mode")
     dev = XMLProperty("./@dev")
+    managed = XMLProperty("./@managed")
+    pf = XMLChildProperty(_NetworkForwardPf)
+
+    def add_pf(self):
+        r = _NetworkForwardPf(self.conn)
+        self.add_child(r)
+        return r
 
     def pretty_desc(self):
         return Network.pretty_forward_desc(self.mode, self.dev)
-- 
2.9.2




More information about the virt-tools-list mailing list