#!/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 routes local zones=$(zones_get_nonlocal) if [ -z "${zones}" ]; then zones=$(zones_get_local) fi local gateway local proto local weight local zone local cmd for proto in ${IP_SUPPORTED_PROTOCOLS}; do # Clear routes routes="" cmd="ip $([ "${proto}" = "ipv6" ] && echo "-6") route" for zone in ${zones}; do # Skip if zone is not up routing_db_exists ${zone} ${proto} || continue 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 device_is_ppp ${zone}; then routes="${routes} dev ${zone}" else routes="${routes} nexthop via ${gateway}" fi if [ -n "${weight}" ]; then routes="${routes} weight ${weight}" fi else log DEBUG "Ignoring zone '${zone}' which is not active." fi done # Remove too much spaces. routes=$(echo ${routes}) # Remove all default routes. while ${cmd} | grep -q "^default"; do ${cmd} del default done if [ -z "${routes}" ]; then log INFO "Removed default route for ${proto}." return ${EXIT_OK} fi log INFO "Setting default route for ${proto}: ${routes}" ${cmd} add default ${routes} assert [ $? -eq 0 ] case "${proto}" in ipv6) # Apply radvd configuration. radvd_update ;; esac done } function routing_table_exists() { local zone=${1} grep -q "${zone}$" < /etc/iproute2/rt_tables } function routing_table_create() { local zone=${1} 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? } function routing_db_path() { local zone=${1} local proto=${2} assert isset zone assert isset proto assert isoneof proto ${IP_SUPPORTED_PROTOCOLS} echo "${ROUTING_DB_DIR}/${zone}/${proto}" } function routing_db_exists() { [ -d "$(routing_db_path $@)" ] } function routing_db_create() { routing_db_exists $@ && return ${EXIT_OK} mkdir -p $(routing_db_path $@) } function routing_db_remove() { rm -rf $(routing_db_path $@) } function routing_db_set() { local zone=${1} local proto=${2} local parameter=${3} shift 3 local value="$@" log INFO "Updating database (${zone} - ${proto}): ${parameter} = ${value}" routing_db_create ${zone} ${proto} echo "${value}" > $(routing_db_path ${zone} ${proto})/${parameter} } function routing_db_get() { local zone=${1} local proto=${2} local parameter=${3} shift 3 cat $(routing_db_path ${zone} ${proto})/${parameter} 2>/dev/null } function routing_db_from_ppp() { local zone=${1} local proto=${2} assert isset zone assert isset proto # Save ppp configuration routing_db_set ${zone} ${proto} type "ppp" if [ "${proto}" = "ipv6" ]; then routing_db_set ${zone} ${proto} local-ip-address ${PPP_LLLOCAL} routing_db_set ${zone} ${proto} remote-ip-address ${PPP_LLREMOTE} elif [ "${proto}" = "ipv4" ]; then routing_db_set ${zone} ${proto} local-ip-address ${PPP_IPLOCAL} routing_db_set ${zone} ${proto} remote-ip-address ${PPP_IPREMOTE} fi routing_db_set ${zone} ${proto} dns ${PPP_DNS1} ${PPP_DNS2} routing_db_set ${zone} ${proto} remote-address ${PPP_MACREMOTE,,} } function routing_update() { local zone=${1} assert isset zone # Nothing to do for local zones. if zone_is_local ${zone}; then return ${EXIT_OK} fi local proto=${2} local table=${zone} assert isset proto # Create routing table if not exists routing_table_create ${table} log DEBUG "Flushing routing table ${table}" cmd ip 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} ;; esac 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} fi cmd ip rule add from ${local_ip_address} lookup ${table} }