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