Skip to content

Commit baf207d

Browse files
committed
[radvd] Add radvd role for IPv6 RA management
Creates a new Ansible role to manage radvd (Router Advertisement Daemon) configuration for IPv6 networks. Features: - Manages system radvd.service and /etc/radvd.conf - Configuration fragment assembly from /etc/cifmw-radvd.d/ - Support for SLAAC and DHCPv6 (M-flag, O-flag) - IPv6 prefix, route, and RDNSS advertisement - Dynamic network addition/removal via tasks_from - Molecule test coverage Assisted-By: Claude Code/claude-4.5-sonnet Signed-off-by: Harald Jensås <[email protected]>
1 parent 3029813 commit baf207d

File tree

16 files changed

+792
-0
lines changed

16 files changed

+792
-0
lines changed

docs/dictionary/en-custom.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ arxcruz
2323
AssignedTeam
2424
auth
2525
authfile
26+
autoconfiguration
2627
autohold
2728
autoholds
2829
autoscale
@@ -147,6 +148,7 @@ dfb
147148
dfce
148149
dfg
149150
dhcp
151+
dhcpv
150152
dib
151153
dicts
152154
dirs
@@ -480,9 +482,11 @@ qtjhbpzc
480482
quickstart
481483
rabbitmq
482484
radosgw
485+
radvd
483486
raukadah
484487
rbd
485488
rdk
489+
rdnss
486490
rdo
487491
rdoinfo
488492
rdoproject
@@ -529,6 +533,7 @@ Sinha
529533
sizepercent
530534
skbg
531535
skiplist
536+
slaac
532537
snr
533538
specificities
534539
spnego
@@ -537,6 +542,7 @@ src
537542
sshkey
538543
ssl
539544
sso
545+
stateful
540546
stderr
541547
stdout
542548
stp
@@ -584,6 +590,7 @@ uidmap
584590
unclaim
585591
undefine
586592
undercloud
593+
unicast
587594
unittest
588595
unmanaged
589596
uoyt

