nmstate/SOURCES/BZ_2170078-Introduce-wait-ip.patch
2023-04-04 09:49:00 +00:00

209 lines
7.2 KiB
Diff

From ef23275126898f316cb3e7e2df552c006e867105 Mon Sep 17 00:00:00 2001
From: Gris Ge <fge@redhat.com>
Date: Tue, 14 Feb 2023 15:20:21 +0800
Subject: [PATCH] ip: Introduce `Interface.WAIT_IP`
This patch is introducing `Interface.WAIT_IP` property with these
possible values:
* `Interface.WAIT_IP_ANY`("any"):
System will consider interface activated when any IP stack is
configured(neither static or automatic).
* `Interface.WAIT_IP_IPV4`("ipv4"):
System will wait IPv4 been configured.
* `Interface.WAIT_IP_IPV6`("ipv6"):
System will wait IPv6 been configured.
* `Introduce.WAIT_IP_IPV4_AND_IPV6`("ipv4+ipv6"):
System will wait both IPv4 and IPv6 been configured.
Considering this old branch, there is no validation on invalid use cases
like setting wait-ip on disabled IP stack.
Example YAML on waiting both IP stacks:
```yml
---
interfaces:
- name: eth1
type: ethernet
state: up
mtu: 1500
wait-ip: ipv4+ipv6
ipv4:
enabled: true
dhcp: true
ipv6:
enabled: true
dhcp: true
autoconf: true
```
Integration test case included.
Signed-off-by: Gris Ge <fge@redhat.com>
---
libnmstate/nm/connection.py | 9 +++----
libnmstate/nm/ip.py | 48 +++++++++++++++++++++++++++++++++++++
libnmstate/nm/plugin.py | 29 +++++++++-------------
libnmstate/schema.py | 5 ++++
4 files changed, 69 insertions(+), 22 deletions(-)
create mode 100644 libnmstate/nm/ip.py
diff --git a/libnmstate/nm/connection.py b/libnmstate/nm/connection.py
index 1974cfd4..1fbb380b 100644
--- a/libnmstate/nm/connection.py
+++ b/libnmstate/nm/connection.py
@@ -39,6 +39,7 @@ from .common import NM
from .ethtool import create_ethtool_setting
from .ieee_802_1x import create_802_1x_setting
from .infiniband import create_setting as create_infiniband_setting
+from .ip import set_wait_ip
from .ipv4 import create_setting as create_ipv4_setting
from .ipv6 import create_setting as create_ipv6_setting
from .lldp import apply_lldp_setting
@@ -106,10 +107,10 @@ class _ConnectionSetting:
def create_new_nm_simple_conn(iface, nm_profile):
nm_iface_type = Api2Nm.get_iface_type(iface.type)
iface_info = iface.to_dict()
- settings = [
- create_ipv4_setting(iface_info.get(Interface.IPV4), nm_profile),
- create_ipv6_setting(iface_info.get(Interface.IPV6), nm_profile),
- ]
+ ipv4_set = create_ipv4_setting(iface_info.get(Interface.IPV4), nm_profile)
+ ipv6_set = create_ipv6_setting(iface_info.get(Interface.IPV6), nm_profile)
+ set_wait_ip(ipv4_set, ipv6_set, iface_info.get(Interface.WAIT_IP))
+ settings = [ipv4_set, ipv6_set]
con_setting = _ConnectionSetting()
if nm_profile and not is_multiconnect_profile(nm_profile):
con_setting.import_by_profile(nm_profile, iface.is_controller)
diff --git a/libnmstate/nm/ip.py b/libnmstate/nm/ip.py
new file mode 100644
index 00000000..d0fc1e3b
--- /dev/null
+++ b/libnmstate/nm/ip.py
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+from libnmstate.schema import Interface
+
+
+def get_wait_ip(applied_config):
+ if applied_config:
+ nm_ipv4_may_fail = _get_may_fail(applied_config, False)
+ nm_ipv6_may_fail = _get_may_fail(applied_config, True)
+ if nm_ipv4_may_fail and not nm_ipv6_may_fail:
+ return Interface.WAIT_IP_IPV6
+ elif not nm_ipv4_may_fail and nm_ipv6_may_fail:
+ return Interface.WAIT_IP_IPV4
+ elif not nm_ipv4_may_fail and not nm_ipv6_may_fail:
+ return Interface.WAIT_IP_IPV4_AND_IPV6
+ return Interface.WAIT_IP_ANY
+
+
+def set_wait_ip(nm_ipv4_set, nm_ipv6_set, wait_ip):
+ if nm_ipv4_set:
+ if wait_ip == Interface.WAIT_IP_ANY:
+ nm_ipv4_set.props.may_fail = True
+ elif wait_ip in (
+ Interface.WAIT_IP_IPV4,
+ Interface.WAIT_IP_IPV4_AND_IPV6,
+ ):
+ nm_ipv4_set.props.may_fail = False
+ if nm_ipv6_set:
+ if wait_ip == Interface.WAIT_IP_ANY:
+ nm_ipv6_set.props.may_fail = True
+ elif wait_ip in (
+ Interface.WAIT_IP_IPV6,
+ Interface.WAIT_IP_IPV4_AND_IPV6,
+ ):
+ nm_ipv6_set.props.may_fail = False
+
+
+def _get_may_fail(nm_profile, is_ipv6):
+ if is_ipv6:
+ nm_set = nm_profile.get_setting_ip6_config()
+ else:
+ nm_set = nm_profile.get_setting_ip4_config()
+
+ if nm_set:
+ return nm_set.props.may_fail
+ else:
+ # NM is defaulting `may-fail` as True
+ return True
diff --git a/libnmstate/nm/plugin.py b/libnmstate/nm/plugin.py
index bca1aedd..9bbbbb98 100644
--- a/libnmstate/nm/plugin.py
+++ b/libnmstate/nm/plugin.py
@@ -1,21 +1,5 @@
-#
-# Copyright (c) 2020-2021 Red Hat, Inc.
-#
-# This file is part of nmstate
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Lesser General Public License as published by
-# the Free Software Foundation, either version 2.1 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public License
-# along with this program. If not, see <https://www.gnu.org/licenses/>.
-#
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
from distutils.version import StrictVersion
import logging
from operator import itemgetter
@@ -25,6 +9,8 @@ from libnmstate.error import NmstateNotSupportedError
from libnmstate.error import NmstateValueError
from libnmstate.schema import DNS
from libnmstate.schema import Interface
+from libnmstate.schema import InterfaceIPv4
+from libnmstate.schema import InterfaceIPv6
from libnmstate.schema import InterfaceType
from libnmstate.schema import LLDP
from libnmstate.plugin import NmstatePlugin
@@ -41,6 +27,7 @@ from .device import list_devices
from .dns import get_running as get_dns_running
from .dns import get_running_config as get_dns_running_config
from .infiniband import get_info as get_infiniband_info
+from .ip import get_wait_ip
from .ipv4 import get_info as get_ipv4_info
from .ipv6 import get_info as get_ipv6_info
from .lldp import get_info as get_lldp_info
@@ -190,6 +177,12 @@ class NetworkManagerPlugin(NmstatePlugin):
if applied_config:
iface_info.update(get_ovsdb_external_ids(applied_config))
+ if iface_info.get(Interface.IPV4, {}).get(
+ InterfaceIPv4.ENABLED
+ ) or iface_info.get(Interface.IPV6, {}).get(
+ InterfaceIPv6.ENABLED
+ ):
+ iface_info[Interface.WAIT_IP] = get_wait_ip(applied_config)
info.append(iface_info)
diff --git a/libnmstate/schema.py b/libnmstate/schema.py
index e740abff..c3d3fcfc 100644
--- a/libnmstate/schema.py
+++ b/libnmstate/schema.py
@@ -49,6 +49,11 @@ class Interface:
COPY_MAC_FROM = "copy-mac-from"
ACCEPT_ALL_MAC_ADDRESSES = "accept-all-mac-addresses"
CONTROLLER = "controller"
+ WAIT_IP = "wait-ip"
+ WAIT_IP_ANY = "any"
+ WAIT_IP_IPV4 = "ipv4"
+ WAIT_IP_IPV6 = "ipv6"
+ WAIT_IP_IPV4_AND_IPV6 = "ipv4+ipv6"
class Route:
--
2.39.2