Blob Blame History Raw
From a43609607abe30b973f1cb78cb1754f1a9a91514 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Mon, 22 Feb 2021 13:33:06 +0100
Subject: [PATCH 4/5] SR-IOV: fail on verification if `total_vfs` does not
 match vfs len

Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
---
 libnmstate/ifaces/ethernet.py | 11 +++++++++++
 libnmstate/ifaces/ifaces.py   | 17 +++++++++++++++++
 2 files changed, 28 insertions(+)

diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py
index 1c3ca266..4903bde7 100644
--- a/libnmstate/ifaces/ethernet.py
+++ b/libnmstate/ifaces/ethernet.py
@@ -52,6 +52,14 @@ class EthernetIface(BaseIface):
         _capitalize_sriov_vf_mac(state)
         return state
 
+    @property
+    def sriov_vfs(self):
+        return (
+            self.raw.get(Ethernet.CONFIG_SUBTREE, {})
+            .get(Ethernet.SRIOV_SUBTREE, {})
+            .get(Ethernet.SRIOV.VFS_SUBTREE, {})
+        )
+
     @property
     def sriov_total_vfs(self):
         return (
@@ -109,6 +117,9 @@ class EthernetIface(BaseIface):
             for i in range(self.sriov_total_vfs, old_sriov_total_vfs)
         ]
 
+    def check_total_vfs_matches_vf_list(self, total_vfs):
+        return total_vfs == len(self.sriov_vfs)
+
 
 def _capitalize_sriov_vf_mac(state):
     vfs = (
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
index b212ebb5..1d30d0c6 100644
--- a/libnmstate/ifaces/ifaces.py
+++ b/libnmstate/ifaces/ifaces.py
@@ -146,6 +146,11 @@ class Ifaces:
                         new_iface.mark_as_desired()
                         new_iface.mark_as_new_sr_iov_vf()
                         new_ifaces.append(new_iface)
+                    else:
+                        # When the VFs are being modified, all VFs link are
+                        # being removed from kernel and created again. Nmstate
+                        # must verify they have been created.
+                        self._ifaces[new_iface.name].mark_as_desired()
         for new_iface in new_ifaces:
             self._ifaces[new_iface.name] = new_iface
 
@@ -403,6 +408,18 @@ class Ifaces:
                                 cur_iface.state_for_verify(),
                             )
                         )
+                    elif (
+                        iface.type == InterfaceType.ETHERNET and iface.is_sriov
+                    ):
+                        if not cur_iface.check_total_vfs_matches_vf_list(
+                            iface.sriov_total_vfs
+                        ):
+                            raise NmstateVerificationError(
+                                "The NIC exceeded the waiting time for "
+                                "verification and it is failing because "
+                                "the `total_vfs` does not match the VF "
+                                "list length."
+                            )
 
     def gen_dns_metadata(self, dns_state, route_state):
         iface_metadata = dns_state.gen_metadata(self, route_state)
-- 
2.29.2