diff -Naur strongswan-4.5.3.org/src/_updown/_updown.in strongswan-4.5.3/src/_updown/_updown.in
--- strongswan-4.5.3.org/src/_updown/_updown.in	2010-10-22 16:33:30.000000000 +0200
+++ strongswan-4.5.3/src/_updown/_updown.in	2011-09-13 14:19:31.000000000 +0200
@@ -183,6 +183,29 @@
 	;;
 esac
 
+function ip_encode() {
+	local IFS=.
+
+	local int=0
+	for field in $1; do
+		int=$(( $(( $int << 8 )) | $field ))
+	done
+
+	echo $int
+}
+
+function ip_in_subnet() {
+	local netmask
+	netmask=$(_netmask $2)
+	[ $(( $(ip_encode $1) & $netmask)) = $(( $(ip_encode ${2%/*}) & $netmask )) ]
+}
+
+function _netmask() {
+	local vlsm
+	vlsm=${1#*/}
+	[ $vlsm -eq 0 ] && echo 0 || echo $(( -1 << $(( 32 - $vlsm )) ))
+}
+
 # utility functions for route manipulation
 # Meddling with this stuff should not be necessary and requires great care.
 uproute() {
@@ -387,12 +410,12 @@
 	# connection to me, with (left/right)firewall=yes, coming up
 	# This is used only by the default updown script, not by your custom
 	# ones, so do not mess with it; see CAUTION comment up at top.
-	iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	iptables -I IPSECINPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	    -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	    -d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
-	iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	iptables -I IPSECOUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
-	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
+	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j MARK --set-mark 50
 	#
 	# log IPsec host connection setup
 	if [ $VPN_LOGGING ]
@@ -400,10 +423,10 @@
 	  if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
 	  then
 	    logger -t $TAG -p $FAC_PRIO \
-	      "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
+	      "host+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
 	  else
 	    logger -t $TAG -p $FAC_PRIO \
-	      "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
+	      "host+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
 	  fi
 	fi
 	;;
@@ -411,12 +434,12 @@
 	# connection to me, with (left/right)firewall=yes, going down
 	# This is used only by the default updown script, not by your custom
 	# ones, so do not mess with it; see CAUTION comment up at top.
-	iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	iptables -D IPSECINPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	    -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	    -d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
-	iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	iptables -D IPSECOUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
-	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
+	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j MARK --set-mark 50
 	#
 	# log IPsec host connection teardown
 	if [ $VPN_LOGGING ]
@@ -424,10 +447,10 @@
 	  if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
 	  then
 	    logger -t $TAG -p $FAC_PRIO -- \
-	      "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
+	      "host- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME"
 	  else
 	    logger -t $TAG -p $FAC_PRIO -- \
-	    "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
+	    "host- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME"
 	  fi
 	fi
 	;;
@@ -437,10 +460,10 @@
 	# ones, so do not mess with it; see CAUTION comment up at top.
 	if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
 	then
-	  iptables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	  iptables -I IPSECFORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	      -s $PLUTO_MY_CLIENT $S_MY_PORT \
-	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
-	  iptables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j MARK --set-mark 50
+	  iptables -I IPSECFORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	      -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	      -d $PLUTO_MY_CLIENT $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
 	fi
@@ -449,12 +472,12 @@
 	# or sometimes host access via the internal IP is needed
 	if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
 	then
-	  iptables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	  iptables -I IPSECINPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	      -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	      -d $PLUTO_MY_CLIENT $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
-	  iptables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	  iptables -I IPSECOUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	      -s $PLUTO_MY_CLIENT $S_MY_PORT \
-	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
+	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j MARK --set-mark 50
 	fi
 	#
 	# log IPsec client connection setup
@@ -463,12 +486,51 @@
 	  if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
 	  then
 	    logger -t $TAG -p $FAC_PRIO \
-	      "+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
+	      "client+ $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
 	  else
 	    logger -t $TAG -p $FAC_PRIO \
-	      "+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
+	      "client+ $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
 	  fi
 	fi
+
+	#
+	# Open Firewall for IPinIP + AH + ESP Traffic
+	  iptables -I IPSECINPUT 1 -i $PLUTO_INTERFACE -p IP \
+	      -s $PLUTO_PEER $S_PEER_PORT \
+	      -d $PLUTO_ME $D_MY_PORT -j ACCEPT
+	  iptables -I IPSECINPUT 1 -i $PLUTO_INTERFACE -p AH \
+	      -s $PLUTO_PEER $S_PEER_PORT \
+	      -d $PLUTO_ME $D_MY_PORT -j ACCEPT
+	  iptables -I IPSECINPUT 1 -i $PLUTO_INTERFACE -p ESP \
+	      -s $PLUTO_PEER $S_PEER_PORT \
+	      -d $PLUTO_ME $D_MY_PORT -j ACCEPT
+	if [ $VPN_LOGGING ]
+	then
+	    logger -t $TAG -p $FAC_PRIO \
+	      "tunnel+ $PLUTO_PEER -- $PLUTO_ME"
+	fi
+
+	# Add source nat so also the gateway can access the other nets
+	eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
+	for _src in ${GREEN_ADDRESS} ${BLUE_ADDRESS} ${ORANGE_ADDRESS}; do
+		ip_in_subnet "${_src}" "${PLUTO_MY_CLIENT}"
+		if [ $? -eq 0 ]; then
+			src=${_src}
+			break
+		fi
+	done
+
+	if [ -n "${src}" ]; then
+		iptables -t nat -A IPSECNAT -o $PLUTO_INTERFACE -s $PLUTO_ME -d $PLUTO_PEER_CLIENT -j SNAT --to $src
+		logger -t $TAG -p $FAC_PRIO \
+			"snat+ $PLUTO_INTERFACE-$PLUTO_ME : $PLUTO_PEER_CLIENT - $src"
+	else
+		logger -t $TAG -p $FAC_PRIO \
+			"Cannot create NAT rule because no IP of the IPFire does match the subnet. $PLUTO_MY_CLIENT"
+	fi
+
+	# Flush routing cache
+	ip route flush cache
 	;;
 down-client:iptables)
 	# connection to client subnet, with (left/right)firewall=yes, going down
@@ -476,11 +538,11 @@
 	# ones, so do not mess with it; see CAUTION comment up at top.
 	if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/32" ]
 	then
-	  iptables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	  iptables -D IPSECFORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	      -s $PLUTO_MY_CLIENT $S_MY_PORT \
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT \
-	         $IPSEC_POLICY_OUT -j ACCEPT
-	  iptables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	         $IPSEC_POLICY_OUT -j MARK --set-mark 50
+	  iptables -D IPSECFORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	      -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	      -d $PLUTO_MY_CLIENT $D_MY_PORT \
 	         $IPSEC_POLICY_IN -j ACCEPT
@@ -490,14 +552,14 @@
 	# or sometimes host access via the internal IP is needed
 	if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
 	then
-	  iptables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	  iptables -D IPSECINPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	      -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	      -d $PLUTO_MY_CLIENT $D_MY_PORT \
 	         $IPSEC_POLICY_IN -j ACCEPT
-	  iptables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	  iptables -D IPSECOUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	      -s $PLUTO_MY_CLIENT $S_MY_PORT \
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT \
-	         $IPSEC_POLICY_OUT -j ACCEPT
+	         $IPSEC_POLICY_OUT -j MARK --set-mark 50
 	fi
 	#
 	# log IPsec client connection teardown
@@ -506,12 +568,51 @@
 	  if [ "$PLUTO_PEER_CLIENT" = "$PLUTO_PEER/32" ]
 	  then
 	    logger -t $TAG -p $FAC_PRIO -- \
-	      "- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
+	      "client- $PLUTO_PEER_ID $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
 	  else
 	    logger -t $TAG -p $FAC_PRIO -- \
-	      "- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
+	      "client- $PLUTO_PEER_ID $PLUTO_PEER_CLIENT == $PLUTO_PEER -- $PLUTO_ME == $PLUTO_MY_CLIENT"
 	  fi
 	fi
+
+	#
+	# Close Firewall for IPinIP + AH + ESP Traffic
+	  iptables -D IPSECINPUT -i $PLUTO_INTERFACE -p IP \
+	      -s $PLUTO_PEER $S_PEER_PORT \
+	      -d $PLUTO_ME $D_MY_PORT -j ACCEPT
+	  iptables -D IPSECINPUT -i $PLUTO_INTERFACE -p AH \
+	      -s $PLUTO_PEER $S_PEER_PORT \
+	      -d $PLUTO_ME $D_MY_PORT -j ACCEPT
+	  iptables -D IPSECINPUT -i $PLUTO_INTERFACE -p ESP \
+	      -s $PLUTO_PEER $S_PEER_PORT \
+	      -d $PLUTO_ME $D_MY_PORT -j ACCEPT
+	if [ $VPN_LOGGING ]
+	then
+	    logger -t $TAG -p $FAC_PRIO \
+	      "tunnel- $PLUTO_PEER -- $PLUTO_ME"
+	fi
+
+	# remove source nat
+	eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings)
+	for _src in ${GREEN_ADDRESS} ${BLUE_ADDRESS} ${ORANGE_ADDRESS}; do
+		ip_in_subnet "${_src}" "${PLUTO_MY_CLIENT}"
+		if [ $? -eq 0 ]; then
+			src=${_src}
+			break
+		fi
+	done
+
+	if [ -n "${src}" ]; then
+		iptables -t nat -D IPSECNAT -o $PLUTO_INTERFACE -s $PLUTO_ME -d $PLUTO_PEER_CLIENT -j SNAT --to $src
+		logger -t $TAG -p $FAC_PRIO \
+			"snat- $PLUTO_INTERFACE-$PLUTO_ME : $PLUTO_PEER_CLIENT - $src"
+	else
+		logger -t $TAG -p $FAC_PRIO \
+			"Cannot remove NAT rule because no IP of the IPFire does match the subnet."
+	fi
+
+	# Flush routing cache
+	ip route flush cache
 	;;
 #
 # IPv6
@@ -546,10 +647,10 @@
 	# connection to me, with (left/right)firewall=yes, coming up
 	# This is used only by the default updown script, not by your custom
 	# ones, so do not mess with it; see CAUTION comment up at top.
-	ip6tables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	ip6tables -I IPSECINPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	    -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	    -d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
-	ip6tables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	ip6tables -I IPSECOUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
@@ -570,10 +671,10 @@
 	# connection to me, with (left/right)firewall=yes, going down
 	# This is used only by the default updown script, not by your custom
 	# ones, so do not mess with it; see CAUTION comment up at top.
-	ip6tables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	ip6tables -D IPSECINPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	    -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	    -d $PLUTO_ME $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
-	ip6tables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	ip6tables -D IPSECOUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	    -s $PLUTO_ME $S_MY_PORT $IPSEC_POLICY_OUT \
 	    -d $PLUTO_PEER_CLIENT $D_PEER_PORT -j ACCEPT
 	#
@@ -596,10 +697,10 @@
 	# ones, so do not mess with it; see CAUTION comment up at top.
 	if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/128" ]
 	then
-	  ip6tables -I FORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	  ip6tables -I IPSECFORWARD 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	      -s $PLUTO_MY_CLIENT $S_MY_PORT \
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
-	  ip6tables -I FORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	  ip6tables -I IPSECFORWARD 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	      -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	      -d $PLUTO_MY_CLIENT $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
 	fi
@@ -608,10 +709,10 @@
 	# or sometimes host access via the internal IP is needed
 	if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
 	then
-	  ip6tables -I INPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	  ip6tables -I IPSECINPUT 1 -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	      -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	      -d $PLUTO_MY_CLIENT $D_MY_PORT $IPSEC_POLICY_IN -j ACCEPT
-	  ip6tables -I OUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	  ip6tables -I IPSECOUTPUT 1 -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	      -s $PLUTO_MY_CLIENT $S_MY_PORT \
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT $IPSEC_POLICY_OUT -j ACCEPT
 	fi
@@ -635,11 +736,11 @@
 	# ones, so do not mess with it; see CAUTION comment up at top.
 	if [ "$PLUTO_PEER_CLIENT" != "$PLUTO_MY_SOURCEIP/128" ]
 	then
-	  ip6tables -D FORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	  ip6tables -D IPSECFORWARD -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	      -s $PLUTO_MY_CLIENT $S_MY_PORT \
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT \
 	         $IPSEC_POLICY_OUT -j ACCEPT
-	  ip6tables -D FORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	  ip6tables -D IPSECFORWARD -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	      -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	      -d $PLUTO_MY_CLIENT $D_MY_PORT \
 	         $IPSEC_POLICY_IN -j ACCEPT
@@ -649,11 +750,11 @@
 	# or sometimes host access via the internal IP is needed
 	if [ -n "$PLUTO_MY_SOURCEIP" -o -n "$PLUTO_HOST_ACCESS" ]
 	then
-	  ip6tables -D INPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
+	  ip6tables -D IPSECINPUT -i $PLUTO_INTERFACE -p $PLUTO_MY_PROTOCOL \
 	      -s $PLUTO_PEER_CLIENT $S_PEER_PORT \
 	      -d $PLUTO_MY_CLIENT $D_MY_PORT \
 	         $IPSEC_POLICY_IN -j ACCEPT
-	  ip6tables -D OUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
+	  ip6tables -D IPSECOUTPUT -o $PLUTO_INTERFACE -p $PLUTO_PEER_PROTOCOL \
 	      -s $PLUTO_MY_CLIENT $S_MY_PORT \
 	      -d $PLUTO_PEER_CLIENT $D_PEER_PORT \
 	         $IPSEC_POLICY_OUT -j ACCEPT
