From: Michael Tremer Date: Thu, 17 Jun 2010 22:58:10 +0000 (+0200) Subject: network: Update routing functions. X-Git-Tag: 001~75 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ff8ec5ef20f32ee87c9be5bd2fd6a94a64be2d73;p=network.git network: Update routing functions. Bigger commit, sorry. --- diff --git a/functions.constants b/functions.constants index 902e4eb4..62c023c4 100644 --- a/functions.constants +++ b/functions.constants @@ -33,7 +33,9 @@ RED_RUN=${RUN_DIR}/red PPP_SECRETS=/etc/ppp/secrets CONFIG_FILE=${CONFIG_DIR}/network_config -CONFIG_FILE_PARAMS="COLORS DEBUG SHELL TIMEOUT_RESTART" +CONFIG_FILE_PARAMS="COLOURS DEBUG SHELL TIMEOUT_RESTART" + +RED_DB_DIR=${RUN_DIR}/red DB_CONNECTION_FILE="${LOG_DIR}/connections.db" diff --git a/functions.events b/functions.events index 720ee20e..7ba44e89 100644 --- a/functions.events +++ b/functions.events @@ -17,6 +17,9 @@ function event_interface_up() { local iface=${1} event_emit network-interface-up IFACE=${iface} + + # XXX Just for now + routing_default_update } function event_interface_down() { diff --git a/functions.ppp b/functions.ppp index 9d472115..7c8d3414 100644 --- a/functions.ppp +++ b/functions.ppp @@ -28,6 +28,8 @@ function ppp_common_ip_pre_up() { return ${EXIT_ERROR} fi + red_db_from_ppp ${zone} + # Request firewall reload event_firewall_reload @@ -43,6 +45,9 @@ function ppp_common_ip_up() { return ${EXIT_ERROR} fi + red_db_set ${zone} active 1 + red_routing_update ${zone} + # Emit interface-up event event_interface_up ${zone} @@ -93,26 +98,3 @@ function ppp_accounting() { db_ppp_update ${zone} --duration="${CONNECT_TIME}" \ --rcvd="${BYTES_RCVD}" --sent="${BYTES_SENT}" } - -function red_defaultroute_update() { - local command="ip route replace default" - - local uplink - for uplink in ${RED_RUN}/*; do - [ -d "${uplink}" ] || continue - - # Skip if no gateway given - [ -e "${uplink}/gateway" ] || continue - - command="${command} nexthop via $(<${uplink}/gateway)" - if [ -e "${uplink}/weight" ]; then - command="${command} weight $(<${uplink}/weight)" - fi - done - $command - #ip route flush cache -} - -function red_dns_update() { - : # XXX todo -} diff --git a/functions.red b/functions.red new file mode 100644 index 00000000..849e6a0a --- /dev/null +++ b/functions.red @@ -0,0 +1,97 @@ +#!/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 . # +# # +############################################################################### + +function red_db_path() { + local zone=${1} + + echo "${RED_DB_DIR}/${zone}" +} + +function red_db_exists() { + local zone=${1} + + [ -d "$(red_db_path ${zone})" ] +} + +function red_db_create() { + local zone=${1} + + red_db_exists ${zone} && return ${EXIT_OK} + + mkdir -p $(red_db_path ${zone}) +} + +function red_db_remove() { + local zone=${1} + + [ -z "${zone}" ] && return ${EXIT_ERROR} + + rm -rf ${RED_DB_DIR} +} + +function red_db_set() { + local zone=${1} + local parameter=${2} + shift 2 + + local value="$@" + + red_db_create ${zone} + + echo "${value}" > $(red_db_path ${zone})/${parameter} +} + +function red_db_get() { + local zone=${1} + local parameter=${2} + shift 2 + + cat $(red_db_path ${zone})/${parameter} 2>/dev/null +} + +function red_db_from_ppp() { + local zone=${1} + + # Save ppp configuration + red_db_set ${zone} type "ppp" + red_db_set ${zone} local-ip-address ${PPP_IPLOCAL} + red_db_set ${zone} remote-ip-address ${PPP_IPREMOTE} + + red_db_set ${zone} dns ${PPP_DNS1} ${PPP_DNS2} + + red_db_set ${zone} remote-address ${PPP_MACREMOTE,,} +} + +function red_routing_update() { + local zone=${1} + + local table=${zone} + + # Create routing table if not exists + routing_table_create ${table} + + local remote_ip_address=$(red_db_get ${zone} remote-ip-address) + local local_ip_address=$(red_db_get ${zone} local-ip-address) + + ip route replace table ${table} default nexthop via ${remote_ip_address} + + ip rule add from ${local_ip_address} lookup ${table} +} diff --git a/functions.routing b/functions.routing new file mode 100644 index 00000000..1733edef --- /dev/null +++ b/functions.routing @@ -0,0 +1,90 @@ +#!/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 . # +# # +############################################################################### + +function routing_has_default() { + ip route | grep -q "^default" +} + +function routing_default_update() { + local zone + local routes + + local gateway + local weight + + log INFO "Updating default route." + + for zone in $(zones_get_nonlocal); do + # Skip if zone is not up + red_db_exists ${zone} || continue + + if [ "$(red_db_get ${zone} active)" = "1" ]; then + gateway=$(red_db_get ${zone} remote-ip-address) + weight=$(red_db_get ${zone} weight) + + routes="${routes} nexthop via ${gateway}" + + if [ -n "${weight}" ]; then + routes="${routes} weight ${weight}" + fi + else + log DEBUG "Ignoring zone '${zone}' which is not active." + fi + done + + if [ -z "${routes}" ]; then + if routing_has_default; then + ip route del default + fi + return ${EXIT_OK} + fi + + ip route replace default ${routes} +} + +function routing_table_exists() { + local zone=${1} + + grep -q "${zone}$" < /etc/iproute2/rt_tables +} + +function routing_table_create() { + local zone=${1} + + if ! zone_is_nonlocal ${zone}; then + error_log "Can only create routing tables for non-local zones." + return ${EXIT_ERROR} + fi + + if routing_table_exists ${zone}; then + return ${EXIT_OK} + fi + + log INFO "Creating routing table for zone '${zone}'" + + local id=$(( ${zone#red} + 1 )) + + echo "${id} ${zone}" >> /etc/iproute2/rt_tables +} + +function routing_table_remove() { + : # XXX do we need this? +}