import nmstate-1.2.1-1.el8

This commit is contained in:
CentOS Sources 2022-05-10 02:59:45 -04:00 committed by Stepan Oksanichenko
parent 89ef9e596d
commit dc622a1561
13 changed files with 101 additions and 957 deletions

3
.gitignore vendored
View File

@ -1,2 +1,3 @@
SOURCES/nmstate-1.1.0.tar.gz
SOURCES/nmstate-1.2.1.tar.gz
SOURCES/nmstate-rust-vendor-1.2.1.tar.xz
SOURCES/nmstate.gpg

View File

@ -1,2 +1,3 @@
0b7795853d1f7735cb05817389f188884d1f6f09 SOURCES/nmstate-1.1.0.tar.gz
d47ab133f1d83391a6b617e1674fe2dec92bf536 SOURCES/nmstate-1.2.1.tar.gz
ee514e17040057d2e83efaf16c2f9779cfe42e8b SOURCES/nmstate-rust-vendor-1.2.1.tar.xz
b5f872551d434e2c62b30d70471efaeede83ab44 SOURCES/nmstate.gpg

View File

@ -1,53 +0,0 @@
From 99c7f643bab33a26c317e1b72ca3b8490cb1ea60 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Fri, 16 Jul 2021 08:57:27 +0200
Subject: [PATCH 1/4] nmstatectl: fix long arguments support
The support for long arguments is broken. This patch is fixing it and
solving the following errors:
```
[root@d0b4a6a0f7a5 nmstate-workspace]# nmstatectl show --running-config
usage: nmstatectl [-h] [--version]
{commit,edit,rollback,set,apply,show,version,gc} ...
nmstatectl: error: unrecognized arguments: --running-config
[root@d0b4a6a0f7a5 nmstate-workspace]# nmstatectl show --show-secrets
usage: nmstatectl [-h] [--version]
{commit,edit,rollback,set,apply,show,version,gc} ...
nmstatectl: error: unrecognized arguments: --show-secrets
```
Integration test case added.
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: Gris Ge <fge@redhat.com>
---
nmstatectl/nmstatectl.py | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/nmstatectl/nmstatectl.py b/nmstatectl/nmstatectl.py
index a9f4cb6..6f83069 100644
--- a/nmstatectl/nmstatectl.py
+++ b/nmstatectl/nmstatectl.py
@@ -223,14 +223,16 @@ def setup_subcommand_show(subparsers):
dest="yaml",
)
parser_show.add_argument(
- "-r, --running-config",
+ "-r",
+ "--running-config",
help="Show running configurations",
default=False,
action="store_true",
dest="running_config",
)
parser_show.add_argument(
- "-s, --show-secrets",
+ "-s",
+ "--show-secrets",
help="Show secrets also",
default=False,
action="store_true",
--
2.32.0

View File

@ -1,105 +0,0 @@
From b1cb57d1dc4bba6592ba5cfc5c810a2ad19ac941 Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Thu, 22 Jul 2021 18:40:50 +0800
Subject: [PATCH 2/4] nm ethtool: Preserve existing ethtool settings when
undesired
When user does not define ethtool settings in desire state,
we should preserve existing ethtool setting.
Integration test case included.
Signed-off-by: Gris Ge <fge@redhat.com>
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
---
libnmstate/nm/connection.py | 18 +++---------------
libnmstate/nm/ethtool.py | 26 +++++++++++++++++++++++++-
2 files changed, 28 insertions(+), 16 deletions(-)
diff --git a/libnmstate/nm/connection.py b/libnmstate/nm/connection.py
index 5d60f6d..5a79c6f 100644
--- a/libnmstate/nm/connection.py
+++ b/libnmstate/nm/connection.py
@@ -22,8 +22,6 @@
import uuid
from libnmstate.error import NmstatePluginError
-from libnmstate.ifaces import IfaceEthtool
-from libnmstate.schema import Ethtool
from libnmstate.schema import Interface
from libnmstate.schema import InterfaceType
from libnmstate.schema import LinuxBridge as LB
@@ -240,19 +238,9 @@ def create_new_nm_simple_conn(iface, nm_profile):
if iface.ieee_802_1x_conf:
settings.append(create_802_1x_setting(iface.ieee_802_1x_conf))
- if Ethtool.CONFIG_SUBTREE in iface.original_desire_dict:
- iface_ethtool = IfaceEthtool(
- iface.original_desire_dict[Ethtool.CONFIG_SUBTREE]
- )
- iface_ethtool.canonicalize(
- iface.original_desire_dict[Ethtool.CONFIG_SUBTREE]
- )
- setting = create_ethtool_setting(
- iface_ethtool,
- nm_profile,
- )
- if setting:
- settings.append(setting)
+ ethtool_setting = create_ethtool_setting(iface, nm_profile)
+ if ethtool_setting:
+ settings.append(ethtool_setting)
nm_simple_conn = NM.SimpleConnection.new()
for setting in settings:
diff --git a/libnmstate/nm/ethtool.py b/libnmstate/nm/ethtool.py
index 466f4f9..3cad1bf 100644
--- a/libnmstate/nm/ethtool.py
+++ b/libnmstate/nm/ethtool.py
@@ -22,6 +22,7 @@ import logging
from .common import NM
from .common import GLib
+from libnmstate.ifaces import IfaceEthtool
from libnmstate.schema import Ethtool
@@ -59,7 +60,7 @@ _NM_COALESCE_OPT_NAME_MAP = {
}
-def create_ethtool_setting(iface_ethtool, base_con_profile):
+def _create_ethtool_setting(iface_ethtool, base_con_profile):
nm_setting = None
if base_con_profile:
@@ -159,3 +160,26 @@ def nm_set_pause(nm_setting, autoneg, rx, tx):
tx_value,
)
# pylint: enable=no-member
+
+
+def create_ethtool_setting(iface, base_con_profile):
+ if Ethtool.CONFIG_SUBTREE in iface.original_desire_dict:
+ iface_ethtool = IfaceEthtool(
+ iface.original_desire_dict[Ethtool.CONFIG_SUBTREE]
+ )
+ iface_ethtool.canonicalize(
+ iface.original_desire_dict[Ethtool.CONFIG_SUBTREE]
+ )
+ return _create_ethtool_setting(
+ iface_ethtool,
+ base_con_profile,
+ )
+ else:
+ # Preserve existing setting but not create new
+ if base_con_profile:
+ ethtool_setting = base_con_profile.get_setting_by_name(
+ NM.SETTING_ETHTOOL_SETTING_NAME
+ )
+ if ethtool_setting:
+ return ethtool_setting.duplicate()
+ return None
--
2.32.0

