Skip to content

Commit b46e4a8

Browse files
authored
Explicit set IPV6_AUTOCONF and IPV6_FORCE_ACCEPT_RA on static6 (canonical#634)
The static and static6 subnet types for network_data.json were being ignored by the Openstack handler, this would cause the code to break and not function properly. As of today, if a static6 configuration is chosen, the interface will still eventually be available to receive router advertisements or be set from NetworkManager to wait for them and cycle the interface in negative case. It is safe to assume that if the interface is manually configured to use static ipv6 address, there's no need to wait for router advertisements. This patch will set automatically IPV6_AUTOCONF and IPV6_FORCE_ACCEPT_RA both to "no" in this case. This patch fixes the specific behavior only for RHEL flavor and sysconfig renderer. It also introduces new unit tests for the specific case as well as adjusts some existent tests to be compatible with the new options. This patch also addresses this problem by assigning the appropriate subnet type for each case on the openstack handler. rhbz: #1889635 rhbz: #1889635 Signed-off-by: Eduardo Otubo otubo@redhat.com
1 parent 3c432b3 commit b46e4a8

File tree

5 files changed

+113
-2
lines changed

5 files changed

+113
-2
lines changed

cloudinit/net/network_state.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -820,7 +820,8 @@ def _normalize_subnet(subnet):
820820

821821
if subnet.get('type') in ('static', 'static6'):
822822
normal_subnet.update(
823-
_normalize_net_keys(normal_subnet, address_keys=('address',)))
823+
_normalize_net_keys(normal_subnet, address_keys=(
824+
'address', 'ip_address',)))
824825
normal_subnet['routes'] = [_normalize_route(r)
825826
for r in subnet.get('routes', [])]
826827

cloudinit/net/sysconfig.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,10 @@ def _render_subnets(cls, iface_cfg, subnets, has_default_route, flavor):
463463
iface_cfg[mtu_key] = subnet['mtu']
464464
else:
465465
iface_cfg[mtu_key] = subnet['mtu']
466+
467+
if subnet_is_ipv6(subnet) and flavor == 'rhel':
468+
iface_cfg['IPV6_FORCE_ACCEPT_RA'] = False
469+
iface_cfg['IPV6_AUTOCONF'] = False
466470
elif subnet_type == 'manual':
467471
if flavor == 'suse':
468472
LOG.debug('Unknown subnet type setting "%s"', subnet_type)

cloudinit/sources/helpers/openstack.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,11 +602,17 @@ def convert_net_json(network_json=None, known_macs=None):
602602
elif network['type'] in ['ipv6_slaac', 'ipv6_dhcpv6-stateless',
603603
'ipv6_dhcpv6-stateful']:
604604
subnet.update({'type': network['type']})
605-
elif network['type'] in ['ipv4', 'ipv6']:
605+
elif network['type'] in ['ipv4', 'static']:
606606
subnet.update({
607607
'type': 'static',
608608
'address': network.get('ip_address'),
609609
})
610+
elif network['type'] in ['ipv6', 'static6']:
611+
cfg.update({'accept-ra': False})
612+
subnet.update({
613+
'type': 'static6',
614+
'address': network.get('ip_address'),
615+
})
610616

611617
# Enable accept_ra for stateful and legacy ipv6_dhcp types
612618
if network['type'] in ['ipv6_dhcpv6-stateful', 'ipv6_dhcp']:

tests/unittests/test_distros/test_netconfig.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,9 @@ def test_apply_network_config_ipv6_rh(self):
514514
DEVICE=eth0
515515
IPV6ADDR=2607:f0d0:1002:0011::2/64
516516
IPV6INIT=yes
517+
IPV6_AUTOCONF=no
517518
IPV6_DEFAULTGW=2607:f0d0:1002:0011::1
519+
IPV6_FORCE_ACCEPT_RA=no
518520
NM_CONTROLLED=no
519521
ONBOOT=yes
520522
TYPE=Ethernet

