aboutsummaryrefslogtreecommitdiffstats
path: root/sysconfig/network-scripts/ifup-ipv6
blob: 1dd30affa318713248410b94dc064779c62b7b1f (plain)
1
2
3
4
5
6
7
8
9
10
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#!/bin/sh
#
# ifup-ipv6
#
#
# Taken from:
# (P) & (C) 2000-2006 by Peter Bieringer <pb@bieringer.de>
#
#  You will find more information on the initscripts-ipv6 homepage at
#   http://www.deepspace6.net/projects/initscripts-ipv6.html
#
# RHL integration assistance by Pekka Savola <pekkas@netcore.fi>
#
# Version: 2006-07-20
#
# Note: if called (like normally) by /etc/sysconfig/network-scripts/ifup
#        exit codes aren't handled by "ifup"
#
# Uses following information from "/etc/sysconfig/network":
#  IPV6_DEFAULTDEV=<device>: controls default route (optional)
#  IPV6_DEFAULTGW=<address>: controls default route (optional)
#
# Uses following information from "/etc/sysconfig/network-scripts/ifcfg-$1":
#  IPV6INIT=yes|no: controls IPv6 configuration for this interface
#  IPV6ADDR=<IPv6 address>[/<prefix length>]: specify primary static IPv6 address
#  IPV6ADDR_SECONDARIES="<IPv6 address>[/<prefix length>] ..." (optional)
#  IPV6_ROUTER=yes|no: controls IPv6 autoconfiguration (no: multi-homed interface without routing)
#  IPV6_AUTOCONF=yes|no: controls IPv6 autoconfiguration
#   defaults:
#    IPV6FORWARDING=yes: IPV6_AUTOCONF=no, IPV6_ROUTER=yes
#    IPV6FORWARDING=no: IPV6_AUTOCONF=yes
#  IPV6_MTU=<MTU for IPv6>: controls IPv6 MTU for this link (optional)
#  IPV6_PRIVACY="rfc3041": control IPv6 privacy (optional)
#    This script only supports "rfc3041" (if kernel supports it)
#
# Optional for 6to4 tunneling (hardwired name of tunnel device is "tun6to4"):
#  IPV6TO4INIT=yes|no: controls 6to4 tunneling setup
#  IPV6TO4_RELAY=<IPv4 address>: IPv4 address of the remote 6to4 relay (default: 192.88.99.1)
#  IPV6TO4_MTU=<MTU for IPv6>: controls IPv6 MTU for the 6to4 link (optional, default is MTU of interface - 20)
#  IPV6TO4_IPV4ADDR=<IPv4 address>: overwrite local IPv4 address (optional)
#  IPV6TO4_ROUTING="<device>-<suffix>/<prefix length> ...": information to setup additional interfaces
#    Example: IPV6TO4_ROUTING="eth0-:f101::1/64 eth1-:f102::1/64"
#
# Optional for 6to4 tunneling to trigger radvd:
#  IPV6_CONTROL_RADVD=yes|no: controls radvd triggering (optional)
#  IPV6_RADVD_PIDFILE=<file>: PID file of radvd for sending signals, default is "/var/run/radvd/radvd.pid" (optional)
#  IPV6_RADVD_TRIGGER_ACTION=startstop|reload|restart|SIGHUP: how to trigger radvd (optional, default is SIGHUP)
#
#  Required version of radvd to use 6to4 prefix recalculation
#   0.6.2p3 or newer supporting option "Base6to4Interface"
#  Required version of radvd to use dynamic ppp links
#   0.7.0 + fixes or newer
#


. /etc/sysconfig/network

cd /etc/sysconfig/network-scripts
. ./network-functions

CONFIG=$1
[ -f "$CONFIG" ] || CONFIG=ifcfg-$CONFIG
source_config

# IPv6 don't need aliases anymore, config is skipped
REALDEVICE=$(echo ${DEVICE} | sed 's/:.*//g')
[ "$DEVICE" != "$REALDEVICE" ] && exit 0

# Test whether IPv6 configuration is enabled for this interface, else stop
[ "$IPV6INIT" = "yes" ] || exit 0

[ -f /etc/sysconfig/network-scripts/network-functions-ipv6 ] || exit 1
. /etc/sysconfig/network-scripts/network-functions-ipv6


# IPv6 test, module loaded, exit if system is not IPv6-ready
ipv6_test || exit 1

# Test device status
ipv6_test_device_status $DEVICE
if [ $? != 0 -a $? != 11 ]; then
	# device doesn't exist or other problem occurs
	exit 1
fi

# Setup IPv6 address on specified interface
if [ -n "$IPV6ADDR" ]; then
	ipv6_add_addr_on_device $DEVICE $IPV6ADDR || exit 1
fi

# Get current global IPv6 forwarding
ipv6_global_forwarding_current="$(ipv6_exec_sysctl -n net.ipv6.conf.all.forwarding)"

