#!/bin/sh
#
# Shorewall 3.2 -- /usr/share/shorewall/lib.proxyarp
#
#     This program is under GPL [http://www.gnu.org/copyleft/gpl.htm]
#
#     (c) 1999,2000,2001,2002,2003,2004,2005,2006 - Tom Eastep (teastep@shorewall.net)
#
#	Complete documentation is available at http://shorewall.net
#
#	This program is free software; you can redistribute it and/or modify
#	it under the terms of Version 2 of the GNU General Public License
#	as published by the Free Software Foundation.
#
#	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, write to the Free Software
#	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA

#
# Setup Proxy ARP
#
setup_proxy_arp() {

    local setlist= resetlist=

    print_error() {
	error_message "Invalid value for HAVEROUTE - ($haveroute)"
	error_message "Entry \"$address $interface $external $haveroute\" ignored"
    }

    print_error1() {
	error_message "Invalid value for PERSISTENT - ($persistent)"
	error_message "Entry \"$address $interface $external $haveroute $persistent\" ignored"
    }

    print_warning() {
	error_message "PERSISTENT setting ignored - ($persistent)"
	error_message "Entry \"$address $interface $external $haveroute $persistent\""
    }

    setup_one_proxy_arp() {

	case $haveroute in
	[Nn][Oo])
	    haveroute=
	    ;;
	[Yy][Ee][Ss])
	    ;;
	*)
	    if [ -n "$haveroute" ]; then
		print_error
		return
	    fi
	    ;;
	esac

	case $persistent in
	[Nn][Oo])
	    persistent=
	    ;;
	[Yy][Ee][Ss])
	    [ -z "$haveroute" ] || print_warning
	    ;;
	*)
	    if [ -n "$persistent" ]; then
		print_error1
		return
	    fi
	    ;;
	esac

	if [ -z "$haveroute" ]; then
	    save_command "[ -n \"\$NOROUTES\" ] || run_ip route replace $address dev $interface"
	    [ -n "$persistent" ] && haveroute=yes
	fi

	indent >&3 << __EOF__
if ! arp -i $external -Ds $address $external pub; then
    fatal_error "Command \"arp -i $external -Ds $address $external pub\" failed"
fi

progress_message "   Host $address connected to $interface added to ARP on $external"

__EOF__
	echo $address $interface $external $haveroute >> $STATEDIR/proxyarp

	progress_message "   Host $address connected to $interface added to ARP on $external"
    }

    > $STATEDIR/proxyarp

    save_progress_message "Setting up Proxy ARP..."

    while read address interface external haveroute persistent; do
	expandv address interface external haveroute persistent
	list_search $interface $setlist   || setlist="$setlist $interface"
	list_search $external  $resetlist || list_search $external $setlist || resetlist="$resetlist $external"
	setup_one_proxy_arp
    done < $TMP_DIR/proxyarp

    for interface in $resetlist; do
	list_search $interface $setlist || \
	    save_command "echo 0 > /proc/sys/net/ipv4/conf/$interface/proxy_arp"
    done

    for interface in $setlist; do
	save_command "echo 1 > /proc/sys/net/ipv4/conf/$interface/proxy_arp"
    done

    interfaces=$(find_interfaces_by_option proxyarp)

    for interface in $interfaces; do
	indent >&3 << __EOF__
if [ -f /proc/sys/net/ipv4/conf/$interface/proxy_arp ] ; then
    echo 1 > /proc/sys/net/ipv4/conf/$interface/proxy_arp
else
    error_message "WARNING: Unable to enable proxy ARP on $interface"
fi

__EOF__
    done

}