roles/radvd/README.md

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
# radvd
2+
3+
Manage radvd (Router Advertisement Daemon) configuration.
4+
5+
This role provides IPv6 Router Advertisements for network interfaces, enabling
6+
Stateless Address Autoconfiguration (SLAAC) and/or DHCPv6.
7+
8+
## Privilege escalation
9+
10+
- Package installation
11+
- Writing in protected locations `/etc/radvd.conf`, `/etc/cifmw-radvd.d`
12+
- Managing system service `radvd.service`
13+
14+
## Common Parameters
15+
16+
* `cifmw_radvd_basedir`: (String) Configuration fragments directory. Defaults to `/etc/cifmw-radvd.d`.
17+
* `cifmw_radvd_networks`: (List) List of networks to configure. Defaults to `[]`.
18+
* `cifmw_radvd_remove_package`: (Bool) Remove the radvd package during cleanup. Defaults to `false`.
19+
20+
## Network Configuration
21+
22+
Each network in `cifmw_radvd_networks` supports the following parameters:
23+
24+
* `name`: (String) Network/interface name. **Required**.
25+
* `state`: (String) Network status. Must be either `present` or `absent`. Defaults to `present`.
26+
* `prefixes`: (List[mapping]) List of IPv6 prefixes to advertise. **Required when state is present**.
27+
* `adv_send_advert`: (Bool) Enable/disable router advertisements. Defaults to `true`.
28+
* `adv_managed_flag`: (Bool) Managed address configuration flag (M-flag). Indicates DHCPv6 for addresses.
29+
* `adv_other_config_flag`: (Bool) Other configuration flag (O-flag). Indicates DHCPv6 for other configuration.
30+
* `adv_ra_solicited_unicast`: (Bool) Enable unicast router advertisements.
31+
* `adv_link_mtu`: (Int) Advertised MTU for the link.
32+
* `min_rtr_adv_interval`: (Int) Minimum router advertisement interval in seconds.
33+
* `max_rtr_adv_interval`: (Int) Maximum router advertisement interval in seconds.
34+
* `routes`: (List[mapping]) List of routes to advertise. Optional.
35+
* `rdnss`: (List[mapping]) List of recursive DNS servers to advertise. Optional.
36+
37+
### Prefix mapping
38+
39+
* `network`: (String) IPv6 prefix (e.g., `2001:db8:1::/64`). **Required**.
40+
* `adv_on_link`: (Bool) On-link flag. Defaults to `true`.
41+
* `adv_autonomous`: (Bool) Autonomous address configuration flag (SLAAC). Defaults to `true`.
42+
* `adv_router_addr`: (Bool) Include router address in prefix information.
43+
* `adv_valid_lifetime`: (String/Int) Valid lifetime for the prefix (e.g., `86400`, `infinity`).
44+
* `adv_preferred_lifetime`: (String/Int) Preferred lifetime for the prefix.
45+
46+
### Route mapping
47+
48+
* `network`: (String) IPv6 route prefix. **Required**.
49+
* `adv_route_preference`: (String) Route preference (`low`, `medium`, `high`).
50+
* `adv_route_lifetime`: (Int) Route lifetime in seconds.
51+
52+
### RDNSS mapping
53+
54+
* `servers`: (List[String]) List of IPv6 DNS server addresses. **Required**.
55+
* `adv_rdnss_lifetime`: (Int) RDNSS lifetime in seconds.
56+
57+
## Examples
58+
59+
### Basic network with SLAAC only
60+
61+
```yaml
62+
- name: Configure radvd networks
63+
vars:
64+
cifmw_radvd_networks:
65+
- name: testnet
66+
adv_managed_flag: false
67+
adv_other_config_flag: false
68+
adv_link_mtu: 1500
69+
min_rtr_adv_interval: 30
70+
max_rtr_adv_interval: 100
71+
prefixes:
72+
- network: "2001:db8:1::/64"
73+
adv_on_link: true
74+
adv_autonomous: true
75+
adv_router_addr: true
76+
ansible.builtin.include_role:
77+
name: radvd
78+
```
79+
80+
### Network with DHCPv6 for addresses and other configuration
81+
82+
```yaml
83+
- name: Configure radvd with DHCPv6
84+
vars:
85+
cifmw_radvd_networks:
86+
- name: provisioning
87+
adv_managed_flag: true
88+
adv_other_config_flag: true
89+
adv_ra_solicited_unicast: true
90+
adv_link_mtu: 1500
91+
min_rtr_adv_interval: 30
92+
max_rtr_adv_interval: 100
93+
prefixes:
94+
- network: "2001:db8:2::/64"
95+
adv_on_link: true
96+
adv_autonomous: false
97+
rdnss:
98+
- servers:
99+
- "2001:db8:2::53"
100+
adv_rdnss_lifetime: 300
101+
ansible.builtin.include_role:
102+
name: radvd
103+
```
104+
105+
### Multiple networks
106+
107+
```yaml
108+
- name: Configure multiple networks
109+
vars:
110+
cifmw_radvd_networks:
111+
- name: net1
112+
adv_managed_flag: true
113+
adv_other_config_flag: true
114+
adv_link_mtu: 1500
115+
min_rtr_adv_interval: 30
116+
max_rtr_adv_interval: 100
117+
prefixes:
118+
- network: "2001:db8:1::/64"
119+
adv_on_link: true
120+
adv_autonomous: true
121+
- name: net2
122+
adv_managed_flag: false
123+
adv_other_config_flag: false
124+
prefixes:
125+
- network: "2001:db8:2::/64"
126+
adv_on_link: true
127+
adv_autonomous: true
128+
ansible.builtin.include_role:
129+
name: radvd
130+
```
131+
132+
### Remove a network configuration
133+
134+
```yaml
135+
- name: Remove radvd configuration for a network
136+
vars:
137+
cifmw_radvd_networks:
138+
- name: testnet
139+
state: absent
140+
ansible.builtin.include_role:
141+
name: radvd
142+
```
143+
144+
### Adding a single network dynamically
145+
146+
You can also add a single network using `tasks_from: manage_network.yml`:
147+
148+
```yaml
149+
- name: Add a single network to radvd
150+
vars:
151+
cifmw_radvd_network:
152+
name: testnet
153+
adv_managed_flag: true
154+
adv_other_config_flag: true
155+
adv_link_mtu: 1500
156+
min_rtr_adv_interval: 30
157+
max_rtr_adv_interval: 100
158+
prefixes:
159+
- network: "2001:db8:1::/64"
160+
adv_on_link: true
161+
adv_autonomous: true
162+
adv_router_addr: true
163+
ansible.builtin.include_role:
164+
name: radvd
165+
tasks_from: manage_network.yml
166+
```
167+
168+
### Cleanup entire radvd service
169+
170+
```yaml
171+
- name: Cleanup radvd
172+
vars:
173+
# Set to true to also remove the radvd package (default: false)
174+
cifmw_radvd_remove_package: false
175+
ansible.builtin.include_role:
176+
name: radvd
177+
tasks_from: cleanup.yml
178+
```
179+
180+
## Understanding the flags
181+
182+
### Managed Flag (M-flag) - `adv_managed_flag`
183+
184+
When set to `true`, hosts should use DHCPv6 to obtain IPv6 addresses (stateful DHCPv6).
185+
When set to `false`, hosts should use SLAAC (Stateless Address Autoconfiguration) based on the advertised prefix.
186+
187+
### Other Config Flag (O-flag) - `adv_other_config_flag`
188+
189+
When set to `true`, hosts should use DHCPv6 to obtain other configuration information (DNS, NTP, etc.).
190+
191+
### Common configurations
192+
193+
1. **SLAAC only**: `adv_managed_flag: false`, `adv_other_config_flag: false`, `adv_autonomous: true`
194+
2. **SLAAC + DHCPv6 for options**: `adv_managed_flag: false`, `adv_other_config_flag: true`, `adv_autonomous: true`
195+
3. **DHCPv6 for everything**: `adv_managed_flag: true`, `adv_other_config_flag: true`, `adv_autonomous: false`
196+
197+
## Notes
198+
199+
- The interface/bridge specified by the `name` parameter must exist before radvd can advertise on it.
200+
- IPv6 forwarding must be enabled on the host for router advertisements to work properly.
201+
- Multiple prefixes can be advertised on the same interface.
202+
- The role uses the system `radvd.service` from the RPM package.
203+
- Configuration is assembled from fragments in `/etc/cifmw-radvd.d/` into `/etc/radvd.conf`.

