Skip to content

Commit

Permalink
feat: Support wait_ip property
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
Wen Liang authored and liangwen12year committed Oct 29, 2024
1 parent 38a61f7 commit d92baac
Show file tree
Hide file tree
Showing 8 changed files with 128 additions and 0 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,16 @@ The IP configuration supports the following options:

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

- `wait_ip`

The property controls whether the system should wait for a specific IP stack to be
configured before considering the connection activated. It can be set to "any",
"ipv4","ipv6," or "ipv4+ipv6". When set to "any," the system considers the connection
activated when any IP stack is configured. "ipv4" ensures the system waits for IPv4
configuration, while "ipv6" ensures the system waits for IPv6 configuration. The
"ipv4+ipv6" option requires both IPv4 and IPv6 to be configured before the connection
is considered activated.

- `ipv4_ignore_auto_dns` and `ipv6_ignore_auto_dns`

If enabled, the automatically configured name servers and search domains (via
Expand Down
18 changes: 18 additions & 0 deletions examples/eth_with_wait_ip.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# SPDX-License-Identifier: BSD-3-Clause
---
- name: Configuring wait_ip on ethernet connection
hosts: all
vars:
network_connections:
- name: eth0
state: up
type: ethernet
interface_name: eth0
ip:
address:
- 192.0.2.42/30
- 2001:db8::23/64
wait_ip: any

roles:
- linux-system-roles.network
16 changes: 16 additions & 0 deletions library/network_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,22 @@ def connection_create(self, connections, idx, connection_current=None):
)
if ip["gateway6"] is not None:
s_ip6.set_property(NM.SETTING_IP_CONFIG_GATEWAY, ip["gateway6"])

# Mapping of wait_ip values to the may-fail settings for IPv4 and IPv6
may_fail_mapping = {
"any": (True, True),
"ipv4": (False, True),
"ipv6": (True, False),
"ipv4+ipv6": (False, False),
}

may_fail_ipv4, may_fail_ipv6 = may_fail_mapping.get(
ip["wait_ip"], (True, True)
)

s_ip4.set_property(NM.SETTING_IP_CONFIG_MAY_FAIL, may_fail_ipv4)
s_ip6.set_property(NM.SETTING_IP_CONFIG_MAY_FAIL, may_fail_ipv6)

if ip["route_metric6"] is not None and ip["route_metric6"] >= 0:
s_ip6.set_property(
NM.SETTING_IP_CONFIG_ROUTE_METRIC, ip["route_metric6"]
Expand Down
14 changes: 14 additions & 0 deletions module_utils/network_lsr/argument_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,11 @@ def __init__(self):
ArgValidatorBool("auto6", default_value=None),
ArgValidatorBool("ipv4_ignore_auto_dns", default_value=None),
ArgValidatorBool("ipv6_ignore_auto_dns", default_value=None),
ArgValidatorStr(
"wait_ip",
enum_values=["any", "ipv4", "ipv6", "ipv4+ipv6"],
default_value="any",
),
ArgValidatorBool("ipv6_disabled", default_value=None),
ArgValidatorIP("gateway6", family=socket.AF_INET6),
ArgValidatorNum(
Expand Down Expand Up @@ -960,6 +965,7 @@ def __init__(self):
"auto6": True,
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"wait_ip": "any",
"ipv6_disabled": False,
"gateway6": None,
"route_metric6": None,
Expand Down Expand Up @@ -2522,6 +2528,14 @@ def _ipv6_is_not_configured(connection):
"ip.ipv4_ignore_auto_dns or ip.ipv6_ignore_auto_dns is not "
"supported by initscripts.",
)
# initscripts does not support ip.wait_ip,
# so raise errors when network provider is initscripts
if connection["ip"]["wait_ip"] != "any":
if mode == self.VALIDATE_ONE_MODE_INITSCRIPTS:
raise ValidationError.from_connection(
idx,
"ip.wait_ip is not supported by initscripts.",
)
# initscripts does not support ip.dns_options, so raise errors when network
# provider is initscripts
if connection["ip"]["dns_options"]:
Expand Down
2 changes: 2 additions & 0 deletions tests/playbooks/tests_dummy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
vars:
autocon_retries: 2
interface: dummy0
wait_ip: ipv4+ipv6
profile: "{{ interface }}"
lsr_fail_debug:
- __network_connections_result
Expand Down Expand Up @@ -32,6 +33,7 @@
- tasks/assert_profile_present.yml
- tasks/assert_device_present.yml
- tasks/assert_autoconnect_retries.yml
- tasks/assert_may_fail.yml
lsr_cleanup:
- tasks/cleanup_profile+device.yml
- tasks/check_network_dns.yml
30 changes: 30 additions & 0 deletions tests/tasks/assert_may_fail.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# SPDX-License-Identifier: BSD-3-Clause
---
- name: Get ipv4.may-fail
command: >
nmcli -f ipv4.may-fail connection show {{ profile }}
register: may_fail4
ignore_errors: true
changed_when: false
- name: Get ipv6.may-fail
command: >
nmcli -f ipv6.may-fail connection show {{ profile }}
register: may_fail6
ignore_errors: true
changed_when: false
- name: "Assert that ipv4.may-fail is configured as specified"
assert:
that:
- may_fail4.stdout.split(":")[1] | trim
== "no"
msg: "ipv4.may-fail is configured as
{{ may_fail4.stdout.split(':')[1] | trim }}
but wait_ip is specified as {{ wait_ip }}"
- name: "Assert that ipv6.may-fail is configured as specified"
assert:
that:
- may_fail6.stdout.split(":")[1] | trim
== "no"
msg: "ipv6.may-fail is configured as
{{ may_fail6.stdout.split(':')[1] | trim }}
but wait_ip is specified as {{ wait_ip }}"
2 changes: 2 additions & 0 deletions tests/tasks/create_dummy_profile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
ip:
address:
- "192.0.2.42/30"
- "2001:db8::23/64"
wait_ip: "{{ wait_ip }}"
- name: Show result
debug:
var: __network_connections_result
Expand Down
Loading

0 comments on commit d92baac

Please sign in to comment.