tests/unittests/test_net.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,9 @@
752752
IPV6ADDR=2001:DB8::10/64
753753
IPV6ADDR_SECONDARIES="2001:DB9::10/64 2001:DB10::10/64"
754754
IPV6INIT=yes
755+
IPV6_AUTOCONF=no
755756
IPV6_DEFAULTGW=2001:DB8::1
757+
IPV6_FORCE_ACCEPT_RA=no
756758
NETMASK=255.255.252.0
757759
NM_CONTROLLED=no
758760
ONBOOT=yes
@@ -1027,6 +1029,8 @@
10271029
IPADDR=192.168.14.2
10281030
IPV6ADDR=2001:1::1/64
10291031
IPV6INIT=yes
1032+
IPV6_AUTOCONF=no
1033+
IPV6_FORCE_ACCEPT_RA=no
10301034
NETMASK=255.255.255.0
10311035
NM_CONTROLLED=no
10321036
ONBOOT=yes
@@ -1253,6 +1257,33 @@
12531257
"""),
12541258
},
12551259
},
1260+
'static6': {
1261+
'yaml': textwrap.dedent("""\
1262+
version: 1
1263+
config:
1264+
- type: 'physical'
1265+
name: 'iface0'
1266+
accept-ra: 'no'
1267+
subnets:
1268+
- type: 'static6'
1269+
address: 2001:1::1/64
1270+
""").rstrip(' '),
1271+
'expected_sysconfig_rhel': {
1272+
'ifcfg-iface0': textwrap.dedent("""\
1273+
BOOTPROTO=none
1274+
DEVICE=iface0
1275+
IPV6ADDR=2001:1::1/64
1276+
IPV6INIT=yes
1277+
IPV6_AUTOCONF=no
1278+
IPV6_FORCE_ACCEPT_RA=no
1279+
DEVICE=iface0
1280+
NM_CONTROLLED=no
1281+
ONBOOT=yes
1282+
TYPE=Ethernet
1283+
USERCTL=no
1284+
"""),
1285+
},
1286+
},
12561287
'dhcpv6_stateless': {
12571288
'expected_eni': textwrap.dedent("""\
12581289
auto lo
@@ -1643,6 +1674,8 @@
16431674
IPADDR=192.168.14.2
16441675
IPV6ADDR=2001:1::1/64
16451676
IPV6INIT=yes
1677+
IPV6_AUTOCONF=no
1678+
IPV6_FORCE_ACCEPT_RA=no
16461679
IPV6_DEFAULTGW=2001:4800:78ff:1b::1
16471680
MACADDR=bb:bb:bb:bb:bb:aa
16481681
NETMASK=255.255.255.0
@@ -2172,6 +2205,8 @@
21722205
IPADDR1=192.168.1.2
21732206
IPV6ADDR=2001:1::1/92
21742207
IPV6INIT=yes
2208+
IPV6_AUTOCONF=no
2209+
IPV6_FORCE_ACCEPT_RA=no
21752210
MTU=9000
21762211
NETMASK=255.255.255.0
21772212
NETMASK1=255.255.255.0
@@ -2277,6 +2312,8 @@
22772312
IPADDR1=192.168.1.2
22782313
IPV6ADDR=2001:1::bbbb/96
22792314
IPV6INIT=yes
2315+
IPV6_AUTOCONF=no
2316+
IPV6_FORCE_ACCEPT_RA=no
22802317
IPV6_DEFAULTGW=2001:1::1
22812318
MTU=2222
22822319
NETMASK=255.255.255.0
@@ -2360,6 +2397,8 @@
23602397
HWADDR=52:54:00:12:34:00
23612398
IPV6ADDR=2001:1::100/96
23622399
IPV6INIT=yes
2400+
IPV6_AUTOCONF=no
2401+
IPV6_FORCE_ACCEPT_RA=no
23632402
NM_CONTROLLED=no
23642403
ONBOOT=yes
23652404
TYPE=Ethernet
@@ -2372,6 +2411,8 @@
23722411
HWADDR=52:54:00:12:34:01
23732412
IPV6ADDR=2001:1::101/96
23742413
IPV6INIT=yes
2414+
IPV6_AUTOCONF=no
2415+
IPV6_FORCE_ACCEPT_RA=no
23752416
NM_CONTROLLED=no
23762417
ONBOOT=yes
23772418
TYPE=Ethernet
@@ -3178,6 +3219,61 @@ def test_dhcpv6_reject_ra_config_v1(self):
31783219
self._compare_files_to_expected(entry[self.expected_name], found)
31793220
self._assert_headers(found)
31803221

