diff --git a/package/network/ipv6/ipv6-support/Makefile b/package/network/ipv6/ipv6-support/Makefile
index db139635987aebb08e17cde69ac4e532529ba082..21d5c00f9547ca9c92b4ebefa3f08f77dd99d34a 100644
--- a/package/network/ipv6/ipv6-support/Makefile
+++ b/package/network/ipv6/ipv6-support/Makefile
@@ -8,7 +8,7 @@
 include $(TOPDIR)/rules.mk
 
 PKG_NAME:=ipv6-support
-PKG_VERSION:=2012-11-29
+PKG_VERSION:=2012-12-03
 PKG_RELEASE:=1
 
 include $(INCLUDE_DIR)/package.mk
diff --git a/package/network/ipv6/ipv6-support/files/dhcpv6.sh b/package/network/ipv6/ipv6-support/files/dhcpv6.sh
index 67fa174d1773b303039bc1513ac2cdb1229c8b79..1d19a681d4f3eadd70dcc36ea68042d91f650c7a 100755
--- a/package/network/ipv6/ipv6-support/files/dhcpv6.sh
+++ b/package/network/ipv6/ipv6-support/files/dhcpv6.sh
@@ -27,11 +27,11 @@ done
 local prefix_fallback
 config_get prefix_fallback "$network" prefix_fallback
 [ "$prefix_fallback" == "relay" -a -z "$PREFIXES" -a "$state" != "unbound" ] &&
-	restart_relay "$network" 1
+	restart_relay "$network" "fallback"
 
 # Disable relay if requested
 [ "$prefix_fallback" != "relay" -o -n "$PREFIXES" -o "$state" == "unbound" ] &&
-	stop_relay "$network"
+	restart_relay "$network"
 
 
 # Operations in case of success
diff --git a/package/network/ipv6/ipv6-support/files/ipv6.hotplug b/package/network/ipv6/ipv6-support/files/ipv6.hotplug
index e3379b6b2c3737a4ac1cbc2e6d3e283270f362d7..52cdf3bde0f1f81dce178972e5184a51de2a0ea1 100644
--- a/package/network/ipv6/ipv6-support/files/ipv6.hotplug
+++ b/package/network/ipv6/ipv6-support/files/ipv6.hotplug
@@ -3,16 +3,11 @@
 [ "$DEVICE" == "lo" ] && exit 0
 . /lib/ipv6/support.sh
 
-local mode
-config_get mode "$INTERFACE" mode
-
 case "$ACTION" in
 	ifup)
-		[ "$mode" != "downstream" ] && enable_static $INTERFACE $DEVICE
-		[ "$mode" == "upstream" ] && enable_upstream $INTERFACE $DEVICE
-		[ "$mode" == "downstream" ] && enable_downstream $INTERFACE $DEVICE
+		enable_interface "$INTERFACE" "$DEVICE"
 	;;
 	ifdown)
-		disable_interface $INTERFACE $DEVICE
+		disable_interface "$INTERFACE" "$DEVICE"
 	;;
 esac
diff --git a/package/network/ipv6/ipv6-support/files/network6.config b/package/network/ipv6/ipv6-support/files/network6.config
index 4632bba0bf04a9987e3f9f130096029dc15162c8..4fc22d0fab004cd95555d6d609f8ebd92dd7091d 100644
--- a/package/network/ipv6/ipv6-support/files/network6.config
+++ b/package/network/ipv6/ipv6-support/files/network6.config
@@ -1,5 +1,5 @@
 config interface wan
-	option mode		upstream
+	option mode		dhcpv6
 	option ula_prefix	auto
 	option request_prefix	auto
 	option prefix_fallback	relay
@@ -7,7 +7,7 @@ config interface wan
 
 
 config interface lan
-	option mode		downstream
+	option mode		router
 	option advertise_prefix	64
 	option relay_master	wan
 
@@ -15,3 +15,4 @@ config interface lan
 config interface 6in4
 	option mode		static
 	list static_prefix	2001:DB8::/48
+
diff --git a/package/network/ipv6/ipv6-support/files/support.sh b/package/network/ipv6/ipv6-support/files/support.sh
index 5525a3a56f00761926dfd63d0590586a42a4d2d9..479ed680a769de7065cc8be469559d0ff94b4440 100644
--- a/package/network/ipv6/ipv6-support/files/support.sh
+++ b/package/network/ipv6/ipv6-support/files/support.sh
@@ -93,93 +93,143 @@ announce_prefix() {
 }
 
 
