Skip to content

Commit d92baac

Browse files
feat: Support wait_ip property
Add support for the `wait_ip` property, the system will consider connection activated only when specific IP stack is configured. This enables flexibility in scenarios such as IPv6-only networks, where the overall network configuration can still succeed when IPv4 configuration fails but IPv6 completes successfully. The `wait_ip` can be configured with the following possible values: * "any": System will consider interface activated when any IP stack is configured. * "ipv4": System will wait IPv4 been configured. * "ipv6": System will wait IPv6 been configured. * "ipv4+ipv6": System will wait both IPv4 and IPv6 been configured. Resolves: https://issues.redhat.com/browse/RHEL-63026 Signed-off-by: Wen Liang <[email protected]>
1 parent 38a61f7 commit d92baac

File tree

8 files changed

+128
-0
lines changed

8 files changed

+128
-0
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,16 @@ The IP configuration supports the following options:
591591

592592
The default gateway for IPv4 (`gateway4`) or IPv6 (`gateway6`) packets.
593593

594+
- `wait_ip`
595+
596+
The property controls whether the system should wait for a specific IP stack to be
597+
configured before considering the connection activated. It can be set to "any",
598+
"ipv4","ipv6," or "ipv4+ipv6". When set to "any," the system considers the connection
599+
activated when any IP stack is configured. "ipv4" ensures the system waits for IPv4
600+
configuration, while "ipv6" ensures the system waits for IPv6 configuration. The
601+
"ipv4+ipv6" option requires both IPv4 and IPv6 to be configured before the connection
602+
is considered activated.
603+
594604
- `ipv4_ignore_auto_dns` and `ipv6_ignore_auto_dns`
595605

596606
If enabled, the automatically configured name servers and search domains (via

examples/eth_with_wait_ip.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
---
3+
- name: Configuring wait_ip on ethernet connection
4+
hosts: all
5+
vars:
6+
network_connections:
7+
- name: eth0
8+
state: up
9+
type: ethernet
10+
interface_name: eth0
11+
ip:
12+
address:
13+
- 192.0.2.42/30
14+
- 2001:db8::23/64
15+
wait_ip: any
16+
17+
roles:
18+
- linux-system-roles.network

library/network_connections.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,22 @@ def connection_create(self, connections, idx, connection_current=None):
12051205
)
12061206
if ip["gateway6"] is not None:
12071207
s_ip6.set_property(NM.SETTING_IP_CONFIG_GATEWAY, ip["gateway6"])
1208+
1209+
# Mapping of wait_ip values to the may-fail settings for IPv4 and IPv6
1210+
may_fail_mapping = {
1211+
"any": (True, True),
1212+
"ipv4": (False, True),
1213+
"ipv6": (True, False),
1214+
"ipv4+ipv6": (False, False),
1215+
}
1216+
1217+
may_fail_ipv4, may_fail_ipv6 = may_fail_mapping.get(
1218+
ip["wait_ip"], (True, True)
1219+
)
1220+
1221+
s_ip4.set_property(NM.SETTING_IP_CONFIG_MAY_FAIL, may_fail_ipv4)
1222+
s_ip6.set_property(NM.SETTING_IP_CONFIG_MAY_FAIL, may_fail_ipv6)
1223+
12081224
if ip["route_metric6"] is not None and ip["route_metric6"] >= 0:
12091225
s_ip6.set_property(
12101226
NM.SETTING_IP_CONFIG_ROUTE_METRIC, ip["route_metric6"]

module_utils/network_lsr/argument_validator.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,11 @@ def __init__(self):
907907
ArgValidatorBool("auto6", default_value=None),
908908
ArgValidatorBool("ipv4_ignore_auto_dns", default_value=None),
909909
ArgValidatorBool("ipv6_ignore_auto_dns", default_value=None),
910+
ArgValidatorStr(
911+
"wait_ip",
912+
enum_values=["any", "ipv4", "ipv6", "ipv4+ipv6"],
913+
default_value="any",
914+
),
910915
ArgValidatorBool("ipv6_disabled", default_value=None),
911916
ArgValidatorIP("gateway6", family=socket.AF_INET6),
912917
ArgValidatorNum(
@@ -960,6 +965,7 @@ def __init__(self):
960965
"auto6": True,
961966
"ipv4_ignore_auto_dns": None,
962967
"ipv6_ignore_auto_dns": None,
968+
"wait_ip": "any",
963969
"ipv6_disabled": False,
964970
"gateway6": None,
965971
"route_metric6": None,
@@ -2522,6 +2528,14 @@ def _ipv6_is_not_configured(connection):
25222528
"ip.ipv4_ignore_auto_dns or ip.ipv6_ignore_auto_dns is not "
25232529
"supported by initscripts.",
25242530
)
2531+
# initscripts does not support ip.wait_ip,
2532+
# so raise errors when network provider is initscripts
2533+
if connection["ip"]["wait_ip"] != "any":
2534+
if mode == self.VALIDATE_ONE_MODE_INITSCRIPTS:
2535+
raise ValidationError.from_connection(
2536+
idx,
2537+
"ip.wait_ip is not supported by initscripts.",
2538+
)
25252539
# initscripts does not support ip.dns_options, so raise errors when network
25262540
# provider is initscripts
25272541
if connection["ip"]["dns_options"]:

tests/playbooks/tests_dummy.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
vars:
66
autocon_retries: 2
77
interface: dummy0
8+
wait_ip: ipv4+ipv6
89
profile: "{{ interface }}"
910
lsr_fail_debug:
1011
- __network_connections_result
@@ -32,6 +33,7 @@
3233
- tasks/assert_profile_present.yml
3334
- tasks/assert_device_present.yml
3435
- tasks/assert_autoconnect_retries.yml
36+
- tasks/assert_may_fail.yml
3537
lsr_cleanup:
3638
- tasks/cleanup_profile+device.yml
3739
- tasks/check_network_dns.yml

tests/tasks/assert_may_fail.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
---
3+
- name: Get ipv4.may-fail
4+
command: >
5+
nmcli -f ipv4.may-fail connection show {{ profile }}
6+
register: may_fail4
7+
ignore_errors: true
8+
changed_when: false
9+
- name: Get ipv6.may-fail
10+
command: >
11+
nmcli -f ipv6.may-fail connection show {{ profile }}
12+
register: may_fail6
13+
ignore_errors: true
14+
changed_when: false
15+
- name: "Assert that ipv4.may-fail is configured as specified"
16+
assert:
17+
that:
18+
- may_fail4.stdout.split(":")[1] | trim
19+
== "no"
20+
msg: "ipv4.may-fail is configured as
21+
{{ may_fail4.stdout.split(':')[1] | trim }}
22+
but wait_ip is specified as {{ wait_ip }}"
23+
- name: "Assert that ipv6.may-fail is configured as specified"
24+
assert:
25+
that:
26+
- may_fail6.stdout.split(":")[1] | trim
27+
== "no"
28+
msg: "ipv6.may-fail is configured as
29+
{{ may_fail6.stdout.split(':')[1] | trim }}
30+
but wait_ip is specified as {{ wait_ip }}"

tests/tasks/create_dummy_profile.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
ip:
1313
address:
1414
- "192.0.2.42/30"
15+
- "2001:db8::23/64"
16+
wait_ip: "{{ wait_ip }}"
1517
- name: Show result
1618
debug:
1719
var: __network_connections_result

0 commit comments

Comments
 (0)