# Set some proc switches depending on defines
if [ "$IPV6FORWARDING" = "yes" ]; then
	# Global forwarding should be enabled

	# Check, if global IPv6 forwarding was already set by global script
	if [ $ipv6_global_forwarding_current -ne 1 ]; then
		echo $"Global IPv6 forwarding is enabled in configuration, but not currently enabled in kernel"
		echo $"Please restart network with '/sbin/service network restart'"
	fi

	ipv6_local_forwarding=1
	ipv6_local_auto=0
	if [ "$IPV6_ROUTER" = "no" ]; then
		ipv6_local_forwarding=0
	fi
	if [ "$IPV6_AUTOCONF" = "yes" ]; then
		ipv6_local_auto=1
	fi
else
	# Global forwarding should be disabled

	# Check, if global IPv6 forwarding was already set by global script
	if [ $ipv6_global_forwarding_current -ne 0 ]; then
		echo $"Global IPv6 forwarding is disabled in configuration, but not currently disabled in kernel"
		echo $"Please restart network with '/sbin/service network restart'"
	fi

	ipv6_local_forwarding=0
	ipv6_local_auto=1
	if [ "$IPV6_AUTOCONF" = "no" ]; then
		ipv6_local_auto=0
	fi
fi
ipv6_exec_sysctl -w net.ipv6.conf.$DEVICE.forwarding=$ipv6_local_forwarding >/dev/null 2>&1
ipv6_exec_sysctl -w net.ipv6.conf.$DEVICE.accept_ra=$ipv6_local_auto >/dev/null 2>&1
ipv6_exec_sysctl -w net.ipv6.conf.$DEVICE.accept_redirects=$ipv6_local_auto >/dev/null 2>&1

# Set IPv6 MTU, if given
if [ -n "$IPV6_MTU" ]; then
	ipv6_set_mtu $DEVICE $IPV6_MTU
fi

# Setup additional IPv6 addresses from list, if given
if [ -n "$IPV6ADDR_SECONDARIES" ]; then
	for ipv6addr in $IPV6ADDR_SECONDARIES; do
		ipv6_add_addr_on_device $DEVICE $ipv6addr
	done
fi

# Enable IPv6 RFC3041 privacy extensions if desired
if [ "$IPV6_PRIVACY" = "rfc3041" ]; then
	ipv6_exec_sysctl -w net.ipv6.conf.$DEVICE.use_tempaddr=2 >/dev/null 2>&1
	if [ $? -ne 0 ]; then
		echo $"Cannot enable IPv6 privacy method '$IPV6_PRIVACY', not supported by kernel"
	fi
fi

# Setup default IPv6 route, check are done by function
if [ -n "$IPV6_DEFAULTDEV" -o -n "$IPV6_DEFAULTGW" ]; then
	ipv6_set_default_route "$IPV6_DEFAULTGW" "$IPV6_DEFAULTDEV" "$DEVICE"
fi

# Setup additional static IPv6 routes on specified interface, if given
if [ -f /etc/sysconfig/static-routes-ipv6 ]; then
	LC_ALL=C grep -w "^$DEVICE" /etc/sysconfig/static-routes-ipv6 | while read device args; do
		ipv6_add_route $args $DEVICE
	done
fi

# Setup additional static IPv6 routes (newer config style)
if [ -f "/etc/sysconfig/network-scripts/route6-$DEVICE" ]; then
	cat "/etc/sysconfig/network-scripts/route6-$DEVICE" | sed 's/#.*//g' | grep -v '^[[:space:]]*$' | while read line; do
		ipv6_exec_ip -6 route add $line
	done
fi

