aboutsummaryrefslogtreecommitdiffstats
path: root/ppp/ip-up.ipv6to4
blob: 609e02c488f0c435a30f7f9c92ac3bd72a72d7e7 (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
#!/bin/sh
#
# ip-up.ipv6to4
#
#
# Taken from:
# (P) & (C) 2000-2002 by Peter Bieringer <pb@bieringer.de>
#  
#  You will find more information in the IPv6-HowTo for Linux at
#   http://www.bieringer.de/linux/IPv6/
#
# Version 2002-11-14
#
# 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:
#  NETWORKING_IPV6=yes|no: controls IPv6 initialization (global setting)
#
# 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 local subnetting
#    Example: IPV6TO4_ROUTING="eth0-:f101::0/64 eth1-:f102::0/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=`echo ${DEVICE} | sed 's/:.*//g'`
[ "$DEVICE" != "$REALDEVICE" ] && exit 0

# Test whether IPv6 should be configured, else stop
[ "$NETWORKING_IPV6" = "yes" ] || 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
                	echo $"Given IPv4 address '$ipv4addr' is not globally usable"
			valid6to4config="no"
		fi
	else
		echo $"IPv6to4 configuration needs an IPv4 address on related interface or otherwise specified"
		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="`echo $devsuf | awk -F- '{ print $1 }'`"
			ipv6_cleanup_routes $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="`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

		# 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
				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' | grep -v '^[[:space:]]*$' | while read line; do
				if echo "$line" | 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 "::$ipv4addr/128"

	        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 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_route ${ipv6to4prefix}$suf :: $dev
					done
				else
					echo $"Error occured while calculating the IPv6to4 prefix"
				fi
			else
				echo $"radvd control enabled, but config is not complete"
			fi
		fi
	fi
fi