aboutsummaryrefslogtreecommitdiffstats
path: root/ppp/ip-up.ipv6to4
blob: 6a85bbb34330f4556bbb0f48f0294b988fbc0356 (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
#!/bin/sh
#
# ip-up.ipv6to4
#
#
# Taken from:
# (P) & (C) 2000-2005 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
#
# Version: 2005-09-22
#
# Calling parameters:
#  $1: interface name
#
# Called (mostly) by /etc/ppp/ip-up.local
#  like: /etc/ppp/ip-up.ipv6to4 $1 >>/var/log/ppp-ipv6to4.log 2>&1
#
# Note: this script will *kill* older still existing 6to4 tunnels regardless
#        whether they were set before by another device
#
# Uses following information from /etc/sysconfig/network-scripts/ifcfg-$1:
#  IPV6TO4INIT=yes|no: controls configuration
#  IPV6TO4_IPV4ADDR=<IPv4 address>: special local address for 6to4 tunneling (only needed behind a NAT gateway)
#  IPV6TO4_RELAY=<IPv4 address>: remote 6to4 relay router address (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_ROUTING="<device>-<suffix>/<prefix length> ...": information to setup additional interfaces
#    Example: IPV6TO4_ROUTING="eth0-:f101::1/64 eth1-:f102::1/64"
#
#  IPV6_CONTROL_RADVD=yes|no: controls radvd triggering
#  IPV6_RADVD_PIDFILE=<file>: PID file of radvd for sending signals, default is "/var/run/radvd/radvd.pid"
#  IPV6_RADVD_TRIGGER_ACTION=startstop|reload|restart|SIGHUP: how to trigger radvd (optional, default is SIGHUP)
#
# Requirements
#  radvd-0.6.2p3 or newer supporting option "Base6to4Interface"
#


if [ -z "$1" ]; then
	echo $"Argument 1 is empty but should contain interface name - skip IPv6to4 initialization"
	exit 1
fi

# Get global network configuration
. /etc/sysconfig/network

# Source IPv4 helper functions
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=${DEVICE%%:*}
[ "$DEVICE" != "$REALDEVICE" ] && exit 0

if [ ! -f /etc/sysconfig/network-scripts/network-functions-ipv6 ]; then
        exit 1
fi

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


# Run basic IPv6 test (and make sure the ipv6 module will be loaded), if not ok, skip IPv6 initialization
ipv6_test || exit 1

# Setup of 6to4, if configured
valid6to4config="yes"
if [ "$IPV6TO4INIT" = "yes" ]; then
	if [ -n "$IPV6TO4_IPV4ADDR" ]; then
		# Take 6to4-dedicated configured IPv4 address from config file (precedence 1)
		ipv4addr="$IPV6TO4_IPV4ADDR"
        else
		# Get IPv4 address from interface (precedence 2)
		ipv4addr="$(ipv6_get_ipv4addr_of_device $DEVICE)"
		if [ -z "$ipv4addr" ]; then
                	# Take configured IPv4 address of interface from config file (precedence 3)
                	ipv4addr="$IPADDR"
            	fi
        fi
        if [ -n "$ipv4addr" ]; then
		# Test for non-global IPv4 address
		if ! ipv6_test_ipv4_addr_global_usable $ipv4addr; then
                	net_log $"Given IPv4 address '$ipv4addr' is not globally usable" info
			valid6to4config="no"
		fi
	else
		net_log $"IPv6to4 configuration needs an IPv4 address on related interface or otherwise specified" info
		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

	if [ "$valid6to4config" = "yes" ]; then
		# Delete routes to local networks
       		for devsuf in $IPV6TO4_ROUTING; do
			dev="${devsuf%%-*}"
			ipv6_cleanup_6to4_device $dev
		done

		# Cleanup all old data (needed, if "ip-down.ipv6to4" wasn't executed), delete all configured 6to4 address
		ipv6_cleanup_6to4_tunnels tun6to4

		# Get MTU of master device
		ipv4mtu="$(/sbin/ip link show dev $DEVICE | awk '/\<mtu\>/ { 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
				net_log $"Warning: configured MTU '$IPV6TO4_MTU' for 6to4 exceeds maximum limit of '$tunnelmtu', ignored" warning
			else
				tunnelmtu=$IPV6TO4_MTU
			fi
		fi

		# Setup new data
		ipv6_add_6to4_tunnel tun6to4 $ipv4addr "" $tunnelmtu || 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
				net_log $"Warning: interface 'tun6to4' does not support 'IPV6_DEFAULTGW', ignored" warning
			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
			sed -ne 's/#.*//' -e '/[^[:space:]]/p' /etc/sysconfig/network-scripts/route6-tun6to4 | while read line; do
				if echo "$line" | grep -vq 'via'; then
					# Add gateway if missing
					line="$line via $ipv6to4_relay"
				fi
				/sbin/ip -6 route add $line
			done
                fi

		# Cleanup autmatically generated autotunnel (not needed for 6to4)
		/sbin/ip -6 route del ::/96 dev tun6to4
		/sbin/ip -6 addr del tun6to4 "::$ipv4addr/128" dev tun6to4

	        if [ "$IPV6_CONTROL_RADVD" = "yes" ]; then
                        # Control running radvd
			ipv6_trigger_radvd up "$IPV6_RADVD_TRIGGER_ACTION" $IPV6_RADVD_PIDFILE

			if [ -n "$IPV6TO4_ROUTING" ]; then
				# Generate 6to4 address
				ipv6to4prefix="$(ipv6_create_6to4_prefix $ipv4addr)"
				if [ -n "$ipv6to4prefix" ]; then
					# Add IPv6 address to interface (required interface route will be set automatically)
					for devsuf in $IPV6TO4_ROUTING; do
						dev="${devsuf%%-*}"
						suf="$(echo $devsuf | awk -F- '{ print $2 }')"
						ipv6_add_addr_on_device ${dev} ${ipv6to4prefix}${suf}
					done
				else
					net_log $"Error occurred while calculating the IPv6to4 prefix"
				fi
			else
				net_log $"radvd control enabled, but config is not complete"
			fi
		fi
	fi
fi