11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'modules/interface/manifests/add_ip6_mapped.pp', line 11
define interface::add_ip6_mapped(
$interface=$facts['interface_primary'],
$ipv4_address=$facts['ipaddress'],
) {
if ! member(split($facts['interfaces'], ','), $interface) {
fail("Not adding IPv6 address to ${interface} because this interface does not exist!")
}
# $v6_mapped_lower64 looks like '::10:0:2:1' for a v4 of '10.0.2.1'
$ipv4_address_with_colons = regsubst($ipv4_address, '\.', ':', 'G')
$v6_mapped_lower64 = "::${ipv4_address_with_colons}"
$ipv6_address = inline_template("<%= require 'ipaddr'; (IPAddr.new(scope.lookupvar(\"::ipaddress6_${interface}\")).mask(64) | IPAddr.new(@v6_mapped_lower64)).to_s() %>")
if $facts['ipaddress6'] != $ipv6_address {
interface::ip { $title:
interface => $interface,
address => $ipv6_address,
prefixlen => '64'
}
# The above sets up an "up" command to add the fixed IPv6 mapping of the v4
# address statically, and also executes the command to add the address
# in the present if not configured.
#
# Below sets "ip token" to the same on distros that support it. The
# token command explicitly configures the lower 64 bits that will be
# used with any autoconf address, as opposed to one derived from the
# macaddr. This aligns the autoconf-assigned address with the fixed
# one set above, and can do so as a pre-up command to avoid ever
# having another address even temporarily, when this is all set up
# before boot.
# We can't rely on the token part exclusively, though, or we'd face
# race conditions: daemons would expect to be able to bind this
# address for listening immediately after network-up, but the address
# wouldn't exist until the next RA arrives on the interface, which can
# be 1-2s in practice.
# By keeping both the static config from above and the token command,
# we get the best of all worlds: no race, and no conflicting
# macaddr-based assignment on the interface either. When this is
# first applied at runtime it will execute the token command as well,
# but any previous macaddr-based address will be flushed.
$v6_token_cmd = "/sbin/ip token set ${v6_mapped_lower64} dev ${interface}"
$v6_flush_dyn_cmd = "/sbin/ip -6 addr flush dev ${interface} dynamic"
$v6_token_check_cmd = "/sbin/ip token get dev ${interface} | grep -qw ${v6_mapped_lower64}"
$v6_token_preup_cmd = "set iface[. = '${interface}']/pre-up '${v6_token_cmd}'"
augeas { "${interface}_v6_token":
incl => '/etc/network/interfaces',
lens => 'Interfaces.lns',
context => '/files/etc/network/interfaces/',
changes => $v6_token_preup_cmd,
}
exec { "${interface}_v6_token":
command => "${v6_token_cmd} && ${v6_flush_dyn_cmd}",
unless => $v6_token_check_cmd,
}
}
}
|