From: Michael Tremer Date: Thu, 31 May 2012 13:39:56 +0000 (+0000) Subject: Add support for teredo (miredo). X-Git-Tag: 004~61 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=28f0b4ab91f906e87880ac089158b467299b5811;p=network.git Add support for teredo (miredo). Teredo is a tunneling protocol for IPv6 tunnels which are able to traverse NAT easily. --- diff --git a/Makefile b/Makefile index 3d2300c0..c8973acf 100644 --- a/Makefile +++ b/Makefile @@ -37,6 +37,10 @@ install: cp -vf systemd/*.service $(DESTDIR)$(systemdunitdir) cp -vf network.tmpfiles $(DESTDIR)$(tmpfilesdir)/network.conf + # Install the helper tools. + -mkdir -pv $(DESTDIR)$(libdir)/network/helpers + cp -vf helpers/* $(DESTDIR)$(libdir)/network/helpers + # Install bridge-stp. install -m 755 bridge-stp $(DESTDIR)$(sbindir)/ diff --git a/functions.device b/functions.device index 3c1005db..2bdfb1d9 100644 --- a/functions.device +++ b/functions.device @@ -126,9 +126,12 @@ function device_is_ppp() { local device=${1} local type=$(__device_get_file ${device} type) - if [ "${type}" = "512" ]; then - return ${EXIT_OK} - fi + + case "${type}" in + 512|65534) + return ${EXIT_OK} + ;; + esac return ${EXIT_ERROR} } diff --git a/functions.radvd b/functions.radvd index 0cc04d1c..279ee8ed 100644 --- a/functions.radvd +++ b/functions.radvd @@ -44,7 +44,7 @@ function radvd_write_config() { # Write the configuration for all zones. local zone - for zone in $(zones_get_all); do + for zone in $(zones_get_local); do __radvd_config_interface ${zone} done } diff --git a/functions.routing b/functions.routing index 986596ac..7fca8ba9 100644 --- a/functions.routing +++ b/functions.routing @@ -49,18 +49,26 @@ function routing_default_update() { if [ "$(routing_db_get ${zone} ${proto} active)" = "1" ]; then gateway=$(routing_db_get ${zone} ${proto} remote-ip-address) - [ -z "${gateway}" ] && continue - - weight=$(routing_db_get ${zone} ${proto} weight) assert device_exists ${zone} + + # If we have got a PPP device, we will directly send all + # packets into the pipe. if device_is_ppp ${zone}; then routes="${routes} dev ${zone}" - else + + # On other devices, we will use the gateway if we got one. + elif isset gateway; then routes="${routes} nexthop via ${gateway}" + + # If none of the cases above apply, we cannot go on. + else + continue fi - if [ -n "${weight}" ]; then + # Apply weight. + weight=$(routing_db_get ${zone} ${proto} weight) + if isinteger ${weight}; then routes="${routes} weight ${weight}" fi else @@ -83,7 +91,7 @@ function routing_default_update() { log INFO "Setting default route for ${proto}: ${routes}" - ${cmd} add default ${routes} + cmd ${cmd} add default ${routes} assert [ $? -eq 0 ] case "${proto}" in @@ -204,30 +212,37 @@ function routing_update() { local table=${zone} assert isset proto + local ip_cmd="ip" + if [ "${proto}" = "ipv6" ]; then + ip_cmd="${ip_cmd} -6" + fi + # Create routing table if not exists routing_table_create ${table} log DEBUG "Flushing routing table ${table}" - cmd ip route flush table ${table} + cmd ${ip_cmd} route flush table ${table} local local_ip_address=$(routing_db_get ${zone} ${proto} local-ip-address) local remote_ip_address=$(routing_db_get ${zone} ${proto} remote-ip-address) - # XXX does not work. case "${proto}" in ipv4) local net_address=$(ipv4_get_netaddress ${local_ip_address}) log DEBUG "Adding route for subnet ${local_ip_address} to table ${table}" - cmd ip route add table ${table} ${net_address} dev ${zone} + cmd ${ip_cmd} route add table ${table} ${net_address} dev ${zone} ;; esac + log DEBUG "Adding default route for table ${table}" + local routing_cmd="${ip_cmd} route add table ${table} default" if isset remote_ip_address; then - log DEBUG "Adding default route for table ${table}" - - cmd ip route add table ${table} default nexthop via ${remote_ip_address} + routing_cmd="${routing_cmd} via ${remote_ip_address}" + else + routing_cmd="${routing_cmd} dev ${zone}" fi + cmd ${routing_cmd} - cmd ip rule add from ${local_ip_address} lookup ${table} + cmd ${ip_cmd} rule add from ${local_ip_address} lookup ${table} } diff --git a/functions.teredo b/functions.teredo new file mode 100644 index 00000000..ca028043 --- /dev/null +++ b/functions.teredo @@ -0,0 +1,85 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2012 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 . # +# # +############################################################################### + +function teredo_start() { + local zone=${1} + assert isset zone + + service_start "miredo-client@${zone}" +} + +function teredo_stop() { + local zone=${1} + assert isset zone + + # Just stop the miredo daemon for this device. + service_stop "miredo-client@${zone}" +} + +function teredo_write_config() { + local zone=${1} + local file=${2} + shift 2 + + assert isset zone + assert isset file + + local server + + while [ $# -gt 0 ]; do + case "${1}" in + --server=*) + server=$(cli_get_val ${1}) + ;; + esac + shift + done + + # Check if all required parameters are correctly set. + assert isset server + + # Create the file's directory if necessary and + # make sure there is nothing in the file, yet. + mkdir -p $(dirname ${file}) 2>/dev/null + : > ${file} + + # Print the header. + ( echo "#" + echo "# This is a miredo client configuration file for ${interface}." + echo "# THIS FILE IS AUTOMATICALLY GENERATED AND WILL OVERWRITE" + echo "# ANY CUSTOM CHANGES!" + echo "#" + echo "# $(date -u)" + echo "#" + echo + ) >>${file} + + # All teredo connections we have are in client mode. + echo "RelayType client" >> ${file} + + # The interface equals the name of the zone. + echo "InterfaceName ${zone}" >> ${file} + + # Add the server information. + echo "ServerAddress ${server}" >> ${file} + + exit ${EXIT_OK} +} diff --git a/helpers/miredo-config-helper b/helpers/miredo-config-helper new file mode 100755 index 00000000..6f522ca8 --- /dev/null +++ b/helpers/miredo-config-helper @@ -0,0 +1,52 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2012 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/functions + +action="${1}" +assert isset action + +zone="${2}" +assert isset zone +assert zone_exists ${zone} + +config_file="${RUN_DIR}/miredo/${zone}/client.conf" + +case "${action}" in + create) + # Create the configuration file for this zone. + zone_config_read ${zone} + + teredo_write_config ${zone} ${config_file} \ + --server="${SERVER}" + ;; + + remove) + rm -f ${config_file} + ;; + + *) + log ERROR "Unknown action passed: ${action}" + exit ${EXIT_ERROR} + ;; +esac + +exit ${EXIT_OK} diff --git a/helpers/miredo-helper b/helpers/miredo-helper new file mode 100755 index 00000000..456fa66d --- /dev/null +++ b/helpers/miredo-helper @@ -0,0 +1,78 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2012 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 . # +# # +############################################################################### + +LOG_FACILITY="miredo-helper" + +. /usr/lib/network/functions + +action="${STATE}" +assert isset action + +zone="${IFACE}" +assert zone_exists ${zone} + +log DEBUG "Called for zone=${zone} action=${action}." + +case "${action}" in + up) + # Configure the requested MTU. + isset MTU && device_set_mtu ${zone} ${MTU} + + # Bring up the device. + device_set_up ${zone} + + # Apply the link-local address. + ip_address_add ${zone} "${LLADDRESS}/64" + + # Apply the public IP address. + ip_address_add ${zone} "${ADDRESS}/32" + + # Write all data to the routing database. + routing_db_set ${zone} ipv6 type "teredo" + routing_db_set ${zone} ipv6 local-ip-address "${ADDRESS}/32" + routing_db_set ${zone} ipv6 active 1 + + # Update the routing database. + routing_update ${zone} ipv6 + routing_default_update + ;; + + down) + # Remove the routing database and update the tables. + routing_db_remove ${zone} ipv6 + routing_update ${zone} ipv6 + routing_default_update + + # Set down the device. + device_set_down ${zone} + ;; + + destroy) + # Do nothing here. + ;; + + *) + log ERROR "Unknown action passed: ${action}" + exit ${EXIT_ERROR} + ;; +esac + +exit ${EXIT_OK} diff --git a/hooks/zones/teredo b/hooks/zones/teredo new file mode 100755 index 00000000..bfbe5711 --- /dev/null +++ b/hooks/zones/teredo @@ -0,0 +1,92 @@ +#!/bin/bash +############################################################################### +# # +# IPFire.org - A linux based firewall # +# Copyright (C) 2010 Michael Tremer & Christian Schmidt # +# # +# 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-zone + +HOOK_SETTINGS="HOOK SERVER" + +SERVER="" + +function _check() { + assert isset SERVER +} + +function _parse_cmdline() { + local value + + while [ $# -gt 0 ]; do + case "${1}" in + --server=*) + SERVER=$(cli_get_val ${1}) + ;; + *) + echo "Unknown option: ${1}" >&2 + exit ${EXIT_ERROR} + ;; + esac + shift + done +} + +function _up() { + local zone=${1} + assert isset zone + + teredo_start ${zone} + + exit ${EXIT_OK} +} + +function _down() { + local zone=${1} + assert isset zone + + teredo_stop ${zone} + + exit ${EXIT_OK} +} + +function _status() { + local zone=${1} + + assert isset zone + + cli_status_headline ${zone} + + zone_config_read ${zone} + + cli_headline " Configuration:" + printf "${DEVICE_PRINT_LINE1}" "Server:" "${SERVER}" + + # Exit if zone is down + if ! zone_is_up ${zone}; then + echo # Empty line + exit ${EXIT_ERROR} + fi + + cli_headline " Protocol information:" + printf "${DEVICE_PRINT_LINE1}" "MTU:" "$(device_get_mtu ${zone})" + echo + + exit ${EXIT_OK} +} + +run $@