View File

@ -1,87 +0,0 @@
From f4d190653c55d399b32afc956b2b4a1ff8d20101 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Mon, 26 Jul 2021 09:58:23 +0200
Subject: [PATCH 3/4] ovs: fix state=ignore for ovs port when removing them
When removing an ovs port while the interface is marked as ignored, the
interface should not being removed from the ovs bridge as the user
specidied it should be ignored.
Example:
```
interfaces:
- name: dummy0
type: dummy
state: ignore
- name: ovsbr0
type: ovs-bridge
state: up
bridge:
port:
- name: ovs0
```
Integration test case added.
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: Gris Ge <fge@redhat.com>
---
libnmstate/nm/profiles.py | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/libnmstate/nm/profiles.py b/libnmstate/nm/profiles.py
index beda5c7..3b0b6be 100644
--- a/libnmstate/nm/profiles.py
+++ b/libnmstate/nm/profiles.py
@@ -23,6 +23,8 @@
import logging
from operator import attrgetter
+from libnmstate.schema import Interface
+from libnmstate.schema import InterfaceState
from libnmstate.schema import InterfaceType
from .common import NM
@@ -359,7 +361,7 @@ def _delete_orphan_nm_ovs_port_profiles(
continue
# When OVS port has no child, delete it
ovs_bridge_iface = ovs_bridge_profile.iface
- if not _nm_ovs_port_has_child(
+ if not _nm_ovs_port_has_child_or_is_ignored(
nm_profile, ovs_bridge_iface, net_state
):
ProfileDelete(
@@ -404,7 +406,9 @@ def _use_uuid_as_controller_and_parent(nm_profiles):
nm_profile.update_parent(uuid)
-def _nm_ovs_port_has_child(nm_profile, ovs_bridge_iface, net_state):
+def _nm_ovs_port_has_child_or_is_ignored(
+ nm_profile, ovs_bridge_iface, net_state
+):
ovs_port_uuid = nm_profile.get_uuid()
ovs_port_name = nm_profile.get_interface_name()
for ovs_iface_name in ovs_bridge_iface.port:
@@ -415,4 +419,18 @@ def _nm_ovs_port_has_child(nm_profile, ovs_bridge_iface, net_state):
and ovs_iface.controller_type == InterfaceType.OVS_PORT
):
return True
+ # Gather the ovs bridge interface from the current state in order to check
+ # if any port is ignored in the original desired state.
+ current_ovs_bridge = net_state.ifaces.get_cur_iface(
+ ovs_bridge_iface.name, InterfaceType.OVS_BRIDGE
+ )
+ if current_ovs_bridge:
+ for port_name in current_ovs_bridge.port:
+ port_iface = net_state.ifaces.all_kernel_ifaces.get(port_name)
+ if (
+ port_iface
+ and port_iface.original_desire_dict.get(Interface.STATE)
+ == InterfaceState.IGNORE
+ ):
+ return True
return False
--
2.32.0

View File

@ -1,86 +0,0 @@
From 369ed3210ecedfa1deda88a6eb7cacc19a47f89d Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Mon, 26 Jul 2021 16:13:15 +0200
Subject: [PATCH 4/4] nispor: fix show of empty next_hop_address and
destination
The correct way of representing an empty next_hop_address is using
"0.0.0.0" for IPv4 and "::" for IPv6. This configuration is valid
because an user should be able to specify the following routes:
```
---
routes:
config:
- destination: 0.0.0.0/0
next-hop-address: 0.0.0.0
next-hop-interface: dummy
- destination: ::/0
next-hop-address: "::"
next-hop-interface: dummy
```
That means each of the hosts within the range of the route are
considered to be directly connected through that interface.
For example, using iproute2 the user should introduce the following
command:
`ip route 0.0.0.0 0.0.0.0 dummy`
Integration test case added.
Ref: https://bugzilla.redhat.com/1985879
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: Gris Ge <fge@redhat.com>
---
libnmstate/nispor/route.py | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/libnmstate/nispor/route.py b/libnmstate/nispor/route.py
index 510ddc3..9852ba5 100644
--- a/libnmstate/nispor/route.py
+++ b/libnmstate/nispor/route.py
@@ -23,6 +23,9 @@ from libnmstate.schema import Route
IPV4_DEFAULT_GATEWAY_DESTINATION = "0.0.0.0/0"
IPV6_DEFAULT_GATEWAY_DESTINATION = "::/0"
+IPV4_EMPTY_NEXT_HOP_ADDRESS = "0.0.0.0"
+IPV6_EMPTY_NEXT_HOP_ADDRESS = "::"
+
LOCAL_ROUTE_TABLE = 255
@@ -50,21 +53,23 @@ def nispor_route_state_to_nmstate_static(np_routes):
def _nispor_route_to_nmstate(np_rt):
if np_rt.dst:
destination = np_rt.dst
- elif np_rt.gateway:
+ else:
destination = (
IPV6_DEFAULT_GATEWAY_DESTINATION
if np_rt.address_family == "ipv6"
else IPV4_DEFAULT_GATEWAY_DESTINATION
)
- else:
- destination = ""
if np_rt.via:
next_hop = np_rt.via
elif np_rt.gateway:
next_hop = np_rt.gateway
else:
- next_hop = ""
+ next_hop = (
+ IPV6_EMPTY_NEXT_HOP_ADDRESS
+ if np_rt.address_family == "ipv6"
+ else IPV4_EMPTY_NEXT_HOP_ADDRESS
+ )
return {
Route.TABLE_ID: np_rt.table,
--
2.32.0

View File

@ -1,45 +0,0 @@
From daad0a535b370d0a3f847526185c185aca2d9935 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Thu, 2 Sep 2021 11:33:14 +0200
Subject: [PATCH] nm.connection: do not rename existing connections
When an user is specifying a custom name for a connection and then use
Nmstate to modify the interface, it will be renamed. That makes
impossible to use other automation tools because it will require to use
the uuid instead.
Integration test case added.
Ref: https://bugzilla.redhat.com/1998222
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: Gris Ge <fge@redhat.com>
---
libnmstate/nm/connection.py | 4 ----
1 file changed, 4 deletions(-)
diff --git a/libnmstate/nm/connection.py b/libnmstate/nm/connection.py
index 5a79c6f..39eb2b5 100644
--- a/libnmstate/nm/connection.py
+++ b/libnmstate/nm/connection.py
@@ -98,9 +98,6 @@ class _ConnectionSetting:
self._setting.props.master = controller
self._setting.props.slave_type = port_type
- def set_profile_name(self, con_name):
- self._setting.props.id = con_name
-
@property
def setting(self):
return self._setting
@@ -116,7 +113,6 @@ def create_new_nm_simple_conn(iface, nm_profile):
con_setting = _ConnectionSetting()
if nm_profile and not is_multiconnect_profile(nm_profile):
con_setting.import_by_profile(nm_profile, iface.is_controller)
- con_setting.set_profile_name(iface.name)
else:
con_setting.create(
iface.name, iface.name, nm_iface_type, iface.is_controller
--
2.27.0

View File

@ -1,110 +0,0 @@
From cd41c2c0f6bef7b952648b358246fffa8ce3cf62 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Thu, 2 Sep 2021 17:39:59 +0200
Subject: [PATCH 1/2] nm.connection: add postfixes to OVS bridges and
interfaces connections
When configuring an OVS bridge and interface with the same using
Nmstate, it will generate two connection with the same name. If the user
is willing to use nmcli to manage this profiles, it is not user friendly
because they will need to use the connection UUID instead.
In order to solve this, Nmstate is adding a postfix on the connection
name. "-if" for OVS interface and "-br" for OVS bridge.
Please, note that this issue does not affect kernel interfaces because
it is not possible to have duplicated interfaces names in kernel.
Integration test case added.
Ref: https://bugzilla.redhat.com/1998218
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
Signed-off-by: Gris Ge <fge@redhat.com>
---
libnmstate/nm/connection.py | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/libnmstate/nm/connection.py b/libnmstate/nm/connection.py
index 39eb2b5..afe3788 100644
--- a/libnmstate/nm/connection.py
+++ b/libnmstate/nm/connection.py
@@ -114,8 +114,20 @@ def create_new_nm_simple_conn(iface, nm_profile):
if nm_profile and not is_multiconnect_profile(nm_profile):
con_setting.import_by_profile(nm_profile, iface.is_controller)
else:
+ # OVS bridge and interfaces could sharing the same interface name, to
+ # distinguish them at NM connection level, instead of using interface
+ # name as connection name, we append a postfix.
+ con_name = iface.name
+ if iface.type == InterfaceType.OVS_BRIDGE:
+ con_name = con_name + "-br"
+ elif iface.type == InterfaceType.OVS_INTERFACE:
+ con_name = con_name + "-if"
+
con_setting.create(
- iface.name, iface.name, nm_iface_type, iface.is_controller
+ con_name,
+ iface.name,
+ nm_iface_type,
+ iface.is_controller,
)
apply_lldp_setting(con_setting, iface_info)
--
2.27.0
From cfdd5afb1ef136d613d5adb3f6f5f6d156962586 Mon Sep 17 00:00:00 2001
From: Radim Hrazdil <rhrazdil@redhat.com>
Date: Wed, 10 Nov 2021 16:57:08 +0100
Subject: [PATCH 2/2] ovs: remove ovs-port prefix
Prepending the prefix causes ovnkube-node pods to crash.
This change adds -port postfix to ovs-interface connection instead.
Signed-off-by: Radim Hrazdil <rhrazdil@redhat.com>
Signed-off-by: Gris Ge <fge@redhat.com>
---
libnmstate/nm/connection.py | 2 ++
libnmstate/nm/ovs.py | 4 +---
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/libnmstate/nm/connection.py b/libnmstate/nm/connection.py
index afe3788..fb4ceba 100644
--- a/libnmstate/nm/connection.py
+++ b/libnmstate/nm/connection.py
@@ -122,6 +122,8 @@ def create_new_nm_simple_conn(iface, nm_profile):
con_name = con_name + "-br"
elif iface.type == InterfaceType.OVS_INTERFACE:
con_name = con_name + "-if"
+ elif iface.type == InterfaceType.OVS_PORT:
+ con_name = con_name + "-port"
con_setting.create(
con_name,
diff --git a/libnmstate/nm/ovs.py b/libnmstate/nm/ovs.py
index 424df36..9f2cba0 100644
--- a/libnmstate/nm/ovs.py
+++ b/libnmstate/nm/ovs.py
@@ -32,8 +32,6 @@ from libnmstate.schema import OvsDB
from .common import NM
-PORT_PROFILE_PREFIX = "ovs-port-"
-
CONTROLLER_TYPE_METADATA = "_controller_type"
CONTROLLER_METADATA = "_controller"
SETTING_OVS_EXTERNALIDS = "SettingOvsExternalIDs"
@@ -311,7 +309,7 @@ def create_iface_for_nm_ovs_port(iface):
if ovs.is_ovs_lag_port(port_options):
port_name = port_options[OB.Port.NAME]
else:
- port_name = PORT_PROFILE_PREFIX + iface_name
+ port_name = iface_name
return OvsPortIface(
{
Interface.NAME: port_name,
--
2.27.0

View File

@ -1,326 +0,0 @@
From b8e3c6928c2a22a828b85a6780de3cea1107aa85 Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Fri, 24 Dec 2021 16:34:30 +0800
Subject: [PATCH] sriov: New way to wait VF been created
By checking `/sys/class/net/<pf_name>/device/virtfn<sriov_id>/net/`
we could tell the interface name of VF.
The old VF name guessing method is removed. The `verify_sriov_vf()` is
created to collect all VF interfaces name, then comparing it with
`total_vfs` count and check whether they exists in current state.
The test indicate kernel/udev does not require extra time to remove VF
interface when decreasing SR-IOV VF count.
Signed-off-by: Gris Ge <fge@redhat.com>
---
libnmstate/ifaces/ethernet.py | 100 +++++++++++++++-------------------
libnmstate/ifaces/ifaces.py | 44 +--------------
libnmstate/nispor/ethernet.py | 17 ++++++
libnmstate/nm/profiles.py | 1 -
libnmstate/nm/sriov.py | 5 +-
5 files changed, 67 insertions(+), 100 deletions(-)
diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py
index 84fc665..720deab 100644
--- a/libnmstate/ifaces/ethernet.py
+++ b/libnmstate/ifaces/ethernet.py
@@ -17,10 +17,9 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
+from libnmstate.error import NmstateVerificationError
from libnmstate.schema import Ethernet
-from libnmstate.schema import Interface
from libnmstate.schema import InterfaceType
-from libnmstate.schema import InterfaceState
from .base_iface import BaseIface
@@ -30,7 +29,7 @@ MULTIPORT_PCI_DEVICE_PREFIX = "n"
class EthernetIface(BaseIface):
- IS_GENERATED_VF_METADATA = "_is_generated_vf"
+ VF_IFACE_NAME_METADATA = "_vf_iface_name"
def __init__(self, info, save_to_disk=True):
super().__init__(info, save_to_disk)
@@ -56,10 +55,6 @@ class EthernetIface(BaseIface):
state = super().state_for_verify()
_capitalize_sriov_vf_mac(state)
EthernetIface._canonicalize(state)
- if self.is_generated_vf:
- # The VF state is unpredictable when PF is changing total_vfs count
- # Just don't verify generated VF state.
- state.pop(Interface.STATE, None)
return state
@property
@@ -102,54 +97,6 @@ class EthernetIface(BaseIface):
def duplex(self):
return self.raw.get(Ethernet.CONFIG_SUBTREE, {}).get(Ethernet.DUPLEX)
- def create_sriov_vf_ifaces(self):
- # Currently there is not a way to see the relation between a SR-IOV PF
- # and its VFs. Broadcom BCM57416 follows a different name pattern for
- # PF and VF, therefore it needs to be parsed if present.
- #
- # PF name: ens2f0np0
- # VF name: ens2f0v0
- #
- # The different name pattern is due to:
- # 1. The `n` is for `multi-port PCI device` support.
- # 2. The `p*` is `phys_port_name` provided by the BCM driver
- # `bnxt_en`.
- #
- # If the NIC is following the standard pattern "pfname+v+vfid", this
- # split will not touch it and the vf_pattern will be the PF name.
- # Ref: https://bugzilla.redhat.com/1959679
- vf_pattern = self.name
- multiport_pattern = (
- MULTIPORT_PCI_DEVICE_PREFIX + BNXT_DRIVER_PHYS_PORT_PREFIX
- )
- if len(self.name.split(multiport_pattern)) == 2:
- vf_pattern = self.name.split(multiport_pattern)[0]
-
- vf_ifaces = [
- EthernetIface(
- {
- # According to manpage of systemd.net-naming-scheme(7),
- # SRIOV VF interface will have v{slot} in device name.
- # Currently, nmstate has no intention to support
- # user-defined udev rule on SRIOV interface naming policy.
- Interface.NAME: f"{vf_pattern}v{i}",
- Interface.TYPE: InterfaceType.ETHERNET,
- # VF will be in DOWN state initialy
- Interface.STATE: InterfaceState.DOWN,
- }
- )
- for i in range(0, self.sriov_total_vfs)
- ]
- # The generated vf metadata cannot be part of the original dict.
- for vf in vf_ifaces:
- vf._info[EthernetIface.IS_GENERATED_VF_METADATA] = True
-
- return vf_ifaces
-
- @property
- def is_generated_vf(self):
- return self._info.get(EthernetIface.IS_GENERATED_VF_METADATA) is True
-
def remove_vfs_entry_when_total_vfs_decreased(self):
vfs_count = len(
self._info[Ethernet.CONFIG_SUBTREE]
@@ -173,6 +120,16 @@ class EthernetIface(BaseIface):
def check_total_vfs_matches_vf_list(self, total_vfs):
return total_vfs == len(self.sriov_vfs)
+ def to_dict(self):
+ info = super().to_dict()
+ for vf_info in (
+ info.get(Ethernet.CONFIG_SUBTREE, {})
+ .get(Ethernet.SRIOV_SUBTREE, {})
+ .get(Ethernet.SRIOV.VFS_SUBTREE, [])
+ ):
+ vf_info.pop(EthernetIface.VF_IFACE_NAME_METADATA, None)
+ return info
+
def _capitalize_sriov_vf_mac(state):
vfs = (
@@ -184,3 +141,36 @@ def _capitalize_sriov_vf_mac(state):
vf_mac = vf.get(Ethernet.SRIOV.VFS.MAC_ADDRESS)
if vf_mac:
vf[Ethernet.SRIOV.VFS.MAC_ADDRESS] = vf_mac.upper()
+
+
+def verify_sriov_vf(iface, cur_ifaces):
+ """
+ Checking whether VF interface is been created
+ """
+ if not (
+ iface.is_up
+ and (iface.is_desired or iface.is_changed)
+ and iface.type == InterfaceType.ETHERNET
+ and iface.sriov_total_vfs > 0
+ ):
+ return
+ cur_iface = cur_ifaces.get_iface(iface.name, iface.type)
+ if not cur_iface:
+ # Other verification will raise proper exception when current interface
+ # is missing
+ return
+ cur_vf_names = []
+ for sriov_vf in cur_iface.sriov_vfs:
+ if sriov_vf.get(EthernetIface.VF_IFACE_NAME_METADATA):
+ cur_vf_names.append(sriov_vf[EthernetIface.VF_IFACE_NAME_METADATA])
+
+ if len(cur_vf_names) != iface.sriov_total_vfs:
+ raise NmstateVerificationError(
+ f"Found VF ports count does not match desired "
+ f"{iface.sriov_total_vfs}, current is: {','.join(cur_vf_names)}"
+ )
+ for cur_vf_name in cur_vf_names:
+ if not cur_ifaces.get_iface(cur_vf_name, InterfaceType.ETHERNET):
+ raise NmstateVerificationError(
+ f"VF interface {cur_vf_name} of PF {iface.name} not found"
+ )
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
index be295e3..4bd6792 100644
--- a/libnmstate/ifaces/ifaces.py
+++ b/libnmstate/ifaces/ifaces.py
@@ -33,6 +33,7 @@ from .base_iface import BaseIface
from .bond import BondIface
from .dummy import DummyIface
from .ethernet import EthernetIface
+from .ethernet import verify_sriov_vf
from .infiniband import InfiniBandIface
from .linux_bridge import LinuxBridgeIface
from .macvlan import MacVlanIface
@@ -151,7 +152,6 @@ class Ifaces:
self._kernel_ifaces[iface.name] = iface
self._create_virtual_port()
- self._create_sriov_vfs_when_changed()
self._mark_vf_interface_as_absent_when_sriov_vf_decrease()
self._validate_unknown_port()
self._validate_unknown_parent()
@@ -241,35 +241,6 @@ class Ifaces:
for iface in new_ifaces:
self._kernel_ifaces[iface.name] = iface
- def _create_sriov_vfs_when_changed(self):
- """
- When plugin set the TOTAL_VFS of PF, it might take 1 seconds or
- more to have the VFs to be ready.
- Nmstate should use verification retry to make sure VFs are full ready.
- To do that, we include VFs into desire state.
- """
- new_ifaces = []
- for iface in self.all_ifaces():
- if (
- iface.is_up
- and (iface.is_desired or iface.is_changed)
- and iface.type == InterfaceType.ETHERNET
- and iface.sriov_total_vfs > 0
- ):
- for new_iface in iface.create_sriov_vf_ifaces():
- cur_iface = self._kernel_ifaces.get(new_iface.name)
- if cur_iface and cur_iface.is_desired:
- raise NmstateNotSupportedError(
- "Does not support changing SR-IOV PF interface "
- "along with VF interface in the single desire "
- f"state: PF {iface.name}, VF {cur_iface.name}"
- )
- else:
- new_iface.mark_as_desired()
- new_ifaces.append(new_iface)
- for new_iface in new_ifaces:
- self._kernel_ifaces[new_iface.name] = new_iface
-
def _mark_vf_interface_as_absent_when_sriov_vf_decrease(self):
"""
When SRIOV TOTAL_VFS decreased, we should mark certain VF interfaces
@@ -647,6 +618,7 @@ class Ifaces:
cur_ifaces._remove_ignore_interfaces(self._ignored_ifaces)
self._remove_ignore_interfaces(self._ignored_ifaces)
for iface in self.all_ifaces():
+ verify_sriov_vf(iface, cur_ifaces)
if iface.is_desired:
if (
iface.is_virtual
@@ -700,18 +672,6 @@ 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)
diff --git a/libnmstate/nispor/ethernet.py b/libnmstate/nispor/ethernet.py
index d6969b9..e4b82ff 100644
--- a/libnmstate/nispor/ethernet.py
+++ b/libnmstate/nispor/ethernet.py
@@ -17,10 +17,13 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
+import os
+
from libnmstate.schema import Ethernet
from libnmstate.schema import InterfaceType
from .base_iface import NisporPluginBaseIface
+from libnmstate.ifaces.ethernet import EthernetIface
class NisporPluginEthernetIface(NisporPluginBaseIface):
@@ -35,6 +38,9 @@ class NisporPluginEthernetIface(NisporPluginBaseIface):
for vf in self.np_iface.sr_iov.vfs:
vf_infos.append(
{
+ EthernetIface.VF_IFACE_NAME_METADATA: _get_vf_name(
+ self.np_iface.name, vf.vf_id
+ ),
Ethernet.SRIOV.VFS.ID: vf.vf_id,
Ethernet.SRIOV.VFS.MAC_ADDRESS: vf.mac.upper(),
Ethernet.SRIOV.VFS.SPOOF_CHECK: vf.spoof_check,
@@ -76,3 +82,14 @@ def np_ethtool_link_mode_to_nmstate(np_link_mode):
info[Ethernet.SPEED] = np_link_mode.speed
return info
+
+
+def _get_vf_name(pf_name, vf_id):
+ try:
+ vf_names = os.listdir(
+ f"/sys/class/net/{pf_name}/device/virtfn{vf_id}/net/"
+ )
+ if len(vf_names) >= 1:
+ return vf_names[0]
+ except Exception:
+ return ""
diff --git a/libnmstate/nm/profiles.py b/libnmstate/nm/profiles.py
index 3b0b6be..9e3020b 100644
--- a/libnmstate/nm/profiles.py
+++ b/libnmstate/nm/profiles.py
@@ -71,7 +71,6 @@ class NmProfiles:
for iface in sorted(
list(net_state.ifaces.all_ifaces()), key=attrgetter("name")
)
- if not getattr(iface, "is_generated_vf", None)
]
for profile in all_profiles:
diff --git a/libnmstate/nm/sriov.py b/libnmstate/nm/sriov.py
index a7e387c..e0bf60b 100644
--- a/libnmstate/nm/sriov.py
+++ b/libnmstate/nm/sriov.py
@@ -102,8 +102,9 @@ def _create_sriov_vfs_from_config(vfs_config, sriov_setting, vf_ids_to_add):
def _set_nm_attribute(vf_object, key, value):
- nm_attr, nm_variant = SRIOV_NMSTATE_TO_NM_MAP[key]
- vf_object.set_attribute(nm_attr, nm_variant(value))
+ if key in SRIOV_NMSTATE_TO_NM_MAP:
+ nm_attr, nm_variant = SRIOV_NMSTATE_TO_NM_MAP[key]
+ vf_object.set_attribute(nm_attr, nm_variant(value))
def _remove_sriov_vfs_in_setting(vfs_config, sriov_setting, vf_ids_to_remove):
--
2.27.0

View File

@ -1,110 +0,0 @@
From af6b1458f852dc164206dc2fc45467ade6a7f7ae Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Wed, 9 Feb 2022 23:33:40 +0800
Subject: [PATCH] python route: Add support of multipath route
Supporting the rout created by below command:
sudo ip -6 route add 2001:db8:e::/64 proto static \
nexthop via 2001:db8:f::254 dev eth1 weight 1 onlink \
nexthop via 2001:db8:f::253 dev eth1 weight 256 onlink
Integration test case included.
Signed-off-by: Gris Ge <fge@redhat.com>
---
libnmstate/nispor/route.py | 53 ++++++++++++++++++++++++++------------
1 file changed, 36 insertions(+), 17 deletions(-)
diff --git a/libnmstate/nispor/route.py b/libnmstate/nispor/route.py
index 9852ba51..87543de2 100644
--- a/libnmstate/nispor/route.py
+++ b/libnmstate/nispor/route.py
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2020 Red Hat, Inc.
+# Copyright (c) 2020-2022 Red Hat, Inc.
#
# This file is part of nmstate
#
@@ -17,6 +17,8 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
+from copy import deepcopy
+
from libnmstate.schema import Route
@@ -30,24 +32,24 @@ LOCAL_ROUTE_TABLE = 255
def nispor_route_state_to_nmstate(np_routes):
- return [
- _nispor_route_to_nmstate(rt)
- for rt in np_routes
- if rt.scope in ["universe", "link"]
- and rt.oif != "lo"
- and rt.table != LOCAL_ROUTE_TABLE
- ]
+ ret = []
+ for np_route in np_routes:
+ if np_route.oif != "lo" and np_route.table != LOCAL_ROUTE_TABLE:
+ ret.extend(_nispor_route_to_nmstate(np_route))
+ return ret
def nispor_route_state_to_nmstate_static(np_routes):
- return [
- _nispor_route_to_nmstate(rt)
- for rt in np_routes
- if rt.scope in ["universe", "link"]
- and rt.protocol not in ["kernel", "ra", "dhcp"]
- and rt.oif != "lo"
- and rt.table != LOCAL_ROUTE_TABLE
- ]
+ ret = []
+ for np_route in np_routes:
+ if (
+ np_route.oif != "lo"
+ and np_route.table != LOCAL_ROUTE_TABLE
+ and np_route.scope in ["universe", "link"]
+ and np_route.protocol in ["static", "boot"]
+ ):
+ ret.extend(_nispor_route_to_nmstate(np_route))
+ return ret
def _nispor_route_to_nmstate(np_rt):
@@ -71,10 +73,27 @@ def _nispor_route_to_nmstate(np_rt):
else IPV4_EMPTY_NEXT_HOP_ADDRESS
)
- return {
+ nm_route = {
Route.TABLE_ID: np_rt.table,
Route.DESTINATION: destination,
Route.NEXT_HOP_INTERFACE: np_rt.oif if np_rt.oif else "",
Route.NEXT_HOP_ADDRESS: next_hop,
Route.METRIC: np_rt.metric if np_rt.metric else 0,
}
+ np_mp_rts = get_multipath_routes(np_rt)
+ if np_mp_rts:
+ ret = []
+ for np_mp_rt in np_mp_rts:
+ nm_route_clone = deepcopy(nm_route)
+ nm_route_clone[Route.NEXT_HOP_INTERFACE] = np_mp_rt["iface"]
+ nm_route_clone[Route.NEXT_HOP_ADDRESS] = np_mp_rt["via"]
+ ret.append(nm_route_clone)
+ return ret
+ else:
+ return [nm_route]
+
+
+# Instead of bumping nispor dependency version, we just use nispor private
+# property temporarily
+def get_multipath_routes(np_route):
+ return np_route._info.get("multipath")
--
2.27.0

View File

@ -1,16 +0,0 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEE8f1XsqXpyNthgIbGbM3lj+QeKP8FAmDvw+4ACgkQbM3lj+Qe
KP+WjA/+Nky4rMOTNG16iwV8wc0hvWJdHL6XzDnHR2rrUHPGLMg4ia2B5MhYGKpl
/1eQk2UnA2rFTLC2P+TlKJbTFTUytxDvoCbR7ODCmneSJ65txG3XFDEd0soGayn4
w5UchowGTqGEMu/P1ORihYtYC6b8Q1gHFUomqcvryOtdE6b6lzQAMyU/VrG3vEwG
dSsFWJh6PyMi2WTS5+CAHUYPbs3wZbNxTU74PyHch1Hcl3zwXa3bheqzHZojYh28
GvvaPXBAHD6xwnCOWTMw3hBgLnjTZKsc62aFqgJ1Zz1VqN+Xlo8mlTZYDGhzwNU3
m0UfRz2tSeqpbTFty3ObzTfDNYiXe4Y3J6ktD3pjt7Pf/uKY8NNbOKlZ4WhWrqPn
VGB67ci/pcMQjw/vCPVjOQwpjVMm/EaZ6GQw8TAxbsb9tB5w2NoTncMkNNiPNB4/
5gquK2zZL8hsPqcE5yY/n+2/zgxhO7E7KuE20dbt1BCW+wmS4e77a7cx3EFgLc7f
oTGGuh3T+zdI/kxt5FAUBNnFiPWN9zJjQ8e080j7UIyL1Rhpvp+xG70ujwHvfL1I
qczeFT77eI2aMNU9iX/vbkVdgEKlxD6YDw626PxJR5WQz99zHiKwfDPUf9rJW72q
tAbGZ3DjfMk/VrerOMFDEGPA1V9Fs9kxGye1DIPAVw4IOwAbqE8=
=9EnL
-----END PGP SIGNATURE-----

View File

@ -0,0 +1,16 @@
-----BEGIN PGP SIGNATURE-----
iQIzBAABCAAdFiEE8f1XsqXpyNthgIbGbM3lj+QeKP8FAmIKEdcACgkQbM3lj+Qe
KP/qUw//UUp2FkgRKtVwmv0uCv3o7DlQAmj5nHmoEgQpRvjzVQZsDIlJzTv2h7/X
O44rQmJPbtqgyQE34mc3uioXtttiIhiwJtkgK4mYe1uQRD1txy9DgTPZMoRJWbi5
vallg5jfPmUBENcMpLrcBZgJo6IRGQBZBpC0rNPfhufNjvVNSAyvARyzTXFaxaDx
ajRYoFHnW38lOhx3Dyz5jtkPsDtq3oLsVI1G/xpeLOGc/SpCDcJJac70ODlJKOrC
Zve9xnOdIrjfnI1QLdZ0gH8rAyreOFqRiPm+jyGuyxw9OIcdWxT37pr7s8I2/ct8
C+qsMOyqY63O01uus9JidbEIbivdaP5l0xFS51tIt/XEt0PCJ64rA0q/RdBGd5v1
V5h+K1ptQvdAmYI11LtLJDIvLYTc6KeFcjNRfT0s2GO/KFkYrVe1dq+yFj2sCB2u
DD6UnZUzE2bUzN5lumqBQEmMSi2H6cTVLQYbif8iJbCgPM71JAio5gYmOC5VBp8P
yaMKBFBYPwQAIZDN71shDVRT9BttRMAnBFOdPLqm03ht9BgkYihbbAZlNUipVrN0
SIhsPZNc53psWH6ehDqYF8gJHucxZBipPd/qslzxhUJpn5Y4gITHJkrnFunz+4Cs
qv01LQrvn7RMz2P13YN5GzLY7WDRcjNO6aj0adgHyO9PI8wSMsc=
=Arcd
-----END PGP SIGNATURE-----

View File

@ -3,26 +3,20 @@
%define libname libnmstate
Name: nmstate
Version: 1.1.0
Release: 6%{?dist}
Version: 1.2.1
Release: 1%{?dist}
Summary: Declarative network manager API
License: LGPLv2+
URL: https://github.com/%{srcname}/%{srcname}
Source0: %{url}/releases/download/v%{version}/%{srcname}-%{version}.tar.gz
Source1: %{url}/releases/download/v%{version}/%{srcname}-%{version}.tar.gz.asc
Source2: https://www.nmstate.io/nmstate.gpg
Patch1: 0001-nmstatectl-fix-long-arguments-support.patch
Patch2: 0002-nm-ethtool-Preserve-existing-ethtool-settings-when-u.patch
Patch3: 0003-ovs-fix-state-ignore-for-ovs-port-when-removing-them.patch
Patch4: 0004-nispor-fix-show-of-empty-next_hop_address-and-destin.patch
Patch5: BZ_2034139-do-not-rename-connection.patch
Patch6: BZ_2034139-ovs-remove-ovs-port-prefix.patch
Patch7: BZ_2039285-sriov-New-way-to-wait-VF-been-created.patch
Patch8: BZ_2054054-support-multipath-route.patch
BuildArch: noarch
Source3: nmstate-rust-vendor-%{version}.tar.xz
BuildRequires: python3-devel
BuildRequires: python3-setuptools
BuildRequires: gnupg2
BuildRequires: rust-toolset
BuildRequires: pkg-config
Requires: python3-setuptools
Requires: python3-%{libname} = %{?epoch:%{epoch}:}%{version}-%{release}
@ -35,6 +29,7 @@ provider support on the southbound.
%package -n python3-%{libname}
Summary: nmstate Python 3 API library
BuildArch: noarch
Requires: NetworkManager-libnm >= 1:1.26.0
# Use Recommends for NetworkManager because only access to NM DBus is required,
# but NM could be running on a different host
@ -50,11 +45,28 @@ Requires: python3dist(varlink)
%package -n nmstate-plugin-ovsdb
Summary: nmstate plugin for OVS database manipulation
BuildArch: noarch
Requires: python3-%{libname} = %{?epoch:%{epoch}:}%{version}-%{release}
# The python-openvswitch rpm pacakge is not in the same repo with nmstate,
# hence state it as Recommends, no requires.
Recommends: python3dist(ovs)
%package libs
Summary: C binding of nmstate
License: ASL 2.0
%package devel
Summary: C binding development files of nmstate
License: ASL 2.0
Requires: nmstate-libs%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}
%description libs
This package contains the C binding of nmstate.
%description devel
This package contains the C binding development files of nmstate.
%description -n python3-%{libname}
This package contains the Python 3 library for nmstate.
@ -66,11 +78,32 @@ gpg2 --import --import-options import-export,import-minimal %{SOURCE2} > ./gpgke
gpgv2 --keyring ./gpgkey-mantainers.gpg %{SOURCE1} %{SOURCE0}
%autosetup -p1
pushd rust
# Source3 is vendored dependencies
%cargo_prep -V 3
# The cargo_prep will create `.cargo/config` which take precedence over
# `.cargo/config.toml` shipped by upstream which fix the SONAME of cdylib.
# To workaround that, merge upstream rustflags into cargo_prep created one.
_FLAGS=`sed -ne 's/rustflags = "\(.\+\)"/\1/p' .cargo/config.toml`
sed -i -e "s/rustflags = \[\(.\+\), \]$/rustflags = [\1, \"$_FLAGS\"]/" \
.cargo/config
rm .cargo/config.toml
popd
%build
%py3_build
pushd rust
make
popd
%install
%py3_install
pushd rust
env SKIP_PYTHON_INSTALL=1 PREFIX=%{_prefix} LIBDIR=%{_libdir} %make_install
popd
%files
%doc README.md
@ -79,6 +112,7 @@ gpgv2 --keyring ./gpgkey-mantainers.gpg %{SOURCE1} %{SOURCE0}
%{_mandir}/man8/nmstate-autoconf.8*
%{python3_sitelib}/nmstatectl
%{_bindir}/nmstatectl
%{_bindir}/nmstatectl-rust
%{_bindir}/nmstate-autoconf
%files -n python3-%{libname}
@ -92,15 +126,45 @@ gpgv2 --keyring ./gpgkey-mantainers.gpg %{SOURCE1} %{SOURCE0}
%{python3_sitelib}/%{libname}/plugins/nmstate_plugin_ovsdb*
%{python3_sitelib}/%{libname}/plugins/__pycache__/nmstate_plugin_ovsdb*
%files libs
%license rust/LICENSE
%{_libdir}/libnmstate.so.*
%files devel
%license LICENSE
%{_libdir}/libnmstate.so
%{_includedir}/nmstate.h
%{_libdir}/pkgconfig/nmstate.pc
%post libs
/sbin/ldconfig
%postun libs
/sbin/ldconfig
%changelog
* Thu Feb 10 2022 Gris Ge <fge@redhat.com> - 1.1.0-6
- Workaround CNV issue by supporting multipath route. RHBZ#2054054
* Mon Feb 14 2022 Gris Ge <fge@redhat.com> - 1.2.1-1
- Upgrade to 1.2.1. RHBZ#1996618
* Wed Jan 12 2022 Gris Ge <fge@redhat.com> - 1.1.0-5
- Remove OVS interface postfix. RHBZ#2034139
* Thu Jan 27 2022 Gris Ge <ferferna@redhat.com> - 1.2.1-0.2.alpha2
- Upgrade to 1.2.1 alpha2. RHBZ#1996618
* Wed Jan 12 2022 Gris Ge <fge@redhat.com> - 1.1.0-4
- Fix SR-IOV on ixgbe. RHBZ#2039285
* Thu Jan 13 2022 Gris Ge <fge@redhat.com> - 1.2.1-0.1.alpha1
- Upgrade to 1.2.1 alpha1. RHBZ#1996618
* Thu Dec 16 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 1.2.0-1
- Upgrade to 1.2.0. RHBZ#1996618
* Thu Dec 09 2021 Gris Ge <fge@redhat.com> - 1.2.0-0.1.alpha2
- Upgrade to 1.2.0 alpha2. RHBZ#1996618
* Tue Oct 12 2021 Gris Ge <fge@redhat.com> - 1.2.0-0.1.alpha1
- Upgrade to 1.2.0 alpha1.
* Wed Sep 15 2021 Ana Cabral <acabral@redhat.com> - 1.1.1-0.1.alpha1
- Upgrade to 1.1.1 alpha1.
- Canonicalize ipv6 addresses for dns nameservers. RHBZ#1911241
- Throw better error when peer is missing for veth interfaces. RHBZ#1973973
* Tue Jul 27 2021 Gris Ge <fge@redhat.com> - 1.1.0-3
- Fix state=ignore for OVS interface. RHBZ#1944054