From: Michael Tremer Date: Sun, 23 Sep 2018 19:18:09 +0000 (+0200) Subject: ip-tunnel: New port hook X-Git-Tag: 010~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8032884dfab9bad07f5a5410fb554a973e65a290;p=network.git ip-tunnel: New port hook This allows to create layer-2 tunnels using the GRETAP protocol Fixes: #11608 Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index 7903fd54..399652e1 100644 --- a/Makefile.am +++ b/Makefile.am @@ -229,6 +229,7 @@ dist_hooks_ports_SCRIPTS = \ src/hooks/ports/bonding \ src/hooks/ports/dummy \ src/hooks/ports/ethernet \ + src/hooks/ports/ip-tunnel \ src/hooks/ports/vlan \ src/hooks/ports/wireless-ap \ src/hooks/ports/wireless-mesh diff --git a/src/hooks/ports/ip-tunnel b/src/hooks/ports/ip-tunnel new file mode 100644 index 00000000..73e803e2 --- /dev/null +++ b/src/hooks/ports/ip-tunnel @@ -0,0 +1,148 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2018 IPFire Network Development 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 . # +# # +############################################################################### + +. /usr/lib/network/header-port + +SUPPORTED_IP_TUNNEL_MODES="gretap" + +HOOK_SETTINGS="ADDRESS MARK MODE PEER LOCAL_ADDRESS" + +hook_check_settings() { + assert isset MODE + assert isoneof MODE ${SUPPORTED_IP_TUNNEL_MODES} + + # Generate a random mark + if ! isset MARK; then + MARK="$(( ${RANDOM} & 0xffffffff ))" + fi +} + +hook_parse_cmdline() { + while [ $# -gt 0 ]; do + case "${1}" in + --local-address=*) + LOCAL_ADDRESS="$(cli_get_val "${1}")" + ;; + + --mode=*) + MODE="$(cli_get_val "${1}")" + + # MODE must be on the list of supported protocols + if ! isoneof MODE ${SUPPORTED_IP_TUNNEL_MODES}; then + error "Unsupported mode: ${mode}" + return ${EXIT_ERROR} + fi + ;; + + --peer=*) + PEER="$(cli_get_val "${1}")" + ;; + + *) + error "Unknown option: ${1}" + return ${EXIT_ERROR} + ;; + esac + shift + done + + # If PEER is set, it must be a valid IP address + if isset PEER && ! ip_is_valid "${PEER}"; then + error "Peer ${PEER} is not a valid IP address" + return ${EXIT_ERROR} + fi + + # If LOCAL_ADDRESS is set, it must be a valid IP address + # of the same protocol than PEER is + if isset LOCAL_ADDRESS; then + if ! ip_is_valid "${LOCAL_ADDRESS}"; then + error "Local address ${LOCAL_ADDRESS} is not a valid IP address" + return ${EXIT_ERROR} + fi + + if ! ip_protocol_match "${PEER}" "${LOCAL_ADDRESS}"; then + error "Peer and local address are of different IP protocols" + return ${EXIT_ERROR} + fi + fi + + return ${EXIT_OK} +} + +hook_create() { + local port="${1}" + assert isset port + + local ${HOOK_SETTINGS} + if ! port_settings_read "${port}" ${HOOK_SETTINGS}; then + log ERROR "Could not read settings for port ${port}" + return ${EXIT_ERROR} + fi + + if ! ip_tunnel_add "${port}" \ + --mode="${MODE}" \ + --address="${ADDRESS}" \ + --remote-address="${PEER}" \ + --local-address="${LOCAL_ADDRESS}" \ + --ikey="${MARK}" \ + --okey="${MARK}"; then + return ${EXIT_ERROR} + fi + + exit ${EXIT_OK} +} + +hook_remove() { + local port="${1}" + assert isset port + + # Remove the device + if ! ip_tunnel_del "${port}"; then + return ${EXIT_ERROR} + fi + + exit ${EXIT_OK} +} + +hook_hotplug_rename() { + local port="${1}" + assert isset port + + local device="${2}" + assert isset device + + local ${HOOK_SETTINGS} + if ! port_settings_read "${port}" ${HOOK_SETTINGS}; then + log ERROR "Could not read settings for port ${port}" + return ${EXIT_ERROR} + fi + + # Get the current MAC address of the device. + local address="$(device_get_address ${device})" + assert isset address + + # Return OK on match + if [ "${ADDRESS}" = "${address}" ]; then + return ${EXIT_OK} + fi + + return ${EXIT_ERROR} +}