#!/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) # Go on if the device is not there anymore. device_exists ${zone} || continue # On other devices, we will use the gateway if we got one. if isset gateway; then routes="${routes} nexthop via ${gateway}" # If we have got a Point-to-Point device, we will directly send all # packets into the pipe. elif device_is_ptp ${zone}; then routes="${routes} dev ${zone}" # If none of the cases above apply, we cannot go on. else continue fi # Apply weight. weight=$(routing_db_get ${zone} ${proto} weight) if isinteger ${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 ${cmd} add default ${routes} assert [ $? -eq 0 ] case "${proto}" in ipv6) # Apply radvd configuration. radvd_update ;; esac done } # XXX deprecated function function routing_table_exists() { route_table_exists $@ } # XXX deprecated function function routing_table_create() { route_table_create $@ } 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 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_cmd} route flush table ${table} # Exit here if there is no routing information. if ! routing_db_exists ${zone} ${proto}; then return ${EXIT_OK} fi local local_ip_address=$(routing_db_get ${zone} ${proto} local-ip-address) local remote_ip_address=$(routing_db_get ${zone} ${proto} remote-ip-address) 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_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 routing_cmd="${routing_cmd} via ${remote_ip_address}" else routing_cmd="${routing_cmd} dev ${zone}" fi cmd ${routing_cmd} cmd ${ip_cmd} rule add from ${local_ip_address} lookup ${table} }