This patch adds an OCF resource agent which maintains proxy arp entries
in a GNU/Linux arp table.

This is especially useful when a high-availability routing setup is built
and it is required to perform proxy arp.

---
 AUTHORS            |    1 +
 heartbeat/proxyarp |  348 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 349 insertions(+)
 create mode 100644 heartbeat/proxyarp

diff --git a/AUTHORS b/AUTHORS
index ee0169a..f39b565 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -11,6 +11,7 @@ Andrew Price <andy at andrewprice.me.uk>
 Benjamin Marzinski <bmarzins at redhat.com>
 Bob Peterson <rpeterso at redhat.com>
 Chris Feist <cfeist at redhat.com>
+Christian Franke <nobody at nowhere dot ws>
 Christian Rishoj <christ...@rishoj.net>
 Christine Caulfield <ccaulfie at redhat.com>
 Daiki Matsuda <d.mat...@gmail.com>
diff --git a/heartbeat/proxyarp b/heartbeat/proxyarp
new file mode 100644
index 0000000..045103d
--- /dev/null
+++ b/heartbeat/proxyarp
@@ -0,0 +1,348 @@
+#!/bin/sh
+#
+#       OCF Resource Agent for Proxy ARP
+# Copyright (c) 2012 Christian Franke <nob...@nowhere.ws>
+#
+# Based on:
+#
+#       OCF Resource Agent compliant IPaddr2 script.
+#
+#      Based on work by Tuomo Soini, ported to the OCF RA API by Lars
+#      Marowsky-Brée. Implements Cluster Alias IP functionality too.
+#
+#      Cluster Alias IP cleanup, fixes and testing by Michael Schwartzkopff
+#
+#
+# Copyright (c) 2003 Tuomo Soini
+# Copyright (c) 2004-2006 SUSE LINUX AG, Lars Marowsky-Brée
+#                    All Rights Reserved.
+#
+# 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 would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like.  Any license provided herein, whether implied or
+# otherwise, applies only to this software file.  Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+#
+
+#      OCF parameters are as below
+#      OCF_RESKEY_ip
+#       OCF_RESKEY_nic
+
+#######################################################################
+# Initialization:
+
+: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
+. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs
+
+# Defaults
+OCF_RESKEY_arp_interval_default=200
+OCF_RESKEY_arp_count_default=5
+OCF_RESKEY_arp_bg_default=true
+OCF_RESKEY_arp_mac_default="ffffffffffff"
+
+: ${OCF_RESKEY_arp_interval=${OCF_RESKEY_arp_interval_default}}
+: ${OCF_RESKEY_arp_count=${OCF_RESKEY_arp_count_default}}
+: ${OCF_RESKEY_arp_bg=${OCF_RESKEY_arp_bg_default}}
+: ${OCF_RESKEY_arp_mac=${OCF_RESKEY_arp_mac_default}}
+#######################################################################
+
+SENDARP=$HA_BIN/send_arp
+SENDARPPIDDIR=$HA_RSCTMP
+
+#######################################################################
+
+meta_data() {
+       cat <<END
+<?xml version="1.0"?>
+<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
+<resource-agent name="proxyarp">
+<version>1.0</version>
+
+<longdesc lang="en">
+This Linux-specific resource manages Proxy arp.
+</longdesc>
+
+<shortdesc lang="en">Manages Proxy arp (Linux specific version)</shortdesc>
+
+<parameters>
+<parameter name="ip" unique="1" required="1">
+<longdesc lang="en">
+The IPv4 address to be configured in dotted quad notation, for example
+"192.168.1.1".
+</longdesc>
+<shortdesc lang="en">IPv4 address</shortdesc>
+<content type="string" />
+</parameter>
+<parameter name="nic" unique="1" required="1">
+<longdesc lang="en">
+The base network interface on which questions for arp will be replied to.
+</longdesc>
+<shortdesc lang="en">Network interface</shortdesc>
+<content type="string"/>
+</parameter>
+<parameter name="arp_interval">
+<longdesc lang="en">
+Specify the interval between unsolicited ARP packets in milliseconds.
+</longdesc>
+<shortdesc lang="en">ARP packet interval in ms</shortdesc>
+<content type="integer" default="${OCF_RESKEY_arp_interval_default}"/>
+</parameter>
+
+<parameter name="arp_count">
+<longdesc lang="en">
+Number of unsolicited ARP packets to send.
+</longdesc>
+<shortdesc lang="en">ARP packet count</shortdesc>
+<content type="integer" default="${OCF_RESKEY_arp_count_default}"/>
+</parameter>
+
+<parameter name="arp_bg">
+<longdesc lang="en">
+Whether or not to send the arp packets in the background.
+</longdesc>
+<shortdesc lang="en">ARP from background</shortdesc>
+<content type="string" default="${OCF_RESKEY_arp_bg_default}"/>
+</parameter>
+
+<parameter name="arp_mac">
+<longdesc lang="en">
+MAC address to send the ARP packets to.
+
+You really shouldn't be touching this.
+
+</longdesc>
+<shortdesc lang="en">ARP MAC</shortdesc>
+<content type="string" default="${OCF_RESKEY_arp_mac_default}"/>
+</parameter>
+
+</parameters>
+<actions>
+<action name="start"   timeout="20s" />
+<action name="stop"    timeout="20s" />
+<action name="status" depth="0"  timeout="20s" interval="10s" />
+<action name="monitor" depth="0"  timeout="20s" interval="10s" />
+<action name="meta-data"  timeout="5s" />
+<action name="validate-all"  timeout="20s" />
+</actions>
+</resource-agent>
+END
+
+       exit $OCF_SUCCESS
+}
+
+ip_init() {
+       local rc
+
+       if [ X`uname -s` != "XLinux" ]; then
+               ocf_log err "IPaddr2 only supported Linux."
+               exit $OCF_ERR_INSTALLED
+       fi
+
+       if [ X"$OCF_RESKEY_ip" = "X" ]; then
+               ocf_log err "IP address (the ip parameter) is mandatory"
+               exit $OCF_ERR_CONFIGURED
+       fi
+
+       if [ X"$OCF_RESKEY_nic" = "X" ]; then
+               ocf_log err "nic (the interface) is mandatory"
+               exit $OCF_ERR_CONFIGURED
+       fi
+
+       if
+          case $__OCF_ACTION in
+            start|stop)                ocf_is_root;;
+            *)                 true;;
+          esac
+        then
+          : YAY!
+        else
+               ocf_log err "You must be root for $__OCF_ACTION operation."
+               exit $OCF_ERR_PERM
+       fi
+
+       IP="$OCF_RESKEY_ip"
+       NIC="$OCF_RESKEY_nic"
+       SENDARPPIDFILE="$SENDARPPIDDIR/send_arp-$OCF_RESKEY_ip"
+}
+
+#
+#        Delete an interface
+#
+delete_interface () {
+       local cmd ipaddr iface
+       ipaddr="$1"
+       iface="$2"
+
+       cmd="$IP2UTIL neigh del proxy $ipaddr dev $iface"
+
+       # Failure of the following command is ignored, as it would cause
+       # the resource to become unmanaged. (This happens e.g. when the
+       # monitor detects failure, and pacemaker tries to restart the resource)
+       ocf_run $cmd
+
+       return $OCF_SUCCESS
+}
+
+#
+#        Add an interface
+#
+add_interface () {
+       local cmd msg ipaddr netmask broadcast iface label
+
+       ipaddr="$1"
+       iface="$2"
+
+       cmd="$IP2UTIL neigh add proxy $ipaddr dev $iface"
+       msg="Adding proxy arp for $ipaddr on $iface"
+
+       ocf_log info "$msg"
+       ocf_run $cmd || return $OCF_ERR_GENERIC
+
+       return $OCF_SUCCESS
+}
+
+#
+# Run send_arp to note peers about new mac address
+#
+run_send_arp() {
+       ARGS="-i $OCF_RESKEY_arp_interval -r $OCF_RESKEY_arp_count -p 
$SENDARPPIDFILE $NIC $OCF_RESKEY_ip auto not_used not_used"
+       ocf_log info "$SENDARP $ARGS"
+       if ocf_is_true $OCF_RESKEY_arp_bg; then
+               ($SENDARP $ARGS || ocf_log err "Could not send gratuitous arps" 
&) >&2
+       else
+               $SENDARP $ARGS || ocf_log err "Could not send gratuitous arps"
+       fi
+}
+
+#######################################################################
+
+ip_usage() {
+       cat <<END
+usage: $0 {start|stop|status|monitor|validate-all|meta-data}
+
+Expects to have a fully populated OCF RA-compliant environment set.
+END
+}
+
+ip_start() {
+       if [ -z "$NIC" -o -z "$IP" ]; then # no nic found or specified
+               exit $OCF_ERR_CONFIGURED
+       fi
+
+       add_interface $OCF_RESKEY_ip $NIC
+
+       if [ $? -ne 0 ]; then
+               ocf_log err "$CMD failed."
+               exit $OCF_ERR_GENERIC
+       fi
+
+       if [ -x $SENDARP ]; then
+               run_send_arp
+       fi
+
+       exit $OCF_SUCCESS
+}
+
+ip_stop() {
+       if [ -f "$SENDARPPIDFILE" ] ; then
+               kill `cat "$SENDARPPIDFILE"`
+               if [ $? -ne 0 ]; then
+                       ocf_log warn "Could not kill previously running 
send_arp for $OCF_RESKEY_ip"
+               else
+                       ocf_log info "killed previously running send_arp for 
$OCF_RESKEY_ip"
+                       rm -f "$SENDARPPIDFILE"
+               fi
+       fi
+
+       delete_interface $OCF_RESKEY_ip $NIC $NETMASK
+       if [ $? -ne 0 ]; then
+               exit $OCF_ERR_GENERIC
+       fi
+
+       exit $OCF_SUCCESS
+}
+
+ip_running() {
+       local proxy_entries
+
+       proxy_entries=`grep ' 0xc ' /proc/net/arp | grep -c -F "$IP"`
+       if [ $proxy_entries -gt 0 ]; then
+               return 0
+       else
+               return 1
+       fi
+}
+
+ip_monitor() {
+       if ip_running; then
+               return $OCF_SUCCESS
+       else
+               exit $OCF_NOT_RUNNING
+       fi
+}
+
+ip_validate() {
+    check_binary $IP2UTIL
+    check_binary grep
+
+    ip_init
+
+    if ocf_is_decimal "$OCF_RESKEY_arp_interval" && [ $OCF_RESKEY_arp_interval 
-gt 0 ]; then
+       :
+    else
+       ocf_log err "Invalid OCF_RESKEY_arp_interval [$OCF_RESKEY_arp_interval]"
+       exit $OCF_ERR_CONFIGURED
+    fi
+
+    if ocf_is_decimal "$OCF_RESKEY_arp_count" && [ $OCF_RESKEY_arp_count -gt 0 
]; then
+       :
+    else
+       ocf_log err "Invalid OCF_RESKEY_arp_count [$OCF_RESKEY_arp_count]"
+       exit $OCF_ERR_CONFIGURED
+    fi
+}
+
+case $__OCF_ACTION in
+meta-data)     meta_data
+               ;;
+usage|help)    ip_usage
+               exit $OCF_SUCCESS
+               ;;
+esac
+
+ip_validate
+
+case $__OCF_ACTION in
+start)         ip_start
+               ;;
+stop)          ip_stop
+               ;;
+status)                if ip_running; then
+                       echo "running"
+                       exit $OCF_SUCCESS
+               else
+                       echo "stopped"
+                       exit $OCF_NOT_RUNNING
+               fi
+               ;;
+monitor)       ip_monitor
+               ;;
+validate-all)  ;;
+*)             ip_usage
+               exit $OCF_ERR_UNIMPLEMENTED
+               ;;
+esac
-- 
1.7.9.2

_______________________________________________________
Linux-HA-Dev: Linux-HA-Dev@lists.linux-ha.org
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to