# Setup of 6to4, if configured
if [ "$IPV6TO4INIT" = "yes" ]; then
	valid6to4config="yes"

	# Test device status of 6to4 tunnel
	ipv6_test_device_status tun6to4
	if [ $? = 0 ]; then
		# device is already up
		echo $"Device 'tun6to4' (from '$DEVICE') is already up, shutdown first"
		exit 1
	fi

	# Get IPv4 address for global 6to4 prefix calculation
	if [ -n "$IPV6TO4_IPV4ADDR" ]; then
		# Take special configured from config file (precedence 1)
		ipv4addr="$IPV6TO4_IPV4ADDR"

		# Get local IPv4 address from interface
		ipv4addrlocal="$(ipv6_get_ipv4addr_of_device $DEVICE)"
		if [ -z "$ipv4addrlocal" ]; then
			# Take configured from config file
			ipv4addrlocal="$IPADDR"
		fi
        else
		# Get IPv4 address from interface first (has precedence 2)
		ipv4addr="$(ipv6_get_ipv4addr_of_device $DEVICE)"
		if [ -z "$ipv4addr" ]; then
			# Take configured from config file (precedence 3)
			ipv4addr="$IPADDR"
		fi
		ipv4addrlocal="$ipv4addr"
        fi

	if [ -n "$ipv4addr" ]; then
		if ! ipv6_test_ipv4_addr_global_usable $ipv4addr; then
			echo $"Given IPv4 address '$ipv4addr' is not globally usable"
	                valid6to4config="no"
        	fi
		if [ -z "$IPV6TO4_RELAY" ]; then
			IPV6TO4_RELAY="192.88.99.1"
		fi

		# Check/generate relay address
		ipv6to4_relay="$(ipv6_create_6to4_relay_address $IPV6TO4_RELAY)"
		if [ $? -ne 0 ]; then
			valid6to4config="no"
		fi
	else
        	echo $"IPv6to4 configuration needs an IPv4 address on related interface or otherwise specified"
		valid6to4config="no"
	fi

	# Setup 6to4 tunnel (hardwired name is "tun6to4"), if config is valid
        if [ "$valid6to4config" = "yes" ]; then
		# Get MTU of master device
		ipv4mtu="$(ipv6_exec_ip link show dev $DEVICE | grep -w "mtu" | awk '{ print $5 }')"
		if [ -n "$ipv4mtu" ]; then
			# IPv6 tunnel MTU is IPv4 MTU minus 20 for IPv4 header
			tunnelmtu=$[ $ipv4mtu - 20 ]
		fi

		if [ -n "$IPV6TO4_MTU" ]; then
			if [ $IPV6TO4_MTU -gt $tunnelmtu ]; then
				echo $"Warning: configured MTU '$IPV6TO4_MTU' for 6to4 exceeds maximum limit of '$tunnelmtu', ignored"
			else
				tunnelmtu=$IPV6TO4_MTU
			fi
		fi

		ipv6_add_6to4_tunnel tun6to4 $ipv4addr "" $tunnelmtu $ipv4addrlocal || exit 1

		# Add route to for compatible addresses (removed later again)
		ipv6_add_route "::/96" "::" tun6to4

		# Add default route, if device matches
		if [ "$IPV6_DEFAULTDEV" = "tun6to4" ]; then
			if [ -n "$IPV6_DEFAULTGW" ]; then
				echo $"Warning: interface 'tun6to4' does not support 'IPV6_DEFAULTGW', ignored"
			fi
			ipv6_set_default_route $ipv6to4_relay tun6to4
		fi

		# Add static routes
		if [ -f /etc/sysconfig/static-routes-ipv6 ]; then
			LC_ALL=C grep -w "^tun6to4" /etc/sysconfig/static-routes-ipv6 | while read device network gateway; do
				if [ -z "$network" ]; then
					continue
				fi
				if [ -z "$gateway" ]; then
					gateway="$ipv6to4_relay"
				fi
				ipv6_add_route $network $gateway tun6to4
			done
		fi

		# Setup additional static IPv6 routes (newer config style)
		if [ -f "/etc/sysconfig/network-scripts/route6-tun6to4" ]; then
			cat "/etc/sysconfig/network-scripts/route6-tun6to4" | sed 's/#.*//g' | LC_ALL=C grep -v '^[[:space:]]*$' | while read line; do
				if echo "$line" | LC_ALL=C grep -vq 'via'; then
					# Add gateway if missing
					line="$line via $ipv6to4_relay"
				fi
				ipv6_exec_ip -6 route add $line
			done
		fi

		# Cleanup autmatically generated autotunnel (not needed for 6to4)
		ipv6_del_route "::/96" "::" tun6to4
		ipv6_del_addr_on_device tun6to4 "::$ipv4addrlocal/128"

	        if [ "$IPV6_CONTROL_RADVD" = "yes" ]; then
			# RADVD is in use, so forwarding of IPv6 packets should be enabled, display warning
			if [ $ipv6_global_forwarding_current -ne 1 ]; then
				echo $"Using 6to4 and RADVD IPv6 forwarding usually should be enabled, but it isn't"
			fi

		        if [ -n "$IPV6TO4_ROUTING" ]; then
				ipv6to4prefix="$(ipv6_create_6to4_prefix $ipv4addr)"
				if [ -n "$ipv6to4prefix" ]; then
					# Add route to local networks
					for devsuf in $IPV6TO4_ROUTING; do
						dev="$(echo $devsuf | awk -F- '{ print $1 }')"
						suf="$(echo $devsuf | awk -F- '{ print $2 }')"
						ipv6_add_addr_on_device ${dev} ${ipv6to4prefix}${suf}
					done
				else
					echo $"Error occurred while calculating the IPv6to4 prefix"
				fi
			else
				echo $"radvd control enabled, but config is not complete"
			fi

			# Control running radvd
			ipv6_trigger_radvd up "$IPV6_RADVD_TRIGGER_ACTION" $IPV6_RADVD_PIDFILE
		fi
	else
		echo $"6to4 configuration is not valid"
		exit 1
        fi
fi