3222+
def test_stattic6_from_json(self):
3223+
net_json = {
3224+
"services": [{"type": "dns", "address": "172.19.0.12"}],
3225+
"networks": [{
3226+
"network_id": "dacd568d-5be6-4786-91fe-750c374b78b4",
3227+
"type": "ipv4", "netmask": "255.255.252.0",
3228+
"link": "tap1a81968a-79",
3229+
"routes": [{
3230+
"netmask": "0.0.0.0",
3231+
"network": "0.0.0.0",
3232+
"gateway": "172.19.3.254",
3233+
}, {
3234+
"netmask": "0.0.0.0", # A second default gateway
3235+
"network": "0.0.0.0",
3236+
"gateway": "172.20.3.254",
3237+
}],
3238+
"ip_address": "172.19.1.34", "id": "network0"
3239+
}, {
3240+
"network_id": "mgmt",
3241+
"netmask": "ffff:ffff:ffff:ffff::",
3242+
"link": "interface1",
3243+
"mode": "link-local",
3244+
"routes": [],
3245+
"ip_address": "fe80::c096:67ff:fe5c:6e84",
3246+
"type": "static6",
3247+
"id": "network1",
3248+
"services": [],
3249+
"accept-ra": "false"
3250+
}],
3251+
"links": [
3252+
{
3253+
"ethernet_mac_address": "fa:16:3e:ed:9a:59",
3254+
"mtu": None, "type": "bridge", "id":
3255+
"tap1a81968a-79",
3256+
"vif_id": "1a81968a-797a-400f-8a80-567f997eb93f"
3257+
},
3258+
],
3259+
}
3260+
macs = {'fa:16:3e:ed:9a:59': 'eth0'}
3261+
render_dir = self.tmp_dir()
3262+
network_cfg = openstack.convert_net_json(net_json, known_macs=macs)
3263+
ns = network_state.parse_net_config_data(network_cfg,
3264+
skip_broken=False)
3265+
renderer = self._get_renderer()
3266+
with self.assertRaises(ValueError):
3267+
renderer.render_network_state(ns, target=render_dir)
3268+
self.assertEqual([], os.listdir(render_dir))
3269+
3270+
def test_static6_from_yaml(self):
3271+
entry = NETWORK_CONFIGS['static6']
3272+
found = self._render_and_read(network_config=yaml.load(
3273+
entry['yaml']))
3274+
self._compare_files_to_expected(entry[self.expected_name], found)
3275+
self._assert_headers(found)
3276+
31813277
def test_dhcpv6_reject_ra_config_v2(self):
31823278
entry = NETWORK_CONFIGS['dhcpv6_reject_ra']
31833279
found = self._render_and_read(network_config=yaml.load(
@@ -3295,6 +3391,8 @@ def test_netplan_dhcp_false_no_dhcp_in_sysconfig(self):
32953391
IPADDR=192.168.42.100
32963392
IPV6ADDR=2001:db8::100/32
32973393
IPV6INIT=yes
3394+
IPV6_AUTOCONF=no
3395+
IPV6_FORCE_ACCEPT_RA=no
32983396
IPV6_DEFAULTGW=2001:db8::1
32993397
NETMASK=255.255.255.0
33003398
NM_CONTROLLED=no

0 commit comments

Comments
 (0)