import nmstate-0.3.4-27.el8_3

This commit is contained in:
CentOS Sources 2021-04-06 09:33:02 -04:00 committed by Andrew Lukoshko
parent 654b4d10bc
commit a764ed7069
8 changed files with 652 additions and 1 deletions

View File

@ -0,0 +1,82 @@
From cc7e6da98cc992d2e6d8aa85cd78f02fb8ef8ac3 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Sun, 21 Feb 2021 22:43:57 +0100
Subject: [PATCH 2/5] SR-IOV: Do not create VF profiles automatically
As VFs are Ethernet type and Nmstate is automatically adding them to the
desired state and marking them as desired, the profile is being created.
This is wrong as Nmstate should only wait for verification of the VFs.
In order to fix this, the new VF interfaces are being marked as so. This
way Nmstate is not creating the profiles anymore.
Integration test case added.
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
---
libnmstate/ifaces/ethernet.py | 10 ++++
libnmstate/ifaces/ifaces.py | 1 +
libnmstate/nm/applier.py | 5 ++
tests/integration/nm/sriov_test.py | 92 ++++++++++++++++++++++++++++++
4 files changed, 108 insertions(+)
create mode 100644 tests/integration/nm/sriov_test.py
diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py
index 3e1bdc5d..f1ece5f5 100644
--- a/libnmstate/ifaces/ethernet.py
+++ b/libnmstate/ifaces/ethernet.py
@@ -25,6 +25,9 @@ from libnmstate.schema import InterfaceState
from .base_iface import BaseIface
+IS_NEW_SR_IOV_VF = "_is_new_sr_iov_vf"
+
+
class EthernetIface(BaseIface):
def merge(self, other):
"""
@@ -57,6 +60,13 @@ class EthernetIface(BaseIface):
.get(Ethernet.SRIOV.TOTAL_VFS, 0)
)
+ @property
+ def is_new_sr_iov_vf(self):
+ return self.raw.get(IS_NEW_SR_IOV_VF)
+
+ def mark_as_new_sr_iov_vf(self):
+ self.raw[IS_NEW_SR_IOV_VF] = True
+
def create_sriov_vf_ifaces(self):
return [
EthernetIface(
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
index 67ab91c4..a7af9712 100644
--- a/libnmstate/ifaces/ifaces.py
+++ b/libnmstate/ifaces/ifaces.py
@@ -144,6 +144,7 @@ class Ifaces:
for new_iface in iface.create_sriov_vf_ifaces():
if new_iface.name not in self._ifaces:
new_iface.mark_as_desired()
+ new_iface.mark_as_new_sr_iov_vf()
new_ifaces.append(new_iface)
for new_iface in new_ifaces:
self._ifaces[new_iface.name] = new_iface
diff --git a/libnmstate/nm/applier.py b/libnmstate/nm/applier.py
index 8e38df54..cd319ffb 100644
--- a/libnmstate/nm/applier.py
+++ b/libnmstate/nm/applier.py
@@ -119,6 +119,11 @@ def apply_changes(context, net_state, save_to_disk):
original_desired_iface_state = {}
if net_state.ifaces.get(ifname):
iface = net_state.ifaces[ifname]
+ if iface.type == InterfaceType.ETHERNET and iface.is_new_sr_iov_vf:
+ # For new vfs automatically added to the desired state is just
+ # for verification, Nmstate should not create a profile for
+ # them.
+ continue
if iface.is_desired:
original_desired_iface_state = iface.original_dict
if (
--
2.29.2

View File

@ -0,0 +1,112 @@
From c55d39e8485a26490afc36d71fd9d20528ab6fd2 Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Thu, 18 Feb 2021 18:01:17 +0800
Subject: [PATCH 1/5] SRIOV: Remove VF interface when total-vfs decrease
When `Ethernet.SRIOV.TOTAL_VFS` decrease, we should mark removed VF
interface as absent.
Both integration and unit test cases have been include.
The integration test has been tested on real SRIOV hardware.
Signed-off-by: Gris Ge <fge@redhat.com>
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
---
libnmstate/ifaces/base_iface.py | 5 +++++
libnmstate/ifaces/ethernet.py | 20 ++++++++++++++++++
libnmstate/ifaces/ifaces.py | 24 +++++++++++++++++++++
tests/integration/sriov_test.py | 37 +++++++++++++++++++++++++++++++++
4 files changed, 86 insertions(+)
diff --git a/libnmstate/ifaces/base_iface.py b/libnmstate/ifaces/base_iface.py
index 564d583a..b4ade867 100644
--- a/libnmstate/ifaces/base_iface.py
+++ b/libnmstate/ifaces/base_iface.py
@@ -177,6 +177,11 @@ class BaseIface:
def mark_as_desired(self):
self._is_desired = True
+ def mark_as_absent_by_desire(self):
+ self.mark_as_desired()
+ self._info[Interface.STATE] = InterfaceState.ABSENT
+ self._origin_info[Interface.STATE] = InterfaceState.ABSENT
+
def to_dict(self):
return deepcopy(self._info)
diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py
index 644fe6dd..3e1bdc5d 100644
--- a/libnmstate/ifaces/ethernet.py
+++ b/libnmstate/ifaces/ethernet.py
@@ -74,6 +74,26 @@ class EthernetIface(BaseIface):
for i in range(0, self.sriov_total_vfs)
]
+ def remove_vfs_entry_when_total_vfs_decreased(self):
+ vfs_count = len(
+ self._info[Ethernet.CONFIG_SUBTREE]
+ .get(Ethernet.SRIOV_SUBTREE, {})
+ .get(Ethernet.SRIOV.VFS_SUBTREE, [])
+ )
+ if vfs_count > self.sriov_total_vfs:
+ [
+ self._info[Ethernet.CONFIG_SUBTREE][Ethernet.SRIOV_SUBTREE][
+ Ethernet.SRIOV.VFS_SUBTREE
+ ].pop()
+ for _ in range(self.sriov_total_vfs, vfs_count)
+ ]
+
+ def get_delete_vf_interface_names(self, old_sriov_total_vfs):
+ return [
+ f"{self.name}v{i}"
+ for i in range(self.sriov_total_vfs, old_sriov_total_vfs)
+ ]
+
def _capitalize_sriov_vf_mac(state):
vfs = (
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
index ee75125d..67ab91c4 100644
--- a/libnmstate/ifaces/ifaces.py
+++ b/libnmstate/ifaces/ifaces.py
@@ -99,6 +99,7 @@ class Ifaces:
self._create_virtual_slaves()
self._create_sriov_vfs_when_changed()
self._validate_unknown_slaves()
+ self._mark_vf_interface_as_absent_when_sriov_vf_decrease()
self._validate_unknown_parent()
self._gen_metadata()
for iface in self._ifaces.values():
@@ -147,6 +148,29 @@ class Ifaces:
for new_iface in new_ifaces:
self._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
+ as absent and also remove the entry in `Ethernet.SRIOV.VFS_SUBTREE`.
+ """
+ for iface_name, iface in self._ifaces.items():
+ if iface.type != InterfaceType.ETHERNET or not iface.is_up:
+ continue
+ if iface_name not in self.current_ifaces:
+ continue
+ cur_iface = self.current_ifaces[iface_name]
+ if (
+ cur_iface.sriov_total_vfs != 0
+ and iface.sriov_total_vfs < cur_iface.sriov_total_vfs
+ ):
+ iface.remove_vfs_entry_when_total_vfs_decreased()
+ for vf_name in iface.get_delete_vf_interface_names(
+ cur_iface.sriov_total_vfs
+ ):
+ vf_iface = self._ifaces.get(vf_name)
+ if vf_iface:
+ vf_iface.mark_as_absent_by_desire()
+
def _pre_edit_validation_and_cleanup(self):
self._validate_over_booked_slaves()
self._validate_vlan_mtu()
--
2.29.2

