#!/bin/sh

gw=$4
WAN=$1
cfg=$6
LAN=br-lan
DHCP6C="/sbin/dhcp6.sh client"
SEND_RS="/bin/pktgen -s $WAN"
RADVD=/usr/sbin/radvd
CONF=/etc/radvd.conf
LAN_STATIC_IPv6=$(uci -q get ipv6.lan.global_addr | tr A-Z a-z)
get_lan_prefix()
{
  #ifconfig $LAN | grep "inet6 addr" | grep -v -E "fe80::|/128" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"
  if [ $LAN_STATIC_IPv6 ]; then
	ifconfig br-lan | grep "inet6 addr" | grep -v -E "fe80::|/128" | grep -v "$LAN_STATIC_IPv6" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"
  else
	ifconfig br-lan | grep "inet6 addr" | grep -v -E "fe80::|/128" | sed -e "s/^.*inet6 addr: //" -e "s/ Scope.*\$//"
  fi
}

config_radvd()
{
  LIFETIME=`uci -q get ipv6.lan_radvd.adv_time`

  echo "interface $LAN" > $CONF
  echo "{" >> $CONF
  echo "  AdvSendAdvert on;" >> $CONF
  echo "  MinRtrAdvInterval 3;" >> $CONF
  echo "  MaxRtrAdvInterval 10;" >> $CONF
  if [ $LIFETIME ]; then
    echo "  AdvDefaultLifetime $LIFETIME;" >> $CONF
  fi

  for PREFIX in $PREFIXES; do
    echo "  prefix $PREFIX" >> $CONF
    echo "  {" >> $CONF
    echo "    AdvOnLink on;" >> $CONF
    echo "    AdvAutonomous on;" >> $CONF
    echo "    AdvRouterAddr on;" >> $CONF
    echo "    AdvValidLifetime 2592000;" >> $CONF
    echo "    AdvPreferredLifetime 604800;" >> $CONF
    echo "  };" >> $CONF
  done

  echo "};" >> $CONF
  echo "" >> $CONF
  chmod 600 $CONF
}

waiting_for_lan_prefix()
{
  TIMEOUT=15    # second
  while [ $TIMEOUT -ge 0 ]; do
    sleep 1
    PREFIXES=`get_lan_prefix`
	#echo "***********waiting_for_lan_prefix():$TIMEOUT $PREFIXES">/dev/console	
    [ $PREFIXES ] && break
    TIMEOUT=`expr $TIMEOUT - 1`
  done
}

init_counter()
{
  PPPD_RETRY=2
  echo $PPPD_RETRY > $COUNTER
}

dec_counter()
{
  expr $PPPD_RETRY - 1 > $COUNTER
}

exit_()
{
  #[ $1 -eq 0 ] && echo "state success!!!">/dev/console || echo "state fail!!!">/dev/console
  rm $COUNTER
  exit $1
}

logger -p 160.5 "[IP6-UP] IFACE=$1 TTY=$2 SPEED=$3 LOCAL=$4 REMOTE=$5 IPPARAM=$6"

. /etc/functions.sh      # common functions
include /lib/network     # include /lib/network/*.sh
scan_interfaces          # read and parse the network config

config_get_bool defaultroute "$cfg" defaultroute 1

if [ ${defaultroute} -eq 1 ]
then
	logger -p 160.5 "[IP6-UP]Add IPv6 default gateway $gw via $WAN"
	#route -A inet6 add default gw ${gw} dev ${WAN}
	#echo "****in ipv6-up******  $5 $1">/dev/console
	route -A inet6 add 2000::/3 gw $5 $1          # add remote LL address as default gateway	
else
	#echo "****in ipv6-up******  no default route">/dev/console
	exit 1
fi


# ipv6-up               +-(got prefix)-->-------->-------->---+-(got RA)-----> end (success)
#   |                   |                                     |
#   +-> A)start dhcp6c -+-(15s)-> B)stop dhcp6c -> C)send RS -+-(15s)--+---+-> end (failed)
#   |                                                                  |   |
#   +----<--------<--------<--------<--------<--------<--(loop*1)------+   +-> D)restart pppd (up to 2 times)

COUNTER=/var/pppd_retry
RADVD_EN=`uci -q get ipv6.lan.radvd_en`
PPPD_RETRY=`cat $COUNTER 2>/dev/null` || init_counter
LOOP=1
WAN_MODE=`uci -q get ipv6.wan.mode`

while [ $LOOP -ge 0 ]; do
	[ "$WAN_MODE" != "ppp" ] && exit 0
	#echo "****in ipv6-up****enter A state...$WAN">/dev/console
	WAN=$WAN $DHCP6C start iapd #&& waiting_for_lan_prefix     # A)
	PREFIXES=`get_lan_prefix`
	[ $PREFIXES ] && exit_ 0          # end (success)
	#echo "****in ipv6-up****enter B state...">/dev/console
	$DHCP6C stop                                  # B)
	# disable/enable forwarding to accept/reject RA
	#echo "****in ipv6-up****enter C state...$WAN">/dev/console
	echo 0 > /proc/sys/net/ipv6/conf/$WAN/forwarding
	$SEND_RS && waiting_for_lan_prefix                        # C)
	echo 1 > /proc/sys/net/ipv6/conf/$WAN/forwarding
	if [ $PREFIXES ]; then
		echo "****C state...ICMP get!!">/dev/console
		echo "$PREFIXES" >/tmp/PPP_PREFIXES
		if [ "$RADVD_EN" -eq "1" ]; then
		killall radvd 2>/dev/null
		config_radvd
		$RADVD -C $CONF
		fi
		exit_ 0                         # end (success)
	fi
	LOOP=`expr $LOOP - 1`
done



[ "$PPPD_RETRY" -eq 0 ] && exit_ 1  # end (failed)

dec_counter
killall pppd 2>/dev/null                                    # D)
pppd file /etc/options.pppoe &
