ipv6-support: Second Iteration * mode 'downstream' renamed to 'router' * mode 'upstream' renamed to 'dhcpv6' * mode 'relay' added * cleanups and minor bugfixes in state handling

SVN-Revision: 34466
This commit is contained in:
Steven Barth 2012-12-03 09:18:53 +00:00
parent 71ed7ae842
commit 4bda16cf27
5 changed files with 120 additions and 54 deletions

View file

@ -8,7 +8,7 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=ipv6-support PKG_NAME:=ipv6-support
PKG_VERSION:=2012-11-29 PKG_VERSION:=2012-12-03
PKG_RELEASE:=1 PKG_RELEASE:=1
include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/package.mk

View file

@ -27,11 +27,11 @@ done
local prefix_fallback local prefix_fallback
config_get prefix_fallback "$network" prefix_fallback config_get prefix_fallback "$network" prefix_fallback
[ "$prefix_fallback" == "relay" -a -z "$PREFIXES" -a "$state" != "unbound" ] && [ "$prefix_fallback" == "relay" -a -z "$PREFIXES" -a "$state" != "unbound" ] &&
restart_relay "$network" 1 restart_relay "$network" "fallback"
# Disable relay if requested # Disable relay if requested
[ "$prefix_fallback" != "relay" -o -n "$PREFIXES" -o "$state" == "unbound" ] && [ "$prefix_fallback" != "relay" -o -n "$PREFIXES" -o "$state" == "unbound" ] &&
stop_relay "$network" restart_relay "$network"
# Operations in case of success # Operations in case of success

View file

@ -3,16 +3,11 @@
[ "$DEVICE" == "lo" ] && exit 0 [ "$DEVICE" == "lo" ] && exit 0
. /lib/ipv6/support.sh . /lib/ipv6/support.sh
local mode
config_get mode "$INTERFACE" mode
case "$ACTION" in case "$ACTION" in
ifup) ifup)
[ "$mode" != "downstream" ] && enable_static $INTERFACE $DEVICE enable_interface "$INTERFACE" "$DEVICE"
[ "$mode" == "upstream" ] && enable_upstream $INTERFACE $DEVICE
[ "$mode" == "downstream" ] && enable_downstream $INTERFACE $DEVICE
;; ;;
ifdown) ifdown)
disable_interface $INTERFACE $DEVICE disable_interface "$INTERFACE" "$DEVICE"
;; ;;
esac esac

View file

@ -1,5 +1,5 @@
config interface wan config interface wan
option mode upstream option mode dhcpv6
option ula_prefix auto option ula_prefix auto
option request_prefix auto option request_prefix auto
option prefix_fallback relay option prefix_fallback relay
@ -7,7 +7,7 @@ config interface wan
config interface lan config interface lan
option mode downstream option mode router
option advertise_prefix 64 option advertise_prefix 64
option relay_master wan option relay_master wan
@ -15,3 +15,4 @@ config interface lan
config interface 6in4 config interface 6in4
option mode static option mode static
list static_prefix 2001:DB8::/48 list static_prefix 2001:DB8::/48

View file

@ -93,93 +93,143 @@ announce_prefix() {
} }
disable_downstream() { disable_router() {
local network="$1" local network="$1"
# Notify the address distribution daemon # Notify the address distribution daemon
ubus call 6distributed deliface '{"network": "'"$network"'"}' ubus call 6distributed deliface '{"network": "'"$network"'"}'
# Disable advertisement daemon # 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 __section="$1"
local __return="$2" local __return="$2"
local __master="$3" local __master="$3"
local __disable="$4" local __mode="$4"
network_is_up "$__section" || return network_is_up "$__section" || return
# Get device
local __device=""
network_get_device __device "$__section"
# Match master network # Match master network
local __cmaster="" local __cmaster=""
config_get __cmaster "$__section" relay_master config_get __cmaster "$__section" relay_master
[ "$__master" != "$__cmaster" ] && return [ "$__master" == "$__cmaster" ] || return
# Test slave mode
local __cmode=""
config_get __cmode "$__section" mode
[ "$__cmode" == "downstream" ] && __cmode="router"
# 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 # Disable any active distribution
disable_downstream "$__section" [ "$__cmode" == "router" ] && disable_router "$__section"
local __device=""
network_get_device __device "$__section"
# Coming from stop relay, reenable distribution
[ "$__disable" == "disable" ] && {
enable_downstream "$__section" "$__device"
return
}
eval "$__return"'="$'"$__return"' '"$__device"'"' eval "$__return"'="$'"$__return"' '"$__device"'"'
} }
stop_relay() { stop_relay() {
local network="$1" local network="$1"
local pid="/var/run/ipv6-relay-$network.pid" local pid_fallback="/var/run/ipv6-relay-fallback-$network.pid"
local was_running="" 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 # 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() { restart_relay() {
local network="$1" local network="$1"
local force="$2" local mode="$2"
local pid="/var/run/ipv6-relay-$network.pid"
local not_running=0 # Stop last active relay
[ -f "$pid" ] || not_running=1
# Don't start if not desired
[ "$force" != "1" ] && [ "$not_running" == "1" ] && return
# Kill current relay and distribution daemon
stop_relay "$network" stop_relay "$network"
# Detect if we have a forced-relay
[ -z "$mode" ] && config_foreach detect_forced_relay_mode interface mode
# Don't start without a mode
[ -z "$mode" ] && return
# Detect master device # Detect master device
local device="" local device=""
network_get_device device $network network_get_device device "$network"
# Generate command string # Generate command string
local cmd="/usr/sbin/6relayd -A $device " local cmd="/usr/sbin/6relayd -A $device"
config_foreach restart_relay_add interface cmd "$network" local ifaces=""
config_foreach add_relay_slave interface ifaces "$network" "$mode"
# Start relay # 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() { restart_master_relay() {
local network="$1" 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 # Disable active relaying to this interface
local relay_master
config_get relay_master "$network" 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" restart_master_relay "$network"
# Disable distribution # Disable distribution
disable_downstream "$network" disable_router "$network"
# Disable relay # Disable relay
stop_relay "$network" stop_relay "$network"
# Disable DHCPv6 client if enabled, state script will take care # 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 # Announce all static prefixes
config_list_foreach "$network" static_prefix announce_prefix $network 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 network="$1"
local device="$2" local device="$2"
@ -259,7 +312,7 @@ enable_downstream() {
[ "$length" -ne "0" ] && ubus call 6distributed newiface '{"network": "'"$network"'", "iface": "'"$device"'", "length": '"$length"'}' [ "$length" -ne "0" ] && ubus call 6distributed newiface '{"network": "'"$network"'", "iface": "'"$device"'", "length": '"$length"'}'
# Start RD & DHCPv6 service # 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" start_service "/usr/sbin/6relayd -Rserver -Dserver . $device" "$pid"
# Try relaying if necessary # Try relaying if necessary
@ -267,7 +320,7 @@ enable_downstream() {
} }
enable_upstream() { enable_dhcpv6() {
local network="$1" local network="$1"
local device="$2" local device="$2"
@ -292,13 +345,30 @@ enable_upstream() {
} }
# Start DHCPv6 client # 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" start_service "/usr/sbin/odhcp6c -s/lib/ipv6/dhcpv6.sh $dhcp6_opts" "$pid"
# Refresh RA on all interfaces # 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") kill -SIGUSR1 $(cat "$pid")
done 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
}