roles/radvd/defaults/main.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
18+
# All variables within this role should have a prefix of "cifmw_radvd"
19+
20+
cifmw_radvd_basedir: "/etc/cifmw-radvd.d"
21+
cifmw_radvd_networks: []
22+
cifmw_radvd_remove_package: false

roles/radvd/handlers/main.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
- name: Restart radvd service
18+
become: true
19+
ansible.builtin.systemd:
20+
name: radvd.service
21+
state: restarted

roles/radvd/meta/main.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
18+
galaxy_info:
19+
author: CI Framework
20+
description: CI Framework Role -- radvd
21+
company: Red Hat
22+
license: Apache-2.0
23+
min_ansible_version: "2.14"
24+
namespace: cifmw
25+
galaxy_tags:
26+
- cifmw
27+
28+
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
29+
# if you add dependencies to this list.
30+
dependencies: []
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
# Copyright Red Hat, Inc.
3+
# All Rights Reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
6+
# not use this file except in compliance with the License. You may obtain
7+
# a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
17+
- name: Cleanup
18+
hosts: all
19+
tasks:
20+
- name: Copy generated content in ci-framework-data/artifacts
21+
vars:
22+
dest_dir: >-
23+
{{
24+
(ansible_user_dir,
25+
'ci-framework-data',
26+
'artifacts') | path_join
27+
}}
28+
ansible.posix.synchronize:
29+
src: "{{ item }}"
30+
dest: "{{ dest_dir }}"
31+
loop:
32+
- /etc/radvd.conf
33+
- /etc/cifmw-radvd.d/
34+
35+
- name: Cleanup radvd
36+
ansible.builtin.import_role:
37+
name: "radvd"
38+
tasks_from: "cleanup.yml"
39+
40+
- name: Check if cleanup files still exist
41+
become: true
42+
ansible.builtin.stat:
43+
path: "{{ item }}"
44+
register: _cleanup_check
45+
loop:
46+
- /etc/radvd.conf
47+
- /etc/cifmw-radvd.d
48+
49+
- name: Assert cleanup was successful
50+
ansible.builtin.assert:
51+
that:
52+
- not (_cleanup_check.results | map(attribute='stat.exists') | list | max)

0 commit comments

Comments
 (0)