209 lines
7.2 KiB
Diff
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
|
|
|