diff --git a/.gitignore b/.gitignore index 54812f7..b8d7bdd 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/.nmstate.metadata b/.nmstate.metadata index f6d19a1..fc5808f 100644 --- a/.nmstate.metadata +++ b/.nmstate.metadata @@ -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 diff --git a/SOURCES/0001-nmstatectl-fix-long-arguments-support.patch b/SOURCES/0001-nmstatectl-fix-long-arguments-support.patch deleted file mode 100644 index 4334857..0000000 --- a/SOURCES/0001-nmstatectl-fix-long-arguments-support.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 99c7f643bab33a26c317e1b72ca3b8490cb1ea60 Mon Sep 17 00:00:00 2001 -From: Fernando Fernandez Mancera -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 -Signed-off-by: Gris Ge ---- - 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 - diff --git a/SOURCES/0002-nm-ethtool-Preserve-existing-ethtool-settings-when-u.patch b/SOURCES/0002-nm-ethtool-Preserve-existing-ethtool-settings-when-u.patch deleted file mode 100644 index 5f5ebec..0000000 --- a/SOURCES/0002-nm-ethtool-Preserve-existing-ethtool-settings-when-u.patch +++ /dev/null @@ -1,105 +0,0 @@ -From b1cb57d1dc4bba6592ba5cfc5c810a2ad19ac941 Mon Sep 17 00:00:00 2001 -From: Gris Ge -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 -Signed-off-by: Fernando Fernandez Mancera ---- - 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 - diff --git a/SOURCES/0003-ovs-fix-state-ignore-for-ovs-port-when-removing-them.patch b/SOURCES/0003-ovs-fix-state-ignore-for-ovs-port-when-removing-them.patch deleted file mode 100644 index ba000ef..0000000 --- a/SOURCES/0003-ovs-fix-state-ignore-for-ovs-port-when-removing-them.patch +++ /dev/null @@ -1,87 +0,0 @@ -From f4d190653c55d399b32afc956b2b4a1ff8d20101 Mon Sep 17 00:00:00 2001 -From: Fernando Fernandez Mancera -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 -Signed-off-by: Gris Ge ---- - 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 - diff --git a/SOURCES/0004-nispor-fix-show-of-empty-next_hop_address-and-destin.patch b/SOURCES/0004-nispor-fix-show-of-empty-next_hop_address-and-destin.patch deleted file mode 100644 index 40be31b..0000000 --- a/SOURCES/0004-nispor-fix-show-of-empty-next_hop_address-and-destin.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 369ed3210ecedfa1deda88a6eb7cacc19a47f89d Mon Sep 17 00:00:00 2001 -From: Fernando Fernandez Mancera -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 -Signed-off-by: Gris Ge ---- - 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 - diff --git a/SOURCES/BZ_2034139-do-not-rename-connection.patch b/SOURCES/BZ_2034139-do-not-rename-connection.patch deleted file mode 100644 index 7036933..0000000 --- a/SOURCES/BZ_2034139-do-not-rename-connection.patch +++ /dev/null @@ -1,45 +0,0 @@ -From daad0a535b370d0a3f847526185c185aca2d9935 Mon Sep 17 00:00:00 2001 -From: Fernando Fernandez Mancera -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 -Signed-off-by: Gris Ge ---- - 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 - diff --git a/SOURCES/BZ_2034139-ovs-remove-ovs-port-prefix.patch b/SOURCES/BZ_2034139-ovs-remove-ovs-port-prefix.patch deleted file mode 100644 index 4225ba0..0000000 --- a/SOURCES/BZ_2034139-ovs-remove-ovs-port-prefix.patch +++ /dev/null @@ -1,110 +0,0 @@ -From cd41c2c0f6bef7b952648b358246fffa8ce3cf62 Mon Sep 17 00:00:00 2001 -From: Fernando Fernandez Mancera -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 -Signed-off-by: Gris Ge ---- - 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 -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 -Signed-off-by: Gris Ge ---- - 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 - diff --git a/SOURCES/BZ_2039285-sriov-New-way-to-wait-VF-been-created.patch b/SOURCES/BZ_2039285-sriov-New-way-to-wait-VF-been-created.patch deleted file mode 100644 index 5d4b1bd..0000000 --- a/SOURCES/BZ_2039285-sriov-New-way-to-wait-VF-been-created.patch +++ /dev/null @@ -1,326 +0,0 @@ -From b8e3c6928c2a22a828b85a6780de3cea1107aa85 Mon Sep 17 00:00:00 2001 -From: Gris Ge -Date: Fri, 24 Dec 2021 16:34:30 +0800 -Subject: [PATCH] sriov: New way to wait VF been created - -By checking `/sys/class/net//device/virtfn/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 ---- - 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 . - # - -+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 . - # - -+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 - diff --git a/SOURCES/BZ_2054054-support-multipath-route.patch b/SOURCES/BZ_2054054-support-multipath-route.patch deleted file mode 100644 index 48850d1..0000000 --- a/SOURCES/BZ_2054054-support-multipath-route.patch +++ /dev/null @@ -1,110 +0,0 @@ -From af6b1458f852dc164206dc2fc45467ade6a7f7ae Mon Sep 17 00:00:00 2001 -From: Gris Ge -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 ---- - 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 . - # - -+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 - diff --git a/SOURCES/nmstate-1.1.0.tar.gz.asc b/SOURCES/nmstate-1.1.0.tar.gz.asc deleted file mode 100644 index 3c2d190..0000000 --- a/SOURCES/nmstate-1.1.0.tar.gz.asc +++ /dev/null @@ -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----- diff --git a/SOURCES/nmstate-1.2.1.tar.gz.asc b/SOURCES/nmstate-1.2.1.tar.gz.asc new file mode 100644 index 0000000..9fdc04f --- /dev/null +++ b/SOURCES/nmstate-1.2.1.tar.gz.asc @@ -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----- diff --git a/SPECS/nmstate.spec b/SPECS/nmstate.spec index b40dd97..a9d79d1 100644 --- a/SPECS/nmstate.spec +++ b/SPECS/nmstate.spec @@ -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 - 1.1.0-6 -- Workaround CNV issue by supporting multipath route. RHBZ#2054054 +* Mon Feb 14 2022 Gris Ge - 1.2.1-1 +- Upgrade to 1.2.1. RHBZ#1996618 -* Wed Jan 12 2022 Gris Ge - 1.1.0-5 -- Remove OVS interface postfix. RHBZ#2034139 +* Thu Jan 27 2022 Gris Ge - 1.2.1-0.2.alpha2 +- Upgrade to 1.2.1 alpha2. RHBZ#1996618 -* Wed Jan 12 2022 Gris Ge - 1.1.0-4 -- Fix SR-IOV on ixgbe. RHBZ#2039285 +* Thu Jan 13 2022 Gris Ge - 1.2.1-0.1.alpha1 +- Upgrade to 1.2.1 alpha1. RHBZ#1996618 + +* Thu Dec 16 2021 Fernando Fernandez Mancera - 1.2.0-1 +- Upgrade to 1.2.0. RHBZ#1996618 + +* Thu Dec 09 2021 Gris Ge - 1.2.0-0.1.alpha2 +- Upgrade to 1.2.0 alpha2. RHBZ#1996618 + +* Tue Oct 12 2021 Gris Ge - 1.2.0-0.1.alpha1 +- Upgrade to 1.2.0 alpha1. + +* Wed Sep 15 2021 Ana Cabral - 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 - 1.1.0-3 - Fix state=ignore for OVS interface. RHBZ#1944054