--- /dev/null
+#!/bin/bash
+###############################################################################
+# #
+# IPFire.org - A linux based firewall #
+# Copyright (C) 2015 IPFire Team #
+# #
+# This program is free software: you can redistribute it and/or modify #
+# it under the terms of the GNU General Public License as published by #
+# the Free Software Foundation, either version 3 of the License, or #
+# (at your option) any later version. #
+# #
+# This program is distributed in the hope that it will be useful, #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
+# GNU General Public License for more details. #
+# #
+# You should have received a copy of the GNU General Public License #
+# along with this program. If not, see <http://www.gnu.org/licenses/>. #
+# #
+###############################################################################
+
+shopt -s nullglob
+
+VPN_CONFIG="/var/ipfire/vpn/config"
+
+eval $(/usr/local/bin/readhash /var/ipfire/vpn/settings)
+
+VARS=(
+ id status name lefthost type ctype x1 x2 x3 leftsubnets
+ remote righthost rightsubnets x5 x6 x7 x8 x9 x10 x11 x12
+ x13 x14 x15 x16 x17 x18 x19 x20 x21 proto x22 x23 x24
+ route x26 mode interface_mode interface_address interface_mtu rest
+)
+
+log() {
+ logger -t ipsec "$@"
+}
+
+main() {
+ # We are done when IPsec is not enabled
+ [ "${ENABLED}" = "on" ] || exit 0
+
+ # Register local variables
+ local "${VARS[@]}"
+ local action
+
+ local interfaces=()
+
+ while IFS="," read -r "${VARS[@]}"; do
+ # Check if the connection is enabled
+ [ "${status}" = "on" ] || continue
+
+ # Check if this a net-to-net connection
+ [ "${type}" = "net" ] || continue
+
+ # Determine the interface name
+ case "${interface_mode}" in
+ gre|vti)
+ local intf="${interface_mode}${id}"
+ ;;
+ *)
+ continue
+ ;;
+ esac
+
+ # Add the interface to the list of all interfaces
+ interfaces+=( "${intf}" )
+
+ local args=(
+ "local" "${VPN_IP}"
+ "remote" "${remote}"
+ "ttl" "255"
+ )
+
+ # Add key for VTI
+ if [ "${interface_mode}" = "vti" ]; then
+ args+=( key "${id}" )
+ fi
+
+ # Update the settings when the interface already exists
+ if [ -d "/sys/class/net/${intf}" ]; then
+ ip link change dev "${intf}" \
+ type "${interface_mode}" "${args[@]}" &>/dev/null
+
+ # Create a new interface and bring it up
+ else
+ log "Creating interface ${intf}"
+ ip link add name "${intf}" type "${interface_mode}" "${args[@]}"
+ fi
+
+ # Add an IP address
+ ip addr flush dev "${intf}"
+ ip addr add "${interface_address}" dev "${intf}"
+
+ # Set MTU
+ ip link set dev "${intf}" mtu "${interface_mtu}"
+
+ # Bring up the interface
+ ip link set dev "${intf}" up
+ done < "${VPN_CONFIG}"
+
+ # Delete all other interfaces
+ local intf
+ for intf in /sys/class/net/gre* /sys/class/net/vti*; do
+ intf="$(basename "${intf}")"
+
+ # Ignore a couple of interfaces that cannot be deleted
+ case "${intf}" in
+ gre0|gretap0)
+ continue
+ ;;
+ esac
+
+ # Check if interface is on the list
+ local i found="false"
+ for i in ${interfaces[@]}; do
+ if [ "${intf}" = "${i}" ]; then
+ found="true"
+ break
+ fi
+ done
+
+ # Nothing to do if interface was found
+ ${found} && continue
+
+ # Delete the interface
+ log "Deleting interface ${intf}"
+ ip link del "${intf}" &>/dev/null
+ done
+}
+
+main || exit $?