View File

@ -0,0 +1,79 @@
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

View File

@ -0,0 +1,102 @@
From afb3f2dfeb5364e8a9a0bde4ad9062f1585a8795 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Mon, 22 Feb 2021 12:03:11 +0100
Subject: [PATCH 3/5] SR-IOV: increase the verification timeout if SR-IOV is
present
Certain drivers like i40e take a long time to modify the VFs in the
kernel. Nmstate is timing out on verification because of that. In order
to fix this, nmstate is incresing the verification time if SR-IOV is
present on the desired state.
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
---
libnmstate/ifaces/ethernet.py | 5 +++++
libnmstate/ifaces/ifaces.py | 4 ++++
libnmstate/netapplier.py | 18 +++++++++++++++++-
3 files changed, 26 insertions(+), 1 deletion(-)
diff --git a/libnmstate/ifaces/ethernet.py b/libnmstate/ifaces/ethernet.py
index f1ece5f5..1c3ca266 100644
--- a/libnmstate/ifaces/ethernet.py
+++ b/libnmstate/ifaces/ethernet.py
@@ -67,6 +67,11 @@ class EthernetIface(BaseIface):
def mark_as_new_sr_iov_vf(self):
self.raw[IS_NEW_SR_IOV_VF] = True
+ def is_sriov(self):
+ return self.raw.get(Ethernet.CONFIG_SUBTREE, {}).get(
+ Ethernet.SRIOV_SUBTREE, {}
+ )
+
def create_sriov_vf_ifaces(self):
return [
EthernetIface(
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
index a7af9712..b212ebb5 100644
--- a/libnmstate/ifaces/ifaces.py
+++ b/libnmstate/ifaces/ifaces.py
@@ -325,6 +325,10 @@ class Ifaces:
def current_ifaces(self):
return self._cur_ifaces
+ @property
+ def all_ifaces(self):
+ return self._ifaces
+
@property
def state_to_edit(self):
return [
diff --git a/libnmstate/netapplier.py b/libnmstate/netapplier.py
index 24df4d56..6aa1ac07 100644
--- a/libnmstate/netapplier.py
+++ b/libnmstate/netapplier.py
@@ -23,6 +23,7 @@ import time
from libnmstate import validator
from libnmstate.error import NmstateVerificationError
+from libnmstate.schema import InterfaceType
from .nmstate import create_checkpoints
from .nmstate import destroy_checkpoints
@@ -35,6 +36,7 @@ from .net_state import NetState
MAINLOOP_TIMEOUT = 35
VERIFY_RETRY_INTERNAL = 1
VERIFY_RETRY_TIMEOUT = 5
+VERIFY_RETRY_TIMEOUT_INCREASE = 4
def apply(
@@ -104,7 +106,13 @@ def _apply_ifaces_state(plugins, net_state, verify_change, save_to_disk):
plugin.apply_changes(net_state, save_to_disk)
verified = False
if verify_change:
- for _ in range(VERIFY_RETRY_TIMEOUT):
+ if _net_state_contains_sriov_interface(net_state):
+ # If SR-IOV is present, the verification timeout is being increased
+ # to avoid timeouts due to slow drivers like i40e.
+ verify_retry = VERIFY_RETRY_TIMEOUT * VERIFY_RETRY_TIMEOUT_INCREASE
+ else:
+ verify_retry = VERIFY_RETRY_TIMEOUT
+ for _ in range(verify_retry):
try:
_verify_change(plugins, net_state)
verified = True
@@ -115,6 +123,14 @@ def _apply_ifaces_state(plugins, net_state, verify_change, save_to_disk):
_verify_change(plugins, net_state)
+def _net_state_contains_sriov_interface(net_state):
+ for iface in net_state.ifaces.all_ifaces.values():
+ if iface.type == InterfaceType.ETHERNET and iface.is_sriov:
+ return True
+
+ return False
+
+
def _verify_change(plugins, net_state):
current_state = show_with_plugins(plugins)
net_state.verify(current_state)
--
2.29.2

View File

@ -0,0 +1,38 @@
From cb4cbff0da01bb1e6546c2b28ef2760ec1f89f74 Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Wed, 24 Feb 2021 17:12:13 +0100
Subject: [PATCH 5/5] bridge: do not bring up existing ports
Nmstate should not try to bring up existing ports on a bridge when
modifying it. The ports will be bring up when being added to the it, if
the bridge is being modified later, the ports are not going to be
automatically up.
Ref: https://bugzilla.redhat.com/1932247
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
---
libnmstate/ifaces/ifaces.py | 5 +
tests/integration/nm/linux_bridge_test.py | 112 +++++++++++++++++++++-
2 files changed, 116 insertions(+), 1 deletion(-)
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
index 1d30d0c6..5f1f548d 100644
--- a/libnmstate/ifaces/ifaces.py
+++ b/libnmstate/ifaces/ifaces.py
@@ -194,7 +194,12 @@ class Ifaces:
"""
for iface in self._ifaces.values():
if iface.is_up and iface.is_master:
+ cur_iface = self.current_ifaces.get(iface.name)
for slave_name in iface.slaves:
+ if cur_iface and slave_name in cur_iface.slaves:
+ # Nmstate should not touch the port interface which has
+ # already been included in current interface.
+ continue
slave_iface = self._ifaces[slave_name]
if not slave_iface.is_desired and not slave_iface.is_up:
slave_iface.mark_as_up()
--
2.29.2

View File

@ -0,0 +1,77 @@
From fb9352b902f8fec813c149e02e97c7014ef6399c Mon Sep 17 00:00:00 2001
From: Fernando Fernandez Mancera <ffmancera@riseup.net>
Date: Mon, 1 Mar 2021 16:25:57 +0100
Subject: [PATCH] nm.applier: ignore not desired unmanaged ifaces
Nmstate will ignore not desired unmanaged interfaces. If an existing
unmanaged port of a bridge is not being included in the desired state
bridge port list, it will not be removed. Basically, Nmstate will not be
able to remove unmanaged ports from a bridge.
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
---
libnmstate/ifaces/ifaces.py | 11 ++++++---
libnmstate/nm/applier.py | 11 ++++++++-
tests/integration/linux_bridge_test.py | 1 +
tests/integration/nm/linux_bridge_test.py | 30 +++--------------------
4 files changed, 21 insertions(+), 32 deletions(-)
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
index 5f1f548d..cfc306c6 100644
--- a/libnmstate/ifaces/ifaces.py
+++ b/libnmstate/ifaces/ifaces.py
@@ -193,7 +193,7 @@ class Ifaces:
if not defiend in desire state
"""
for iface in self._ifaces.values():
- if iface.is_up and iface.is_master:
+ if iface.is_desired and iface.is_up and iface.is_master:
cur_iface = self.current_ifaces.get(iface.name)
for slave_name in iface.slaves:
if cur_iface and slave_name in cur_iface.slaves:
@@ -353,14 +353,17 @@ class Ifaces:
def _remove_unknown_interface_type_slaves(self):
"""
- When master containing slaves with unknown interface type, they should
- be removed from master slave list before verifying.
+ When master containing slaves with unknown interface type or down
+ state, they should be removed from master slave list before verifying.
"""
for iface in self._ifaces.values():
if iface.is_up and iface.is_master and iface.slaves:
for slave_name in iface.slaves:
slave_iface = self._ifaces[slave_name]
- if slave_iface.type == InterfaceType.UNKNOWN:
+ if (
+ slave_iface.type == InterfaceType.UNKNOWN
+ or slave_iface.state != InterfaceState.UP
+ ):
iface.remove_slave(slave_name)
def verify(self, cur_iface_infos):
diff --git a/libnmstate/nm/applier.py b/libnmstate/nm/applier.py
index cd319ffb..da2dab5b 100644
--- a/libnmstate/nm/applier.py
+++ b/libnmstate/nm/applier.py
@@ -80,7 +80,16 @@ def apply_changes(context, net_state, save_to_disk):
_preapply_dns_fix(context, net_state)
_mark_nm_external_subordinate_changed(context, net_state)
- ifaces_desired_state = net_state.ifaces.state_to_edit
+ ifaces_desired_state = []
+ for iface in net_state.ifaces.all_ifaces.values():
+ nm_dev = context.get_nm_dev(iface.name)
+ if nm_dev and not nm_dev.get_managed() and not iface.is_desired:
+ # We don't change NM.Device from unmanaged to managed unless
+ # been asked explicitly in desire state
+ continue
+ if iface.is_changed or iface.is_desired:
+ ifaces_desired_state.append(iface.to_dict())
+
ifaces_desired_state.extend(
_create_proxy_ifaces_desired_state(ifaces_desired_state)
)
--
2.29.2

View File

@ -0,0 +1,146 @@
From 34b689a86c7cd4bcf5ab5cf7d903acba7d60f4be Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Wed, 10 Feb 2021 23:28:37 +0800
Subject: [PATCH] bridge/bond: New property `Interface.COPY_MAC_FROM`
Introducing `Interface.COPY_MAC_FROM` allowing bridge or bond
to use MAC address from specified port.
Example:
```yaml
---
interfaces:
- name: bond99
type: bond
state: up
copy-mac-from: eth1
link-aggregation:
mode: balance-rr
port:
- eth2
- eth1
```
Integration test case included.
Signed-off-by: Gris Ge <fge@redhat.com>
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net>
---
libnmstate/ifaces/base_iface.py | 14 +++++++++++
libnmstate/ifaces/ifaces.py | 30 +++++++++++++++++++++++
libnmstate/schema.py | 1 +
libnmstate/schemas/operational-state.yaml | 4 +++
tests/integration/bond_test.py | 13 ++++++++++
tests/integration/linux_bridge_test.py | 14 +++++++++++
6 files changed, 76 insertions(+)
diff --git a/libnmstate/ifaces/base_iface.py b/libnmstate/ifaces/base_iface.py
index b4ade867..3dbcfe52 100644
--- a/libnmstate/ifaces/base_iface.py
+++ b/libnmstate/ifaces/base_iface.py
@@ -391,6 +391,20 @@ class BaseIface:
for family, rules in route_rule_metadata.items():
self.raw[family][BaseIface.ROUTE_RULES_METADATA] = rules
+ @property
+ def copy_mac_from(self):
+ return self._info.get(Interface.COPY_MAC_FROM)
+
+ def apply_copy_mac_from(self, mac):
+ """
+ * Add MAC to original desire.
+ * Remove Interface.COPY_MAC_FROM from original desire.
+ * Update MAC of merge iface
+ """
+ self.raw[Interface.MAC] = mac
+ self._origin_info[Interface.MAC] = mac
+ self._origin_info.pop(Interface.COPY_MAC_FROM, None)
+
def _remove_empty_description(state):
if state.get(Interface.DESCRIPTION) == "":
diff --git a/libnmstate/ifaces/ifaces.py b/libnmstate/ifaces/ifaces.py
index cfc306c6..1e4d2231 100644
--- a/libnmstate/ifaces/ifaces.py
+++ b/libnmstate/ifaces/ifaces.py
@@ -101,12 +101,42 @@ class Ifaces:
self._validate_unknown_slaves()
self._mark_vf_interface_as_absent_when_sriov_vf_decrease()
self._validate_unknown_parent()
+ self._apply_copy_mac_from()
self._gen_metadata()
for iface in self._ifaces.values():
iface.pre_edit_validation_and_cleanup()
self._pre_edit_validation_and_cleanup()
+ def _apply_copy_mac_from(self):
+ for iface in self._ifaces.values():
+ if iface.type not in (
+ InterfaceType.LINUX_BRIDGE,
+ InterfaceType.BOND,
+ ):
+ continue
+ if not iface.copy_mac_from:
+ continue
+
+ if iface.copy_mac_from not in iface.slaves:
+ raise NmstateValueError(
+ f"The interface {iface.name} is holding invalid "
+ f"{Interface.COPY_MAC_FROM} property "
+ f"as {iface.copy_mac_from} is not in the port "
+ f"list: {iface.port}"
+ )
+ port_iface = self._ifaces.get(iface.copy_mac_from)
+ # TODO: bridge/bond might refering the mac from new veth in the
+ # same desire state, it too complex to support that.
+ if not port_iface:
+ raise NmstateValueError(
+ f"The interface {iface.name} is holding invalid "
+ f"{Interface.COPY_MAC_FROM} property "
+ f"as the port {iface.copy_mac_from} does not exists yet"
+ )
+
+ iface.apply_copy_mac_from(port_iface.mac)
+
def _create_virtual_slaves(self):
"""
Certain master interface could have virtual slaves which does not
diff --git a/libnmstate/schema.py b/libnmstate/schema.py
index 8a86c48d..455dbf8f 100644
--- a/libnmstate/schema.py
+++ b/libnmstate/schema.py
@@ -44,6 +44,7 @@ class Interface:
MAC = "mac-address"
MTU = "mtu"
+ COPY_MAC_FROM = "copy-mac-from"
class Route:
diff --git a/libnmstate/schemas/operational-state.yaml b/libnmstate/schemas/operational-state.yaml
index d856aa5c..8fdeaeec 100644
--- a/libnmstate/schemas/operational-state.yaml
+++ b/libnmstate/schemas/operational-state.yaml
@@ -249,6 +249,8 @@ definitions:
type: string
enum:
- bond
+ copy-mac-from:
+ type: string
link-aggregation:
type: object
properties:
@@ -267,6 +269,8 @@ definitions:
- $ref: "#/definitions/interface-linux-bridge/ro"
ro:
properties:
+ copy-mac-from:
+ type: string
bridge:
type: object
properties:
--
2.29.2

View File

@ -4,7 +4,7 @@
Name: nmstate
Version: 0.3.4
Release: 25%{?dist}
Release: 27%{?dist}
Summary: Declarative network manager API
License: LGPLv2+
URL: https://github.com/%{srcname}/%{srcname}
@ -29,6 +29,13 @@ Patch15: BZ_1908724-sriov-use-verification-retry-to-wait-VF-been-created.
Patch16: BZ_1916073_better-handling-for-timeout.patch
Patch17: BZ_1918712_use_uuid_for_vlan_vxlan_parent.patch
Patch18: BZ_1916073_retry_on_failure_when_activate.patch
Patch19: BZ_1931290-SRIOV-Remove-VF-interface-when-total-vfs-decrease.patch
Patch20: BZ_1931290-SRIOV-Do-not-create-VF-profiles-automatically.patch
Patch21: BZ_1931784-SR-IOV-increase-the-verification-timeout-if-SR-IOV.patch
Patch22: BZ_1931784-SR-IOV-fail-on-verification-if-total_vfs-does-not-ma.patch
Patch23: BZ_1932247-bridge-do-not-bring-up-existing-ports.patch
Patch24: BZ_1932247-nm.applier-ignore-not-desired-unmanaged-ifaces.patch
Patch25: BZ_1933538-bridge-bond-New-property-Interface.COPY_MAC_FROM.patch
BuildArch: noarch
BuildRequires: python3-devel
BuildRequires: python3-setuptools
@ -99,6 +106,14 @@ gpgv2 --keyring ./gpgkey-mantainers.gpg %{SOURCE1} %{SOURCE0}
%{python3_sitelib}/%{libname}/plugins/__pycache__/nmstate_plugin_ovsdb*
%changelog
* Wed Mar 03 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 0.3.4-27
- Introduce `Interface.COPY_MAC_FROM` from bond and bridge. RHBZ#1933538
* Wed Mar 03 2021 Fernando Fernandez Mancera <ferferna@redhat.com> - 0.3.4-26
- New patch do not activating SR-IOV VFs automatically. RHBZ#1931290
- New patch fixing Nmstate waits when SR-IOV VFs are decreased. RHBZ#1931784
- New patch fixing Nmstate activating unmanaged bridge ports. RHBZ#1932247
* Fri Feb 05 2021 Gris Ge <fge@redhat.com> - 0.3.4-25
- Remove patch for fixing the autoconnect on existing profile. RHBZ#1918712