#!/bin/sh
#
#     Template Copyright (C) 1995--2005  Kurt Garloff, SUSE / Novell Inc.
#     IPv6 tunnel setup -- by jimc, 2008-10-24

### BEGIN INIT INFO
# Provides:          network6
# Required-Start:    network
# Should-Start:
# Required-Stop:
# Should-Stop:
# Default-Start:     2 3 5
# Default-Stop:      0 1 6
# Short-Description: IPv6 network tunnel
# Description:       Sets up the tunnel giving us access to the IPv6 network.
### END INIT INFO

# Cowboy programming, all the parameters are set here.  Properly these
# should come from /etc/sysconfig/network6.
MODULES="ipv6 sit"		# Modules that need to be loaded
IFC=he-ipv6			# Pro forma name of tunnel interface (sit type)
WILD=eth1			# Wild side IPv4 interface
TUNNELv4=72.52.104.74		# IPv4 address of remote tunnel endpoint
TPREFIX=2001:470:1f04:844	# Prefix of tunnel endpoints
TREMOTEv6=$TPREFIX::1/128	# IPv6 remote endpoint (not used)
TLOCALv6=$TPREFIX::2/128	# IPv6 local endpoint
# Parameters for the local interface
LETH=eth0			# Local Ethernet interface
LPREFIX=2001:470:1f05:844	# Our IPv6 prefix (1f05 not 1f04)
SUBNETv6=$LPREFIX::/64		# Our IPv6 address block
LEUI64=240:caff:fea0:88b2	# Address derived from our MAC address
LADDR=$LPREFIX:$LEUI64/64	# Address of local interface

# Check for missing binaries (stale symlinks should not happen)
# Note: Special treatment of stop for LSB conformance
test -x /sbin/ip || { echo "/sbin/ip not installed"; 
	if [ "$1" = "stop" ]; then exit 0;
	else exit 5; fi; }

# SuSE init script functions (and reset the status)
. /etc/rc.status
rc_reset

# Executes a command line and if it fails, sets the status.
function try () {
    "$@"
    rc_status
}

# Determine our wild-side IP address, left in global variable LOCALv4.  Prints
# error message on stderr and returns nonzero (1) if the IP address cannot be
# determined.
function myip () {
    local f
    local rc=0
    for f in 1 1 2 4 8 16 ; do
	LOCALv4=`ip -f inet addr show dev $WILD | sed -e '/inet /!d' -e '/192\.168\./d' -e 's/^.*inet[^0-9]*//' -e 's/[^0-9.].*//'`
	if [ -n "$LOCALv4" ] ; then break ; fi
	if [ $f -gt 1 ] ; then 
	    echo "Waiting $f secs for IPv4 adr on $WILD" 1>&2
	fi
	sleep $f
    done
    if [ -z "$LOCALv4" ] ; then 
	echo "Can't determine local IPv4 address on $WILD" 1>&2
	rc=1
    fi
    return $rc
}

case "$1" in
    start)
	echo -n "Starting network6 "
	for f in $MODULES ; do
	    modprobe $f
	done
	while /bin/true ; do		#Executed only once
			# Determine our wild-side IP address
	    if myip ; then : ; else rc_failed ; break ; fi
			# Set up the tunnel.
	    try ip tunnel add $IFC mode sit remote $TUNNELv4 local $LOCALv4 ttl 255 || break
	    try ip link set $IFC up || break
	    try ip addr add $TLOCALv6 dev $IFC || break
	    try ip route add 2000::/3 dev $IFC || break	#Default offsite route
			# The router does not listen to its own router
			# advertisement broadcasts because it doesn't know
			# which interface is on which net.  So let's tell it.
	    try ip addr add $LADDR dev $LETH || break
	    # ip -f inet6 addr  #-- for debugging
	    break
	done
	rc_status -v
	;;
    stop)
	echo -n "Shutting down network6 "
			# Determine our wild-side IP address
	if myip ; then : ; else rc_failed ; break ; fi
	ip route del 2000::/3 dev $IFC		#Default offsite route
	ip route del $SUBNETv6 dev $LETH
	ip link set $IFC down
	ip tunnel del $IFC mode sit remote $TUNNELv4 local $LOCALv4
	
	rc_status -v
	;;
    try-restart|condrestart|force-reload|reload)
	## Do a restart only if the service was active before.
	$0 status
	if test $? = 0; then
		$0 restart
	else
		rc_reset	# Not running is not a failure.
	fi
	# Remember status and be quiet
	rc_status
	;;
    restart)
	## Stop the service and regardless of whether it was
	## running or not, start it again.
	$0 stop
	$0 start

	# Remember status and be quiet
	rc_status
	;;
    status)
	echo -n "Checking on network6 "
	if ip link show $IFC 2> /dev/null | grep -w UP > /dev/null
	    then rc_status -v ; else rc_status -u ; fi
	;;
esac
rc_exit