-disable_downstream() {
+disable_router() {
 	local network="$1"
 
 	# Notify the address distribution daemon
 	ubus call 6distributed deliface '{"network": "'"$network"'"}'
 
 	# Disable advertisement daemon
-	stop_service /usr/sbin/6relayd "/var/run/ipv6-downstream-$network.pid"
+	stop_service /usr/sbin/6relayd "/var/run/ipv6-router-$network.pid"
 }
 
 
-restart_relay_add() {
+restart_relay_slave() {
+	local __section="$1"
+	local __master="$2"
+
+	network_is_up "$__section" || return
+
+	local __device=""
+	network_get_device __device "$__section"
+
+	local __cmaster=""
+	config_get __cmaster "$__section" relay_master
+
+	[ "$__master" == "$__cmaster" ] && {
+		disable_interface "$__section"
+		enable_interface "$__section" "$__device"
+	}
+}
+
+
+add_relay_slave() {
 	local __section="$1"
 	local __return="$2"
 	local __master="$3"
-	local __disable="$4"
+	local __mode="$4"
 
 	network_is_up "$__section" || return
 
+	# Get device
+	local __device=""
+	network_get_device __device "$__section"
+
 	# Match master network
 	local __cmaster=""
 	config_get __cmaster "$__section" relay_master
-	[ "$__master" != "$__cmaster" ] && return
+	[ "$__master" == "$__cmaster" ] || return
 	
-	# Disable any active distribution
-	disable_downstream "$__section"
+	# Test slave  mode
+	local __cmode=""
+	config_get __cmode "$__section" mode
+	[ "$__cmode" == "downstream" ] && __cmode="router"
 
-	local __device=""
-	network_get_device __device "$__section"
-	
-	# Coming from stop relay, reenable distribution
-	[ "$__disable" == "disable" ] && {
-		enable_downstream "$__section" "$__device"
-		return
-	}
+	# Don't start fallback interfaces if we are in forced-relay mode
+	[ "$__cmode" == "relay" -o "$__mode" == "fallback" ] || return
+
+	# Don't make non-relay or non-router interfaces slaves
+	[ "$__cmode" == "relay" -o "$__cmode" == "router" ] || return
+
+	# Disable any active distribution
+	[ "$__cmode" == "router" ] && disable_router "$__section"
 
-	
 	eval "$__return"'="$'"$__return"' '"$__device"'"'
 }
 
 
 stop_relay() {
 	local network="$1"
-	local pid="/var/run/ipv6-relay-$network.pid"
-	local was_running=""
+	local pid_fallback="/var/run/ipv6-relay-fallback-$network.pid"
+	local pid_forced="/var/run/ipv6-relay-forced-$network.pid"
+	local was_fallback=""
 	
-	stop_service /usr/sbin/6relayd "$pid" was_running
+	stop_service /usr/sbin/6relayd "$pid_fallback" was_fallback
+	stop_service /usr/sbin/6relayd "$pid_forced"
 
 	# Reenable normal distribution on slave interfaces	
-	[ -n "$was_running" ] && config_foreach restart_relay_add interface dummy "$network" disable
+	[ -n "$was_fallback" ] && config_foreach restart_relay_slave interface "$network"
+}
+
+
+detect_forced_relay_mode() {
+	local __section="$1"
+	local __mode="$2"
+
+	local __cmode
+	config_get __cmode "$__section" mode
+	[ "$__cmode" == "relay" ] && eval "$__mode=forced"
 }
 
 
 restart_relay() {
 	local network="$1"
-	local force="$2"
-	local pid="/var/run/ipv6-relay-$network.pid"
+	local mode="$2"
 
-	local not_running=0
-	[ -f "$pid" ] || not_running=1
+	# Stop last active relay
+	stop_relay "$network"
 
-	# Don't start if not desired
-	[ "$force" != "1" ] && [ "$not_running" == "1" ] && return
+	# Detect if we have a forced-relay
+	[ -z "$mode" ] && config_foreach detect_forced_relay_mode interface mode
 
-	# Kill current relay and distribution daemon
-	stop_relay "$network"
+	# Don't start without a mode
+	[ -z "$mode" ] && return
 
 	# Detect master device
 	local device=""
-	network_get_device device $network
+	network_get_device device "$network"
 
 	# Generate command string
-	local cmd="/usr/sbin/6relayd -A $device "
-	config_foreach restart_relay_add interface cmd "$network"
+	local cmd="/usr/sbin/6relayd -A $device"
+	local ifaces=""
+	config_foreach add_relay_slave interface ifaces "$network" "$mode"
 
 	# Start relay
-	start_service "$cmd" "$pid"
+	local pid="/var/run/ipv6-relay-$mode-$network.pid"
+	[ -n "$ifaces" ] && start_service "$cmd $ifaces" "$pid"
+
+	# There are no slave interface, however indicate that we want to relay
+	[ -z "$ifaces" ] && touch "$pid"
 }
 
 
 restart_master_relay() {
 	local network="$1"
+	local mode="$2"
+	local pid_fallback="/var/run/ipv6-relay-fallback-$network.pid"
+	local pid_forced="/var/run/ipv6-relay-forced-$network.pid"
 
 	# Disable active relaying to this interface
-	local relay_master
 	config_get relay_master "$network" relay_master
-	[ -n "$relay_master" ] && restart_relay "$relay_master"
+	[ -z "$relay_master" ] && return
+	network_is_up "$relay_master" || return
+
+	# Detect running mode
+	[ -z "$mode" && -f "$pid_fallback" ] && mode="fallback"
+	[ -z "$mode" && -f "$pid_forced" ] && mode="forced"
+
+	# Restart relay if running or start requested
+	[ -n "$mode" ] && restart_relay "$relay_master" "$mode"
 }
 
 
@@ -193,13 +243,13 @@ disable_interface() {
 	restart_master_relay "$network"
 
 	# Disable distribution
-	disable_downstream "$network"
+	disable_router "$network"
 
 	# Disable relay
 	stop_relay "$network"
 
 	# Disable DHCPv6 client if enabled, state script will take care
-	stop_service /usr/sbin/odhcp6c "/var/run/ipv6-upstream-$network.pid"
+	stop_service /usr/sbin/odhcp6c "/var/run/ipv6-dhcpv6-$network.pid"
 }
 
 
@@ -245,10 +295,13 @@ enable_static() {
 
 	# Announce all static prefixes
 	config_list_foreach "$network" static_prefix announce_prefix $network
+
+	# start relay if there are forced relay members
+	restart_relay "$network"
 }
 
 
-enable_downstream() {
+enable_router() {
 	local network="$1"
 	local device="$2"
 
@@ -259,7 +312,7 @@ enable_downstream() {
 	[ "$length" -ne "0" ] && ubus call 6distributed newiface '{"network": "'"$network"'", "iface": "'"$device"'", "length": '"$length"'}'
 
 	# Start RD & DHCPv6 service
-	local pid="/var/run/ipv6-downstream-$network.pid"
+	local pid="/var/run/ipv6-router-$network.pid"
 	start_service "/usr/sbin/6relayd -Rserver -Dserver . $device" "$pid"
 
 	# Try relaying if necessary
@@ -267,7 +320,7 @@ enable_downstream() {
 }
 
 
-enable_upstream() {
+enable_dhcpv6() {
 	local network="$1"
 	local device="$2"
 	
@@ -292,13 +345,30 @@ enable_upstream() {
 	}
 	
 	# Start DHCPv6 client
-	local pid="/var/run/ipv6-upstream-$network.pid"
+	local pid="/var/run/ipv6-dhcpv6-$network.pid"
 	start_service "/usr/sbin/odhcp6c -s/lib/ipv6/dhcpv6.sh $dhcp6_opts" "$pid"
 
 	# Refresh RA on all interfaces
-	for pid in /var/run/ipv6-downstream-*.pid; do
+	for pid in /var/run/ipv6-router-*.pid; do
 		kill -SIGUSR1 $(cat "$pid")
 	done
 }
 
 
+enable_interface()
+{
+	local network="$1"
+	local device="$2"
+	local mode=""
+	config_get mode "$network" mode
+
+	# Compatibility with old mode names
+	[ "$mode" == "downstream" ] && mode=router
+	[ "$mode" == "upstream" ] && mode=dhcpv6
+
+	# Run mode startup code
+	[ "$mode" == "dhcpv6" -o "$mode" == "static" ] && enable_static "$network" "$device"
+	[ "$mode" == "dhcpv6" ] && enable_dhcpv6 "$network" "$device"
+	[ "$mode" == "router" ] && enable_router "$network" "$device"
+	[ "$mode" == "relay" ] && restart_master_relay "$network" forced
+}