#!/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} assert isset ADDRESS assert mac_is_valid "${ADDRESS}" # Generate a random mark if ! isset MARK; then MARK="$(( ${RANDOM} & 0xffffffff ))" fi } hook_parse_cmdline() { while [ $# -gt 0 ]; do case "${1}" in --address=*) ADDRESS="$(cli_get_val "${1}")" if ! isset ADDRESS || ! mac_is_valid "${ADDRESS}"; then error "Invalid MAC address: ${ADDRESS}" return ${EXIT_ERROR} fi ;; --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 # Generate a random MAC address if none is set if ! isset ADDRESS; then ADDRESS="$(mac_generate)" fi # 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}"; 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() { hook_hotplug_rename_by_address "$@" }