keepalived-2.3.1/0000775000175000017500000000000014624033731010634 500000000000000keepalived-2.3.1/CONTRIBUTORS0000664000175000017500000000146713220013273012432 00000000000000Jan Holmberg, : o Memory framework o HTTP/SSL checkers Bradley Baetz, : o MISC checker redesign o Scheduler framework extension to support child process handling. o Daemon framework extension to block SIGCHLD to only receive it when its unblocked in the scheduling select loop. Jeremy Rumpf, : o Added SMTP checker Chris Caputo, : o Added dont_track_primary, nopreempt, preempt_delay, and misc_dynamic. Kevin Lindsay, : o Fixed shadowed declaration reported by -Wshadow. o Redesigned signal handling. Nick Couchman, : o Patch for u_threshold and l_threshold support. Willy Tarreau, : o Extended VRRP framework to support floating priority. keepalived-2.3.1/autogen.sh0000775000175000017500000000014413767727575012603 00000000000000#!/bin/sh mkdir -p build-aux aclocal --install -I m4 autoheader automake --add-missing autoreconf keepalived-2.3.1/TODO0000664000175000017500000001536214023433056011250 00000000000000BUG - If have VIP on a different interface from the VRRP instance, the interface isn't tracked and so we do nothing if the interface is deleted. Add INTERFACE_CHECK and ADDRESS_CHECK checkers - see issue#1679 and pull request #1680. Fix building on CentOS 6.10 Add a TCP_KEEPALIVE_CHECK that established a TCP connection and uses keepalives like hg635_config to check the remote end is there. Remove definitions that simply access structure fields, e.g. VRRP_ISUP Stop making structure fields such as base_ifp and configured_ifp conditional. In parsers, using LIST_TAIL to find object to configure doesn't work if error in first line means not created. TAIL could be null, or previous object. No SMTP alert for vrrp instance FAULT/BACKUP/MASTER following track file changes Shutdown SMTP messages not completing before keepalived terminates (especially for connect timeout. Causes memory leak!) Test LVS forwarding via VIP if no_accept set If interface is deleted and recreated, then index changes - does that cause OIDs to change? Is the RFC flawed? How do we deal with it? We could have our own ifindex incremented as we create interface_t's Add track_route, track_address PKG_CONFIG_* autoconf options - see man pkg.m4 Whatever you want ! Real servers Add quorum_weight, defaults to weight. May want to set different between quorum and IPVS weight Rationalise use of timer_now()/gettimeofday()/set_time_now() virtual route: 1. How do we handle virtual_routes { 192.168.210.0/24 via 10.1.0.1 } if there is no route to 10.1.0.1? If we go to fault state if it cannot be installed when attempt to transition to master, how do we know to transiton out of fault state. IPVS 1. Can we have an IPv4 fwmark and specify tunnel to IPv6, and vice versa etc. What does ipvsadm do? 2. Sort out IP_VS_SO vs LVS_CMD... 3. Make sure log/email messages contain relevant info re VS -> RS. See FMT_CHK The following are still outstanding from the ideas for what became v2.0.0: * Sort out termination in vrrp and checker - stop_vrrp/check, and phase2 are inconsistent between vrrp and checker. What about bfd? * A route with multiple nexthops will only be deleted if all interfaces are down. Each nexthop needs to record the interface, and only remove once all down * Don't add RTNMGRP_IPV4_ADDR/IPV6_ADDR if not monitoring one of those families * May want to stop VS down at start for alpha mode RSs (except SNMP) * Have a socket to connect to for receiving notifications. A process can register for what notifications it wants to receive. * Allow variable parameters to be passed to scripts - see issue #837 * Make tarball include git version if not a tag * If an address owner recovers from fault, transition directly to master * If configuration_state=MASTER && !OWNER, transition to master after 1 * advert_int + skew. Sort out all initialisation around states * Split vrrp_snmp.c into vrrp_snmp_keepalived.c vrrp_snmp_rfcv2.c and vrrp_snmp_rfcv3.c * Only send correct type of trap, and respond to correct SNMP version, controlled by config, defaults to type of instance. Flags snmp_v2 and snmp_v3 to force other, or both. * Ensure unicast peers groups check source address of received advert so that the same VRID can be used between different peer groups on the same interface. * Add process checking: Add track_process for vrrp instances Add PROCESS_CHECK for checkers - Find PID and remember it. If PID has gone, try and find new pid Look at how pidof/killall find processes * Allow dynamic definitions, e.g. $_VI_NAME Also $*_INSTANCE net_namspace $_INSTANCE so $* means only do if $_INSTANCE not blank. */ * ng-scheduler Other issues awaiting resolution: ipvs_group_range_cmd() appears nonsense, and inet_stor returning a uint8_t doesn't work for IPv6. The virtual_service_entry_t thing needs range to be uint32_t. Why would mask be 0xffffffff for IPv6? ip_vs_daemon_kern vs /usr/include/linux/ip_vs.h ip_vs_daemon_user vrrp_timer_fd should return 0 if an fd's timer is in the past? Make vrrp->send_buffer a single buffer for all Check timers passto to thread_... functions are reasonable, and stacktrace if not. In function socket_state, should thread_add_write use timer_long() or -timer_long() vrrp_timer_fd() - see comment In thread functions with a timer, ensure not > LONG_MAX (or even some lower value); Change tcp_socket_state etc to socket_state etc Add noreturn function attribute on stop_vrrp/check in ipvswrapper.c, get rid of static srule etc and make them procedure local and pass as parameters Stop passing base_ifp to netlink3_set_interface_parameters() etc ipsecah issues ============== 1. sync and vmac ignore counter 2. Start up just after master dies, but have lowest priority so become master with counter == 1 3. cycle won't happen 4. In vrrp_backup, don't check auth type matches 5. ? if cycle becomes set, we must become backup. How do we get out of state? epoll ===== Use timerfd (see timerfd_create(2)) for microsecond timing with epoll, and do not bother with its timeout. If not available, then simply use the epoll timer. Optimise calls to timer_now() and see set_time_now() ==================================================== After select completes, get time. Before calculating next select expire time, get time again. To test time processing, save time after select and log time taken before next select. Also initialise timer at startup. Add api ======= Add pipe for updates ==================== track_script like for absolute or relative priority Upstream issues =============== 1. Kernel. Socket receive buffers growing to fill memory See issue #839. If the following setting are in place: net.core.rmem_default = 37748736 net.core.rmem_max = 37748736 and vrrp_tx_bufs_policy NO_SEND_RX is configured, then all system memory can be consumed. Why is it not limited to 37748736 bytes? 2. Kernel. Corruption when netlink sends status of large number of links - see issues #392/#803. When using default socket receive buffer size, and have 500 vmac interfaces configured on a physical interface and the physical interface is downed, lots of netlink messages are received, and we get an ENOBUFS. However, after that we then see a repeat of some of the earlier messages, so it looks like a circular buffer corruption. Running ip -ts monitor link addr route we see precisely the same problem at exactly the same message, although which message it is varies each time. 3. net-snmp. Display-hint only works on indices. See issue #866. # snmpwalk -v2c -c public localhost KEEPALIVED-MIB::virtualServerAddress KEEPALIVED-MIB::virtualServerAddress.1 = STRING: " 0," The address is attempted to be output as text, rather than using the display hint keepalived-2.3.1/aclocal.m40000664000175000017500000012651114624033717012426 00000000000000# generated automatically by aclocal 1.16.5 -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY, to the extent permitted by law; without # even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],, [m4_warning([this file was generated for autoconf 2.71. You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) # Copyright (C) 2002-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_AUTOMAKE_VERSION(VERSION) # ---------------------------- # Automake X.Y traces this macro to ensure aclocal.m4 has been # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. m4_if([$1], [1.16.5], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) # _AM_AUTOCONF_VERSION(VERSION) # ----------------------------- # aclocal traces this macro to find the Autoconf version. # This is a private macro too. Using m4_define simplifies # the logic in aclocal, which can simply ignore this definition. m4_define([_AM_AUTOCONF_VERSION], []) # AM_SET_CURRENT_AUTOMAKE_VERSION # ------------------------------- # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], [AM_AUTOMAKE_VERSION([1.16.5])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Copyright (C) 2011-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_AR([ACT-IF-FAIL]) # ------------------------- # Try to determine the archiver interface, and trigger the ar-lib wrapper # if it is needed. If the detection of archiver interface fails, run # ACT-IF-FAIL (default is to abort configure with a proper error message). AC_DEFUN([AM_PROG_AR], [AC_BEFORE([$0], [LT_INIT])dnl AC_BEFORE([$0], [AC_PROG_LIBTOOL])dnl AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([ar-lib])dnl AC_CHECK_TOOLS([AR], [ar lib "link -lib"], [false]) : ${AR=ar} AC_CACHE_CHECK([the archiver ($AR) interface], [am_cv_ar_interface], [AC_LANG_PUSH([C]) am_cv_ar_interface=ar AC_COMPILE_IFELSE([AC_LANG_SOURCE([[int some_variable = 0;]])], [am_ar_try='$AR cru libconftest.a conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=ar else am_ar_try='$AR -NOLOGO -OUT:conftest.lib conftest.$ac_objext >&AS_MESSAGE_LOG_FD' AC_TRY_EVAL([am_ar_try]) if test "$ac_status" -eq 0; then am_cv_ar_interface=lib else am_cv_ar_interface=unknown fi fi rm -f conftest.lib libconftest.a ]) AC_LANG_POP([C])]) case $am_cv_ar_interface in ar) ;; lib) # Microsoft lib, so override with the ar-lib wrapper script. # FIXME: It is wrong to rewrite AR. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__AR in this case, # and then we could set am__AR="$am_aux_dir/ar-lib \$(AR)" or something # similar. AR="$am_aux_dir/ar-lib $AR" ;; unknown) m4_default([$1], [AC_MSG_ERROR([could not determine $AR interface])]) ;; esac AC_SUBST([AR])dnl ]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets # $ac_aux_dir to '$srcdir/foo'. In other projects, it is set to # '$srcdir', '$srcdir/..', or '$srcdir/../..'. # # Of course, Automake must honor this variable whenever it calls a # tool from the auxiliary directory. The problem is that $srcdir (and # therefore $ac_aux_dir as well) can be either absolute or relative, # depending on how configure is run. This is pretty annoying, since # it makes $ac_aux_dir quite unusable in subdirectories: in the top # source directory, any form will work fine, but in subdirectories a # relative path needs to be adjusted first. # # $ac_aux_dir/missing # fails when called from a subdirectory if $ac_aux_dir is relative # $top_srcdir/$ac_aux_dir/missing # fails if $ac_aux_dir is absolute, # fails when called from a subdirectory in a VPATH build with # a relative $ac_aux_dir # # The reason of the latter failure is that $top_srcdir and $ac_aux_dir # are both prefixed by $srcdir. In an in-source build this is usually # harmless because $srcdir is '.', but things will broke when you # start a VPATH build or use an absolute $srcdir. # # So we could use something similar to $top_srcdir/$ac_aux_dir/missing, # iff we strip the leading $srcdir from $ac_aux_dir. That would be: # am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` # and then we would define $MISSING as # MISSING="\${SHELL} $am_aux_dir/missing" # This will work as long as MISSING is not called from configure, because # unfortunately $(top_srcdir) has no meaning in configure. # However there are other variables, like CC, which are often used in # configure, and could therefore not use this "fixed" $ac_aux_dir. # # Another solution, used here, is to always expand $ac_aux_dir to an # absolute PATH. The drawback is that using absolute paths prevent a # configured tree to be moved without reconfiguration. AC_DEFUN([AM_AUX_DIR_EXPAND], [AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl # Expand $ac_aux_dir to an absolute path. am_aux_dir=`cd "$ac_aux_dir" && pwd` ]) # AM_CONDITIONAL -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_CONDITIONAL(NAME, SHELL-CONDITION) # ------------------------------------- # Define a conditional. AC_DEFUN([AM_CONDITIONAL], [AC_PREREQ([2.52])dnl m4_if([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl AC_SUBST([$1_TRUE])dnl AC_SUBST([$1_FALSE])dnl _AM_SUBST_NOTMAKE([$1_TRUE])dnl _AM_SUBST_NOTMAKE([$1_FALSE])dnl m4_define([_AM_COND_VALUE_$1], [$2])dnl if $2; then $1_TRUE= $1_FALSE='#' else $1_TRUE='#' $1_FALSE= fi AC_CONFIG_COMMANDS_PRE( [if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then AC_MSG_ERROR([[conditional "$1" was never defined. Usually this means the macro was only invoked conditionally.]]) fi])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # There are a few dirty hacks below to avoid letting 'AC_PROG_CC' be # written in clear, in which case automake, when reading aclocal.m4, # will think it sees a *use*, and therefore will trigger all it's # C support machinery. Also note that it means that autoscan, seeing # CC etc. in the Makefile, will ask for an AC_PROG_CC use... # _AM_DEPENDENCIES(NAME) # ---------------------- # See how the compiler implements dependency checking. # NAME is "CC", "CXX", "OBJC", "OBJCXX", "UPC", or "GJC". # We try a few techniques and use that to set a single cache variable. # # We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was # modified to invoke _AM_DEPENDENCIES(CC); we would have a circular # dependency, and given that the user is not expected to run this macro, # just rely on AC_PROG_CC. AC_DEFUN([_AM_DEPENDENCIES], [AC_REQUIRE([AM_SET_DEPDIR])dnl AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl AC_REQUIRE([AM_MAKE_INCLUDE])dnl AC_REQUIRE([AM_DEP_TRACK])dnl m4_if([$1], [CC], [depcc="$CC" am_compiler_list=], [$1], [CXX], [depcc="$CXX" am_compiler_list=], [$1], [OBJC], [depcc="$OBJC" am_compiler_list='gcc3 gcc'], [$1], [OBJCXX], [depcc="$OBJCXX" am_compiler_list='gcc3 gcc'], [$1], [UPC], [depcc="$UPC" am_compiler_list=], [$1], [GCJ], [depcc="$GCJ" am_compiler_list='gcc3 gcc'], [depcc="$$1" am_compiler_list=]) AC_CACHE_CHECK([dependency style of $depcc], [am_cv_$1_dependencies_compiler_type], [if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then # We make a subdir and do the tests there. Otherwise we can end up # making bogus files that we don't know about and never remove. For # instance it was reported that on HP-UX the gcc test will end up # making a dummy file named 'D' -- because '-MD' means "put the output # in D". rm -rf conftest.dir mkdir conftest.dir # Copy depcomp to subdir because otherwise we won't find it if we're # using a relative directory. cp "$am_depcomp" conftest.dir cd conftest.dir # We will build objects and dependencies in a subdirectory because # it helps to detect inapplicable dependency modes. For instance # both Tru64's cc and ICC support -MD to output dependencies as a # side effect of compilation, but ICC will put the dependencies in # the current directory while Tru64 will put them in the object # directory. mkdir sub am_cv_$1_dependencies_compiler_type=none if test "$am_compiler_list" = ""; then am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` fi am__universal=false m4_case([$1], [CC], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac], [CXX], [case " $depcc " in #( *\ -arch\ *\ -arch\ *) am__universal=true ;; esac]) for depmode in $am_compiler_list; do # Setup a source with many dependencies, because some compilers # like to wrap large dependency lists on column 80 (with \), and # we should not choose a depcomp mode which is confused by this. # # We need to recreate these files for each test, as the compiler may # overwrite some of them when testing with obscure command lines. # This happens at least with the AIX C compiler. : > sub/conftest.c for i in 1 2 3 4 5 6; do echo '#include "conftst'$i'.h"' >> sub/conftest.c # Using ": > sub/conftst$i.h" creates only sub/conftst1.h with # Solaris 10 /bin/sh. echo '/* dummy */' > sub/conftst$i.h done echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf # We check with '-c' and '-o' for the sake of the "dashmstdout" # mode. It turns out that the SunPro C++ compiler does not properly # handle '-M -o', and we need to detect this. Also, some Intel # versions had trouble with output in subdirs. am__obj=sub/conftest.${OBJEXT-o} am__minus_obj="-o $am__obj" case $depmode in gcc) # This depmode causes a compiler race in universal mode. test "$am__universal" = false || continue ;; nosideeffect) # After this tag, mechanisms are not by side-effect, so they'll # only be used when explicitly requested. if test "x$enable_dependency_tracking" = xyes; then continue else break fi ;; msvc7 | msvc7msys | msvisualcpp | msvcmsys) # This compiler won't grok '-c -o', but also, the minuso test has # not run yet. These depmodes are late enough in the game, and # so weak that their functioning should not be impacted. am__obj=conftest.${OBJEXT-o} am__minus_obj= ;; none) break ;; esac if depmode=$depmode \ source=sub/conftest.c object=$am__obj \ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \ >/dev/null 2>conftest.err && grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 && grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && grep $am__obj sub/conftest.Po > /dev/null 2>&1 && ${MAKE-make} -s -f confmf > /dev/null 2>&1; then # icc doesn't choke on unknown options, it will just issue warnings # or remarks (even with -Werror). So we grep stderr for any message # that says an option was ignored or not supported. # When given -MP, icc 7.0 and 7.1 complain thusly: # icc: Command line warning: ignoring option '-M'; no argument required # The diagnosis changed in icc 8.0: # icc: Command line remark: option '-MP' not supported if (grep 'ignoring option' conftest.err || grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else am_cv_$1_dependencies_compiler_type=$depmode break fi fi done cd .. rm -rf conftest.dir else am_cv_$1_dependencies_compiler_type=none fi ]) AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) AM_CONDITIONAL([am__fastdep$1], [ test "x$enable_dependency_tracking" != xno \ && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) ]) # AM_SET_DEPDIR # ------------- # Choose a directory name for dependency files. # This macro is AC_REQUIREd in _AM_DEPENDENCIES. AC_DEFUN([AM_SET_DEPDIR], [AC_REQUIRE([AM_SET_LEADING_DOT])dnl AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl ]) # AM_DEP_TRACK # ------------ AC_DEFUN([AM_DEP_TRACK], [AC_ARG_ENABLE([dependency-tracking], [dnl AS_HELP_STRING( [--enable-dependency-tracking], [do not reject slow dependency extractors]) AS_HELP_STRING( [--disable-dependency-tracking], [speeds up one-time build])]) if test "x$enable_dependency_tracking" != xno; then am_depcomp="$ac_aux_dir/depcomp" AMDEPBACKSLASH='\' am__nodep='_no' fi AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) AC_SUBST([AMDEPBACKSLASH])dnl _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl AC_SUBST([am__nodep])dnl _AM_SUBST_NOTMAKE([am__nodep])dnl ]) # Generate code to set up dependency tracking. -*- Autoconf -*- # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], [{ # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. # TODO: see whether this extra hack can be removed once we start # requiring Autoconf 2.70 or later. AS_CASE([$CONFIG_FILES], [*\'*], [eval set x "$CONFIG_FILES"], [*], [set x $CONFIG_FILES]) shift # Used to flag and report bootstrapping failures. am_rc=0 for am_mf do # Strip MF so we end up with the name of the file. am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` # Check whether this is an Automake generated Makefile which includes # dependency-tracking related rules and includes. # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ || continue am_dirpart=`AS_DIRNAME(["$am_mf"])` am_filepart=`AS_BASENAME(["$am_mf"])` AM_RUN_LOG([cd "$am_dirpart" \ && sed -e '/# am--include-marker/d' "$am_filepart" \ | $MAKE -f - am--depfiles]) || am_rc=$? done if test $am_rc -ne 0; then AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments for automatic dependency tracking. If GNU make was not used, consider re-running the configure script with MAKE="gmake" (or whatever is necessary). You can also try re-running configure with the '--disable-dependency-tracking' option to at least be able to build the package (albeit without support for automatic dependency tracking).]) fi AS_UNSET([am_dirpart]) AS_UNSET([am_filepart]) AS_UNSET([am_mf]) AS_UNSET([am_rc]) rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS # AM_OUTPUT_DEPENDENCY_COMMANDS # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # # This code is only required when automatic dependency tracking is enabled. # This creates each '.Po' and '.Plo' makefile fragment that we'll need in # order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # This macro actually does too much. Some checks are only needed if # your package does certain things. But this isn't really a big deal. dnl Redefine AC_PROG_CC to automatically invoke _AM_PROG_CC_C_O. m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC]) [_AM_PROG_CC_C_O ]) # AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) # AM_INIT_AUTOMAKE([OPTIONS]) # ----------------------------------------------- # The call with PACKAGE and VERSION arguments is the old style # call (pre autoconf-2.50), which is being phased out. PACKAGE # and VERSION should now be passed to AC_INIT and removed from # the call to AM_INIT_AUTOMAKE. # We support both call styles for the transition. After # the next Automake release, Autoconf can make the AC_INIT # arguments mandatory, and then we can depend on a new Autoconf # release and drop the old call support. AC_DEFUN([AM_INIT_AUTOMAKE], [AC_PREREQ([2.65])dnl m4_ifdef([_$0_ALREADY_INIT], [m4_fatal([$0 expanded multiple times ]m4_defn([_$0_ALREADY_INIT]))], [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl dnl Autoconf wants to disallow AM_ names. We explicitly allow dnl the ones we care about. m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl if test "`cd $srcdir && pwd`" != "`pwd`"; then # Use -I$(srcdir) only when $(srcdir) != ., so that make's output # is not polluted with repeated "-I." AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl # test to see if srcdir already configured if test -f $srcdir/config.status; then AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) fi fi # test whether we have cygpath if test -z "$CYGPATH_W"; then if (cygpath --version) >/dev/null 2>/dev/null; then CYGPATH_W='cygpath -w' else CYGPATH_W=echo fi fi AC_SUBST([CYGPATH_W]) # Define the identity of the package. dnl Distinguish between old-style and new-style calls. m4_ifval([$2], [AC_DIAGNOSE([obsolete], [$0: two- and three-arguments forms are deprecated.]) m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl AC_SUBST([PACKAGE], [$1])dnl AC_SUBST([VERSION], [$2])], [_AM_SET_OPTIONS([$1])dnl dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT. m4_if( m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]), [ok:ok],, [m4_fatal([AC_INIT should be called with package and version arguments])])dnl AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl _AM_IF_OPTION([no-define],, [AC_DEFINE_UNQUOTED([PACKAGE], ["$PACKAGE"], [Name of package]) AC_DEFINE_UNQUOTED([VERSION], ["$VERSION"], [Version number of package])])dnl # Some tools Automake needs. AC_REQUIRE([AM_SANITY_CHECK])dnl AC_REQUIRE([AC_ARG_PROGRAM])dnl AM_MISSING_PROG([ACLOCAL], [aclocal-${am__api_version}]) AM_MISSING_PROG([AUTOCONF], [autoconf]) AM_MISSING_PROG([AUTOMAKE], [automake-${am__api_version}]) AM_MISSING_PROG([AUTOHEADER], [autoheader]) AM_MISSING_PROG([MAKEINFO], [makeinfo]) AC_REQUIRE([AM_PROG_INSTALL_SH])dnl AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: # # AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. AC_REQUIRE([AC_PROG_AWK])dnl AC_REQUIRE([AC_PROG_MAKE_SET])dnl AC_REQUIRE([AM_SET_LEADING_DOT])dnl _AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], [_AM_PROG_TAR([v7])])]) _AM_IF_OPTION([no-dependencies],, [AC_PROVIDE_IFELSE([AC_PROG_CC], [_AM_DEPENDENCIES([CC])], [m4_define([AC_PROG_CC], m4_defn([AC_PROG_CC])[_AM_DEPENDENCIES([CC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_CXX], [_AM_DEPENDENCIES([CXX])], [m4_define([AC_PROG_CXX], m4_defn([AC_PROG_CXX])[_AM_DEPENDENCIES([CXX])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJC], [_AM_DEPENDENCIES([OBJC])], [m4_define([AC_PROG_OBJC], m4_defn([AC_PROG_OBJC])[_AM_DEPENDENCIES([OBJC])])])dnl AC_PROVIDE_IFELSE([AC_PROG_OBJCXX], [_AM_DEPENDENCIES([OBJCXX])], [m4_define([AC_PROG_OBJCXX], m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl ]) # Variables for tags utilities; see am/tags.am if test -z "$CTAGS"; then CTAGS=ctags fi AC_SUBST([CTAGS]) if test -z "$ETAGS"; then ETAGS=etags fi AC_SUBST([ETAGS]) if test -z "$CSCOPE"; then CSCOPE=cscope fi AC_SUBST([CSCOPE]) AC_REQUIRE([AM_SILENT_RULES])dnl dnl The testsuite driver may need to know about EXEEXT, so add the dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This dnl macro is hooked onto _AC_COMPILER_EXEEXT early, see below. AC_CONFIG_COMMANDS_PRE(dnl [m4_provide_if([_AM_COMPILER_EXEEXT], [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl # POSIX will say in a future version that running "rm -f" with no argument # is OK; and we want to be able to make that assumption in our Makefile # recipes. So use an aggressive probe to check that the usage we want is # actually supported "in the wild" to an acceptable degree. # See automake bug#10828. # To make any issue more visible, cause the running configure to be aborted # by default if the 'rm' program in use doesn't match our expectations; the # user can still override this though. if rm -f && rm -fr && rm -rf; then : OK; else cat >&2 <<'END' Oops! Your 'rm' program seems unable to run without file operands specified on the command line, even when the '-f' option is present. This is contrary to the behaviour of most rm programs out there, and not conforming with the upcoming POSIX standard: Please tell bug-automake@gnu.org about your system, including the value of your $PATH and any error possibly output before this message. This can help us improve future automake versions. END if test x"$ACCEPT_INFERIOR_RM_PROGRAM" = x"yes"; then echo 'Configuration will proceed anyway, since you have set the' >&2 echo 'ACCEPT_INFERIOR_RM_PROGRAM variable to "yes"' >&2 echo >&2 else cat >&2 <<'END' Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM to "yes", and re-run configure. END AC_MSG_ERROR([Your 'rm' program is bad, sorry.]) fi fi dnl The trailing newline in this macro's definition is deliberate, for dnl backward compatibility and to allow trailing 'dnl'-style comments dnl after the AM_INIT_AUTOMAKE invocation. See automake bug#16841. ]) dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further dnl mangled by Autoconf and run in a shell conditional statement. m4_define([_AC_COMPILER_EXEEXT], m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])]) # When config.status generates a header, we must update the stamp-h file. # This file resides in the same directory as the config header # that is generated. The stamp files are numbered to have different names. # Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the # loop where config.status creates the headers, so we can generate # our stamp files there. AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], [# Compute $1's index in $config_headers. _am_arg=$1 _am_stamp_count=1 for _am_header in $config_headers :; do case $_am_header in $_am_arg | $_am_arg:* ) break ;; * ) _am_stamp_count=`expr $_am_stamp_count + 1` ;; esac done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_SH # ------------------ # Define $install_sh. AC_DEFUN([AM_PROG_INSTALL_SH], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl if test x"${install_sh+set}" != xset; then case $am_aux_dir in *\ * | *\ *) install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;; *) install_sh="\${SHELL} $am_aux_dir/install-sh" esac fi AC_SUBST([install_sh])]) # Copyright (C) 2003-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # Check whether the underlying file-system supports filenames # with a leading dot. For instance MS-DOS doesn't. AC_DEFUN([AM_SET_LEADING_DOT], [rm -rf .tst 2>/dev/null mkdir .tst 2>/dev/null if test -d .tst; then am__leading_dot=. else am__leading_dot=_ fi rmdir .tst 2>/dev/null AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MAKE_INCLUDE() # ----------------- # Check whether make has an 'include' directive that can support all # the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], [AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) cat > confinc.mk << 'END' am__doit: @echo this is the am__doit target >confinc.out .PHONY: am__doit END am__include="#" am__quote= # BSD make does it like this. echo '.include "confinc.mk" # ignored' > confmf.BSD # Other make implementations (GNU, Solaris 10, AIX) do it like this. echo 'include confinc.mk # ignored' > confmf.GNU _am_result=no for s in GNU BSD; do AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) AS_CASE([$?:`cat confinc.out 2>/dev/null`], ['0:this is the am__doit target'], [AS_CASE([$s], [BSD], [am__include='.include' am__quote='"'], [am__include='include' am__quote=''])]) if test "$am__include" != "#"; then _am_result="yes ($s style)" break fi done rm -f confinc.* confmf.* AC_MSG_RESULT([${_am_result}]) AC_SUBST([am__include])]) AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- # Copyright (C) 1997-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_MISSING_PROG(NAME, PROGRAM) # ------------------------------ AC_DEFUN([AM_MISSING_PROG], [AC_REQUIRE([AM_MISSING_HAS_RUN]) $1=${$1-"${am_missing_run}$2"} AC_SUBST($1)]) # AM_MISSING_HAS_RUN # ------------------ # Define MISSING if not defined so far and test if it is modern enough. # If it is, set am_missing_run to use it, otherwise, to nothing. AC_DEFUN([AM_MISSING_HAS_RUN], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([missing])dnl if test x"${MISSING+set}" != xset; then MISSING="\${SHELL} '$am_aux_dir/missing'" fi # Use eval to expand $SHELL if eval "$MISSING --is-lightweight"; then am_missing_run="$MISSING " else am_missing_run= AC_MSG_WARN(['missing' script is too old or missing]) fi ]) # Helper functions for option handling. -*- Autoconf -*- # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_MANGLE_OPTION(NAME) # ----------------------- AC_DEFUN([_AM_MANGLE_OPTION], [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) # _AM_SET_OPTION(NAME) # -------------------- # Set option NAME. Presently that only means defining a flag for this option. AC_DEFUN([_AM_SET_OPTION], [m4_define(_AM_MANGLE_OPTION([$1]), [1])]) # _AM_SET_OPTIONS(OPTIONS) # ------------------------ # OPTIONS is a space-separated list of Automake options. AC_DEFUN([_AM_SET_OPTIONS], [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) # _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) # ------------------------------------------- # Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) # Copyright (C) 1999-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_CC_C_O # --------------- # Like AC_PROG_CC_C_O, but changed for automake. We rewrite AC_PROG_CC # to automatically call this. AC_DEFUN([_AM_PROG_CC_C_O], [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl AC_REQUIRE_AUX_FILE([compile])dnl AC_LANG_PUSH([C])dnl AC_CACHE_CHECK( [whether $CC understands -c and -o together], [am_cv_prog_cc_c_o], [AC_LANG_CONFTEST([AC_LANG_PROGRAM([])]) # Make sure it works both with $CC and with simple cc. # Following AC_PROG_CC_C_O, we do the test twice because some # compilers refuse to overwrite an existing .o file with -o, # though they will create one. am_cv_prog_cc_c_o=yes for am_i in 1 2; do if AM_RUN_LOG([$CC -c conftest.$ac_ext -o conftest2.$ac_objext]) \ && test -f conftest2.$ac_objext; then : OK else am_cv_prog_cc_c_o=no break fi done rm -f core conftest* unset am_i]) if test "$am_cv_prog_cc_c_o" != yes; then # Losing compiler, so override with the script. # FIXME: It is wrong to rewrite CC. # But if we don't then we get into trouble of one sort or another. # A longer-term fix would be to have automake use am__CC in this case, # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)" CC="$am_aux_dir/compile $CC" fi AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_RUN_LOG(COMMAND) # ------------------- # Run COMMAND, save the exit status in ac_status, and log it. # (This has been adapted from Autoconf's _AC_RUN_LOG macro.) AC_DEFUN([AM_RUN_LOG], [{ echo "$as_me:$LINENO: $1" >&AS_MESSAGE_LOG_FD ($1) >&AS_MESSAGE_LOG_FD 2>&AS_MESSAGE_LOG_FD ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD (exit $ac_status); }]) # Check to make sure that the build environment is sane. -*- Autoconf -*- # Copyright (C) 1996-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SANITY_CHECK # --------------- AC_DEFUN([AM_SANITY_CHECK], [AC_MSG_CHECKING([whether build environment is sane]) # Reject unsafe characters in $srcdir or the absolute working directory # name. Accept space and tab only in the latter. am_lf=' ' case `pwd` in *[[\\\"\#\$\&\'\`$am_lf]]*) AC_MSG_ERROR([unsafe absolute working directory name]);; esac case $srcdir in *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*) AC_MSG_ERROR([unsafe srcdir value: '$srcdir']);; esac # Do 'set' in a subshell so we don't clobber the current shell's # arguments. Must try -L first in case configure is actually a # symlink; some systems play weird games with the mod time of symlinks # (eg FreeBSD returns the mod time of the symlink's containing # directory). if ( am_has_slept=no for am_try in 1 2; do echo "timestamp, slept: $am_has_slept" > conftest.file set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null` if test "$[*]" = "X"; then # -L didn't work. set X `ls -t "$srcdir/configure" conftest.file` fi if test "$[*]" != "X $srcdir/configure conftest.file" \ && test "$[*]" != "X conftest.file $srcdir/configure"; then # If neither matched, then we have a broken ls. This can happen # if, for instance, CONFIG_SHELL is bash and it inherits a # broken ls alias from the environment. This has actually # happened. Such a system could not be considered "sane". AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken alias in your environment]) fi if test "$[2]" = conftest.file || test $am_try -eq 2; then break fi # Just in case. sleep 1 am_has_slept=yes done test "$[2]" = conftest.file ) then # Ok. : else AC_MSG_ERROR([newly created file is older than distributed files! Check your system clock]) fi AC_MSG_RESULT([yes]) # If we didn't sleep, we still need to ensure time stamps of config.status and # generated files are strictly newer. am_sleep_pid= if grep 'slept: no' conftest.file >/dev/null 2>&1; then ( sleep 1 ) & am_sleep_pid=$! fi AC_CONFIG_COMMANDS_PRE( [AC_MSG_CHECKING([that generated files are newer than configure]) if test -n "$am_sleep_pid"; then # Hide warnings about reused PIDs. wait $am_sleep_pid 2>/dev/null fi AC_MSG_RESULT([done])]) rm -f conftest.file ]) # Copyright (C) 2009-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_SILENT_RULES([DEFAULT]) # -------------------------- # Enable less verbose build rules; with the default set to DEFAULT # ("yes" being less verbose, "no" or empty being verbose). AC_DEFUN([AM_SILENT_RULES], [AC_ARG_ENABLE([silent-rules], [dnl AS_HELP_STRING( [--enable-silent-rules], [less verbose build output (undo: "make V=1")]) AS_HELP_STRING( [--disable-silent-rules], [verbose build output (undo: "make V=0")])dnl ]) case $enable_silent_rules in @%:@ ((( yes) AM_DEFAULT_VERBOSITY=0;; no) AM_DEFAULT_VERBOSITY=1;; *) AM_DEFAULT_VERBOSITY=m4_if([$1], [yes], [0], [1]);; esac dnl dnl A few 'make' implementations (e.g., NonStop OS and NextStep) dnl do not support nested variable expansions. dnl See automake bug#9928 and bug#10237. am_make=${MAKE-make} AC_CACHE_CHECK([whether $am_make supports nested variables], [am_cv_make_support_nested_variables], [if AS_ECHO([['TRUE=$(BAR$(V)) BAR0=false BAR1=true V=1 am__doit: @$(TRUE) .PHONY: am__doit']]) | $am_make -f - >/dev/null 2>&1; then am_cv_make_support_nested_variables=yes else am_cv_make_support_nested_variables=no fi]) if test $am_cv_make_support_nested_variables = yes; then dnl Using '$V' instead of '$(V)' breaks IRIX make. AM_V='$(V)' AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)' else AM_V=$AM_DEFAULT_VERBOSITY AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY fi AC_SUBST([AM_V])dnl AM_SUBST_NOTMAKE([AM_V])dnl AC_SUBST([AM_DEFAULT_V])dnl AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl AC_SUBST([AM_DEFAULT_VERBOSITY])dnl AM_BACKSLASH='\' AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) # Copyright (C) 2001-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # AM_PROG_INSTALL_STRIP # --------------------- # One issue with vendor 'install' (even GNU) is that you can't # specify the program used to strip binaries. This is especially # annoying in cross-compiling environments, where the build's strip # is unlikely to handle the host's binaries. # Fortunately install-sh will honor a STRIPPROG variable, so we # always use install-sh in "make install-strip", and initialize # STRIPPROG with the value of the STRIP variable (set by the user). AC_DEFUN([AM_PROG_INSTALL_STRIP], [AC_REQUIRE([AM_PROG_INSTALL_SH])dnl # Installed binaries are usually stripped using 'strip' when the user # run "make install-strip". However 'strip' might not be the right # tool to use in cross-compilation environments, therefore Automake # will honor the 'STRIP' environment variable to overrule this program. dnl Don't test for $cross_compiling = yes, because it might be 'maybe'. if test "$cross_compiling" != no; then AC_CHECK_TOOL([STRIP], [strip], :) fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) # Copyright (C) 2006-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_SUBST_NOTMAKE(VARIABLE) # --------------------------- # Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in. # This macro is traced by Automake. AC_DEFUN([_AM_SUBST_NOTMAKE]) # AM_SUBST_NOTMAKE(VARIABLE) # -------------------------- # Public sister of _AM_SUBST_NOTMAKE. AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- # Copyright (C) 2004-2021 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. # _AM_PROG_TAR(FORMAT) # -------------------- # Check how to create a tarball in format FORMAT. # FORMAT should be one of 'v7', 'ustar', or 'pax'. # # Substitute a variable $(am__tar) that is a command # writing to stdout a FORMAT-tarball containing the directory # $tardir. # tardir=directory && $(am__tar) > result.tar # # Substitute a variable $(am__untar) that extract such # a tarball read from stdin. # $(am__untar) < result.tar # AC_DEFUN([_AM_PROG_TAR], [# Always define AMTAR for backward compatibility. Yes, it's still used # in the wild :-( We should find a proper way to deprecate it ... AC_SUBST([AMTAR], ['$${TAR-tar}']) # We'll loop over all known methods to create a tar archive until one works. _am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' m4_if([$1], [v7], [am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'], [m4_case([$1], [ustar], [# The POSIX 1988 'ustar' format is defined with fixed-size fields. # There is notably a 21 bits limit for the UID and the GID. In fact, # the 'pax' utility can hang on bigger UID/GID (see automake bug#8343 # and bug#13588). am_max_uid=2097151 # 2^21 - 1 am_max_gid=$am_max_uid # The $UID and $GID variables are not portable, so we need to resort # to the POSIX-mandated id(1) utility. Errors in the 'id' calls # below are definitely unexpected, so allow the users to see them # (that is, avoid stderr redirection). am_uid=`id -u || echo unknown` am_gid=`id -g || echo unknown` AC_MSG_CHECKING([whether UID '$am_uid' is supported by ustar format]) if test $am_uid -le $am_max_uid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi AC_MSG_CHECKING([whether GID '$am_gid' is supported by ustar format]) if test $am_gid -le $am_max_gid; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) _am_tools=none fi], [pax], [], [m4_fatal([Unknown tar format])]) AC_MSG_CHECKING([how to create a $1 tar archive]) # Go ahead even if we have the value already cached. We do so because we # need to set the values for the 'am__tar' and 'am__untar' variables. _am_tools=${am_cv_prog_tar_$1-$_am_tools} for _am_tool in $_am_tools; do case $_am_tool in gnutar) for _am_tar in tar gnutar gtar; do AM_RUN_LOG([$_am_tar --version]) && break done am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' am__untar="$_am_tar -xf -" ;; plaintar) # Must skip GNU tar: if it does not support --format= it doesn't create # ustar tarball either. (tar --version) >/dev/null 2>&1 && continue am__tar='tar chf - "$$tardir"' am__tar_='tar chf - "$tardir"' am__untar='tar xf -' ;; pax) am__tar='pax -L -x $1 -w "$$tardir"' am__tar_='pax -L -x $1 -w "$tardir"' am__untar='pax -r' ;; cpio) am__tar='find "$$tardir" -print | cpio -o -H $1 -L' am__tar_='find "$tardir" -print | cpio -o -H $1 -L' am__untar='cpio -i -H $1 -d' ;; none) am__tar=false am__tar_=false am__untar=false ;; esac # If the value was cached, stop now. We just wanted to have am__tar # and am__untar set. test -n "${am_cv_prog_tar_$1}" && break # tar/untar a dummy directory, and stop if the command works. rm -rf conftest.dir mkdir conftest.dir echo GrepMe > conftest.dir/file AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) rm -rf conftest.dir if test -s conftest.tar; then AM_RUN_LOG([$am__untar /dev/null 2>&1 && break fi done rm -rf conftest.dir AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) AC_MSG_RESULT([$am_cv_prog_tar_$1])]) AC_SUBST([am__tar]) AC_SUBST([am__untar]) ]) # _AM_PROG_TAR m4_include([m4/as-ac-expand.m4]) m4_include([m4/pkg.m4]) keepalived-2.3.1/build-aux/0000775000175000017500000000000014624033726012532 500000000000000keepalived-2.3.1/build-aux/ar-lib0000755000175000017500000001336314215102164013537 00000000000000#! /bin/sh # Wrapper for Microsoft lib.exe me=ar-lib scriptversion=2019-07-04.01; # UTC # Copyright (C) 2010-2021 Free Software Foundation, Inc. # Written by Peter Rosin . # # 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 2, 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . # func_error message func_error () { echo "$me: $1" 1>&2 exit 1 } file_conv= # func_file_conv build_file # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv in mingw) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin | msys) file=`cygpath -m "$file" || echo "$file"` ;; wine) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_at_file at_file operation archive # Iterate over all members in AT_FILE performing OPERATION on ARCHIVE # for each of them. # When interpreting the content of the @FILE, do NOT use func_file_conv, # since the user would need to supply preconverted file names to # binutils ar, at least for MinGW. func_at_file () { operation=$2 archive=$3 at_file_contents=`cat "$1"` eval set x "$at_file_contents" shift for member do $AR -NOLOGO $operation:"$member" "$archive" || exit $? done } case $1 in '') func_error "no command. Try '$0 --help' for more information." ;; -h | --h*) cat <. # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # Originally written by Alexandre Oliva . case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: depcomp [--help] [--version] PROGRAM [ARGS] Run PROGRAMS ARGS to compile a file, generating dependencies as side-effects. Environment variables: depmode Dependency tracking mode. source Source file read by 'PROGRAMS ARGS'. object Object file output by 'PROGRAMS ARGS'. DEPDIR directory where to store dependencies. depfile Dependency file to output. tmpdepfile Temporary file to use when outputting dependencies. libtool Whether libtool is used (yes/no). Report bugs to . EOF exit $? ;; -v | --v*) echo "depcomp $scriptversion" exit $? ;; esac # Get the directory component of the given path, and save it in the # global variables '$dir'. Note that this directory component will # be either empty or ending with a '/' character. This is deliberate. set_dir_from () { case $1 in */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; *) dir=;; esac } # Get the suffix-stripped basename of the given path, and save it the # global variable '$base'. set_base_from () { base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` } # If no dependency file was actually created by the compiler invocation, # we still have to create a dummy depfile, to avoid errors with the # Makefile "include basename.Plo" scheme. make_dummy_depfile () { echo "#dummy" > "$depfile" } # Factor out some common post-processing of the generated depfile. # Requires the auxiliary global variable '$tmpdepfile' to be set. aix_post_process_depfile () { # If the compiler actually managed to produce a dependency file, # post-process it. if test -f "$tmpdepfile"; then # Each line is of the form 'foo.o: dependency.h'. # Do two passes, one to just change these to # $object: dependency.h # and one to simply output # dependency.h: # which is needed to avoid the deleted-header problem. { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" } > "$depfile" rm -f "$tmpdepfile" else make_dummy_depfile fi } # A tabulation character. tab=' ' # A newline character. nl=' ' # Character ranges might be problematic outside the C locale. # These definitions help. upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ lower=abcdefghijklmnopqrstuvwxyz digits=0123456789 alpha=${upper}${lower} if test -z "$depmode" || test -z "$source" || test -z "$object"; then echo "depcomp: Variables source, object and depmode must be set" 1>&2 exit 1 fi # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. depfile=${depfile-`echo "$object" | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} rm -f "$tmpdepfile" # Avoid interferences from the environment. gccflag= dashmflag= # Some modes work just like other modes, but use different flags. We # parameterize here, but still list the modes in the big case below, # to make depend.m4 easier to write. Note that we *cannot* use a case # here, because this file can only contain one case statement. if test "$depmode" = hp; then # HP compiler uses -M and no extra arg. gccflag=-M depmode=gcc fi if test "$depmode" = dashXmstdout; then # This is just like dashmstdout with a different argument. dashmflag=-xM depmode=dashmstdout fi cygpath_u="cygpath -u -f -" if test "$depmode" = msvcmsys; then # This is just like msvisualcpp but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvisualcpp fi if test "$depmode" = msvc7msys; then # This is just like msvc7 but w/o cygpath translation. # Just convert the backslash-escaped backslashes to single forward # slashes to satisfy depend.m4 cygpath_u='sed s,\\\\,/,g' depmode=msvc7 fi if test "$depmode" = xlc; then # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. gccflag=-qmakedep=gcc,-MF depmode=gcc fi case "$depmode" in gcc3) ## gcc 3 implements dependency tracking that does exactly what ## we want. Yay! Note: for some reason libtool 1.4 doesn't like ## it if -MD -MP comes after the -MF stuff. Hmm. ## Unfortunately, FreeBSD c89 acceptance of flags depends upon ## the command line argument order; so add the flags where they ## appear in depend2.am. Note that the slowdown incurred here ## affects only configure: in makefiles, %FASTDEP% shortcuts this. for arg do case $arg in -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; *) set fnord "$@" "$arg" ;; esac shift # fnord shift # $arg done "$@" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi mv "$tmpdepfile" "$depfile" ;; gcc) ## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. ## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. ## (see the conditional assignment to $gccflag above). ## There are various ways to get dependency output from gcc. Here's ## why we pick this rather obscure method: ## - Don't want to use -MD because we'd like the dependencies to end ## up in a subdir. Having to rename by hand is ugly. ## (We might end up doing this anyway to support other compilers.) ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like ## -MM, not -M (despite what the docs say). Also, it might not be ## supported by the other compilers which use the 'gcc' depmode. ## - Using -M directly means running the compiler twice (even worse ## than renaming). if test -z "$gccflag"; then gccflag=-MD, fi "$@" -Wp,"$gccflag$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The second -e expression handles DOS-style file names with drive # letters. sed -e 's/^[^:]*: / /' \ -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" ## This next piece of magic avoids the "deleted header file" problem. ## The problem is that when a header file which appears in a .P file ## is deleted, the dependency causes make to die (because there is ## typically no way to rebuild the header). We avoid this by adding ## dummy dependencies for each header file. Too bad gcc doesn't do ## this for us directly. ## Some versions of gcc put a space before the ':'. On the theory ## that the space means something, we add a space to the output as ## well. hp depmode also adds that space, but also prefixes the VPATH ## to the object. Take care to not repeat it in the output. ## Some versions of the HPUX 10.20 sed can't process this invocation ## correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; sgi) if test "$libtool" = yes; then "$@" "-Wp,-MDupdate,$tmpdepfile" else "$@" -MDupdate "$tmpdepfile" fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files echo "$object : \\" > "$depfile" # Clip off the initial element (the dependent). Don't try to be # clever and replace this with sed code, as IRIX sed won't handle # lines with more than a fixed number of characters (4096 in # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; # the IRIX cc adds comments like '#:fec' to the end of the # dependency line. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ | tr "$nl" ' ' >> "$depfile" echo >> "$depfile" # The second pass generates a dummy entry for each header file. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" ;; xlc) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; aix) # The C for AIX Compiler uses -M and outputs the dependencies # in a .u file. In older versions, this file always lives in the # current directory. Also, the AIX compiler puts '$object:' at the # start of each line; $object doesn't have directory information. # Version 6 uses the directory in both cases. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.u tmpdepfile2=$base.u tmpdepfile3=$dir.libs/$base.u "$@" -Wc,-M else tmpdepfile1=$dir$base.u tmpdepfile2=$dir$base.u tmpdepfile3=$dir$base.u "$@" -M fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done aix_post_process_depfile ;; tcc) # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 # FIXME: That version still under development at the moment of writing. # Make that this statement remains true also for stable, released # versions. # It will wrap lines (doesn't matter whether long or short) with a # trailing '\', as in: # # foo.o : \ # foo.c \ # foo.h \ # # It will put a trailing '\' even on the last line, and will use leading # spaces rather than leading tabs (at least since its commit 0394caf7 # "Emit spaces for -MD"). "$@" -MD -MF "$tmpdepfile" stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. # We have to change lines of the first kind to '$object: \'. sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" # And for each line of the second kind, we have to emit a 'dep.h:' # dummy dependency, to avoid the deleted-header problem. sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" rm -f "$tmpdepfile" ;; ## The order of this option in the case statement is important, since the ## shell code in configure will try each of these formats in the order ## listed in this file. A plain '-MD' option would be understood by many ## compilers, so we must ensure this comes after the gcc and icc options. pgcc) # Portland's C compiler understands '-MD'. # Will always output deps to 'file.d' where file is the root name of the # source file under compilation, even if file resides in a subdirectory. # The object file name does not affect the name of the '.d' file. # pgcc 10.2 will output # foo.o: sub/foo.c sub/foo.h # and will wrap long lines using '\' : # foo.o: sub/foo.c ... \ # sub/foo.h ... \ # ... set_dir_from "$object" # Use the source, not the object, to determine the base name, since # that's sadly what pgcc will do too. set_base_from "$source" tmpdepfile=$base.d # For projects that build the same source file twice into different object # files, the pgcc approach of using the *source* file root name can cause # problems in parallel builds. Use a locking strategy to avoid stomping on # the same $tmpdepfile. lockdir=$base.d-lock trap " echo '$0: caught signal, cleaning up...' >&2 rmdir '$lockdir' exit 1 " 1 2 13 15 numtries=100 i=$numtries while test $i -gt 0; do # mkdir is a portable test-and-set. if mkdir "$lockdir" 2>/dev/null; then # This process acquired the lock. "$@" -MD stat=$? # Release the lock. rmdir "$lockdir" break else # If the lock is being held by a different process, wait # until the winning process is done or we timeout. while test -d "$lockdir" && test $i -gt 0; do sleep 1 i=`expr $i - 1` done fi i=`expr $i - 1` done trap - 1 2 13 15 if test $i -le 0; then echo "$0: failed to acquire lock after $numtries attempts" >&2 echo "$0: check lockdir '$lockdir'" >&2 exit 1 fi if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" # Each line is of the form `foo.o: dependent.h', # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. # Do two passes, one to just change these to # `$object: dependent.h' and one to simply `dependent.h:'. sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this invocation # correctly. Breaking it into two sed invocations is a workaround. sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; hp2) # The "hp" stanza above does not work with aCC (C++) and HP's ia64 # compilers, which have integrated preprocessors. The correct option # to use with these is +Maked; it writes dependencies to a file named # 'foo.d', which lands next to the object file, wherever that # happens to be. # Much of this is similar to the tru64 case; see comments there. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then tmpdepfile1=$dir$base.d tmpdepfile2=$dir.libs/$base.d "$@" -Wc,+Maked else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d "$@" +Maked fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" do test -f "$tmpdepfile" && break done if test -f "$tmpdepfile"; then sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" # Add 'dependent.h:' lines. sed -ne '2,${ s/^ *// s/ \\*$// s/$/:/ p }' "$tmpdepfile" >> "$depfile" else make_dummy_depfile fi rm -f "$tmpdepfile" "$tmpdepfile2" ;; tru64) # The Tru64 compiler uses -MD to generate dependencies as a side # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put # dependencies in 'foo.d' instead, so we check for that too. # Subdirectories are respected. set_dir_from "$object" set_base_from "$object" if test "$libtool" = yes; then # Libtool generates 2 separate objects for the 2 libraries. These # two compilations output dependencies in $dir.libs/$base.o.d and # in $dir$base.o.d. We have to check for both files, because # one of the two compilations can be disabled. We should prefer # $dir$base.o.d over $dir.libs/$base.o.d because the latter is # automatically cleaned when .libs/ is deleted, while ignoring # the former would cause a distcleancheck panic. tmpdepfile1=$dir$base.o.d # libtool 1.5 tmpdepfile2=$dir.libs/$base.o.d # Likewise. tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 "$@" -Wc,-MD else tmpdepfile1=$dir$base.d tmpdepfile2=$dir$base.d tmpdepfile3=$dir$base.d "$@" -MD fi stat=$? if test $stat -ne 0; then rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" exit $stat fi for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" do test -f "$tmpdepfile" && break done # Same post-processing that is required for AIX mode. aix_post_process_depfile ;; msvc7) if test "$libtool" = yes; then showIncludes=-Wc,-showIncludes else showIncludes=-showIncludes fi "$@" $showIncludes > "$tmpdepfile" stat=$? grep -v '^Note: including file: ' "$tmpdepfile" if test $stat -ne 0; then rm -f "$tmpdepfile" exit $stat fi rm -f "$depfile" echo "$object : \\" > "$depfile" # The first sed program below extracts the file names and escapes # backslashes for cygpath. The second sed program outputs the file # name when reading, but also accumulates all include files in the # hold buffer in order to output them again at the end. This only # works with sed implementations that can handle large buffers. sed < "$tmpdepfile" -n ' /^Note: including file: *\(.*\)/ { s//\1/ s/\\/\\\\/g p }' | $cygpath_u | sort -u | sed -n ' s/ /\\ /g s/\(.*\)/'"$tab"'\1 \\/p s/.\(.*\) \\/\1:/ H $ { s/.*/'"$tab"'/ G p }' >> "$depfile" echo >> "$depfile" # make sure the fragment doesn't end with a backslash rm -f "$tmpdepfile" ;; msvc7msys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; #nosideeffect) # This comment above is used by automake to tell side-effect # dependency tracking mechanisms from slower ones. dashmstdout) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout, regardless of -o. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done test -z "$dashmflag" && dashmflag=-M # Require at least two characters before searching for ':' # in the target name. This is to cope with DOS-style filenames: # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. "$@" $dashmflag | sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" rm -f "$depfile" cat < "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process this sed invocation # correctly. Breaking it into two sed invocations is a workaround. tr ' ' "$nl" < "$tmpdepfile" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; dashXmstdout) # This case only exists to satisfy depend.m4. It is never actually # run, as this mode is specially recognized in the preamble. exit 1 ;; makedepend) "$@" || exit $? # Remove any Libtool call if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # X makedepend shift cleared=no eat=no for arg do case $cleared in no) set ""; shift cleared=yes ;; esac if test $eat = yes; then eat=no continue fi case "$arg" in -D*|-I*) set fnord "$@" "$arg"; shift ;; # Strip any option that makedepend may not understand. Remove # the object too, otherwise makedepend will parse it as a source file. -arch) eat=yes ;; -*|$object) ;; *) set fnord "$@" "$arg"; shift ;; esac done obj_suffix=`echo "$object" | sed 's/^.*\././'` touch "$tmpdepfile" ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" rm -f "$depfile" # makedepend may prepend the VPATH from the source file name to the object. # No need to regex-escape $object, excess matching of '.' is harmless. sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" # Some versions of the HPUX 10.20 sed can't process the last invocation # correctly. Breaking it into two sed invocations is a workaround. sed '1,2d' "$tmpdepfile" \ | tr ' ' "$nl" \ | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ | sed -e 's/$/ :/' >> "$depfile" rm -f "$tmpdepfile" "$tmpdepfile".bak ;; cpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi # Remove '-o $object'. IFS=" " for arg do case $arg in -o) shift ;; $object) shift ;; *) set fnord "$@" "$arg" shift # fnord shift # $arg ;; esac done "$@" -E \ | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ | sed '$ s: \\$::' > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" cat < "$tmpdepfile" >> "$depfile" sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" rm -f "$tmpdepfile" ;; msvisualcpp) # Important note: in order to support this mode, a compiler *must* # always write the preprocessed file to stdout. "$@" || exit $? # Remove the call to Libtool. if test "$libtool" = yes; then while test "X$1" != 'X--mode=compile'; do shift done shift fi IFS=" " for arg do case "$arg" in -o) shift ;; $object) shift ;; "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") set fnord "$@" shift shift ;; *) set fnord "$@" "$arg" shift shift ;; esac done "$@" -E 2>/dev/null | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" rm -f "$depfile" echo "$object : \\" > "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" echo "$tab" >> "$depfile" sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" rm -f "$tmpdepfile" ;; msvcmsys) # This case exists only to let depend.m4 do its work. It works by # looking at the text of this script. This case will never be run, # since it is checked for above. exit 1 ;; none) exec "$@" ;; *) echo "Unknown depmode $depmode" 1>&2 exit 1 ;; esac exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: keepalived-2.3.1/build-aux/missing0000755000175000017500000001533614215102164014044 00000000000000#! /bin/sh # Common wrapper for a few potentially missing GNU programs. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1996-2021 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # 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 2, 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. if test $# -eq 0; then echo 1>&2 "Try '$0 --help' for more information" exit 1 fi case $1 in --is-lightweight) # Used by our autoconf macros to check whether the available missing # script is modern enough. exit 0 ;; --run) # Back-compat with the calling convention used by older automake. shift ;; -h|--h|--he|--hel|--help) echo "\ $0 [OPTION]... PROGRAM [ARGUMENT]... Run 'PROGRAM [ARGUMENT]...', returning a proper advice when this fails due to PROGRAM being missing or too old. Options: -h, --help display this help and exit -v, --version output version information and exit Supported PROGRAM values: aclocal autoconf autoheader autom4te automake makeinfo bison yacc flex lex help2man Version suffixes to PROGRAM as well as the prefixes 'gnu-', 'gnu', and 'g' are ignored when checking the name. Send bug reports to ." exit $? ;; -v|--v|--ve|--ver|--vers|--versi|--versio|--version) echo "missing $scriptversion (GNU Automake)" exit $? ;; -*) echo 1>&2 "$0: unknown '$1' option" echo 1>&2 "Try '$0 --help' for more information" exit 1 ;; esac # Run the given program, remember its exit status. "$@"; st=$? # If it succeeded, we are done. test $st -eq 0 && exit 0 # Also exit now if we it failed (or wasn't found), and '--version' was # passed; such an option is passed most likely to detect whether the # program is present and works. case $2 in --version|--help) exit $st;; esac # Exit code 63 means version mismatch. This often happens when the user # tries to use an ancient version of a tool on a file that requires a # minimum version. if test $st -eq 63; then msg="probably too old" elif test $st -eq 127; then # Program was missing. msg="missing on your system" else # Program was found and executed, but failed. Give up. exit $st fi perl_URL=https://www.perl.org/ flex_URL=https://github.com/westes/flex gnu_software_URL=https://www.gnu.org/software program_details () { case $1 in aclocal|automake) echo "The '$1' program is part of the GNU Automake package:" echo "<$gnu_software_URL/automake>" echo "It also requires GNU Autoconf, GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/autoconf>" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; autoconf|autom4te|autoheader) echo "The '$1' program is part of the GNU Autoconf package:" echo "<$gnu_software_URL/autoconf/>" echo "It also requires GNU m4 and Perl in order to run:" echo "<$gnu_software_URL/m4/>" echo "<$perl_URL>" ;; esac } give_advice () { # Normalize program name to check for. normalized_program=`echo "$1" | sed ' s/^gnu-//; t s/^gnu//; t s/^g//; t'` printf '%s\n' "'$1' is $msg." configure_deps="'configure.ac' or m4 files included by 'configure.ac'" case $normalized_program in autoconf*) echo "You should only need it if you modified 'configure.ac'," echo "or m4 files included by it." program_details 'autoconf' ;; autoheader*) echo "You should only need it if you modified 'acconfig.h' or" echo "$configure_deps." program_details 'autoheader' ;; automake*) echo "You should only need it if you modified 'Makefile.am' or" echo "$configure_deps." program_details 'automake' ;; aclocal*) echo "You should only need it if you modified 'acinclude.m4' or" echo "$configure_deps." program_details 'aclocal' ;; autom4te*) echo "You might have modified some maintainer files that require" echo "the 'autom4te' program to be rebuilt." program_details 'autom4te' ;; bison*|yacc*) echo "You should only need it if you modified a '.y' file." echo "You may want to install the GNU Bison package:" echo "<$gnu_software_URL/bison/>" ;; lex*|flex*) echo "You should only need it if you modified a '.l' file." echo "You may want to install the Fast Lexical Analyzer package:" echo "<$flex_URL>" ;; help2man*) echo "You should only need it if you modified a dependency" \ "of a man page." echo "You may want to install the GNU Help2man package:" echo "<$gnu_software_URL/help2man/>" ;; makeinfo*) echo "You should only need it if you modified a '.texi' file, or" echo "any other file indirectly affecting the aspect of the manual." echo "You might want to install the Texinfo package:" echo "<$gnu_software_URL/texinfo/>" echo "The spurious makeinfo call might also be the consequence of" echo "using a buggy 'make' (AIX, DU, IRIX), in which case you might" echo "want to install GNU make:" echo "<$gnu_software_URL/make/>" ;; *) echo "You might have modified some files without having the proper" echo "tools for further handling them. Check the 'README' file, it" echo "often tells you about the needed prerequisites for installing" echo "this package. You may also peek at any GNU archive site, in" echo "case some other package contains this missing '$1' program." ;; esac } give_advice "$1" | sed -e '1s/^/WARNING: /' \ -e '2,$s/^/ /' >&2 # Propagate the correct exit status (expected to be 127 for a program # not found, 63 for a program that failed due to version mismatch). exit $st # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: keepalived-2.3.1/build-aux/compile0000755000175000017500000001635014215102164014020 00000000000000#! /bin/sh # Wrapper for compilers which do not understand '-c -o'. scriptversion=2018-03-07.03; # UTC # Copyright (C) 1999-2021 Free Software Foundation, Inc. # Written by Tom Tromey . # # 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 2, 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 . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a # configuration script generated by Autoconf, you may include it under # the same distribution terms that you use for the rest of that program. # This file is maintained in Automake, please report # bugs to or send patches to # . nl=' ' # We need space, tab and new line, in precisely that order. Quoting is # there to prevent tools from complaining about whitespace usage. IFS=" "" $nl" file_conv= # func_file_conv build_file lazy # Convert a $build file to $host form and store it in $file # Currently only supports Windows hosts. If the determined conversion # type is listed in (the comma separated) LAZY, no conversion will # take place. func_file_conv () { file=$1 case $file in / | /[!/]*) # absolute file, and not a UNC file if test -z "$file_conv"; then # lazily determine how to convert abs files case `uname -s` in MINGW*) file_conv=mingw ;; CYGWIN* | MSYS*) file_conv=cygwin ;; *) file_conv=wine ;; esac fi case $file_conv/,$2, in *,$file_conv,*) ;; mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) file=`winepath -w "$file" || echo "$file"` ;; esac ;; esac } # func_cl_dashL linkdir # Make cl look for libraries in LINKDIR func_cl_dashL () { func_file_conv "$1" if test -z "$lib_path"; then lib_path=$file else lib_path="$lib_path;$file" fi linker_opts="$linker_opts -LIBPATH:$file" } # func_cl_dashl library # Do a library search-path lookup for cl func_cl_dashl () { lib=$1 found=no save_IFS=$IFS IFS=';' for dir in $lib_path $LIB do IFS=$save_IFS if $shared && test -f "$dir/$lib.dll.lib"; then found=yes lib=$dir/$lib.dll.lib break fi if test -f "$dir/$lib.lib"; then found=yes lib=$dir/$lib.lib break fi if test -f "$dir/lib$lib.a"; then found=yes lib=$dir/lib$lib.a break fi done IFS=$save_IFS if test "$found" != yes; then lib=$lib.lib fi } # func_cl_wrapper cl arg... # Adjust compile command to suit cl func_cl_wrapper () { # Assume a capable shell lib_path= shared=: linker_opts= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. eat=1 case $2 in *.o | *.[oO][bB][jJ]) func_file_conv "$2" set x "$@" -Fo"$file" shift ;; *) func_file_conv "$2" set x "$@" -Fe"$file" shift ;; esac ;; -I) eat=1 func_file_conv "$2" mingw set x "$@" -I"$file" shift ;; -I*) func_file_conv "${1#-I}" mingw set x "$@" -I"$file" shift ;; -l) eat=1 func_cl_dashl "$2" set x "$@" "$lib" shift ;; -l*) func_cl_dashl "${1#-l}" set x "$@" "$lib" shift ;; -L) eat=1 func_cl_dashL "$2" ;; -L*) func_cl_dashL "${1#-L}" ;; -static) shared=false ;; -Wl,*) arg=${1#-Wl,} save_ifs="$IFS"; IFS=',' for flag in $arg; do IFS="$save_ifs" linker_opts="$linker_opts $flag" done IFS="$save_ifs" ;; -Xlinker) eat=1 linker_opts="$linker_opts $2" ;; -*) set x "$@" "$1" shift ;; *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) func_file_conv "$1" set x "$@" -Tp"$file" shift ;; *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) func_file_conv "$1" mingw set x "$@" "$file" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -n "$linker_opts"; then linker_opts="-link$linker_opts" fi exec "$@" $linker_opts exit 1 } eat= case $1 in '') echo "$0: No command. Try '$0 --help' for more information." 1>&2 exit 1; ;; -h | --h*) cat <<\EOF Usage: compile [--help] [--version] PROGRAM [ARGS] Wrapper for compilers which do not understand '-c -o'. Remove '-o dest.o' from ARGS, run PROGRAM with the remaining arguments, and rename the output as expected. If you are trying to build a whole package this is not the right script to run: please start by reading the file 'INSTALL'. Report bugs to . EOF exit $? ;; -v | --v*) echo "compile $scriptversion" exit $? ;; cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac ofile= cfile= for arg do if test -n "$eat"; then eat= else case $1 in -o) # configure might choose to run compile as 'compile cc -o foo foo.c'. # So we strip '-o arg' only if arg is an object. eat=1 case $2 in *.o | *.obj) ofile=$2 ;; *) set x "$@" -o "$2" shift ;; esac ;; *.c) cfile=$1 set x "$@" "$1" shift ;; *) set x "$@" "$1" shift ;; esac fi shift done if test -z "$ofile" || test -z "$cfile"; then # If no '-o' option was seen then we might have been invoked from a # pattern rule where we don't need one. That is ok -- this is a # normal compilation that the losing compiler can handle. If no # '.c' file was seen then we are probably linking. That is also # ok. exec "$@" fi # Name of file we expect compiler to create. cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` # Create the lock directory. # Note: use '[/\\:.-]' here to ensure that we don't use the same name # that we are using for the .o file. Also, base the name on the expected # object file name, since that is what matters with a parallel build. lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d while true; do if mkdir "$lockdir" >/dev/null 2>&1; then break fi sleep 1 done # FIXME: race condition here if user kills between mkdir and trap. trap "rmdir '$lockdir'; exit 1" 1 2 15 # Run the compile. "$@" ret=$? if test -f "$cofile"; then test "$cofile" = "$ofile" || mv "$cofile" "$ofile" elif test -f "${cofile}bj"; then test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" fi rmdir "$lockdir" exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: keepalived-2.3.1/build-aux/install-sh0000755000175000017500000003577614215102164014463 00000000000000#!/bin/sh # install - install a program, script, or datafile scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 # Create dirs (including intermediate dirs) using mode 755. # This is like GNU 'install' as of coreutils 8.32 (2020). mkdir_umask=22 backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -p pass -p to $cpprog. -s $stripprog installed files. -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG By default, rm is invoked with -f; when overridden with RMPROG, it's up to you to specify -f if you want it. If -S is not specified, no backups are attempted. Email bug reports to bug-automake@gnu.org. Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; -S) backupsuffix="$2" shift;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? # Don't chown directories that already exist. if test $dstdir_status = 0; then chowncmd="" fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false # The $RANDOM variable is not portable (e.g., dash). Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap ' ret=$? rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null exit $ret ' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && { test -z "$stripcmd" || { # Create $dsttmp read-write so that cp doesn't create it read-only, # which would cause strip to fail. if test -z "$doit"; then : >"$dsttmp" # No need to fork-exec 'touch'. else $doit touch "$dsttmp" fi } } && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # If $backupsuffix is set, and the file being installed # already exists, attempt a backup. Don't worry if it fails, # e.g., if mv doesn't support -f. if test -n "$backupsuffix" && test -f "$dst"; then $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null fi # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: keepalived-2.3.1/doc/0000775000175000017500000000000014624033726011405 500000000000000keepalived-2.3.1/doc/source/0000775000175000017500000000000014451020261012671 500000000000000keepalived-2.3.1/doc/source/license.rst0000664000175000017500000000054213220013273014764 00000000000000####### License ####### Copyright (c) 2001-2015 Alexandre Cassen. This document is released under the terms of the GNU General Public Licence. You can redistribute it and/or modify it under the terms of the GNU General Public Licence as published by the Free Software Foundation; either version 2 of the Licence, or (at your option) any later version. keepalived-2.3.1/doc/source/case_study_failover.rst0000664000175000017500000001651413257461204017415 00000000000000############################### Case Study: Failover using VRRP ############################### As an example we can introduce the following LVS topology: Architecture Specification ************************** To create a virtual LVS director using the VRRPv2 protocol, we define the following architecture: * 2 LVS directors in active-active configuration. * 4 VRRP Instances per LVS director: 2 VRRP Instance in the MASTER state and 2 in BACKUP state. We use a symmetric state on each LVS directors. * 2 VRRP Instances in the same state are to be synchronized to define a persistent virtual routing path. * Strong authentication: IPSEC-AH is used to protect our VRRP advertisements from spoofed and reply attacks. The VRRP Instances are compounded with the following IP addresses: * VRRP Instance VI_1: owning VRRIP VIPs VIP1 & VIP2. This instance defaults to the MASTER state on LVS director 1. It stays synchronized with VI_2. * VRRP Instance VI_2: owning DIP1. This instance is by default in MASTER state on LVS director 1. It stays synchronized with VI_1. * VRRP Instance VI_3: owning VRRIP VIPs VIP3 & VIP4. This instance is in default MASTER state on LVS director 2. It stays synchronized with VI_4. * VRRP Instance VI_4: owning DIP2. This instance is in default MASTER state on LVS director 2. It stays synchronized with VI_3. Keepalived Configuration ************************ The whole configuration is done in the /etc/keepalived/keepalived.conf file. In our case study this file on LVS director 1 looks like:: vrrp_sync_group VG1 { group { VI_1 VI_2 } } vrrp_sync_group VG2 { group { VI_3 VI_4 } } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 150 advert_int 1 authentication { auth_type AH auth_pass k@l!ve1 } virtual_ipaddress { 192.168.200.10 192.168.200.11 } } vrrp_instance VI_2 { state MASTER interface eth1 virtual_router_id 52 priority 150 advert_int 1 authentication { auth_type AH auth_pass k@l!ve2 } virtual_ipaddress { 192.168.100.10 } } :: vrrp_instance VI_3 { state BACKUP interface eth0 virtual_router_id 53 priority 100 advert_int 1 authentication { auth_type AH auth_pass k@l!ve3 } virtual_ipaddress { 192.168.200.12 192.168.200.13 } } vrrp_instance VI_4 { state BACKUP interface eth1 virtual_router_id 54 priority 100 advert_int 1 authentication { auth_type AH auth_pass k@l!ve4 } virtual_ipaddress { 192.168.100.11 } } Then we define the symmetric configuration file on LVS director 2. This means that VI_3 & VI_4 on LVS director 2 are in MASTER state with a higher priority 150 to start with a stable state. Symmetrically VI_1 & VI_2 on LVS director 2 are in default BACKUP state with lower priority of 100. | This configuration file specifies 2 VRRP Instances per physical NIC. When you run Keepalived on LVS director 1 without running it on LVS director 2, LVS director 1 will own all the VRRP VIP. So if you use the ip utility you may see something like: (On Debian the ip utility is part of iproute):: [root@lvs1 tmp]# ip address list 1: lo: mtu 3924 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 brd 127.255.255.255 scope host lo 2: eth0: mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:00:5e:00:01:10 brd ff:ff:ff:ff:ff:ff inet 192.168.200.5/24 brd 192.168.200.255 scope global eth0 inet 192.168.200.10/32 scope global eth0 inet 192.168.200.11/32 scope global eth0 inet 192.168.200.12/32 scope global eth0 inet 192.168.200.13/32 scope global eth0 3: eth1: mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:00:5e:00:01:32 brd ff:ff:ff:ff:ff:ff inet 192.168.100.5/24 brd 192.168.201.255 scope global eth1 inet 192.168.100.10/32 scope global eth1 inet 192.168.100.11/32 scope global eth1 Then simply start Keepalived on the LVS director 2 and you will see:: [root@lvs1 tmp]# ip address list 1: lo: mtu 3924 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 brd 127.255.255.255 scope host lo 2: eth0: mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:00:5e:00:01:10 brd ff:ff:ff:ff:ff:ff inet 192.168.200.5/24 brd 192.168.200.255 scope global eth0 inet 192.168.200.10/32 scope global eth0 inet 192.168.200.11/32 scope global eth0 3: eth1: mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:00:5e:00:01:32 brd ff:ff:ff:ff:ff:ff inet 192.168.100.5/24 brd 192.168.201.255 scope global eth1 inet 192.168.100.10/32 scope global eth1 Symmetrically on LVS director 2 you will see:: [root@lvs2 tmp]# ip address list 1: lo: mtu 3924 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 brd 127.255.255.255 scope host lo 2: eth0: mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:00:5e:00:01:10 brd ff:ff:ff:ff:ff:ff inet 192.168.200.5/24 brd 192.168.200.255 scope global eth0 inet 192.168.200.12/32 scope global eth0 inet 192.168.200.13/32 scope global eth0 3: eth1: mtu 1500 qdisc pfifo_fast qlen 100 link/ether 00:00:5e:00:01:32 brd ff:ff:ff:ff:ff:ff inet 192.168.100.5/24 brd 192.168.201.255 scope global eth1 inet 192.168.100.11/32 scope global eth1 The VRRP VIPs are: * VIP1 = 192.168.200.10 * VIP2 = 192.168.200.11 * VIP3 = 192.168.200.12 * VIP4 = 192.168.200.13 * DIP1 = 192.168.100.10 * DIP2 = 192.168.100.11 The use of VRRP keyword “sync_instance†imply that we have defined a pair of MASTER VRRP Instance per LVS directors ó (VI_1,VI_2) & (VI_3,VI_4). This means that if eth0 on LVS director 1 fails then VI_1 enters the MASTER state on LVS director 2 so the MASTER Instance distribution on both directors will be: (VI_2) on director 1 & (VI_1,VI_3,VI_4) on director 2. We use “sync_instance†so VI_2 is forced to BACKUP the state on LVS director 1. The final VRRP MASTER instance distribution will be: (none) on LVS director 1 & (VI_1,VI_2,VI_3,VI_4) on LVS director 2. If eth0 on LVS director 1 became available the distribution will transition back to the initial state. For more details on this state transition please refer to the “Linux Virtual Server High Availability using VRRPv2†paper (available at http://www.linux-vs.org/~acassen/), which explains the implementation of this functionality. Using this configuration both LVS directors are active at a time, thus sharing LVS directors for a global director. That way we introduce a virtual LVS director. .. note:: This VRRP configuration sample is an illustration for a high availability router (not LVS specific). It can be used for many more common/simple needs. keepalived-2.3.1/doc/source/software_design.rst0000664000175000017500000003552714070347010016543 00000000000000############### Software Design ############### Keepalived is written in pure ANSI/ISO C. The software is articulated around a central I/O multiplexer that provides realtime networking design. The main design focus is to provide a homogenous modularity between all elements. This is why a core library was created to remove code duplication. The goal is to produce a safe and secure code, ensuring production robustness and stability. To ensure robustness and stability, daemon is split into 4 distinct processes: * A minimalistic parent process in charge with forked children process monitoring. * Up to three child processes, one responsible for VRRP framework, one for healthchecking and IPVS configuration, and one for BFD. Each child process has its own scheduling I/O multiplexer, that way VRRP scheduling jitter is optimized since VRRP and BFD scheduling are more sensitive/critical than healthcheckers. This split design minimalizes for healthchecking the usage of foreign libraries and minimalizes its own action down to an idle mainloop in order to avoid malfunctions caused by itself. The parent process monitoring framework is called watchdog. If the parent process detects that a child has terminated it simply restarts child process:: PID 111 Keepalived <-- Parent process monitoring children 112 \_ Keepalived <-- VRRP child 113 \_ Keepalived <-- Healthchecking child 114 \_ Keepalived <-- BFD child Kernel Components ***************** Keepalived uses four Linux kernel components: 1. LVS Framework: Uses the getsockopt and setsockopt calls to get and set options on sockets. #. Netfilter Framework: IPVS code that supports NAT and Masquerading. #. Netlink Interface: Sets and removes VRRP virtual IPs on network interfaces. #. Multicast: VRRP advertisements are sent to the reserved VRRP MULTICAST group (224.0.0.18). Atomic Elements *************** .. image:: images/software_design.png :align: center :scale: 80% :alt: keepalived software design Control Plane ============= Keepalived configuration is done through the file keepalived.conf. A compiler design is used for parsing. Parser work with a keyword tree hierarchy for mapping each configuration keyword with specifics handler. A central multi-level recursive function reads the configuration file and traverses the keyword tree. During parsing, configuration file is translated into an internal memory representation. Scheduler - I/O Multiplexer =========================== For each process, all the events are scheduled into the same process. Keepalived is network routing software, it is so close to I/O. The design used here is a central epoll_wait(...) that is in charge of scheduling all internal tasks. POSIX thread libs are NOT used. This framework provides its own thread abstraction optimized for networking purpose. Memory Management ================= This framework provides access to some generic memory management functions like allocation, reallocation, release,... This framework can be used in two modes: normal_mode & debug_mode. When using debug_mode it provides a strong way to eradicate and track memory leaks. This low-level env provides buffer under-run protection by tracking allocation and release of memory. All the buffers used are length fixed to prevent against eventual buffer-overflow. Core Components =============== This framework defines some common and global libraries that are used in all the code. Those libraries are html parsing, link-list, timer, vector, string formating, buffer dump, networking utils, daemon management, pid handling, low-level TCP layer4. The goal here is to factorize code to the max to limit as much as possible code duplication to increase modularity. Checkers ======== This is one of the main Keepalived functionality. Checkers are in charge of adding, removing and changing the weight of realservers. There are several types of checkers, most of which relate to realserver healthchecking. A checker tests if realserver is alive, this test either ends on a binary decision: remove or add realserver from/into the LVS topology, or changing the weight of the realserver. The internal checker design is realtime networking software, it uses a fully multi-threaded FSM design (Finite State Machine). This checker stack provides LVS topology manipulation according to layer4 to layer5/7 test results. It's run in an independent process monitored by the parent process. VRRP Stack ========== The other most important Keepalived functionality. VRRP (Virtual Router Redundancy Protocol: RFC2338/RFC3768/RFC5798) is focused on director takeover, it provides low-level design for router backup. It implements full IETF RFC5798 standard with some provisions and extensions for LVS and Firewall design (with legacy support for RFC2338, i.e. authentication). It implements the vrrp_sync_group extension that guarantees persistence routing path after protocol takeover. It implements IPSEC-AH using MD5-96bit crypto provision for securing protocol adverts exchange. For more information on VRRP please read the RFC. Important things: VRRP code can be used without the LVS support, it has been designed for independent use. It's run in an independent process monitored by parent process. BFD Stack ========== An implementation of BFD (Bidirectional Forwarding and Detection: RFC5880). This can be used by both the VRRP process as a tracker for VRRP instance(s) and by the checker process as a checker for realserver. It's run in an independent process monitored by parent process. System Call =========== This framework offers the ability to launch extra system script. It is mainly used in the MISC checker. In VRRP framework it provides the ability to launch extra script during protocol state transition. The system call is done into a forked process to not pertube the global scheduling timer. Netlink Reflector ================= Same as IPVS wrapper. Keepalived works with its own network interface representation. IP address and interface flags are set and monitored through kernel Netlink channel. The Netlink messaging sub-system is used for setting VRRP VIPs. On the other hand, the Netlink kernel messaging broadcast capability is used to reflect into our userspace Keepalived internal data representation any events related to interfaces. So any other userspace (others program) netlink manipulation is reflected our Keepalived data representation via Netlink Kernel broadcast (RTMGRP_LINK & RTMGRP_IPV4_IFADDR). SMTP ==== The SMTP protocol is used for administration notification. It implements the IETF RFC821 using a multi-threaded FSM design. Administration notifications are sent for healthcheckers activities and VRRP protocol state transition. SMTP is commonly used and can be interfaced with any other notification sub-system such as GSM-SMS, pagers, etc. IPVS Wrapper ============ This framework is used for sending rules to the Kernel IPVS code. It provides translation between Keepalived internal data representation and IPVS rule_user representation. It uses the IPVS libipvs to keep generic integration with IPVS code. IPVS ==== The Linux Kernel code provided by Wensong from LinuxVirtualServer.org OpenSource Project. IPVS (IP Virtual Server) implements transport-layer load balancing inside the Linux kernel, also referred to as Layer-4 switching. NETLINK ======= The Linux Kernel code provided by Alexey Kuznetov with its very nice advanced routing framework and sub-system capabilities. Netlink is used to transfer information between kernel and user-space processes. It consists of a standard sockets-based interface for userspace processes and an internal kernel API for kernel modules. Syslog ====== All keepalived daemon notification messages are logged using the syslog service. Healthcheck Framework ********************* Each health check is registered to the global scheduling framework. These health check worker threads implement the following types of health checks: .. glossary:: TCP_CHECK Working at layer4. To ensure this check, we use a TCP Vanilla check using nonblocking/timed-out TCP connections. If the remote server does not reply to this request (timed-out), then the test is wrong and the server is removed from the server pool. HTTP_GET Working at layer5. Performs a HTTP GET to a specified URL. The HTTP GET result is then summed using the MD5 algorithm. If this sum does not match with the expected value, the test is wrong and the server is removed from the server pool. This module implements a multi-URL get check on the same service. This functionality is useful if you are using a server hosting more than one application servers. This functionality gives you the ability to check if an application server is working properly. The MD5 digests are generated using the genhash utility (included in the keepalived package). SSL_GET Same as HTTP_GET but uses a SSL connection to the remote webservers. MISC_CHECK This check allows a user-defined script to be run as the health checker. The result must be 0 or 1. The script is run on the director box and this is an ideal way to test in-house applications. Scripts that can be run without arguments can be called using the full path (i.e. /path_to_script/script.sh). Those requiring arguments need to be enclosed in double quotes (i.e. “/path_to_script/script.sh arg 1 ... arg n â€) SMTP_CHECK This check ensures that an SMTP server can be connected to and the initial SMTP handshake completed. DNS_CHECK This check queries a DNS server for the configured name of the specified type (e.g. A, AAAA, MX record). BFD_CHECK This is updated by the BFD process, and allows a realserver to be removed if the BFD session goes down. UDP_CHECK This check sends a UDP packet to the specified remote host/port. It can be configured to require a specific response, or to fail if an ICMP error is returned. PING_CHECK This check sends and ICMP echo request and will fail if an appropriate ICMP echo response is not received. FILE_CHECK This check monitors a file using inotify(). If the file is modified or created, its contents are read and interpreted as a numeric value. This can either indicate the realserver should be removed, or its weight changed, depending on the configuration. The goal for Keepalived is to define a generic framework easily extensible for adding new checkers modules. If you are interested in the development of existing or new checkers, have a look at the *keepalived/check* and *keepalived/trackers* directories in the source: https://github.com/acassen/keepalived/tree/master/keepalived/check Failover (VRRP) Framework ************************* Keepalived implements the VRRP protocol for director failover. Within the implemented VRRP stack, the VRRP Packet dispatcher is responsible for demultiplexing specific I/O for each VRRP instance. From RFC5798, VRRP is defined as:: “VRRP specifies an election protocol that dynamically assigns responsibility for a virtual router to one of the VRRP routers on a LAN. The VRRP router controlling the IPv4 or IPv6 address(es) associated with a virtual router is called the Master, and it forwards packets sent to these IPv4 or IPv6 addresses. VRRP Master routers are configured with virtual IPv4 or IPv6 addresses, and VRRP Backup routers infer the address family of the virtual addresses being carried based on the transport protocol. Within a VRRP router, the virtual routers in each of the IPv4 and IPv6 address families are a domain unto themselves and do not overlap. The election process provides dynamic failover in the forwarding responsibility should the Master become unavailable. For IPv4, the advantage gained from using VRRP is a higher-availability default path without requiring configuration of dynamic routing or router discovery protocols on every end-host. For IPv6, the advantage gained from using VRRP for IPv6 is a quicker switchover to Backup routers than can be obtained with standard IPv6 Neighbor Discovery mechanisms.†[rfc5798] .. note:: This framework is LVS independent, so you can use it for LVS director failover, even for other Linux routers needing a Hot-Standby protocol. This framework has been completely integrated in the Keepalived daemon for design & robustness reasons. The main functionalities provided by this framework are: * Failover: The native VRRP protocol purpose, based on a roaming set of VRRP VIPs. * VRRP Instance synchronization: We can specify a state monitoring between 2 or more VRRP Instances, also known as a *VRRP sync group*. It guarantees that the VRRP Instances remain in the same state. The synchronized instances monitor each other. * Nice Fallback * Advert Packet integrity: Using IPSEC-AH ICV. * System call: During a VRRP state transition, an external script/program may be called. Note on Using VRRP with Virtual MAC Address =========================================== To reduce takeover impact, some networking environment would require using VRRP with VMAC address. To reach that goal Keepalived VRRP framework implements VMAC support by the invocation of 'use_vmac' keyword in configuration file. Internally, Keepalived code will bring up virtual interfaces, each interface dedicated to a specific virtual_router. Keepalived uses Linux kernel macvlan driver to defines these interfaces. It is then mandatory to use kernel compiled with macvlan support. By default MACVLAN interface are in VEPA mode which filters out received packets whose MAC source address matches that of the MACVLAN interface. Setting MACVLAN interface in private mode will not filter based on source MAC address. Alternatively, you can specify 'vmac_xmit_base' which will cause the VRRP messages to be transmitted and received on the underlying interface whilst ARP will happen from the VMAC interface. You may also need to tweak your physical interfaces to play around with well known ARP issues. Keepalived sets the following configuration when using VMACs: 1) Global configuration:: net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 1 net.ipv4.conf.all.arp_filter = 0 2) Physical interface configuration For the physical ethernet interface running VRRP instance use:: net.ipv4.conf.eth0.arp_filter = 1 3) VMAC interface consider the following VRRP configuration:: vrrp_instance instance1 { state BACKUP interface eth0 virtual_router_id 250 use_vmac vmac_xmit_base # Transmit VRRP adverts over physical interface priority 150 advert_int 1 virtual_ipaddress { 10.0.0.254 } } The ``use_vmac`` keyword will drive keepalived code to create a macvlan interface named *vrrp.250* (default internal paradigm is vrrp.{virtual_router_id}, you can override this naming by giving an argument to 'use_vmac' keyword, eg: use_vmac vrrp250). keepalived-2.3.1/doc/source/protocol_support.rst0000664000175000017500000000123013263401262017000 00000000000000##################### IPVS Protocol Support ##################### IPVS Transport Protocol Load Balancing Support ********************************************** IPVS supports load balancing the following transport protocols: * TCP * UDP * SCTP * ESP (Encapsulation Security Payload) * AH (Authentication Header) IPVS Application Helpers ************************ FTP Protocol Helper =================== Netfilter Connection Tracking ============================= SIP Persistence Engine ====================== Depends on UDP and SIP netfilter connection tracking. .. todo:: Mention Netfilter Connection Tracking .. todo:: Mention ipip kernel module keepalived-2.3.1/doc/source/conf.py0000664000175000017500000002236013274320716014125 00000000000000# -*- coding: utf-8 -*- # # Keepalived documentation build configuration file, created by # sphinx-quickstart on Mon Dec 29 18:59:45 2014. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. import sys import os import time # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. #sys.path.insert(0, os.path.abspath('.')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. #needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ 'sphinx.ext.todo', ] # Support for todo items todo_include_todos = True # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix of source filenames. source_suffix = '.rst' # The encoding of source files. #source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = u'Keepalived' copyright = u'2001-%s, Alexandre Cassen' % time.strftime('%Y') # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '1.3' # The full version, including alpha/beta/rc tags. release = '1.4.3' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. #language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: today = '' # Else, today_fmt is used as the format for a strftime call. today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. exclude_patterns = [] # The reST default role (used for this markup: `text`) to use for all # documents. #default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. #add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). #add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. #show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. #keep_warnings = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. html_theme = 'sphinx_rtd_theme' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. #html_theme_options = {'collapsiblesidebar': True} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = ['tools'] #html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. html_short_title = '%s %s User Guide' % (project, release) # The name of an image file (relative to this directory) to place at the top # of the sidebar. #html_logo = None # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. #html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. #html_extra_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. #html_last_updated_fmt = '%b %d, %Y' # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. #html_use_smartypants = True # Custom sidebar templates, maps document names to template names. #html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. #html_additional_pages = {} # If false, no module index is generated. #html_domain_indices = True # If false, no index is generated. #html_use_index = True # If true, the index is split into individual pages for each letter. #html_split_index = False # If true, links to the reST sources are added to the pages. html_show_sourcelink = False # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. #html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. #html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). #html_file_suffix = None # Output file base name for HTML help builder. htmlhelp_basename = 'Keepaliveddoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). #'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). #'pointsize': '10pt', # Additional stuff for the LaTeX preamble. #'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ ('index', 'Keepalived_UserGuide.tex', u'Keepalived User Guide', u'Alexandre Cassen and Contributors', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. #latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. #latex_use_parts = False # If true, show page references after internal links. #latex_show_pagerefs = False # If true, show URL addresses after external links. #latex_show_urls = False # Documents to append as an appendix to all manuals. #latex_appendices = [] # If false, no module index is generated. #latex_domain_indices = True # -- Options for Epub output ---------------------------------------------- # Bibliographic Dublin Core info. epub_title = u'Keepalived User Guide' epub_author = u'Alexandre Cassen and Contributors' epub_publisher = u'Alexandre Cassen and Contributors' epub_copyright = u'%s, Alexandre Cassen' % time.strftime('%Y') # The basename for the epub file. It defaults to the project name. #epub_basename = u'Keepalived' # The HTML theme for the epub output. Since the default themes are not optimized # for small screen space, using the same theme for HTML and epub output is # usually not wise. This defaults to 'epub', a theme designed to save visual # space. #epub_theme = 'epub' # The language of the text. It defaults to the language option # or en if the language is not set. #epub_language = '' # The scheme of the identifier. Typical schemes are ISBN or URL. #epub_scheme = '' # The unique identifier of the text. This can be a ISBN number # or the project homepage. #epub_identifier = '' # A unique identification for the text. #epub_uid = '' # A tuple containing the cover image and cover page html template filenames. #epub_cover = () # A sequence of (type, uri, title) tuples for the guide element of content.opf. #epub_guide = () # HTML files that should be inserted before the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_pre_files = [] # HTML files shat should be inserted after the pages created by sphinx. # The format is a list of tuples containing the path and title. #epub_post_files = [] # A list of files that should not be packed into the epub file. epub_exclude_files = ['search.html'] # The depth of the table of contents in toc.ncx. #epub_tocdepth = 3 # Allow duplicate toc entries. #epub_tocdup = True # Choose between 'default' and 'includehidden'. #epub_tocscope = 'default' # Fix unsupported image types using the PIL. #epub_fix_images = False # Scale large images. #epub_max_image_width = 0 # How to display URL addresses: 'footnote', 'no', or 'inline'. #epub_show_urls = 'inline' # If false, no index is generated. #epub_use_index = True keepalived-2.3.1/doc/source/_static/0000775000175000017500000000000014105735173014332 500000000000000keepalived-2.3.1/doc/source/_static/.gitignore0000664000175000017500000000000012635650721016231 00000000000000keepalived-2.3.1/doc/source/_static/.gitkeep0000664000175000017500000000000012635650721015672 00000000000000keepalived-2.3.1/doc/source/snmp_support.rst0000664000175000017500000001024513220013273016114 00000000000000######################## Configuring SNMP Support ######################## Keepalived provides an SNMP subsystem that can gather various metrics about the VRRP stack and the health checker system. The keepalived MIB is in the ``doc`` directory of the project. The base SNMP OID for the MIB is `.1.3.6.1.4.1.9586.100.5`, which is hosted under the `Debian OID space`_ assigned by IANA. .. _Debian OID space: https://dsa.debian.org/iana/ Prerequisites ************* Install the SNMP protocol tools and libraries onto your system. This requires the installation of a few packages:: yum install net-snmp net-snmp-utils net-snmp-libs Once SNMP has been installed on your system, configure keepalived with SNMP support. When compiling keepalived, add the ``--enable-snmp`` configure option. For example:: ./configure --enable-snmp During the configure step of the compiling process, you will get a configuration summary before building with ``make``. For example, you may see similar output on a CentOS 6 machine:: ./configure --prefix=/usr/local/keepalived-1.2.15 --enable-snmp Keepalived configuration ------------------------ Keepalived version : 1.2.15 Compiler : gcc Compiler flags : -g -O2 -I/usr/include/libnl3 Extra Lib : -Wl,-z,relro -Wl,-z,now -L/usr/lib64 -lnetsnmpagent -lnetsnmphelpers -lnetsnmpmibs -lnetsnmp -Wl,-E -Wl,-rpath,/usr/lib64/perl5/CORE -lssl -lcrypto -lcrypt -lnl-genl-3 -lnl-3 Use IPVS Framework : Yes IPVS sync daemon support : Yes IPVS use libnl : Yes fwmark socket support : Yes Use VRRP Framework : Yes Use VRRP VMAC : Yes SNMP support : Yes SHA1 support : No Use Debug flags : No Notice the *Extra Lib* section of the configuration summary. It lists various library flags that gcc will use to build keepalived, several of which have to do with SNMP. Configuring Support ******************* Enable SNMP AgentX support by including the following line in the SNMP daemon configuration file, typically ``/etc/snmp/snmpd.conf`` if you installed via RPMs on a CentOS machine:: master agentx .. note:: Be sure to reload or restart the SNMP service for the configuration change to take effect. Adding the MIB ************** You can query keepalived SNMP managed objects by using the OID. For example:: snmpwalk -v2c -c public localhost .1.3.6.1.4.1.9586.100.5.1.1.0 SNMPv2-SMI::enterprises.9586.100.5.1.1.0 = STRING: "Keepalived v1.2.15 (01/10,2015)" Alternatively, with the keepalived MIB, you can query using the MIB available from the project. First, copy the MIB to the system's global MIB directory or to the user's local MIB directory:: cp /usr/local/src/keepalived-1.2.15/doc/KEEPALIVED-MIB /usr/share/snmp/mibs or:: cp /usr/local/src/keepalived-1.2.15/doc/KEEPALIVED-MIB ~/.snmp/mibs The SNMP daemon will check both directories for the existence of the MIB. Once the MIB is in place, the SNMP query can look as follows:: snmpwalk -v2c -c public localhost KEEPALIVED-MIB::version KEEPALIVED-MIB::version.0 = STRING: Keepalived v1.2.15 (01/10,2015) MIB Overview ************ There are four main sections to the keepalived MIB: * global * vrrp * check * conformance Global ====== The global section includes objects that contain information about the keepalived instance such as version, router ID and administrative email addresses. VRRP ==== The VRRP section includes objects that contain information about each configured VRRP instance. Within each instance, there are objects that include instance name, current state, and virtual IP addresses. Check ===== The Check section includes objects that contain information about each configured virtual server. It includes server tables for virtual and real servers and also configured load balancing algorithms, load balancing method, protocol, status, real and virtual server network connection statistics. Conformance =========== .. todo:: do conformance .. note:: Use a MIB browser, such as mbrowse, to see what managed objects are available to query for monitoring the health of your LVS servers. keepalived-2.3.1/doc/source/installing_keepalived.rst0000664000175000017500000001140314373712662017717 00000000000000##################### Installing Keepalived ##################### Install keepalived from the distribution's repositories or, alternatively, compile from source. Although installing from the repositories is generally the fastest way to get keepalived running on a system, the version of keepalived available in the repositories are typically a few releases behind the latest available stable version. Installing from the Repositories ******************************** Installing on Red Hat Enterprise Linux ====================================== As of Red Hat 6.4, Red Hat and the clones have included the keepalived package in the base repository. Therefore, run the following to install the keepalived package and all the required dependencies using dnf (or yum on older systems):: dnf install keepalived Installing on Debian ==================== Run the following to install the keepalived package and all the required dependencies using Debian's APT package handling utility:: apt-get install keepalived Compiling and Building from Source ********************************** In order to run the latest stable version, compile keepalived from source. Compiling keepalived requires a compiler, OpenSSL and the Netlink Library. You may optionally install Net-SNMP, which is required for SNMP support. Install Prerequisites on RHEL/CentOS/Fedora =========================================== On RHEL, Centos, Fedora etc install the following prerequisites (on older systems replace dnf with yum):: dnf install gcc make autoconf automake openssl-devel libnl3-devel \ iptables-devel ipset-devel net-snmp-devel libnfnetlink-devel file-devel \ glib2-devel pcre2-revel libnftnl-devel libmnl-devel systemd-devel kmod-devel For DBUS support:: dnf install glib2-devel For JSON support:: dnf install json-c-devel Note: On RHEL the codeready-builder-for-rhel-8-x86_64-rpms (or equivalent) repo needs to be enabled, and on CentOS the PowerTools repo is needed. Install Prerequisites on Debian/Ubuntu ====================================== On Debian/Ubuntu, install the following prerequisites:: apt-get install build-essential pkg-config curl gcc autoconf automake libssl-dev \ libnl-3-dev libnl-genl-3-dev libsnmp-dev libnl-route-3-dev libnfnetlink-dev \ iptables-dev* libipset-dev libsnmp-dev libmagic-dev libglib2.0-dev libpcre2-dev \ libnftnl-dev libmnl-dev libsystemd-dev libkmod-dev * on more recent versions replace iptables-dev with libxtables-dev libip4tc-dev libip6tc-dev For DBUS support:: dnf install libglib2.0-dev Install Prerequisites on Alpine Linux ===================================== On Alpine Linux install the following prerequisites:: autoconf automake iptables-dev ipset-dev libnfnetlink-dev libnl3-dev musl-dev libnftnl-dev file-dev pcre2-dev and openssl-dev or libressl-dev For SNMP support:: net-snmp-dev (requires libressl-dev and not openssl-dev) Install Prerequisites on Archlinux ================================== On Archlinux run the following to install the required libraries:: pacman -S ipset libnfnetlink libnl1 pcre-2 For SNMP support:: pacman -S net-snmp Build and Install ================= Use *curl* or any other transfer tool such as *wget* to download keepalived. The software is available at http://www.keepalived.org/download.html or https://github.com/acassen/keepalived. Then, compile the package:: curl --location --progress http://keepalived.org/software/keepalived-1.2.15.tar.gz | tar xz cd keepalived-1.2.15 ./build_setup ./configure make sudo make install It is a general recommendation when compiling from source to specify a PREFIX. For example:: ./configure --prefix=/usr/local/keepalived-1.2.15 This makes it easy to uninstall a compiled version of keepalived simply by deleting the parent directory. Additionally, this method of installation allows for multiple versions of Keepalived installed without overwriting each other. Use a symlink to point to the desired version. For example, your directory layout could look like this:: [root@lvs1 ~]# cd /usr/local [root@lvs1 local]# ls -l total 12 lrwxrwxrwx. 1 root root 17 Feb 24 20:23 keepalived -> keepalived-1.2.15 drwxr-xr-x. 2 root root 4096 Feb 24 20:22 keepalived-1.2.13 drwxr-xr-x. 2 root root 4096 Feb 24 20:22 keepalived-1.2.14 drwxr-xr-x. 2 root root 4096 Feb 24 20:22 keepalived-1.2.15 Setup Init Scripts ================== After compiling, create an init script in order to control the keepalived daemon. On RHEL:: ln -s /etc/rc.d/init.d/keepalived.init /etc/rc.d/rc3.d/S99keepalived On Debian:: ln -s /etc/init.d/keepalived.init /etc/rc2.d/S99keepalived Note: The link should be added in your default run level directory. keepalived-2.3.1/doc/source/tools/0000775000175000017500000000000014105735173014044 500000000000000keepalived-2.3.1/doc/source/tools/pydoctheme/0000775000175000017500000000000014105735173016205 500000000000000keepalived-2.3.1/doc/source/tools/pydoctheme/static/0000775000175000017500000000000014105735173017474 500000000000000keepalived-2.3.1/doc/source/tools/pydoctheme/static/pydoctheme.css0000664000175000017500000000526712635650721022302 00000000000000@import url("default.css"); body { background-color: white; margin-left: 1em; margin-right: 1em; } div.related { margin-bottom: 1.2em; padding: 0.5em 0; border-top: 1px solid #ccc; margin-top: 0.5em; } div.related a:hover { color: #0095C4; } div.related:first-child { border-top: 0; border-bottom: 1px solid #ccc; } div.sphinxsidebar { background-color: #eeeeee; border-radius: 5px; line-height: 130%; font-size: smaller; } div.sphinxsidebar h3, div.sphinxsidebar h4 { margin-top: 1.5em; } div.sphinxsidebarwrapper > h3:first-child { margin-top: 0.2em; } div.sphinxsidebarwrapper > ul > li > ul > li { margin-bottom: 0.4em; } div.sphinxsidebar a:hover { color: #0095C4; } div.sphinxsidebar input { font-family: 'Lucida Grande',Arial,sans-serif; border: 1px solid #999999; font-size: smaller; border-radius: 3px; } div.sphinxsidebar input[type=text] { max-width: 150px; } div.body { padding: 0 0 0 1.2em; } div.body p { line-height: 140%; } div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6 { margin: 0; border: 0; padding: 0.3em 0; } div.body hr { border: 0; background-color: #ccc; height: 1px; } div.body pre { border-radius: 3px; border: 1px solid #ac9; } div.body div.admonition, div.body div.impl-detail { border-radius: 3px; } div.body div.impl-detail > p { margin: 0; } div.body div.seealso { border: 1px solid #dddd66; } div.body a { color: #0072aa; } div.body a:visited { color: #6363bb; } div.body a:hover { color: #00B0E4; } tt, code, pre { font-family: monospace, sans-serif; font-size: 96.5%; } div.body tt, div.body code { border-radius: 3px; } div.body tt.descname, div.body code.descname { font-size: 120%; } div.body tt.xref, div.body a tt, div.body code.xref, div.body a code { font-weight: normal; } .deprecated { border-radius: 3px; } table.docutils { border: 1px solid #ddd; min-width: 20%; border-radius: 3px; margin-top: 10px; margin-bottom: 10px; } table.docutils td, table.docutils th { border: 1px solid #ddd !important; border-radius: 3px; } table p, table li { text-align: left !important; } table.docutils th { background-color: #eee; padding: 0.3em 0.5em; } table.docutils td { background-color: white; padding: 0.3em 0.5em; } table.footnote, table.footnote td { border: 0 !important; } div.footer { line-height: 150%; margin-top: -2em; text-align: right; width: auto; margin-right: 10px; } div.footer a:hover { color: #0095C4; } .refcount { color: #060; } .stableabi { color: #229; } keepalived-2.3.1/doc/source/tools/pydoctheme/theme.conf0000664000175000017500000000102312635650721020073 00000000000000[theme] inherit = default stylesheet = pydoctheme.css pygments_style = sphinx [options] bodyfont = 'Lucida Grande', Arial, sans-serif headfont = 'Lucida Grande', Arial, sans-serif footerbgcolor = white footertextcolor = #555555 relbarbgcolor = white relbartextcolor = #666666 relbarlinkcolor = #444444 sidebarbgcolor = white sidebartextcolor = #444444 sidebarlinkcolor = #444444 bgcolor = white textcolor = #222222 linkcolor = #0090c0 visitedlinkcolor = #00608f headtextcolor = #1a1a1a headbgcolor = white headlinkcolor = #aaaaaa keepalived-2.3.1/doc/source/case_study_mixing.rst0000664000175000017500000000765613167617067017122 00000000000000######################################### Case Study: Mixing Healthcheck & Failover ######################################### For this example, we use the same topology used in the Failover part. The idea here is to use VRRP VIPs as LVS VIPs. That way we will introduce a High Available LVS director performing LVS real server pool monitoring. Keepalived Configuration ************************ The whole configuration is done in the /etc/keepalived/keepalived.conf file. In our case study this file on LVS director 1 looks like:: # Configuration File for keepalived global_defs { notification_email { admin@domain.com 0633225522@domain.com } notification_email_from keepalived@domain.com smtp_server 192.168.200.20 smtp_connect_timeout 30 lvs_id LVS_MAIN } # VRRP Instances definitions vrrp_sync_group VG1 { group { VI_1 VI_2 } } vrrp_sync_group VG2 { group { VI_3 VI_4 } } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 150 advert_int 1 authentication { auth_type PASS auth_pass k@l!ve1 } virtual_ipaddress { 192.168.200.10 192.168.200.11 } } vrrp_instance VI_2 { state MASTER interface eth1 virtual_router_id 52 priority 150 advert_int 1 authentication { auth_type PASS auth_pass k@l!ve2 } virtual_ipaddress { 192.168.100.10 } } vrrp_instance VI_3 { state BACKUP interface eth0 virtual_router_id 53 priority 100 advert_int 1 authentication { auth_type PASS auth_pass k@l!ve3 } virtual_ipaddress { 192.168.200.12 192.168.200.13 } } vrrp_instance VI_4 { state BACKUP interface eth1 virtual_router_id 54 priority 100 advert_int 1 authentication { auth_type PASS auth_pass k@l!ve4 } virtual_ipaddress { 192.168.100.11 } } # Virtual Servers definitions virtual_server 192.168.200.10 80 { delay_loop 30 lb_algo wrr lb_kind NAT persistence_timeout 50 protocol TCP sorry_server 192.168.100.100 80 real_server 192.168.100.2 80 { weight 2 HTTP_GET { url { path /testurl/test.jsp digest ec90a42b99ea9a2f5ecbe213ac9eba03 } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 retry 3 delay_before_retry 2 } } real_server 192.168.100.3 80 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 retry 3 delay_before_retry 2 } } } virtual_server 192.168.200.12 443 { delay_loop 20 lb_algo rr lb_kind NAT persistence_timeout 360 protocol TCP real_server 192.168.100.2 443 { weight 1 TCP_CHECK { connect_timeout 3 } } real_server 192.168.100.3 443 { weight 1 TCP_CHECK { connect_timeout 3 } } } We define the symmetric VRRP configuration file on LVS director 2. That way both directors are active at a time, director 1 handling HTTP stream and director 2 SSL stream. keepalived-2.3.1/doc/source/programs_synopsis.rst0000664000175000017500000001707513334344241017164 00000000000000############################ Keepalived programs synopsis ############################ Keepalived package comes with 2 programs. keepalived daemon ***************** The keepalived command line arguments are: .. glossary:: -f, --use-file=FILE Use the specified configuration file. The default configuration file is "/etc/keepalived/keepalived.conf". -P, --vrrp Only run the VRRP subsystem. This is useful for configurations that do not use IPVS load balancer. -C, --check Only run the healthcheck subsystem. This is useful for configurations that use the IPVS load balancer with a single director with no failover. -l, --log-console Log messages to the local console. The default behavior is to log messages to syslog. -D, --log-detail Detailed log messages. -S, --log-facility=[0-7] Set syslog facility to LOG_LOCAL[0-7]. The default syslog facility is LOG_DAEMON. -V, --dont-release-vrrp Don’t remove VRRP VIPs and VROUTEs on daemon stop. The default behavior is to remove all VIPs and VROUTEs when keepalived exits -I, --dont-release-ipvs Don’t remove IPVS topology on daemon stop. The default behavior is to remove all entries from the IPVS virtual server table on when keepalived exits. -R, --dont-respawn Don’t respawn child processes. The default behavior is to restart the VRRP and checker processes if either process exits. -n, --dont-fork Don’t fork the daemon process. This option will cause keepalived to run in the foreground. -d, --dump-conf Dump the configuration data. -p, --pid=FILE Use specified pidfile for parent keepalived process. The default pidfile for keepalived is "/var/run/keepalived.pid". -r, --vrrp_pid=FILE Use specified pidfile for VRRP child process. The default pidfile for the VRRP child process is "/var/run/keepalived_vrrp.pid". -c, --checkers_pid=FILE Use specified pidfile for checkers child process. The default pidfile for the checker child process is "/var/run/keepalived_checkers.pid". -x, --snmp Enable SNMP subsystem. -v, --version Display the version and exit. -h, --help Display this help message and exit. genhash utility *************** The ``genhash`` binary is used to generate digest strings. The genhash command line arguments are: .. glossary:: --use-ssl, -S Use SSL to connect to the server. --server , -s Specify the ip address to connect to. --port , -p Specify the port to connect to. --url , -u Specify the path to the file you want to generate the hash of. --use-virtualhost , -V Specify the virtual host to send along with the HTTP headers. --hash , -H Specify the hash algorithm to make a digest of the target page. Consult the help screen for list of available ones with a mark of the default one. --verbose, -v Be verbose with the output. --help, -h Display the program help screen and exit. --release, -r Display the release number (version) and exit. Running Keepalived daemon ************************* To run Keepalived simply type:: [root@lvs tmp]# /etc/rc.d/init.d/keepalived.init start Starting Keepalived for LVS: [ OK ] All daemon messages are logged through the Linux syslog. If you start Keepalived with the “dump configuration data†option, you should see in your /var/log/messages (on Debian this may be */var/log/daemon.log* depending on your syslog configuration) something like this:: Jun 7 18:17:03 lvs1 Keepalived: Starting Keepalived v0.6.1 (06/13, 2002) Jun 7 18:17:03 lvs1 Keepalived: Configuration is using : 92013 Bytes Jun 7 18:17:03 lvs1 Keepalived: ------< Global definitions >------ Jun 7 18:17:03 lvs1 Keepalived: LVS ID = LVS_PROD Jun 7 18:17:03 lvs1 Keepalived: Smtp server = 192.168.200.1 Jun 7 18:17:03 lvs1 Keepalived: Smtp server connection timeout = 30 Jun 7 18:17:03 lvs1 Keepalived: Email notification from = keepalived@domain.com Jun 7 18:17:03 lvs1 Keepalived: Email notification = alert@domain.com Jun 7 18:17:03 lvs1 Keepalived: Email notification = 0633556699@domain.com Jun 7 18:17:03 lvs1 Keepalived: ------< SSL definitions >------ Jun 7 18:17:03 lvs1 Keepalived: Using autogen SSL context Jun 7 18:17:03 lvs1 Keepalived: ------< LVS Topology >------ Jun 7 18:17:03 lvs1 Keepalived: System is compiled with LVS v0.9.8 Jun 7 18:17:03 lvs1 Keepalived: VIP = 10.10.10.2, VPORT = 80 Jun 7 18:17:03 lvs1 Keepalived: VirtualHost = www.domain1.com Jun 7 18:17:03 lvs1 Keepalived: delay_loop = 6, lb_algo = rr Jun 7 18:17:03 lvs1 Keepalived: persistence timeout = 50 Jun 7 18:17:04 lvs1 Keepalived: persistence granularity = 255.255.240.0 Jun 7 18:17:04 lvs1 Keepalived: protocol = TCP Jun 7 18:17:04 lvs1 Keepalived: lb_kind = NAT Jun 7 18:17:04 lvs1 Keepalived: sorry server = 192.168.200.200:80 Jun 7 18:17:04 lvs1 Keepalived: RIP = 192.168.200.2, RPORT = 80, WEIGHT = 1 Jun 7 18:17:04 lvs1 Keepalived: RIP = 192.168.200.3, RPORT = 80, WEIGHT = 2 Jun 7 18:17:04 lvs1 Keepalived: VIP = 10.10.10.3, VPORT = 443 Jun 7 18:17:04 lvs1 Keepalived: VirtualHost = www.domain2.com Jun 7 18:17:04 lvs1 Keepalived: delay_loop = 3, lb_algo = rr Jun 7 18:17:04 lvs1 Keepalived: persistence timeout = 50 Jun 7 18:17:04 lvs1 Keepalived: protocol = TCP Jun 7 18:17:04 lvs1 Keepalived: lb_kind = NAT Jun 7 18:17:04 lvs1 Keepalived: RIP = 192.168.200.4, RPORT = 443, WEIGHT = 1 Jun 7 18:17:04 lvs1 Keepalived: RIP = 192.168.200.5, RPORT = 1358, WEIGHT = 1 Jun 7 18:17:05 lvs1 Keepalived: ------< Health checkers >------ Jun 7 18:17:05 lvs1 Keepalived: 192.168.200.2:80 Jun 7 18:17:05 lvs1 Keepalived: Keepalive method = HTTP_GET Jun 7 18:17:05 lvs1 Keepalived: Connection timeout = 3 Jun 7 18:17:05 lvs1 Keepalived: Nb get retry = 3 Jun 7 18:17:05 lvs1 Keepalived: Delay before retry = 3 Jun 7 18:17:05 lvs1 Keepalived: Checked url = /testurl/test.jsp, Jun 7 18:17:05 lvs1 Keepalived: digest = 640205b7b0fc66c1ea91c463fac6334d Jun 7 18:17:05 lvs1 Keepalived: 192.168.200.3:80 Jun 7 18:17:05 lvs1 Keepalived: Keepalive method = HTTP_GET Jun 7 18:17:05 lvs1 Keepalived: Connection timeout = 3 Jun 7 18:17:05 lvs1 Keepalived: Nb get retry = 3 Jun 7 18:17:05 lvs1 Keepalived: Delay before retry = 3 Jun 7 18:17:05 lvs1 Keepalived: Checked url = /testurl/test.jsp, Jun 7 18:17:05 lvs1 Keepalived: digest = 640205b7b0fc66c1ea91c463fac6334c Jun 7 18:17:05 lvs1 Keepalived: Checked url = /testurl2/test.jsp, Jun 7 18:17:05 lvs1 Keepalived: digest = 640205b7b0fc66c1ea91c463fac6334c Jun 7 18:17:06 lvs1 Keepalived: 192.168.200.4:443 Jun 7 18:17:06 lvs1 Keepalived: Keepalive method = SSL_GET Jun 7 18:17:06 lvs1 Keepalived: Connection timeout = 3 Jun 7 18:17:06 lvs1 Keepalived: Nb get retry = 3 Jun 7 18:17:06 lvs1 Keepalived: Delay before retry = 3 Jun 7 18:17:06 lvs1 Keepalived: Checked url = /testurl/test.jsp, Jun 7 18:17:05 lvs1 Keepalived: digest = 640205b7b0fc66c1ea91c463fac6334d Jun 7 18:17:06 lvs1 Keepalived: Checked url = /testurl2/test.jsp, Jun 7 18:17:05 lvs1 Keepalived: digest = 640205b7b0fc66c1ea91c463fac6334d Jun 7 18:17:06 lvs1 Keepalived: 192.168.200.5:1358 Jun 7 18:17:06 lvs1 Keepalived: Keepalive method = TCP_CHECK Jun 7 18:17:06 lvs1 Keepalived: Connection timeout = 3 Jun 7 18:17:06 lvs1 Keepalived: Registering Kernel netlink reflector keepalived-2.3.1/doc/source/_templates/0000775000175000017500000000000014105735173015041 500000000000000keepalived-2.3.1/doc/source/_templates/.gitignore0000664000175000017500000000000012635650721016740 00000000000000keepalived-2.3.1/doc/source/_templates/.gitkeep0000664000175000017500000000000012635650721016401 00000000000000keepalived-2.3.1/doc/source/about.rst0000664000175000017500000000230513220013273014453 00000000000000##################### About These Documents ##################### These documents are generated from `reStructuredText`_ sources by `Sphinx`_, a document processor specifically written for the Python documentation. .. _reStructuredText: http://docutils.sourceforge.net/rst.html .. _Sphinx: http://sphinx-doc.org/ Building The Documentation ************************** To build the keepalived documentation, you will need to have a recent version of Sphinx installed on your system. Alternatively, you could use a python virtualenv. From the root of the repository clone, run the following command to build the documentation in HTML format:: cd keepalived-docs make html For PDF, you will also need ``docutils`` and various ``texlive-*`` packages for converting reStructuredText to LaTex and finally to PDF:: pip install docutils cd keepalived-docs make latexpdf Alternatively, you can use the ``sphinx-build`` command that comes with the Sphinx package:: cd keepalived-docs sphinx-build -b html . build/html .. todo:: make latexpdf needs pdflatex provided by texlive-latex on RHEL6 and texlive-latex-bin-bin on Fedora21 .. todo:: make linkcheck to check for broken links keepalived-2.3.1/doc/source/todo.rst0000664000175000017500000000005712635650721014326 00000000000000######### TODO List ######### .. todolist:: keepalived-2.3.1/doc/source/configuration_synopsis.rst0000664000175000017500000002254713667645552020223 00000000000000################################# Keepalived configuration synopsis ################################# The Keepalived configuration file uses the following synopsis (configuration keywords are Bold/Italic): Global Definitions Synopsis *************************** .. parsed-literal:: **global_defs** { **notification_email** { email email } **notification_email_from** email **smtp_server** host **smtp_connect_timeout** num **router_id** string } ======================== ====================================================== ========= Keyword Definition Type ======================== ====================================================== ========= global_defs identify the global def configuration block notification_email email accounts that will receive the notification mail List notification_email_from email to use when processing “MAIL FROM:†SMTP command List smtp_server remote SMTP server to use for sending mail notifications alphanum smtp_connect_timeout specify a timeout for SMTP stream processing numerical router_id specify the name of the LVS director string ======================== ====================================================== ========= Email type: Is a string using charset as specified into the SMTP RFC eg: “user@domain.com†Virtual Server Definitions Synopsis *********************************** .. parsed-literal:: **virtual_server** (@IP PORT)|(*fwmark* num) { **delay_loop** num **lb_algo** *rr|wrr|lc|wlc|sh|dh|lblc* **lb_kind** *NAT|DR|TUN* **(nat_mask** @IP) **persistence_timeout** num **persistence_granularity** @IP **virtualhost** string **protocol** *TCP|UDP* **sorry_server** @IP PORT **real_server** @IP PORT { **weight** num **TCP_CHECK** { **connect_port** num **connect_timeout** num } } **real_server** @IP PORT { **weight** num **MISC_CHECK** { **misc_path** /path_to_script/script.sh (or **misc_path** “ /path_to_script/script.sh â€) } } } **real_server** @IP PORT { **weight** num **HTTP_GET|SSL_GET** { **url** { # You can add multiple url block **path** alphanum **digest** alphanum } **connect_port** num **connect_timeout** num **retry** num **delay_before_retry** num } } ======================= =========================================================== ========= Keyword Definition Type ======================= =========================================================== ========= virtual_server identify a virtual server definition block fwmark specify that virtual server is a FWMARK delay_loop specify in seconds the interval between checks numerical lb_algo select a specific scheduler (rr|wrr|lc|wlc...) string lb_kind select a specific forwarding method (NAT|DR|TUN) string persistence_timeout specify a timeout value for persistent connections numerical persistence_granularity specify a granularity mask for persistent connections virtualhost specify a HTTP virtualhost to use for HTTP|SSL_GET alphanum protocol specify the protocol kind (TCP|UDP) numerical sorry_server server to be added to the pool if all real servers are down real_server specify a real server member weight specify the real server weight for load balancing decisions numerical TCP_CHECK check real server availability using TCP connect MISC_CHECK check real server availability using user defined script misc_path identify the script to run with full path path HTTP_GET check real server availability using HTTP GET request SSL_GET check real server availability using SSL GET request url identify a url definition block path specify the url path alphanum digest specify the digest for a specific url path alphanum connect_port connect remote server on specified TCP port numerical connect_timeout connect remote server using timeout numerical retry maximum number of retries numerical delay_before_retry delay between two successive retries numerical ======================= =========================================================== ========= .. note:: The "nat_mask" keyword is obsolete if you are not using LVS with Linux kernel 2.2 series. This flag give you the ability to define the reverse NAT granularity. .. note:: Currently, Healthcheck framework, only implements TCP protocol for service monitoring. .. note:: Type "path" refers to the full path of the script being called. Note that for scripts requiring arguments the path and arguments must be enclosed in double quotes ("). VRRP Instance Definitions Synopsis ********************************** .. parsed-literal:: **vrrp_sync_group** string { **group** { string string } **notify_master** /path_to_script/script_master.sh (or **notify_master** “ /path_to_script/script_master.sh â€) **notify_backup** /path_to_script/script_backup.sh (or **notify_backup** “/path_to_script/script_backup.sh â€) **notify_fault** /path_to_script/script_fault.sh (or **notify_fault** “ /path_to_script/script_fault.sh â€) } **vrrp_instance** string { **state** *MASTER|BACKUP* **interface** string **mcast_src_ip** @IP **lvs_sync_daemon_interface** string **virtual_router_id** num **priority** num **advert_int** num **smtp_alert** **authentication** { **auth_type** *PASS|AH* **auth_pass** string } **virtual_ipaddress** { # Block limited to 20 IP addresses @IP @IP @IP } **virtual_ipaddress_excluded** { # Unlimited IP addresses @IP @IP @IP } **notify_master** /path_to_script/script_master.sh (or **notify_master** “ /path_to_script/script_master.sh â€) **notify_backup** /path_to_script/script_backup.sh (or **notify_backup** “ /path_to_script/script_backup.sh â€) **notify_fault** /path_to_script/script_fault.sh (or **notify_fault** “ /path_to_script/script_fault.sh â€) } ========================== ======================================================================= ========= Keyword Definition Type ========================== ======================================================================= ========= vrrp_instance identify a VRRP instance definition block state specify the instance state in standard use Interface specify the network interface for the instance to run on string mcast_src_ip specify the src IP address value for VRRP adverts IP header lvs_sync_daemon_inteface specify the network interface for the LVS sync_daemon to run on string virtual_router_id specify to which VRRP router id the instance belongs numerical priority specify the instance priority in the VRRP router numerical advert_int specify the advertisement interval in seconds (set to 1) numerical smtp_alert Activate the SMTP notification for MASTER state transition authentication identify a VRRP authentication definition block auth_type specify which kind of authentication to use (PASS|AH) auth_pass specify the password string to use string virtual_ipaddress identify a VRRP VIP definition block virtual_ipaddress_excluded identify a VRRP VIP excluded definition block (not protocol VIPs) notify_master specify a shell script to be executed during transition to master state path notify_backup specify a shell script to be executed during transition to backup state path notify_fault specify a shell script to be executed during transition to fault state path vrrp_sync_group Identify the VRRP synchronization instances group string ========================== ======================================================================= ========= Path type: A system path to a script eg: “/usr/local/bin/transit.sh †keepalived-2.3.1/doc/source/case_study_healthcheck.rst0000664000175000017500000002352713334344241020050 00000000000000####################### Case Study: Healthcheck ####################### As an example we can introduce the following LVS topology: First of all, you need a well-configured LVS topology. In the rest of this document, we will assume that all system configurations have been done. This kind of topology is generally implemented in a DMZ architecture. For more information on LVS NAT topology and system configuration please read the nice Joseph Mack LVS HOWTO. Main architecture components **************************** * LVS Router: Owning the load balanced IP Class routed (192.168.100.0/24). * Network Router: The default router for the entire internal network. All the LAN workstations are handled through this IP address. * Network DNS Server: Referencing the internal network IP topology. * SMTP Server: SMTP server receiving the mail alerts. * SERVER POOL: Set of servers hosting load balanced services. Server pool specifications ************************** In this sample configuration we have 2 server pools: * Server pool 1: Hosting the HTTP & SSL services. Each server owns two application servers (IBM WEBSPHERE & BEA WEBLOGIC) * Server pool 2: Hosting the SMTP service. Keepalived configuration ************************ You are now ready to configure the Keepalived daemon according to your LVS topology. The whole configuration is done in the /etc/keepalived/keepalived.conf file. In our case study this file looks like:: # Configuration File for keepalived global_defs { notification_email { admin@domain.com 0633225522@domain.com } notification_email_from keepalived@domain.com smtp_server 192.168.200.20 smtp_connect_timeout 30 lvs_id LVS_MAIN } virtual_server 192.168.200.15 80 { delay_loop 30 lb_algo wrr lb_kind NAT persistence_timeout 50 protocol TCP sorry_server 192.168.100.100 80 real_server 192.168.100.2 80 { weight 2 HTTP_GET { url { path /testurl/test.jsp digest ec90a42b99ea9a2f5ecbe213ac9eba03 } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 retry 3 delay_before_retry 2 } } real_server 192.168.100.3 80 { weight 1 HTTP_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 retry 3 delay_before_retry 2 } } } virtual_server 192.168.200.15 443 { delay_loop 20 lb_algo rr lb_kind NAT persistence_timeout 360 protocol TCP real_server 192.168.100.2 443 { weight 1 TCP_CHECK { connect_timeout 3 } } real_server 192.168.100.3 443 { weight 1 TCP_CHECK { connect_timeout 3 } } } virtual_server 192.168.200.15 25 { delay_loop 15 lb_algo wlc lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.100.4 25 { weight 1 TCP_CHECK { connect_timeout 3 } } real_server 192.168.100.5 25 { weight 2 TCP_CHECK { connect_timeout 3 } } } According to this configuration example, the Keepalived daemon will drive the kernel using the following information: * The LVS server will own the name: LVS_MAIN * Notification: * SMTP server will be: 192.168.200.20 * SMTP connection timeout is set to: 30 seconded * Notification emails will be: admin@domain.com & 0633225522@domain.com * Load balanced services: * HTTP: VIP 192.168.200.15 port 80 * Load balancing: Using Weighted Round Robin scheduler with NAT forwarding. Connection persistence is set to 50 seconds on each TCP service. If you are using Linux kernel 2.2 you need to specify the NAT netmask to define the IPFW masquerade granularity (nat_mask keyword). The delay loop is set to 30 seconds * Sorry Server: If all real servers are removed from the VS’s server pools, we add the sorry_server 192.168.100.100 port 80 to serve clients requests. * Real server 192.168.100.2 port 80 will be weighted to 2. Failure detection will be based on HTTP_GET over 2 URLS. The service connection timeout will be set to 3 seconds. The real server will be considered down after 3 retries. The daemon will wait for 2 seconds before retrying. * Real server 192.168.100.3 port 80 will be weighted to 1. Failure detection will be based on HTTP_GET over 1 URL. The service connection timeout will be set to 3 seconds. The real server will be considered down after 3 retries. The daemon will wait for 2 seconds before retrying. * SSL: VIP 192.168.200.15 port 443 * Load balancing: Using Round Robin scheduler with NAT forwarding. Connection persistence is set to 360 seconds on each TCP service. The delay loop is set to 20 seconds * Real server 192.168.100.2 port 443 will be weighted to 2. Failure detection will be based on TCP_CHECK. The real server will be considered down after a 3-second connection timeout. * Real server 192.168.100.3 port 443 will be weighted to 2. Failure detection will be based on TCP_CHECK. The real server will be considered down after a 3-second connection timeout. * SMTP: VIP 192.168.200.15 port 25 * Load balancing: Using Weighted Least Connection scheduling algorithm in a NAT topology with connection persistence set to 50 seconds. The delay loop is set to 15 seconds * Real server 192.168.100.4 port 25 will be weighted to 1. Failure detection will be based on TCP_CHECK. The real server will be considered down after a 3-second connection timeout. * Real server 192.168.100.5 port 25 will be weighted to 2. Failure detection will be based on TCP_CHECK. The real server will be considered down after a 3-second connection timeout. For SSL server health check, we can use SSL_GET checkers. The configuration block for a corresponding real server will look like:: virtual_server 192.168.200.15 443 { delay_loop 20 lb_algo rr lb_kind NAT persistence_timeout 360 protocol TCP real_server 192.168.100.2 443 { weight 1 SSL_GET { url { path /testurl/test.jsp digest ec90a42b99ea9a2f5ecbe213ac9eba03 } url { path /testurl2/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 retry 3 delay_before_retry 2 } } real_server 192.168.100.3 443 { weight 1 SSL_GET { url { path /testurl/test.jsp digest 640205b7b0fc66c1ea91c463fac6334c } connect_timeout 3 retry 3 delay_before_retry 2 } } } To generate a sum over an URL simply proceed as follows:: [root@lvs /root]# genhash –s 192.168.100.2 –p 80 –u /testurl/test.jsp --------------------------[ HTTP Header Buffer ]-------------------------- 0000 48 54 54 50 2f 31 2e 31 - 20 34 30 31 20 55 6e 61 HTTP/1.1 401 Una 0010 75 74 68 6f 72 69 7a 65 - 64 0d 0a 44 61 74 65 3a uthorized..Date: 0020 20 4d 6f 6e 2c 20 32 33 - 20 41 70 72 20 32 30 30 Mon, 23 Apr 200 0030 31 20 31 35 3a 34 31 3a - 35 34 20 47 4d 54 0d 0a 1 15:41:54 GMT.. 0040 41 6c 6c 6f 77 3a 20 47 - 45 54 2c 20 48 45 41 44 Allow: GET, HEAD 0050 0d 0a 53 65 72 76 65 72 - 3a 20 4f 72 61 63 6c 65 ..Server: Oracle 0060 5f 57 65 62 5f 4c 69 73 - 74 65 6e 65 72 2f 34 2e _Web_Listener/4. 0070 30 2e 38 2e 31 2e 30 45 - 6e 74 65 72 70 72 69 73 0.8.1.0Enterpris 0080 65 45 64 69 74 69 6f 6e - 0d 0a 43 6f 6e 74 65 6e eEdition..Conten 0090 74 2d 54 79 70 65 3a 20 - 74 65 78 74 2f 68 74 6d t-Type: text/htm 00a0 6c 0d 0a 43 6f 6e 74 65 - 6e 74 2d 4c 65 6e 67 74 l..Content-Lengt 00b0 68 3a 20 31 36 34 0d 0a - 57 57 57 2d 41 75 74 68 h: 164..WWW-Auth 00c0 65 6e 74 69 63 61 74 65 - 3a 20 42 61 73 69 63 20 enticate: Basic 00d0 72 65 61 6c 6d 3d 22 41 - 43 43 45 53 20 20 20 20 realm="ACCES 00e0 22 0d 0a 43 61 63 68 65 - 2d 43 6f 6e 74 72 6f 6c "..Cache-Control 00f0 3a 20 70 75 62 6c 69 63 - 0d 0a 0d 0a : public.... ------------------------------[ HTML Buffer ]----------------------------- 0000 3c 48 54 4d 4c 3e 3c 48 - 45 41 44 3e 3c 54 49 54 Unauthorized< 0020 2f 54 49 54 4c 45 3e 3c - 2f 48 45 41 44 3e 0d 0a /TITLE>.. 0030 3c 42 4f 44 59 3e 54 68 - 69 73 20 64 6f 63 75 6d This docum 0040 65 6e 74 20 69 73 20 70 - 72 6f 74 65 63 74 65 64 ent is protected 0050 2e 20 20 59 6f 75 20 6d - 75 73 74 20 73 65 6e 64 . You must send 0060 0d 0a 74 68 65 20 70 72 - 6f 70 65 72 20 61 75 74 ..the proper aut 0070 68 6f 72 69 7a 61 74 69 - 6f 6e 20 69 6e 66 6f 72 horization infor 0080 6d 61 74 69 6f 6e 20 74 - 6f 20 61 63 63 65 73 73 mation to access 0090 20 69 74 2e 3c 2f 42 4f - 44 59 3e 3c 2f 48 54 4d it... -----------------------[ HTML MD5 final resulting ]----------------------- MD5 Digest : ec90a42b99ea9a2f5ecbe213ac9eba03 The only thing to do is to copy the generated MD5 Digest value generated and paste it into your Keepalived configuration file as a digest value keyword. keepalived-2.3.1/doc/source/images/0000775000175000017500000000000014105735173014151 500000000000000keepalived-2.3.1/doc/source/images/software_design.png0000664000175000017500000006676112635650721020003 00000000000000‰PNG  IHDR;ˆ¾Ñ/gAMA± üa cHRMz&€„ú€èu0ê`:˜pœºQ<÷PLTEÿÿÿýýýúúúøøøöööõõõôôôûûüþþþîîîçèçáááßßÞÞÞÞàààäääåååííí÷÷÷ëµ ¼¼»ÈÈÇÖÖÖèèèòòòùùùÏÐÏÜÛÜÑÒÑñññ§§§ÅÅÄ×××ê´ ¯¯¯ÂÂÁüüü¡¡¡ÃÃÃÚÚÚ††…ËËÊééé¿¿¾ÔÔÔððð€ÍÎÍìì옘˜”””¶¶µóóó{{z‡‡‡ØØØëëëvvvmmmŽŽŽÉÊÉqqqeeeÌÌËËœ ¬…Ú¨ kkk~~~½’ <-}aN<^HmjjjÊÊÊ ygRè² ºcdݪ JJJUUU^^^ÝÝÞççæÇÇÆÓÓÓïïïÙÙÙÆÆÅgggÒÒÒƒƒƒÅÆÅããâÉÉÈÎÎÍå° ä¯ à­ Ü±+Ò«/ˤ'Ö¥ ÆÅÅ·”&ÇÈÆÈÇÆš}$§€߬ {i-ÊÊÉÊÉÉub&ÌËÊËÌÊÍÍÌÏÏÎÐÑÐÐÐÏÐÏÐÒÒÑÔÔÓÕÕÕÖÖÕØØ×aV2Žw0ƒs?ÛÛÛÚÚÙÝÝÜÜÜÛiii!!!888ãäãäã㈈ˆèççèè猌ŒêêêèçèìëëëììëìëììëîííîîííîîííîîíîíîíððïïðððïðïïððïïòñòñòòòòñòññññòôóôÓ¢ ôôóôóóóóôóôôã½GæÐˆíäÉÓÌ´Ï»yá8õöööõõöõöõõöúúù«™`÷ø÷ø÷÷ø÷øøø÷÷÷øâà×¥Š1»±’ûüûüüûûüüüûûüûüÿþþÙÄýþþ‚.ˆˆ‡ÎÍÍÐÏÏÒÑÑÔÓÓÓÔÔÒÑÒÕÖÕààßרררÕÖÖŠŠŠÙÚÙÚÙÚÙÚÚŽÞÞÝÜÛÛÛÜÛÝÞÝÞÝÝàßßÞÝÞÝÞÞÔÓÔäãäääããääçèèqÏÐÐúùùúùúùúùùùúùúúŽŽþýýýþýýýþŽŽ2Ø‘xbKGDI‡ä|j IDATxÚí½{@W¶/,ò_¾sÍ—s&‰'ê™ø}F“sïxæÞ¼n’ûÇ·ÖÚ»ª«< º©nÂêªýX{í]{ïú­U»ª«ö6lˆ†hˆ†hˆ†hˆ†hˆ†hˆ†hˆ†hˆ†hˆ†hˆ†hˆ†hÈk¸·¯ßÙ·¿W€§ö•ÃÊ;9Þ¾AÁ#F‘5=&ÄÏÛ?À#ûÊQåOþ¡!£Â†È…<>b‚B}=¨¯x击<þ¾AZ7Ó)|bd · ë«ðI#£\ ß1Z7Ñ­)zò”À žÙW1º‡‚ý\7è‰õ°îxŠ{xªP^Ïë«GtñÓ¼]žo2šPÜt®¼žØW†Ï™à"ì OкuîO3u³Ñðxd_%ÕtÑÍ–§Ya-(9e$Ï쫸‡Fû¸;^©Sµn›Pí«Ç¢gGĺ<Þs´nšGPrJ°OÀð­«Ñ'Ò'MLpv¼|GhÝ4 ™ÑS"bC=o¤Œ4÷ñy‰®ÀÎð@­[æ4u×7Xëjô‰žHšäŠ;-¼éÔ„æ>šëç)FØÐ/t#\1XöQ©JC†+›iÈ'ÓÅé-x<>$6ÕC¯ï ñ‚ë|ðøªR¥,#2f)Xu$i`Ìd‰™3ôP4”‹`™a™‹ð ÙK^––ˬÄc£]º¨P?é—¿x°3²—Òl(ã­ê aVP lÖU×zßÌù®,û©R%l ïEˆ“1,SDÊaâÌq„:5î‰8ó¹ýÄN.GŸÃ®ËQQ2]p]€Þv‡ècfF)D†ÉdÊ¢63y(,ßdÊÍäÜ|ÄŽÁ|t8v2sM¦|HÎ2de˜l;„÷²±`1È32sd@<˜ ®/™™ÜÁô§À ÂÕ efÊ’ëÂ/~ܵƒÔ#Sí©T<8ó9àb«¤¾‚z@*l2‰~"6¶êF½Emãý‘æ6K0`FÑ:Ì2RÓ{GtÁÕ;¨9'¤Rx-£Ícùa™t=ËËâ&"±C§ÂNcf˜‘³íŒÇ3Ä@1O- ãåØYÄLY,Ï(DKG4‰ 1›ªA1¹.Fp ’—)s X\V°ÿØYÄAa«róä¾ZÁ<´¤ÆÅ–þ æeæ±<ì»<©?€¶ˆW–g„Ö0?4EjºŠÊkŒ°&†"ØFÞ,– °“S——,Ls€°(„íÎ3æ;ÂŽ…-fÞ(`Èkb‹`³ÇŽs% èâ†1¹.pBŒ9(.sðrb\¤:ê±c L°¯²±¯°¢ÌˆÀ¸f€Œº*Mèe…¡±ý}˜•ÇLV yrp8(5Ýs°fÈ!eÉ€å.ÎDóŠç+ÏœÓßAÛ²0 í’ v²°ƒL ìœ,£ÑX ÀŽÉ( +ìd°¼E,×;1(&a'’fU—°|¬nA˜…§5{±jè¨ÇŽ!›å€‘† šÐX£mÁ¾ZœÚSÀû#Gy(€3°Îv ?è)o,ïäÅØ¸ÅÐ ©éžƒ,¼Xg@­M–Á¯Œ& q)Í`‡ƒ$ h6 v@ûy÷)¯Y4Fϰ·;ÖØ ³$ÈuAÃ^Œ…‡ü•zèô;xåÎØ!2RÕ¨cD˜x LTÃ0¸@é”îC Ç9¹±¢„ż­ž†èŽE™x m"³’aÌɵ4+›Ã½\Ñ;ˆìÌ| ;¨g™8¾³4‘¹R_1P-ÆÊ&ê% ;t5Ø1ecÇf”ìŽ\º>ÂXÂÂ1ô~˜Ð?ìä ûŒý7LÜF+°“A3¼ŒJŠ9²åÊaC}ÖØÁK_.óDìd ‚¡g¿tç[Ù–l£èº¢›¤[za.01Ù›’|÷è1ùhÕ;¹rw D§â2Û¦.ˆµ,¼\ÈœÃ]c;R_¬±C•Ï–cHÙL2¶„lT¦vbèL7o¼éžƒ°üléÙ Ý$ä™×,>†Û:Ád|0P _jž6бG—Ø) 1l†Ý³A¼ÖçvÐæd[®Yùò¥ùü.OY—,é±¢I®Ý€a.¾4 –ú*ׯî„eæˆ.4)†vòí'ˆÅpy…Ý Ë_´(Ÿú/ßæy—ÛcŸÍHO d“&ÿ•)ÉdZ?‚È0ž‹é¦ð ›‚ìiñSVGÍ”‡`f¬lŠèßê°Ã«º8Fj«}_IURÆßV·N11‹m†õ‹L™™Ùt/7½—•×;îJj.ÿ}¡>`G-Ù>±wD9ü’]ЇÊa§+*0ºâŸ vpóT2™øŒ$[íEw;ÝQLÿ‹èž;x•sM¹ w v<ô•”¦ÁŽ«h~ò,Wüê3&\ë–y‘êz(v Óâf¸â ï1cµnšG©®‡b§h¾.ÒßûŽÓºiž@\uS=óÿÄÌð1¡.ÀŽ—_ðÐE«gZ¢×ûyùzæ~þ£óæ¸b.Œï¥ñZ·Íý©PŸ¼l¼·W¨GöUÑ̸å .ù¨Ø¿$2EëÖ¹=ÙYáà‘}U8ÿ‘ðQ®™FÅËgt|´Öíss*Ò'¯ òŽ ðľ*|F¯[•8Á%Ø ðˆ|8Nëº5Í_5Ü+Àûê‰ùqñã}\ò9:€gBàì‡ãfjÝF·¥Â%úÕºå‰ÞØý×W…O<’´f´ŸË¦;õòœ:]—œ¦u;Ý’9úä”åÓ|b©û=«¯°òq@“éè`‡D•ÎJñ˜8*,z&Mÿ¨ned¢¯¤¹žÓWTùd]Ù¨„ .ºb ÷Kù$ôÈÌùsürˆ8-˜Ÿ6ÿ±$ݲ㣼ceÍõ¾²T>bx¬K'èð‰O‰Nzôñ_ §Ç“ãtÓË‹9þÊÞ÷Œ¾ê¢ò.õHð¸‰ñO‘Dé«"—úQçx\_uQy—¡Ç'¢$0dˆdJðóFƒo×ùÑW]UÞEè ðŠ"+êªï=¢¯ 8r— ‘yt_ lT¬ëÓÅÒ:ž²2ÐχÜo $ÇKëxÌÊ@?rÇ5ì×ò¨•~>äžk Y¯ äq+ý|È×@R® äy+ýŒH7ÝíÖ@б¬ ä‰+ý|È-×@Š“í‰+ý|È×@’ÖòЕ~>äŽk ‰u”%rŒFõsˆª'ÃÀôú !7\)MK |f%£«ÁcÊví¼ƒÜq $Z.YÒÊ@8¡g~Íð‘ÁgR62pN¸\œ§PP¾e2fœ¥§Z6eâÎÃ4ÿLÉà3<£Á„Ó1Kñ§ŒÌh Éš³zWϘÅÏ>Wá:zîÙÅ.ŸJ¡_äŽk ÍäËÈ#ešX/Ìdˆ‰ÉöðŒ|Žr¤L1÷—Ä3ÑìÌ8£Ú".“ÌäÐLàŒÏ9l§¬P@¶<]jÐyþùʵ.¤Ê*Ü<X¦@^ÎÄ2ùi3eæÑd•yùY&–—iSN›h]ãÓçĹ/¥é>a:‹OŠ³Ùæˆ A­â¹Ù,'“5åæöÊð,~~òä•]Ò‹]0Ö8–S'ËBÿ)ë…gÝ;X¦@^΄c'7ƒÏ‘g¤™ pJ®<£4[²QÌ‘g3é‰9då]â…ñ¹† "Žùå8Ÿxæ¸6ô¦šÏV.SÐ:Úh_ö’²ÐKöQ–-ýç_g¼ìÞ†ÇMÖ@R’X¦@^Î$ ¡‚S’fY°cÂY¤³M&1â¡Ón ©„Õ`ó¬°–iZ”'ÍŸß==·vÝØ±cËÆŽn™ˆÈœ2Ê,¾Ì±2«¼ec×çf=íÞØq‹5¬ILEf™:Ìȇ.†˜l¶(ŸO‚o¢aP~Î">Ïà ËËÈ%?;Ì;xýÊÌàsgHX¡8Üú+°“mÈ*0fô;k7Ì+Û°qÞ¼y6lÜX6oÞFð!^V HÙ°öÞœ ˜.üe(ˆ±yuæƒmŠ¡Ô,kãorŸÊtoì¸ÅH=`‡FÀ8,Í [À' k“ˆ¡I@?;Ë;y4¦Æµ;@FÆJ.WËqœ6_:To°ÿʦôWâã7A(>}Ó+Ø´iSzz…DòlÁX+D`l’,æ[Aaà‰b~ûÛ!ìôµJîŒ=H¿Û»oßÞ©SÑÙ7U"dˆmß>áOEw/ºûˆ»—²ñL\X<7p¥ào~µž£u[»¦!쨣=òù|¹rdäþÈý@‘û¹_½_A‘R’"¶¿sT+¬(R’ƒ\³^@»³Çm4„Þ’í9¬X;iäA#ãôzÝH½^_U¥×?bI‹!Kèõ<òHé“­r+Ê<ëñŽ;"h;½ ‡ç­¢rT°DŠfì÷3Æ’“ÓØú³, üQ(l¦!Í[¬²“g)2ØÑXÙ½4è±Ó¿Ñf7ê^QYz ônÜyuÀá5ÀÄ=cI’ÒÒÒÖH13sÜ3^ÃH)ciIiÑvÒ`_Rz`çki¯í€ìÑiÑk¢SJ_¥²x‘]Þg¹ ÂNÔãz¹rŒ5• Y-«×´,µ+ÉÂŒI©E/i pÀO î˜15¬†'Ô¦ŒIC3ÄÌVÅõpîÒ;]þU 5vzyV**Ǭ :t¶º:pI£ËQPZaZD^„¤M3³šÙ…µKB\Ï0΂ƣSÈÌàÖÕ0óìZf®ƒò€ ¨ ºº^=ßÑAÚagQWËSjˆ5g¢¢rZ}}ý4 z±½Ž°‰¯ÁËÖÒx¼(±´z°&õÓ[²Óêñzr0a¡ðA2±¾ž‰Å©x6¨€´Ãމ-ê¶J‹õ \Q™xè ØzüÇ7£Å™6Ü_T7°¢p@Ä!@DàaÞ~è ôaO,dì0¤šëØÂ7;o6°%‰`¦½qèÃ@‡¿‘¨ö¹òÀ› ¯YÙ,Ûh4tU¥ÂN_û¼¢20ðH`ã[|+00°1ðÈ[o7‚É™ÛØ™®ˆÌ‡½±ÕèJÐËR#2`?Âï³XRàJXrd!weïÀÞNcàú>ý'1ÒÒîðOöbº¨Ò`§_ý\Qy4!áØQtŽOx7áhBIcº„£Œ5$ü¡`fKŽ"’txcÅj¦—06RgÒ˜(.á(Ý­›G;>Ó<ìÎñcG¡Ä÷Ž=~<á½¾a§Û†9SÚc§«*õ;11‹Ÿ}v±Ôû6Ýæõ¬¨¨XÃ{ÏÉCŠJŸs­­­ç|[Á;îü9__Ÿs<ü|}[}}ÏQÌd.çÜ… ­­Äº@¹Ài=ç'¯^½zà{þ•ñòž=……Î@VT†††¶] ½t)”Ó¥¶ÐË¡WBÛ®bøò¥Ð«È¢Ä«(×F2—®`àJ›ˆQƶPžŽ™Ú®\…œÈw*v8ñŽø¢kúuí°ƒ_Î ÒçÂöUêv:ÆùÌ 9úÿþ§õë©Ëœz**'X‘w—+¦·2ê=ÁzW’+°Sñ»ä$©kžúà9ÏÄN.}½ëà!Oÿ±Sñ_¡^õ~©©ÿ-7ëi—Ü·VTÔ>܆Ú釾ÿp;òÇ$YNÁWzÇ»ÄîYuM¿Ž vrX¾É˜™ÝU•úƒ§ÿ+á]âíü'“áƒgcÂ\öØØŽØöŽÎŽXÿök±±×;:®uÆvtt@èº{絎ÿN!±kþþþ±×bÕ~½³³ã:ÈùÇv\‡(¤wÆ^¿†¢×¯·_o'¶ó±ƒ ä kúLÚaÇÈÂLFt»¨R?°³ø…^‹9¥ã^ÉÉÏè—eîŠ**½º£X/Ud/î»ãä®Ñô?‰EÆf\ÜE•l‹`½ßŸeÿ!Ö¿dôŠÿÆ ƒTä•÷ž±c¿Ò‡]D>ü0 ×$‰ö;êÚõ쓇É]“Ã;}ï ÿ“àÏM]ÁYY„Ê/;ŸýàÿáÕð™3êûª\=³¢Òé½fE½ÁŽú/^ûß5–cjxnêbA'\³2ÿ®êüÞýSAÁ¯ûw7ѹv´í-Ÿ ŠÙ»¨R°ót†è¡?­ÏÉuÑüYŠ'v†Ø;DcoìŽzÃóÜOýÓ?þéâŸþ± ÇôëŒ>?>íöÈšc§OS48¥kÄ‘µï˜røt:6ä„gƒ‹_Îx*ß”““SkÈxúÙ˜!»ãŠ®Ñ;8•ä¢<—ü=”eÈÏÏ7<•‘颹f]ŒöôóÉë»FÃç;ÙaŒ=]À\òþNÌâçžþ ##ãƒðßb—`ç¹çÿáŸö¬wíùçü —Ì7è¼®Ñð}åì\–‘×U•¤"ú6ó¾¢òÜs4Áu?ú§»c?›™õëÜÜ¿û•‹(7ÿ©^î®ê}ž‘Ê ]íí»_9&×½ûåjZ\ñBFÖS.£¬Œ\4Psiø?zËËÊu0‡º‡`lÿËOgº*Ü}Q-ßß1d„¹êý °ø‹]Jý¹Ú¹ÿ·}®™i²wÔñc\Lý©ÛôË ÿ¶oˆ\FƒþÛ¾!r úoû†Èeäþßgi]wOÒ¾_Ü; rñJyî¿T^7¤Á*‚žômŸ«WÊ[»ÖÝ—Êëš´XEPCìd˜ˆz\)Ï¥äöKåuM®îG]£v2òÔŽwž­„F¬™<ùÅ5“×¼¸f oÔšÉ+a_C$M^¹œ5<}Í‹+Ahò‹/’f&Ai_I%ˆÀd»¥òë¹µ€ \Ls2.«9ùEZY“°³r ¡ƒI/vÖ ‹>G¬Ä‰Y3˜ì•/rààoÍ‹¿qû¥òº$è—’£Uµ|6˜ŸW«æ»ÐеˆŒ5Ê[» ,‚ ÑÉî¿T^—T±v )ˆ0£kP¸u%¥"ƒKÜ•dŸ¹r¡Q^) ò!ŠGæœJ–øŽºFÓï³- 3ª°;ˆeËð,sך–IIËäT©eÈXfÍáLÎìþKåuƒ2ȈaŒqñcŒÀ…×?²`€K!4¾7_ÃÕh %c`2a y‘på¨k´|o°ÀÄòÕ¼¿S±–CÂ…eZiµÊ/ÑJÛÅWÆØ2+ÈýÆdÓAž3Þ켸²{z±¹Ë2¬±£ñx'Æ„_£3¦â›b[’W“k›b³Šô:±øôKV P[Â+=Ûî(Mê2…'9Ë–I†v™d…—YYße²a^&çZ&2:šýPËy0…e÷òÛ>©Ö­;°nݲ±ëƂ˃˽iyiì²—ƒQˆ¿´ì¥±cQ楗  ÅløfY‡XZ†ù–½TàöËuƒnB…+Y\)¶RŽYŒ²ÅÞ*­eá5î…°Åa&Kwƒ„®J¾nlW´®W,䮳 ¯sÿ%«ºÃZÕ®LêKJ6ñA¥”ÂRè%žD% ;ź™Ýé’ºï”I‹Ø“DkÒ—ÉËÒË‹ÙKëÚ—IKØ[–··Ú­W½·»fyÒx‡T`™`°¬c_"kºŽ"`bÉP À /ã–ÑAÖÛ‚,”G°`!h¥q@"ÖCA­Ÿï„eä‹Ô¼7Ø!À(ˆPbG¹V̱ÊèX‰e7VöBì86ª=šà.d—YÅ4¶;&œ5Eþ\Ùþ¢Õ v6ò“=ol°C4¹Èl^^V¶`A2O¢ßPø.Û¸òˆ¼ðÛ0¯lcÙ† ß(Dç­ôèkV™ÒöÊVµ¬L¶Ód©e;lQ+Û-G¤—•-Ó;øh˜bh\ úôе€€y°oœ·a#ü€hõV>±À!ŒÐ¶‘ò‰0 °0/Å6 ¹FZçÑ÷YŽ ­•ß+’G6¤)v2aÇò8gþaby=Í¿£ïÄoxrÆxØžÄÀ“Oê71¶1òØ‚d`êæ.H{ý ÒÂ7Ä367<99yÓisçê6Äë’ã’èÂÓæ.ˆÃ"â©0.ˆzôóóÈš’iEcŠæ´ŒÛg0¯dbÁ#è%Bœô …„tÙFnÓ7r2AåÊæi:ÞÉe€Éùø¾r>˱ë”nìN¼ ÙIÛ°aAr|<_^(îI2D5Ó¹_«þ’ ¯¡5fâ粚Z†‹Ë0ö'>þI©(Ò<¶;ó„qݰŒïÆ Â0k#7·de7 ÃK‚¡dÉË„5ÞˆÚ(Œ2ÙiM펉;&ËÿW†lf4æÁnÌuX%GØy%>~œçôMñ¯lÚ¡¹Œ%§ã™ß€ù´1µ°7_^S37±Ž™ÚpØ1CÑcI`¤ÒÒââã_á°²Ò12Ö£Ç; tšÉ‹'ûŒ?n¨Ÿ¤žÌ-—"™øxÉô’=R*…‚< -v ÌXÀLyLž3Eün?õW7ØIO%]IˆMñiºtÀÈÜͰ'†ÌµÌ ~r|YY|: 9ÞÌjÍ`k’!Cxz8š¨šd,`S:à†Ó¦ô êìŽoêu‡x;z²g޽Ç’SSìdÚ¾®Ó[ì(Ç;xŽ7K;P\’ÒÁÞ,AÜ ~À¤Í;7 üäÍq„)¸>Õ”›YÍàë;yúÜÂZÖ°˰Å©ïhñ¦^X—u› Ö~d†ÁAmØÄch£!Цõ•WâQ[Èz£ñ&Y ¼ÏcÂoÂÜñÈ¥râãµý?+Á“myÅ4à Q†µ`7vg³-ár1`E’6 »³¹†¦™—Äm†k–ÀÔP§Áð絢¹›;€¸%æ¸%¬Ö®°tUvßÔSñ§â‹¶o‡¼è0u²,¤î%F®Wh=•´IßdŸÞm². ?ßÉ4™r3{Ñ Ý`gÖæòY³Êÿ<«¼Y›á7ªM›õgÀÍ,ÄN^Š6—ÇáàØ<ñT8™^„rѳ;³Êª¡L›¡ YX6ÿ¹|ó¬ ªÆ;ÏVÚ<æ_'=ÚiÕÿŽþ–}ÉžeKv/1ö€B?QnEÓ7o–-j:ç 7²é›¥›…$çË©¼‘][ìtõz²ì”ÛSJR’5#))½ÍÉÜ´ä6o‘ªhÛLDêìÎsk×µk–5eRpH­ÒgI›uî0ÞéÅ“nÆ;[ˆÊËÑ¡ öò-²pÐ%8±|I˜óTwðIeÞÍÂmìÆø|ï|7âSº#Æ[ß ô´²ŒžGÎÛÈïŽñv¸ Å-2¿«Æh›G÷Ó(ÓÓKŒ¶ãò?—ÿùψ0ËhOÑ@ƒógP˜?#8å¸-Ÿ…‚À4Ì ›) (Çœ›EJœe¾ÓGì(ûgËÇ«ð,Ù.Y3¡hÿ*¡TÛ· ã(¥),0gMš$³>‘·kûl03 Z^¹èíúYÊñjèË?Ì@àÓÿ6ŒaÂ7nÜ@Œã¾9\µ?Â8ˆÝ@ÁO?½AÀZÁOwÜP9Þ™½»wχ²O!‘<[0$Ö X›$‹ùVPx¢µãU’m]EWÉåüZ !™VŠ®B–°Ìh¯¹×V$¼¾bÀQ~•¦ã°0Ö×,5ëgÉØ™!ÛôÜäïDk?C\fÌ.;v‚·“dv IÉ!.30óN gÆŽå*íÎÞ}ûöNŠÎ¾©!Clûö *º{ÑÝGܽ”gâòÀâ¹+‚ûÔÚŸ’!^Nê°4mì§ËA[„Þ!Ìð§˜*,0¥îà¶xwo,§\û·Ôî0ÞQ|ªzý¬ŠµŸí´¡];Òg”²kçg6»ädG¤nxZQ¹?2rä~ Èýܯޯ H)IÛ_9ª• V)ÉAH-vHiÈ’î&Xu}:cÇ ¿¡kñÔ|°FÆy íX.‰}*Ævhüî—ÉhÌÏVšµëgU¬Å‘Àg¸¶s—†ñäJâ}&D%.9¢"£¡äêìN夑è<ô{³¹ð#Æ‘7b„2j ´eˆÓëGÂ.óÔb†×hŒwîœAÆ•‡v@€¬,iÁá6x'Ic2ìhƒw #NAökçN­±c0å…™„ÝÉ2JTÐv”ã>ÆÄ)îSÆM‘GšÈ7e [e! ÑëžO⌳ N‰)ÿÔw*o z¸–lª>X¦QäD›Ù¨`k%Òd!9 gŒv‰ÔŽw¸QÝEf•ÿP‹ˆGÔ'¶SØdT`bô³]d£wYå]R„TUÓñN>>Ì1-büƒüâ—ªï$vßš2eÊmÚ1Äé…¹{[Á2e·àßâAEªL»w+"*íNéÒ¸Àצ“jYíŒèèv€³&--mÍ5EŒEï(=ðFJ×D§{ÆdØ•&¥¥¥€œ´¤R,¤öT*¤ªµ;ãø­œDÊ0š\P—ÏÆ)níd!qs8nÜ¿}&±jÿ&’¥[EMíN~%”Ñìܺ · ·ÉÁ›“)»‰níÞ ¼[·vóöîÛ³w߯”[(AΟ‚b·nßB‘[˜áöíÛPÀmºÍ›Û»Õ=Ry¹rŒDaÌœ Z–‘Ú”ZVÃjWÒûöÑ7ð#ö—1iøš=½©VH™8Á˜eµÜiÚ%Rqh†Ç¡ñGaô§ˆ\Š‹tpxÒ.ÔŠŽ“§Œ“D)?/Aãï³òð-cÏÝÐÝ¡›Xq,h÷ ~gKü+ø.2IlÅnKêl‘¾bö bï äãVoOמ=X›Êñë‚‚<4—¾ÊH JcæƒKØ€@xZR\²XÚØ4V»ö 4N…°s‘3ÏŽžk.[<ˆ×¥aTW'*³§·ØݹEæöÚWSôYÛ[ F·$#©àï¦h„P• „nßBî­Ý”m Ék·Æï fà›ƒ½xq°›ñΊ}Ÿ¯XìwV¬X±oúŸÃ~gn+î@‚ Ï?¿ÃpòÙÑÏ÷¡ (àóÈ"¿·ß£ïìL«¯¯ŸNüëK{2ž±²®C(ÆO[ÈX}½™5˜/:ÀÅ4Ü‘ 9§™™ü9Ó¦½Ž_Ÿgà%ÖÓÙÚ³§KìØŽwøc"þðh÷n鱑x°´[<\â›xµ[„¹Ý-?›š­–¤µ}¾cEYÆ‚Ü^Ž••ýgþÿ¥ç&°ßAwŸ.žbº8¢;SÃãt†Ñpšºïsz¨‚.E÷Y²Bôsb‰â¦îëíxgOa!œÔÊÄCoÀvèЛ`6ƒíÑ^ YÍœC›Z  ‡ͬfaÚÂ…é9„ ܑ̬°>R—øÆBÖðÿAÞD)èPâá7álÁA {mwФ‚ Ì–—bĘmq)Y¸³å(I)R²Tϧ¡Ý‘o«Ä5ËÀ©Ÿ›»b-=LÃ=jƒ=®põtì5óÂö>ƒo)oâQ=î^ʸ—söJA pÖÔ½pÍZ¿§WT´çw l|ëo>ÊÀ¶À^üZœ…qK ïšYQ @!n$B|áˆ4ÂŽÌÀ#o–Ì~!k¨láËÕRZc`ã;ïþö·ëñ8½«ÐžŠµw>ÿ|ß}wîÜY&øZXP´­wÐßÙvøspöEþœ ô´ßŸß¹#ì6JB4ß“Iþ%Q„4ÄŽ<4fvL}ÁÎ_ìýö½{¿¸W îÞêgXnï½{{Wëáèõ«Y­¾–é¿€ëA!«­þbï=Añ½Õ_Ü£0¹ÕPFuõ=,l/p¾€4,å¾ ÂîMH8vcóùר o„F%Lo hÉ6ðg«Ä¦'VŽÂŽ>æ:–€™=ˆLܧ´÷Ž=~<á½õ*íŽôd{ß^) Õ©ÜÈÊϺEXìâQö>NS÷í“3ï•tȰ“e4dØ~[Óv”ãýÕ@‘àb`ud¤¾¨fd5‘ž™÷W²gªã’§W›™>™1±H¤ÄGÅXüÈý\Nåxçĉˆ“M'š"""Juº‡šš"‚ƒÁÜD55½Ñˆ¦¦`.8¢é_u:Œ4EDð‰¦¦'O@4*b•Nw""¢i•®4"1ðOBMëÿíýx§ ¨9d:!¹©S»ÎïFãË5±.¾™èÆîàÓúâýÅÅûù¾?²xÛVbíߨ)Þ˜¡]³Ì SÌs`&é_d+ÿ ([oçß÷YÍgš››Oûùõknn9{Úït3~É£óköó;Ýâ×’zÒ[šýZZζ€ßÒ’ê èŸn9Órºù4ä8ÓœŠÉg[N·€lËY?OÅßéõ*ï³È˜~ùEõÞj2£@÷ª¿îf°Ç_€réõ÷ôDºÈêÕHÞ{o:âÀ8G‚)ޤl`ÚÁ¡{ q{ïUkyŸ•e2¬°Ó§ç;wïß/¾{÷þÝ»Å_ß…íþ—À¸w;w‹‹XÑ—EæG`°Qc.Úrÿþ—(}ÿKÈñe1æQ€ –P ñâ/!_1†Pàî—Õ*ÿÏò9×ÚÚzη¼óçΟóõõMY½zç¹s瀱V__ð!æ2€sîÂ…ÖVb] \à´ž¿€Œó˜qßóç!zÁ·õ¼ïzuÏw*÷Ó?eÕôo™ø+{SkXíþý0+Ú/ú<¹ZŒÁJó€¾Züå&þvÈ`UÓ¿lb'+X €Rß°3bäÈ»ø—ÑÝwaƒg€Ø1zzå‘‘`@â. ¸ 2wGÔÊ8‚€1’v,ÅîªÄNhhhÛ¥ÐK—B9]j ½z%´í*†/_ ½Š,J¼Šrm$sé ®´‰el å阩íÊUȉ|ÕØAczÏüýbܾÜ_|Íëýb=CtâŠa¦‡Û 3f=Œ Ù}ì1àÔÞ§ì_Þ§ld§!3n÷‹)ECìdNž¶0LF¾ôšºÿ³,ÿÞaE7G vFŒxtL?bbgÄW#T”¨j¾ÁŠÊ VäÝeÄŠé­ŒzO°Þ•ÔvlÇ;‘¤+#ïƒ{÷ßG~9òK´ª@_Þ@AS|÷.`'úÆ A¹X\2ôÕ—€ýH¸Í£¼ÿ^|$Úðb(âË‘ÿ ¤â $ Ç;Œ-*`Öïµ÷a¼S9â«›_Ýuiøø»9ê+ŠCpÄM ~…i7yÚM! \!%/fÔW<ËW$8J¥Ý.¨}¸ µÓ}ÿáväIþ²œ‚¯ô†WkwäÿäGŠê-qÀÍ*†ê$l}ÜqÍÒìÔtj‚­ÿïi«YšÞgeÆ|¡;kG)(÷›ø¿4+ƒÜã¡`™g IKù‚ƒƒÕ½öPQÙÛÛÞÑÙëß~-6özGÇµÎØŽŽ]÷oï¼ÖÑáß "$v­Óß¿³Ã?öZ,°Ú¯wvv\9ÿØŽë…ôÎØë×PôúõöëíÄV‡—+o¢¡…íæM2¢7É’’fŒx ®ãŒ=„Ø©%Ãü•™.îE_}MjH¹IY¾ý&Ï Yo"ë«›ÚbÇ`Èf&Cÿæ2¨ v)ÝT‰¯î(ÖKÙ‹«´;k¿5Š[O$t…Ù…ðVüoÖ ,¼ùÌD§†9úQ€%ÑÑ$­ÜoÞ¼)xTÔ¨›nô|Gv”ã~ŽKKÅÉ.¥0n1É)åü`“óYDä2¤ÒTŽwìèÃ."~Ðk’DÕŽwÄ;CÊ7ƒFI>>ž| €Rv‚·×²Úí€ýÍ›J ¥|³¨‹·‰x¼Ógì(û/¸p)ÿƒPr#:º´4:zÇäh¢Ü›ŒÑ”RtÀ.€!•vÇé½fEjÇ;ÝYT@H-*Âqƒÿðã?û’æ8O©•ç™vGÑ?kÿzàÀ¯¾zàÁpþ {tákkþ ,è‚ Oøœ¹Œ_ÅiÊ&è.dõæÆb¨>xKUýº•{açåJ²³Ž(¸›x°mºã"«•†óºgÑ|Ë6Z*Š\OÆÚdñ:âƒÂ4ƒó*x¯¾JI<¹¯‚ó*¹ÂÞr•¥Ò›‹„‰Ý ;†^>TŒw*Œ±ÐhtÒ–˜KÑìàK2ÑcD‹Wï02&™wQÀžF;ˆÙuP÷ãm±c;Þ)Eu -xõ?þãÕyõÁhØÀÞŽ~ /&?øØ_©ûëèWAšëãƒW% !xp`ô_ùWbþõýŸÆçyWù\±³T>ßÚ±|ŒÀ]«(¤Ä¾Ï7N–盢 [8mwF3z4× ‘;fŒl[)ˆ©£%UÌ1BØC=Ú½ìN3Ô­þråÒ®³t)ÀE„–ŠHk0†/í-¹v>Ú“›¥j¼3Æ¥ä^Ø1°‚ź±;AKƒ‚êðe_AKÉ©[/ú"\xˆcß 6/ BV<´ô Ä­‰KªÃÎsÏÿÃ?íYï2ÚóÏùjæäz5f©ÒC3 ´n®Ù\øäNIì1< ËÒÒ^£ÐŸ1K¥D©Š»vŒLíÿY•Kë¬;X7~|@àouAuãÿADÌA€ËÁñT‘ñã;s@¼nü0ä ÿ‡ñP@ÝÁ ñuøññ肯j¼ólfÖ¯ssÿîW.¢Üü§>x9FÅxg èÀÒ¥¤7K1D1dŒå_¥-]º¤6R–‘ÉF“^$Ä¥DÒ,Q†Ýk¼Ó‡÷+ëÆO›†ÛxÉŸ&"£ŸÄD>8õÓxÉ/E¦Ép1;‹+^ÈÈzÊe”•ñÁÓÏÆ¨°;ƒÖý-• ík]Ý‚jýí`P}=ÖÀjëðrøÁÙ¯§¥½>”&<--©î b§,::òßøƒú[ˆýâ jÚÙGŸö;ÓÄg 6Tß¿ÞJ¢Þ^DÁªŸV§ ;1‹Ÿ{ùéLR…šE oÈÜŽ·§×áta4¨=ìÃß‹_·„ûøp°–Õ†[r 5³&í°£ø”O>¾˜×]ÅX¹¢²Þµ¤îsº˜˜˜Å.¥˜Þ›I¯}=Ö„_ø˜ñdš9 г݇³ôXCø´È-°Ós7t3Þ©›CT?ÇBõ–@½±0ëëe¢[ÏÅy¢¥°zU㎗R··ïL#øO³Õ´¨üë±øzÆÖ×ëæ¢åÁÏÅ@8ñMzºÑ0•2J™éû0ŸÆ=÷ï„ešŒÆï»wcwæ¼yOòáÄÃoÎysÎáC‡‡ßgΛo&†ë6ïÍp]ú¡C‡tº{o¾¢‡š3çHÎI<ôFCüÍ7ç‚ü‡!ñ0±ÌC(íÉk Uʺ"m¤°ã×cõøõaí ØÝBÆæÔëöÍA»ÓÀ抜"¿P-™Q?Gãy¿l ²˜&sʳO7ØI<œ(u…ÏBŸ¾ÈZ’8•{‰Ð7‰‡A $Ñš#“œDeQy8vÞDµzSQÔòçüB|=¶÷0c…áøÍ~¦@‚p`'$ÒQr/´‹tô’JzCSìØAELô®fݾJÀBˆÍe5ÓÑ_ÈjA³¦ƒ7¼è…M[.ŽûDü˜4â0)ÇaÒ0³‰o&Òx§&<‘³ès°_~?"››ØÑá÷ÍáP"ÿ&2"]:$ôëð‡Ök‰;¨`8—õ8Ï©r¼óÎ;ïüñÆÆ#!GŽ4†¼òÇ…KÌsÞi<òÖã¬a~ÜÝ?>ÊæÆÝ}§ú#ðHÈ[o7i|»1³¼ÒxäwCŽ„„¼ÓÅ@rÈ‘·1 b!o5ùãÛêÆ;¯½f;ÞáøO$} ƒË•H.œXÓuÓC"u³¸Ì~n¿™óf æ¦<< 忥Pt½–ëgÙB%ÆÈpÒ/¦fžÓÊÆ@¤ÜK(¸¿š³E«\HÞ–@ÀŽHÔØ•HÔÝ£?ÿ¼+—^[»¶‡µ×lûT"$ämÐŒ·CÞ((Ù;GÞyçH"*Û;лwÞ V#j£"‚$rç²H%¡HM¯YvP11c®a‘ºç;%œKléñ™q!f¶Px%ˆ‡‚ö9•¤îÙàó“r©\{­¤¤QhI£P˜F 5Zô‡öFîJŽäQæÆÆF¥¾IjzͲƒJ–úyN+Ž; tìhBBÉñãÇ€Þ-9~4á(~ä çQá%€Whžžðî±£%ÇA2¼—ðÞ{ï-ðcï’cÇ1õxIÉ{P\ÉÑcÇÞ;vô˜ºµ×ÖNv)ýOuk¯UJºa­d¢E‚,RBv¶ e’Ó”ehŠ{¨ä:*w7ÞÌE%ØÑ¨% ¬f¦ð¢èP:ÙlHÕxç¹µ“•k8¾ø¢ý:”¼f¥CöÊרópñG(håˆô°öšíxçXɱ’’£GKJŽ+y·„wßÅØ{ïŠÖ@ú{V °@ôÝ£˜†üãÇÞ}ÒŽ¾!LFyP%•$@…5ï8€J†õwÆ]`GÙ?Q.¥uï`¬]‰ë6®+>¾¤\ÃÑ\·î¥eö+@ÚÅEî—,©ë rÕ½¿Ö7á¨2 ‘F®UêÐQ?j Úe&ÆQ‘¬íüÊ%Tú6wSeÓÉ÷q–‰ˆS'O¾ÿþɨ§NEDE5Š8q¢édSÓÉ“M'¢¢N‚XSÄÉ“Q q'—ˆjŠ:u¤Nâ´M'#N8y Ü÷Ož„=Ä€qòª›op­Õ‚ܳ^ËQ鈔2Ë"‘–U ¥%· ¹*ßýø§M8­ =!AUl¹TL‚ÄÁ|š^³)?GWÎÝd×=Ý`'B¥Â¯WbO¥Ý)›·±ŒVhœ;_Ø×xÜ Öv¤„!‰V…܈ 9bŠ 2ô6à’‘¸n$f€ Ç“9êÖí«ôGE:õ>(Ï©¦ÐS  Q4E5<JLP6T•“'O¼Êu˜Q¨@'#@ÿ@¢N½¨º ›àžÔx¬¼Hqhs7)Ç;©¤)`Kö±ˆ.“íDÕ½¯¼¶,ž/â(-÷ø _ŒœxÄ¥ ÓiÛDKoâlŒr_HËKFŠ%!ùòè˜Ô½¯L“÷4É:Ñ$fóAŽ‚kÑ–.¨É±¯éxÇÀç.(èY…º±;Í--gÎ4§ú9ã×Ü’z¦ùtêC•::%eyËrnysJJ©_Ëò”‡›[NŸñ{Í~g CssjË™³˜»¥%µåìY?œóË8ë—Ú|Ư匩´;=¬á¨XÅÑ&ÐcF”é ;¶}A`Ñ-ax-º¡ŒJja­ˆY²ŒB÷4¶;}ü]Ù?~HÍ~Ò%/GF c…~«[íÇXŠßøfÊh¿ÒBðç[g°&_ëˆÊñŽ´T£´@²eUG/ß"EdžbIÎrËŠÊå–e“wÖÿÊQ9ÞImNME8“š Ê ÒÒœTPš³ gΜ= ª’šz¶8©gpö(ðNƒæ577cž³”å,æNEAHF5ÃøÙÔ÷ÂN1+,,ߨêû,__?__îðÀ|V3€U(°3ÓÀfú>ÁÌó!ê+eä‡Åšü|UÚ±&)­â(/ˆKâÑj´v-¨È%!ZR^¢´Š»U´¾©X@–ßÛö¿ÔŽ•…4ã[EiV(HøÑ&ÄfÑ´f*E*HSì Y^õÊ0ŒÌd0˜z^óQ9ÞÁÉ´p¶¬ ­ ûê'̾>­RX!Kaf¶ú<€å0öDòŒ ¾ ,.59eŒOkë¹ pr.œ® iʼn¸|[}|[Ïcú…sçTŽwþU^ßL¬j¶]ŽH 7ÊË@n—×=³,ú¸Ê²šX„PCíxGèim¾¤r„§Ê¶–«‹%“U‹‹øiû|ÇŠ2ä—ÁÔ¬ZéãsÞÇçÜ9 VŸsn}0œVŸ6“±GØjÀŽOJQ-cÑçÐæœ?O”rŸo…Œ¸!òãaÁUiw> v‰ew(ç’VR®9C¬ìÈ·b™ÇòÊrFŒÞP;Þñ­Õ¸à{®•Ÿõs|Þ:܉Óz¾UpÉ#AÐ!ÈÑJy[E¢”]d¥D_mÿGÇ«S†çqçjÒJÊZ„Št¾U¨ ¤œo=¸jŤVÔÎVP8`ùH™@[[µÃN¦ÁÃr †|–'ŽŸaÊf9?Gï;¡|Š?>w_hè%ú!jV³Bp¯ v`¤ÜÀ–´®fµfÆþ­íRÉJsû…†^ •éR¨‚TÚÛ³gË UÌÞ­\÷‘Vt¤….v‹m·Xøq¶4 ÿ ÜЧe.¤e!g Åì+Pù|GhˆÐ¡!¡B+¸~X\9j“óËQ‰«¡ÝÉ–ÌŒeݾ\“êù•+¯z·…^¾|ÅN¹wÛ•+W®^öönó¾äݨá[`çêêVûDÐå«0b®‰¾äí}Õû^¹Úvr]½z2^ºzõÊUï«WaÎïËè©ïÜáÓWËóYËk=‚7ý ³¹põÔ}á8'íÔGÁÊç¥Õëãļ´S-ó`‹ù´÷rŸ¦ÌÞ«v¼êRÒp¼“ë`xÓ‡y0¼‘&x+½.hÂe[†c1«˜J»¹_±x£<--­è8]¬Æ¶?Ž& ÅWa÷‹9þ˜^š—–òTï·.…ÏTY}OíxçJèeïKW.Ãæ Úu¹­í*h„w(èI[襫ÀºÒvåòÐ4oÔž¶« rµ­ gf½‚r¡ z º…³±‚ª]¾z ²‚z] ½¬åxÇddF„ŠeÒ¸ü>Œw¤)Aéœó¹B¹/Íêí-æ¥9Ud±™sÔ[9ù(n*±ãh5GAz€Fr-«Å¹ ™™æˆñˆ^sÔêãpæ­ß3H´Ë:Ò2Sd±4ÞéÝäÜ WWìUãŠ#}¹ÒUBw¤éXÙ`ûŸ¹±/ØùzÂ7¿>áâwp¿¾øõ·ßMøú»¯1a·ä^üvÂÅ‹_ÿÍ· 2_}ñ»ïPèâ×¾ý øúëï'|3³`æáß ’_«[?k­Í mÁŠYÛxè£ùŒ[æZ|z€«?Ž¢y·§iV,ïè€FãÞÎë^ÉõCV ®ÞÞrXš“W9#¯"î-)¤8/T[ìØ]¢ò²sYnA^ë+Ç;ß_üzøÅáß_¼øÝÅo¾ýfÂÅáÃ/~óÝ÷_óõðï.~?|ø·ß~CÓË~s‘<ä ¿¸(úþ›á¿ÿòbÊEp¿)à}òßó $|ÓÛñ_Obíiº¤òTGòôG¿¤Ù[’Jñ³Kú±Ò¯Àï2^ N4:Ê’÷UKVš0 ºf©XOB Úû(ÂE®5Àøukôèdu¿¢¨\è»ï8÷[‘Nʈ‰BC×kù}–ÝTMÌ3…©³;þ8ÿ°¿rJâ²i¦0VLVÜî0ÙZÔ_ÊÐk»CëØ¬ívÒ‘•Ycž•€“$V;ã“™åÉ‚jSºÍÿ`wÔ¬cS‰ZAhÃT‡‹¿Eë šôíůAµ.ÿÔí›ïH·.’}ñ;P®o.~²ß¡&AÂ7ß’B} Eº}÷ý÷¿ÑÔîØNÕ´ØÈòÙùêž ¶û#üa§¾N)Jº#ÅXRäÛÛ‡ âÏœC¥¶·W¹~Öã´ä#N€+?ý&i©ûÎò‚ßÓœ‹“Ø16C3»¬ƒdàóÒ. ÂIpÂ>LÍð‚ë=ÄÉ>þCåúY•í6s{w¥)6u«ë™Â;6S5-â¯a¨ú>Ëÿœcÿk×!=«™Gák×ý—S‡"Œ@¹&Áê SŽvŽB’$N»ºõ³ÖÊßßòE§‰ÏoÑy]|O·OÇØx3@…1”ì@:~š9MúÞWdáÅì ƒk–*»Ê„›PÔ£á<ˆLP´vÒ7LoÞî/4×Þ.ei—°$ib;W5,AÛ±2+°>tVž ÿ™0ô„åxÇ¿£ÃÿzGGçuÿŽk×b;:cyÂÜ~ýúµŽë€XÿØÎŽšGýzg;ˆvâlé(x#×®CæÎXœfýšÿõØöNˆàë×Á÷÷ ©ï¼¼ö®Ï˜ø&~› Þ‰oN<Äy‡KßÓN—°ÿÞ¡ÄC¸ä‡!²ð Øøö; u¿&|çðñ³–#¸ƒàÛ„!âùN¯í®#p­”¥%ðï•ò'…µèl'Õ5ñÇôëà\óïìÄ€fnu⪠SþÀƒÆ¯£Š#«Ó½ÞÁÈ£¶P7ØÁ©óq‹…-VL¥a ÓK‚W¬àp9/Α$h þX [8*Ÿïà{àÇøåÇ';žpôøÑw¾›ðÞÑ„ãGK8N/’¿wüøqþRù±„÷èåñcÇ…°ÞK(9vŒxÇéÃ!(¿aþÞ±wÕþŸåP:œ¥Vî…cÖ±±Y‚Á²Ãcì±pVèÅXë8,9”S‰¦ˆˆSM@'O½O/Ñã[ôâ%ÏS§š"ðí`|G˜Þþ„PSÄIÌþ©ü%ü¦ˆ¦MQMïCÂIˆB&4:ù¾ZìxÉÊ#TÊKÒ+ +Ö¢KVÊ&÷Hl¬”76VÒ,Ô;vS5™òè"ÖãÊñŽWÀ^^?þøº?yýàåõÓ^ØÎ$ýðÓO?aŠ×AØ Cä@¦~ü 2üð£×G óÈþô/?:ÀN÷ÿgùµðW¥Nûµ´4Ÿi9ã×rúôYðÎ÷ÌÙæ\ï1×lö;Ó|ú p[š›Ïú¥¶œ9K@6·¤"÷ ®÷xö4”ƒoð5§úµ4§â‘jÿÏR·ô‰Ê¥R¼4ïØÍ¡Ò—çÊ?0~ĵ:~úñ‡Ÿ>ú)à‡Ÿ~üáG„Kl;ø?R¼€P†¤! #àÇ?ÿ&üÒ€pÈb¶UÚ| —}<ï‹+7âË/­´ dkëHÀ7ÌÎã»1$ÑŠA<‡¯H´Ò‹P†Ä%ðU™s<(Zíÿè^‘~`ó~"}ðZƒ Ðvˆ£®Hô¥„Zø#t,fûᣰˆ ]ýÉ?jjwìæPév¬Vzù°Ë5`8 ëýâ1œTb_éhk»ÔÖvå¤Mz¥ƒVxÄåÛhAǶK$À—€o„´ñwI®ð%!1k›ôj ÑUµ×¬>úìlÀ¨=^¨púQ!¼¼@i ÕéÇÐâ’‚ýX#ÅX!ÿ#äCØPª)jeªÕî5‡J½ÖcP5wÂaØ0‚ÂäÃaö¡€ Ɔ Ô|(1(%%Ƈ<‘ËÒ6ŒR‡©ÆNWk;Zþ:²qì—†ôv”—˜ª±Óí‚JêmHSìØM·“Kÿo9¸Iïf¼ãèP _шej€Äú0@¤|8ÌF4@l*דøÆvÉÇvEÄz5Gz"çoYÒþ®¿2Žaµã¡* •!IIˆ÷!ç&iØ0ŠJªfáIâTåÒr¼c?ÝN_®YN¯§5©\ÀŸž>Ævv^Ç'íøXòE;® \Øn“Û;ð¡ „À뼎·Îí éO‰±¸d{;çÓS–ëþþjíŽE„~|h¥%¤²fñD›3ÿ!×­¬5ËñêÚÍ¡âéØyYº³Q{ËÒ;êì3v\Bî5‡J vr³|ëç!Ø©X«jÀ v ñÑv,äpºSÏv§§ñŽÉ­ÖÏR;Þqmm´}¾c;ÝŽ•sòÔ½ƒáÚþQ;Þqme†ìŽ9°g)oÈÅx§ÀS±ó²‹×ÏÂŽ Lc6=TüÁ±c|ZÍü;®í·²;^¿QµöÚ Æ%#,°bùï<‹þÞZl¿þš‡Œwž«üOÿù7.£ßüÏÖ^û¹Œwà&ËØÉaýœCŵý£ÎîÐÚk¿ú•ÉE?\{­BÍúY®íí쎉±Ð/°ú.”“Ý[<‚Z{Í…‹¯e|𲪵×\Û5šbÇÊG2JŸŠÚÞ·{v\½öÚÓ/«[{͵]£vòùCÁL#3Êã;,Ëa•´ï(ßî~= m×^û¹Œwp”œmD´X^xÏÊ[dÈÍË1ؽ?¨¥Ý¡olz­ìš®½ös±;Ò§Lñ¨î¼ÀÉ4¸ v’~ûÛõÒQ*N›[РƾaÊèfK&ÆÐî0w²;ëés:Âô֘͜pì|´ÇÁÓ¦ûOÂö=¯EÜeÙ}¢Õåxç¹çÿáŸ÷üÆu´þŸó3¬¿¦c2†ÜDÖãè›Ú³Þe´çŸ­ž6i½^hY¢\ƒÝ#Ÿ.í_Í^õ*õ¿U³œýÓ]ÁÄm1¤ì›¿sv—(»Æîi“–kÍæšLa™[~—ØéãjöëU,gTº‡‡›"U}³¾×]ÒíÓ&°“kÌ-àk‘¨˜÷«OTöôþ‘ŠšåìÝ CªúfÏúÞ÷I7O›4ÂŽ‰™zýÞ åÂÞ·'*{žíë#•–G·ÆÐ€ƒ¨Wµs\ãÂ=ýZQWY3ìÔ¿sÚ×®rR9=Ç­ QwÅçN(GÃñNUò8ìÈÇss9­ršw2³ ™ÝVIYDŸÍ3õUß²õë˜üÀ.ÇPŸê¸·¾×ÊrL°³ˆeL½£¬’m¬¯ûž¾ås¹Öõ¥m5ýèO»5ÐØ±ü:xÆ;½¨‰»\ÌœSÍÆÊ?GìÈ5ÒDÌ#ŸBEÍóM;Ê%¤ˆ<;axÙ2,î®J?ìXê8°òtì„å÷n.7騡2DžŽÓÏw¼Ó›J»CžŽì!ìô¦ò.‘çc'Ç nî&M;Jkr*†<;&ÕsäjÚQîBý7DN¡vØÉÍËsý=úž0ñ ~ðQŸ1DËaxðÿYa}™»©=쌢ܔÔ"Ïÿ} °ã$%sê5†z¿ÂI÷¤áûÊ|²nW•¥džC="'bOz'fñ³ÏU¨%T2Õ™TÒsj¾þí–úÔÄ®›.ÖÖ²OpJ 5ÄNFŽÑhrðOW؉yþùʵêéw¿û]r©¢Ê*œž>6±ç°éÕ=â°…Úa'ƒí×ãü;2-~~r_háÂ>eSCÿ)ë…g‚>6±ôp7±¾¶P;ìˆE {þlåäÉkV âùþâ‹+ôâÊ5ÊèÊ™²¸EB²Æ:nö¤¬á»u)”ü"òþó¯3^vŠáÁ&ÂQÖX·ÐR1ÛšZäÓÛÌ/:J^c-㨶P3ìð ärT¬ùøÜÚeîI/­ÏÍzÚ)ØyníKXÞ²eëf`¯ëE•Ö9’{ÉAÕ­B/ñ¬ë”éëºn¡vv‡±L\ Ò~"°®°S±v¬DebWÆ-LeŠ2jÃw(m'㘬ÄÖ©›°Â&–•IG(³9¤”Ù_Ѻ2ë•Ù ‹>*S¤L™ÛFTŠ;n¡–ÏwåçU<ß©X[6o^ÙÆ² @7–moÞÆ eeóÊ6Ì›·±lÞž 1ˆCxŠÄ7@σ8¥ÌÃL(óFðhÛHbQ [f€Bæm@ºK¡"°H,˜hÆߨZ®¨[ìP;èˆT*^T«6Û]&R±=¼3P²Œ·´ s”ñFÏò°0ª<ÉRåçñfòÚ£D–Ì¥¨Óðˆæ‰AJ™ÃjþF–]Bר‰wSr"vâã7m¥¾B[:mœ—¾é)(I@ü•t”ÀdbPú& mâYA’„Ø+R›Ä‘^¡É\†ŸJºvø`Ù~¨Ü v6§§Ã†´yófî 6<}³ÄݼYˆ£°’Ot9,åÙåde9C.¢ñªæšë;›-V¸›mÙ½£t›`¯óÚ ¦;l¡†÷èaY&S–ƒ„®±S.Ó–rڲŒ´ENFî–®3IÜ-[¬[ìe¥2íùå峜ˆ<ÐQ©-",BÜGÖ–r‹oIâbåÊår©úR–r^?Š” w‹,àVØÉÊÎÁ©äò€§kìT}\4q[ÕÄ*"ˆN¬úx[ÕÇ'VMÄ´ÿU%h›Ø! s|Œ‰Û&VQNð>‡—ññ6)ËDb` yÁUS6~<ì6^þD.º‚DNÄÎÖmÛ¶mݶUÔ~+xÛÀX[!± ùÛ0E(W&£ ÊmÝÊËÀ¦Qq&Ù­X&$¡<–C9·rzbÛŠEòʸv2óp¶|«E {ÆÎöíÛ?Ù>iû'“¶bB¸OBÆ °ÈÇ$daLçØI"“°œI!dw/•JÄà'ès.¥"(†‡üDä™äDìlß¾ ¶U¸-G%2‰K©ÛWQ”§‰D‘o»$FI‚·\.bË·óüÂ[%ŠI(²œŽd)#î„(/ãcTó?zÅÚŸ.¿±ãƧ;è÷)F–ïØqƒXÈY¾cùòŸB¥HÒoܸñ)I,§n@ÞKY~ƒä–zãÆr„[~6` øòO—ƒ °yXÊ¢äLw"vv휱cÇ ÜÑÅ8<Œ< QÒÎIRò žE)²ƒ—6C*y†³ä² _â¸vÄ"l‹*Ö±©X»k×g»`ÿ ¶üŒâ;‰ÞNp¸ÞN…¤Ï ðñw~†Ò;I 3@³îäQÄÄÏ8› 2 ÷3:ÔN’Ú)Š£ý3*Õ‰ØÙµk<þÛ5Üq",Øw¥ÈÎáÞ.‘i/PÜ5N°D)Ò-eï²°D‘ãÜ ;ÒDËFUÏoÝÞ 4åÖ­Ý·nMÙ ‘Û»!¸{÷­Û·oï¾} 6!g m·§ÜBY b†)(z›rMA„ÅÓ§ìžéXÚ-:Ân¿}ë6Ænã±vc–Û<„‘s{Êm”ƒô)NÄÎìÝøÛ={Åîp¤Ù³)>ƒ™½‚‡Ñ!1.°› ðâ9gKÜÙ<—Æsí–œ%•CÂ+¤¬³ùQ1Õ°SÀò a4ç` ììû|ÐçwÀ_qvŒ®ø|Å;w îô>‡”}ƒŠ~þùŠ™(‡J€\Áœè}Ž€$æÿ %î@> ÑA°Ø”cß+0ã’Ù‡t"v¦"íÃß> NÝ»o/q¬i/ð¹r{E2ùåq(Ã$w/mRL‚¢DYÂE2±4t èF؉ÉÇ¿Ði²nûÞ»ÂÎË•Õ_|Q]}oo5Ò½jŠ}qï¸{÷b¨Z¯_]=]w/Y¯Ÿ~ï^œ^¯»Wd6Å}Q½÷ Èr¶ê{÷@|o5–†¿{†rÞ‘_àöÞ‹¡/ЃXd5ð v¦_7ž“äËiã¡SA',‰ŽÆt¸&A‡Œjµú‡‘ØëpIµ¬lôÝ´ñ+`XŽçvìÝ9â¼è ˜´´´×‘¯8JìÖM£ƒ¢;މؙ†T?ò0„n=cº±†•^¤«‡:†Ôc¥9nŠ0´Ù\GY ÅK@µdaÚÿÁ‰Ña3Ó¢?mšîÎ4lv"ô!X\=?vêëçÐFúÜ#ï…‡‰= þqCnýÔÆÒ_‡XÝœ…ŒÕ×£ø\Øçp³?¿^òkXáëæ¹ásð´Ð¡,Ÿ#18sN½±“xøÐ¡ÄÄÉàBèp"À= gvÞAÞŒØ1/¬N,d5ºDˆàÉ ñð\øß‰‡ßx#Lmbuk¸-ù?æùáo˜Yá4ÄŽ(â‹pôá¾‹ŠšRp€GßÀ¢æ†C½ñÆ›oBU ¶Þ㱓(($$1Dã/„Gáf„°ÃSJÌ<ÈïVÍ_’pâÀ×~Æ^OL„~K !Ó—6È ¨2ï—üðP&&ŠâBøQ‡Uxë‡Æ·CBß‚Ð;àil„Sþv(Á‘ÆG±1!$a[!ia Âg>k E1£4´qátjIcc!3¿…Øyûq,âñÀG1a~H=5½#G°ÖéHôè{ À?–PBú%=zôXTBdÁâŽétÛŽ%@DÊ:E|…rà߯¤J§;~È@´ Ë€BššNE'ê}pORv, 36EA^pPx§šÄ¡B'×»Ù;§ê±“aKöœ®(ÕaKT§[•Šqðæ´Í˜Êw"'Ú¿3--~-ͰûI…`óéT?¿ÓÍ-gÎø>}RO·´œiò)H=s¦¹åt*¤ž=}¦åŒ_ó™Ô³µ¹8 sºÅϯùlKKóéÓ§! rø† g H> G2!¹ålóÙÓÍ©xØ3§A(õÌi8¦_3æ½ÙóíŽ_WÔÜ+– ·¹Ù6ɾÍVbŽK±ÉwÚ‰Øiõñ=ßzîü¹VßÖ ¾­­­Z[}Ο;ßÚzé<Ä{áÜy8w|Z[}Ïcòœó…âàsÎÇ×çâƒ%aä.жž‰ Tzëy,$|ÀÑó˜Іš@¦ Ä<;ç ?ZÑj=ÏЯçÏ#Û—¸ÐSð;¡VbÐONò$HöÅèH8-çHðtá9t[k+¥•‹ca­t:è”`ô}rAn'bçjh[[(§K¡¡W®†^¢è%ˆ„R¨-ôê¥Ð¶«’—»t54”D1Ü6^ÈÕ+—B¯„^¹BY)£%Ó%žµ­í%]m»Šþ%~Ëè^QÖó±såRÛ%츫mØ.ï+W¯^¹z¥ Z}é tßïË—°#½±syåòU ¶ËW½/ƒ\èeèTèŸ+mh»rµíÒåKW¡ç Œ+W¼½{ù”ê}ùÊU8mW/{õr( J¿rÉÎÄ•Ëp`{C—¯^†3A;q¼3È{‚LÞ2$Ø„•Yì³{Ûçõ¶-ƒJ‘<;ßZ5MûzB/ékÛœ6ô­µ`OR‚œhw†ûGjÎÉß´pü¥€ä¶ÛJµË鎿2O»sfûp…¼u>qDÏÇÎðvEP'Êaì>©‹¤î!f;ÏÅ;ÝߟºUêIYÚŸŠ¤^ÅLÈñÛÞî‡ò=Žåù[N]{»±s½³ózllgGûµöØXÿŽØÎöë±í±±×Ûc; Åßÿpcc;:;:b¯w¶w¶w´û_ï¸v½£„€×Ù É<èÛëß ù †¹:®A ö:”Dí±”áŽN8"=‚À»~ý:*ÜöÎkžXAØ®ØöëдNjüõÎk±Ô¿„.î Wˆ¡×KÒ‰D¢À“‹"ÿúuìx ãà,tQ¸y±ÔÓpú £ ŒG!'bÇ«{Šõ²;Œçc§Ÿ=ò£zõGa'b'À1}ÐOúÐâö¥,ÏÇŽMg(úþsÀ¦ªë?¤Ÿ²d+&ŠqT”±ãô3áò|ìh݃ªzv;}¤!ì a§¯4„Ÿv<>„~Ó§Íûå®MtØÂùɳ]Q}ï@gûùŸÿ‡Ú³ÞéŸó3œ4ß »6ÑQ Óâf$¸;>cÂûÜÎöóœffý:÷WN¤ß:©œÜü§>¨ˆqÊ<§În¢+[X4_éçå|ìx/ïkÿIp¶3]‹+^ÈÈÊzÊy´ÞIåde|ðô³NÁŽóšè¬¶uÓÂ'f† uvüKöêúØœíLWÌâç^~:Ó‰´ÇY=]á¤Eœ×Ä=Nk\—-œûèØ9Ãa^>¥cûØÏ<2})ÂÙÞtÅÄÄ,v"=»ÇyeÅ8Åì8¯‰{ö8±qŽ[ׇU þ.ÀN€àÔ¾žÂ´¤mgG¦+Æ©´Ç‰e99ÎkâžÂ=Îl£.IÓ»b¸ÓÃó V Gïý0]½¤Á»4®æâÖé“ÇŽ÷v vÀðD¦<ªºF…K‰Û0ªÔÇÔô°k{WC¢ç\Ú¼Âù«S"#\qÉ"ß’¬¶FÏÌOš>BT©O%¨êaWv®–äú…. ç¦éV%z»àéžXߥåáIªjT47-n͈„ ¼J})A]»°sµ¦=.m_Ñ܅ѳÆûĺä’ÅOý´ÅÍìu… —èWGo5Aª’(Á¥ý;XÉ¥FN”®<È×ßUÐSïå8uº.iæü¹ ~Ù#-˜Ÿ¦OJY5² Y] ª©Èeº ¹®müDýë4WB‡N}TiyJtÒ£ÿ¢Gz<9N762kзTÓï]P¦»Ð3.+OÔ²{‰®…žûá~!ÁS&Æ?Ù J_^<-ÊÛöª¦µ4Ó…º ¹°mŽO”+LÏpŸˆ’ÀÞP‚Ÿ·¿}Ô” ’uE¡nB»°lÇ'Êà ðŠí-yô¯U”äšbÝ‚\Û6‡'ªk VžÞErxxq7ðé-õ¿5”ì¢rÝ\Ü6u$œ±aÃô¬Èab:ΤwžµJÒº?—¶½Æ †™Ùkh€0ŽfhXzx Ù›"š´/]Ц+D$y7$·ê_g·ÍõÑÞS!Ø•ÆÂ£ÁÄ4¢¡iˆ,1Ë3ŒÕBjXk(QÁIÈ’†%á¬Åý>¼+hPcGë (( p¶%¤E§6°×ÐÁ…*S‹pnÖ@Žž½’]\ÀQT+kåŽäNýëd p«¶ÉëVͰ'ŸcÎj õáGІ /[…0"z-¼'öff¸jat«–Èäžµ„m+d €ˆ¤p€IMC1X“'Šž|Œ=CiÑ`Ìì±ÇX \ÑŠáê!y†½–ÄÌÑEO$j]{‡äVýëì¶¹Ñx' .K5¯ Ãi{ÍÑÃ’`h£‡aŽèþ×X­àUÔÐÔ£ sÀk ×*}-«qÓ“ä¦Õ´m ðÖÕÝ= ‰ä1±Ú'š;öïÏ´mÅbôã1äaý;Ô67¢ÁÜ¿ƒ¹mî@ƒ¹sÛÜsÿºWÛ˜’ºù= ¸¬ÖM5vGФ¬·0Ô¨®b¯k ªZ£ÖUä^º9Ô6O¢ÁÜ¿ƒ¹mî@ƒ¹Ý«møFEz7ïS‹·¿ŠÝö [r¯þÄm+f¬8‰±®ëô ÿ·ü¨¥k]Û^‘[õ¯³ÛæNö£YC¾²Ãßå O;^\Œ6†¿Ýeféà¦3]ÄŠ('Ë`¶ÜêEžA­+ $=®£ –…¿ËÍ žÑ³"ÆŠ'„ßybú@à5àK¨ø¢dJÂ7ÅÒCÌqr«þÄm (¤§ÃÄ»\¯±šèBöÌkøÖqðå$„‹¦0¥¿鬡8¾ð1v«~wêßAÝ6Fë͇‹w¹ qàà ßÕA„ð[T",¼…²ü4Ô „~X`|c Wè¥uC,äVý;ˆÛã˜Èa5ìñ.¾n‘f¨ˆ%qN`F›™®n‰pqz†=&)ÜLà…×°G)ŒÖº! r§þÌmKÂ,`dHïróØ3€¦bñvW ½¼0®mæôp°E¬0®j5f=ì ˆã¢@­¢l“Öj›5yáŠ/¯±gè 0ØßžºÓ aIIIпè>òì¶=ÃܾÞI‚´®ÇPÛ<’’ ÝöŽ~·-ið¶Í-ûw°ªæ`n›;(ç íÞÁÜ6'’×po_¿¾PrarŸòùx»zÊ«þ·°¯mÓ¨‰Z×pŸÔ¥Á#Fö…^ûË_ú’mÔè1!~Þ.šYØA½}ƒT·ð/}k›ÔÄ1KK|¬…Úh˜©>høØqÁã#& ˆbzyûÍéÓRdý›çtzüÞÑÔBÈß7¨_=Ôw Ÿèšùð­)64¤‹ØõƒbRfíjDþ¾c4‚NXXôä)\Þ³^ÞõÚµðáh¡F«!tÂÂâžåŠÅ£¬È;d°·P ðÖê‚%ºvz°kV²jñ o¡F4ÁZwlØü¤‰®ìY7háܸ5ÓáEKóÁ®žèBì¸A ÃO5/Z~#´î×°LJ¸;nа…®½,kD~#ÚIYƒê<¿üÅ“.ÅŽs[Ø'rñeY#Rß³&Ær²hB¡¼œÌ°lÆ2€›Ã˜1,?¹ž†hL^&5Á„­#ÊÉ”§MÊ5Ém2B EŒ†¶ 93,+8™ÝÁÅ—eH=v‰þ#2aÔ–á,tŒyÈô,온! 6‡7Ì c'‹ZL”‡Š‚"Yaˆ-D]6AgÑ ÝÁÅ—eH=v²±çHGsQMÔï9hŒH? F£§a*XŒ`à­C2˜L&£ÉdBÄp(G‰@c Øxè„N޶MÔˆTcKØbÒQ“èC13HµXÔ;t¥52(d0V  i‹%Ä åJ"p#EA•é¡ÂQ>öl£ûƒFn†Â2óøHÁðƒÉc9¨ ‹óÅuªHAD‹Ã$0aÚ™‹CŸ£ a§WD×(1ÈÎ'­ÍÎàƒÍ°Lc¯zÒͰƒÇ¿b—m†ÅÐEL´)F²¶p5ËÆ¡O ™ /a§ý—OW+aØqèÈÍN–É”aX$:܃°ƒWŸ >*æ­S`Jn1¡£¹R!cfNÏ­!ìHý—ÁïU-]CMêc^ò< ;tõYD`ÀÖåãx'ƒ7,g1oq ÇÌj'u›Et·ž¹X²ºCØé讔߫ZÔ“#)·o·èšc‡ƒ£xlŸ¡·æÏ(?Ùʦ‘>‘+)Ívz¤\Ô· ¥q¡q3êg˜ µ1O-t´ÆŽhL¶xêÀ)#L¾]Ï•‡ÏÒƒ‰Ea1t?&Iz4±.VJ°­#Ò%-œ;h[¨yyG•ÎJÑ%Ïœ?wÁ/ŒÌOÓ'ëÖD&úº~ †Q¥å)qq¿X8MÈjFÃýG¦§D'=úø/ŒOŽÓ-[1>Ê{ tZ¼|ÍÀ6q@[¨xz‚ÇMŒr)}y1ô«ÿÀt,´Ð'aÚW;˲‰ÚBÍ(û6¢$0d )Áúu`:6 vÀ›8 -ÔŽ o½bš¼²_µhâÀ¶P; xüMÔú¤Ñ Ñ Ñ Ñ Ñ Ñ Q—ôÿ­s(¨%tEXtdate:create2015-02-23T20:50:38-05:00tn¸%tEXtdate:modify2015-02-23T20:50:22-05:00mé_ãIEND®B`‚keepalived-2.3.1/doc/source/introduction.rst0000664000175000017500000000250213334344241016071 00000000000000############ Introduction ############ Load balancing is a method of distributing IP traffic across a cluster of real servers, providing one or more highly available virtual services. When designing load-balanced topologies, it is important to account for the availability of the load balancer itself as well as the real servers behind it. Keepalived provides frameworks for both load balancing and high availability. The load balancing framework relies on the well-known and widely used Linux Virtual Server (IPVS) kernel module, which provides Layer 4 load balancing. Keepalived implements a set of health checkers to dynamically and adaptively maintain and manage load balanced server pools according to their health. High availability is achieved by the Virtual Redundancy Routing Protocol (VRRP). VRRP is a fundamental brick for router failover. In addition, keepalived implements a set of hooks to the VRRP finite state machine providing low-level and high-speed protocol interactions. Each Keepalived framework can be used independently or together to provide resilient infrastructures. In this context, load balancer may also be referred to as a *director* or an *LVS router*. In short, Keepalived provides two main functions: * Health checking for LVS systems * Implementation of the VRRPv2 stack to handle load balancer failover keepalived-2.3.1/doc/source/terminology.rst0000664000175000017500000000567614410446624015743 00000000000000########### Terminology ########### .. todo:: put image here LVS stands for “Linux Virtual Server“. LVS is a patched Linux kernel that adds a load balancing facility. For more information on LVS, please refer to the project homepage: http://www.linux-vs.org. LVS acts as a network bridge (using NAT) to load balance TCP/UDP stream. The LVS router components are: * WAN Interface: Ethernet Network Interface Controller that will be accessed by all the clients. * LAN Interface: Ethernet Network Interface Controller to manage all the load balanced servers. * Linux kernel: The kernel is patched with the latest LVS and is used as a router OS. In this document, we will use the following keywords: LVS Component ************* .. glossary:: IPVS (IP Virtual Server) The linux kernel module that provides packet forwarding services for network load balancing (Layer-4 switching). Director The server running IPVS which is responsible for distributing incoming network traffic among a pool of backend servers. Real server A real server hosts the application accessed by client requests. WEB SERVER 1 & WEB SERVER 2 in our synopsis. Server pool A farm of real servers. RIP (Real IP) Real IP address configured at a real server in the LVS cluster. VIP The Virtual IP is the IP address that will be accessed by all the clients. The clients only access this IP address. DIP (Director IP) IP address of the LVS director node. Director uses this when communicating with a Real server. Virtual server The access point to a Server pool. Virtual Service A TCP/UDP service associated with the VIP. VRRP Component ************** .. glossary:: VRRP The protocol implemented for the directors’ failover/virtualization. IP Address owner The VRRP Instance that has the IP address(es) as real interface address(es). This is the VRRP Instance that, when up, will respond to packets addressed to one of these IP address(es) for ICMP, TCP connections, ... MASTER state VRRP Instance state when it is assuming the responsibility of forwarding packets sent to the IP address(es) associated with the VRRP Instance. This state is illustrated on “Case study: Failover†by a red line. BACKUP state VRRP Instance state when it is capable of forwarding packets in the event that the current VRRP Instance MASTER fails. Real Load Balancer An LVS director running one or many VRRP Instances. Virtual Load balancer A set of Real Load balancers. Synchronized Instance VRRP Instance with which we want to be synchronized. This provides VRRP Instance monitoring. Advertisement The name of a simple VRRPv2 packet sent to a set of VRRP Instances while in the MASTER state. .. todo:: keepalived-2.3.1/doc/source/index.rst0000664000175000017500000000063013046656321014464 00000000000000##################### Keepalived User Guide ##################### .. toctree:: :maxdepth: 1 introduction software_design load_balancing_techniques installing_keepalived configuration_synopsis programs_synopsis scheduling_algorithms protocol_support snmp_support case_study_healthcheck case_study_failover case_study_mixing terminology license about todo keepalived-2.3.1/doc/source/load_balancing_techniques.rst0000664000175000017500000000567513334344241020533 00000000000000######################### Load Balancing Techniques ######################### Virtual Server via NAT ********************** NAT Routing is used when the Load-Balancer (or LVS Router) has two Network Interface Cards (NICs), one assigned an outside-facing IP address and the other, a private, inside-facing IP address. In this method, the Load-Balancer receives requests from users on the public network and uses network address translation (NAT) to forward those requests to the real servers located on the private network. The replies are also translated in the reverse direction, when the real servers reply to the users’ requests. As a result, an advantage is that the real servers are protected from the public network as they are hidden behind the Load-Balancer. Another advantage is IP address preservation, as the private network can use private address ranges. The main disadvantage is that the Load-Balancer becomes a bottleneck. It has to serve not only requests but also replies to and from the public users, while also forwarding to and from the private real servers. Virtual Server via Tunneling **************************** In Tunneling mode, the Load-Balancer sends requests to real servers through IP tunnel in the former, and the Load-Balancer sends request to real servers via network address translation in the latter. The main advantage of this method is scalability, Load-Balancer will forward incoming request to farm nodes, latter nodes will then respond directly to the client requests without having to proxy through Load-Balancer. It offers you a way to locate nodes in different networking segments. The main disadvantage is the cost you will put into it to finally get a working env since it is deeply dependent upon your network architecture. Virtual Server via Direct Routing ********************************* In Direct Routing, users issue requests to the VIP on the Load-Balancer. The Load-Balancer uses its predefined scheduling (distribution) algorithm and forwards the requests to the appropriate real server. Unlike using NAT Routing, the real servers respond directly to the public users, bypassing the need to route through the Load-Balancer. The main advantage with this routing method is scalability, as the Load-Balancer does not have the additional responsibility of routing outgoing packets from the real servers to the public users. The disadvantage to this routing method lies in its ARP limitation. In order for the real servers to directly respond to the public users’ requests, each real server must use the VIP as its source address when sending replies. As a result, the VIP and MAC address combination are shared amongst the Load-Balancer itself as well as each of the real servers that can lead to situations where the real servers receive the requests directly, bypassing the Load-Balancer on incoming requests. There are methods available to solve this problem at the expense of added configuration complexity and manageability. keepalived-2.3.1/doc/source/scheduling_algorithms.rst0000664000175000017500000002161214450042610017724 00000000000000########################## IPVS Scheduling Algorithms ########################## The following scheduling algorithms are supported by the IPVS kernel code. (heavily stolen from LVS website). Round Robin (rr) **************** The round-robin scheduling algorithm sends each incoming request to the next server in its list. Thus in a three server cluster (servers A, B, and C) request 1 would go to server A, request 2 would go to server B, request 3 would go to server C, and request 4 would go to server A, thus completing the cycling or 'round-robin' of servers. It treats all real servers as equals regardless of the number of incoming connections or response time each server is experiencing. Virtual Server provides a few advantages over traditional round-robin DNS. Round-robin DNS resolves a single domain to the different IP addresses, the scheduling granularity is host-based, and the caching of DNS queries hinders the basic algorithm, these factors lead to significant dynamic load imbalances among the real servers. The scheduling granularity of Virtual Server is network connection-based, and it is much superior to round-robin DNS due to the fine scheduling granularity. Weighted Round Robin (wrr) ************************** The weighted round-robin scheduling is designed to better handle servers with different processing capacities. Each server can be assigned a weight, an integer value that indicates the processing capacity. Servers with higher weights receive new connections first than those with less weights, and servers with higher weights get more connections than those with less weights and servers with equal weights get equal connections. For example, the real servers, A, B, and C, have the weights, 4, 3, 2 respectively, a good scheduling sequence will be AABABCABC in a scheduling period (mod sum(Wi)). In the implementation of the weighted round-robin scheduling, a scheduling sequence will be generated according to the server weights after the rules of Virtual Server are modified. The network connections are directed to the different real servers based on the scheduling sequence in a round-robin manner. The weighted round-robin scheduling is better than the round-robin scheduling, when the processing capacity of real servers is different. However, it may lead to dynamic load imbalance among the real servers if the load of the requests vary highly. In short, there is the possibility that a majority of requests requiring large responses may be directed to the same real server. Actually, the round-robin scheduling is a special instance of the weighted round-robin scheduling, in which all the weights are equal. Least Connection (lc) ********************* The least-connection scheduling algorithm directs network connections to the server with the least number of established connections. This is one of the dynamic scheduling algorithms; because it needs to count live connections for each server dynamically. For a Virtual Server that is managing a collection of servers with similar performance, least-connection scheduling is good to smooth distribution when the load of requests varies a lot. Virtual Server will direct requests to the real server with the fewest active connections. At a first glance, it might seem that least-connection scheduling can also perform well even when there are servers of various processing capacities, because the faster server will get more network connections. In fact, it cannot perform very well because of the TCP's TIME_WAIT state. The TCP's TIME_WAIT is usually 2 minutes, during this 2 minutes a busy website often receives thousands of connections, for example, the server A is twice as powerful as the server B, the server A is processing thousands of requests and keeping them in the TCP's TIME_WAIT state, but server B is crawling to get its thousands of connections finished. So, the least-connection scheduling cannot get load well balanced among servers with various processing capacities. Weighted Least Connection (wlc) ******************************* The weighted least-connection scheduling is a superset of the least-connection scheduling, in which you can assign a performance weight to each real server. The servers with a higher weight value will receive a larger percentage of live connections at any one time. The Virtual Server Administrator can assign a weight to each real server, and network connections are scheduled to each server in which the percentage of the current number of live connections for each server is a ratio to its weight. The default weight is one. The weighted least-connections scheduling works as follows: Supposing there are n real servers, each server i has weight Wi (i=1,..,n), and alive connections Ci (i=1,..,n), ALL_CONNECTIONS is the sum of Ci (i=1,..,n), the next network connection will be directed to the server j, in which (Cj/ALL_CONNECTIONS)/Wj = min { (Ci/ALL_CONNECTIONS)/Wi } (i=1,..,n) Since the ALL_CONNECTIONS is a constant in this lookup, there is no need to divide Ci by ALL_CONNECTIONS, it can be optimized as Cj/Wj = min { Ci/Wi } (i=1,..,n) The weighted least-connection scheduling algorithm requires additional division than the least-connection. In a hope to minimize the overhead of scheduling when servers have the same processing capacity, both the least-connection scheduling and the weighted least-connection scheduling algorithms are implemented. Locality-Based Least Connection (lblc) ************************************** The locality-based least-connection scheduling algorithm is for destination IP load balancing. It is usually used in cache cluster. This algorithm usually directs packet destined for an IP address to its server if the server is alive and under load. If the server is overloaded (its active connection numbers is larger than its weight) and there is a server in its half load, then allocate the weighted least-connection server to this IP address. Locality-Based Least Connection with Replication (lblcr) ******************************************************** The locality-based least-connection with replication scheduling algorithm is also for destination IP load balancing. It is usually used in cache cluster. It differs from the LBLC scheduling as follows: the load balancer maintains mappings from a target to a set of server nodes that can serve the target. Requests for a target are assigned to the least-connection node in the target's server set. If all the node in the server set are over loaded, it picks up a least-connection node in the cluster and adds it in the sever set for the target. If the server set has not been modified for the specified time, the most loaded node is removed from the server set, in order to avoid high degree of replication. Destination Hashing (dh) ************************ The destination hashing scheduling algorithm assigns network connections to the servers through looking up a statically assigned hash table by their destination IP addresses. Source Hashing (sh) ******************* The source hashing scheduling algorithm assigns network connections to the servers through looking up a statically assigned hash table by their source IP addresses. Shortest Expected Delay (sed) ***************************** The shortest expected delay scheduling algorithm assigns network connections to the server with the shortest expected delay. The expected delay that the job will experience is (Ci + 1) / Ui if sent to the ith server, in which Ci is the number of connections on the ith server and Ui is the fixed service rate (weight) of the ith server. Never Queue (nq) **************** The never queue scheduling algorithm adopts a two-speed model. When there is an idle server available, the job will be sent to the idle server, instead of waiting for a fast one. When there is no idle server available, the job will be sent to the server that minimizes its expected delay (The Shortest Expected Delay scheduling algorithm). Overflow-Connection (ovf) ************************* The Overflow connection scheduling algorithm implements "overflow" loadbalancing according to a number of active connections, will keep all connections to the node with the highest weight and overflow to the next node if the number of connections exceeds the node's weight. Note that this scheduler might not be suitable for UDP because it only uses active connections Weighted failover (fo) ********************** The weighted failover scheduling algorithm implements the simple failover solution. Connections are always directed to the selected server based solely on highest weight value and server availability. Maglev hashing (mh) ******************* Google's Maglev hashing scheduler. It provides consistent hashing but with minimal disruption and each destination receiving an almost equal number of connections. Weighted random twos choice (twos) ********************************** The algorithm picks two random servers based on weights and then selects the server with the fewest connections normalized by weight. keepalived-2.3.1/doc/VRRP-MIB.txt0000664000175000017500000006410512766347655013310 00000000000000VRRP-MIB DEFINITIONS ::= BEGIN IMPORTS MODULE-IDENTITY, OBJECT-TYPE, NOTIFICATION-TYPE, Counter32, Integer32, IpAddress, mib-2 FROM SNMPv2-SMI TEXTUAL-CONVENTION, RowStatus, MacAddress, TruthValue, TimeStamp FROM SNMPv2-TC MODULE-COMPLIANCE, OBJECT-GROUP, NOTIFICATION-GROUP FROM SNMPv2-CONF ifIndex FROM IF-MIB; vrrpMIB MODULE-IDENTITY LAST-UPDATED "200003030000Z" ORGANIZATION "IETF VRRP Working Group" CONTACT-INFO "Brian R. Jewell Postal: Copper Mountain Networks, Inc. 2470 Embarcadero Way Palo Alto, California 94303 Tel: +1 650 687 3367 E-Mail: bjewell@coppermountain.com" DESCRIPTION "This MIB describes objects used for managing Virtual Router Redundancy Protocol (VRRP) routers." REVISION "200003030000Z" -- 03 Mar 2000 DESCRIPTION "Initial version as published in RFC 2787." ::= { mib-2 68 } -- ******************************************************************* -- Textual Conventions -- ******************************************************************* VrId ::= TEXTUAL-CONVENTION STATUS current DESCRIPTION "A number which, along with an interface index (ifIndex), serves to uniquely identify a virtual router on a given VRRP router. A set of one or more associated addresses is assigned to a VRID." SYNTAX Integer32 (1..255) -- ******************************************************************* -- VRRP MIB Groups -- ******************************************************************* vrrpOperations OBJECT IDENTIFIER ::= { vrrpMIB 1 } vrrpStatistics OBJECT IDENTIFIER ::= { vrrpMIB 2 } vrrpConformance OBJECT IDENTIFIER ::= { vrrpMIB 3 } -- ******************************************************************* -- Start of MIB objects -- ******************************************************************* vrrpNodeVersion OBJECT-TYPE SYNTAX Integer32 MAX-ACCESS read-only STATUS current DESCRIPTION "This value identifies the particular version of the VRRP supported by this node." ::= { vrrpOperations 1 } vrrpNotificationCntl OBJECT-TYPE SYNTAX INTEGER { enabled (1), disabled (2) } MAX-ACCESS read-write STATUS current DESCRIPTION "Indicates whether the VRRP-enabled router will generate SNMP traps for events defined in this MIB. 'Enabled' results in SNMP traps; 'disabled', no traps are sent." DEFVAL { enabled } ::= { vrrpOperations 2 } -- ******************************************************************* -- VRRP Operations Table -- ******************************************************************* vrrpOperTable OBJECT-TYPE SYNTAX SEQUENCE OF VrrpOperEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "Operations table for a VRRP router which consists of a sequence (i.e., one or more conceptual rows) of 'vrrpOperEntry' items." ::= { vrrpOperations 3 } vrrpOperEntry OBJECT-TYPE SYNTAX VrrpOperEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry in the vrrpOperTable containing the operational characteristics of a virtual router. On a VRRP router, a given virtual router is identified by a combination of the IF index and VRID. Rows in the table cannot be modified unless the value of `vrrpOperAdminState' is `disabled' and the `vrrpOperState' has transitioned to `initialize'." INDEX { ifIndex, vrrpOperVrId } ::= { vrrpOperTable 1 } VrrpOperEntry ::= SEQUENCE { vrrpOperVrId VrId, vrrpOperVirtualMacAddr MacAddress, vrrpOperState INTEGER, vrrpOperAdminState INTEGER, vrrpOperPriority Integer32, vrrpOperIpAddrCount Integer32, vrrpOperMasterIpAddr IpAddress, vrrpOperPrimaryIpAddr IpAddress, vrrpOperAuthType INTEGER, vrrpOperAuthKey OCTET STRING, vrrpOperAdvertisementInterval Integer32, vrrpOperPreemptMode TruthValue, vrrpOperVirtualRouterUpTime TimeStamp, vrrpOperProtocol INTEGER, vrrpOperRowStatus RowStatus } vrrpOperVrId OBJECT-TYPE SYNTAX VrId MAX-ACCESS not-accessible STATUS current DESCRIPTION "This object contains the Virtual Router Identifier (VRID)." ::= { vrrpOperEntry 1 } vrrpOperVirtualMacAddr OBJECT-TYPE SYNTAX MacAddress MAX-ACCESS read-only STATUS current DESCRIPTION "The virtual MAC address of the virtual router. Although this object can be derived from the 'vrrpOperVrId' object, it is defined so that it is easily obtainable by a management application and can be included in VRRP-related SNMP traps." ::= { vrrpOperEntry 2 } vrrpOperState OBJECT-TYPE SYNTAX INTEGER { initialize(1), backup(2), master(3) } MAX-ACCESS read-only STATUS current DESCRIPTION "The current state of the virtual router. This object has three defined values: - `initialize', which indicates that all the virtual router is waiting for a startup event. - `backup', which indicates the virtual router is monitoring the availability of the master router. - `master', which indicates that the virtual router is forwarding packets for IP addresses that are associated with this router. Setting the `vrrpOperAdminState' object (below) initiates transitions in the value of this object." ::= { vrrpOperEntry 3 } vrrpOperAdminState OBJECT-TYPE SYNTAX INTEGER { up(1), down(2) } MAX-ACCESS read-create STATUS current DESCRIPTION "This object will enable/disable the virtual router function. Setting the value to `up', will transition the state of the virtual router from `initialize' to `backup' or `master', depending on the value of `vrrpOperPriority'. Setting the value to `down', will transition the router from `master' or `backup' to `initialize'. State transitions may not be immediate; they sometimes depend on other factors, such as the interface (IF) state. The `vrrpOperAdminState' object must be set to `down' prior to modifying the other read-create objects in the conceptual row. The value of the `vrrpOperRowStatus' object (below) must be `active', signifying that the conceptual row is valid (i.e., the objects are correctly set), in order for this object to be set to `up'." DEFVAL { down } ::= { vrrpOperEntry 4 } vrrpOperPriority OBJECT-TYPE SYNTAX Integer32 (0..255) MAX-ACCESS read-create STATUS current DESCRIPTION "This object specifies the priority to be used for the virtual router master election process. Higher values imply higher priority. A priority of '0', although not settable, is sent by the master router to indicate that this router has ceased to participate in VRRP and a backup virtual router should transition to become a new master. A priority of 255 is used for the router that owns the associated IP address(es)." DEFVAL { 100 } ::= { vrrpOperEntry 5 } vrrpOperIpAddrCount OBJECT-TYPE SYNTAX Integer32 (0..255) MAX-ACCESS read-only STATUS current DESCRIPTION "The number of IP addresses that are associated with this virtual router. This number is equal to the number of rows in the vrrpAssoIpAddrTable that correspond to a given IF index/VRID pair." ::= { vrrpOperEntry 6 } vrrpOperMasterIpAddr OBJECT-TYPE SYNTAX IpAddress MAX-ACCESS read-only STATUS current DESCRIPTION "The master router's real (primary) IP address. This is the IP address listed as the source in VRRP advertisement last received by this virtual router." ::= { vrrpOperEntry 7 } vrrpOperPrimaryIpAddr OBJECT-TYPE SYNTAX IpAddress MAX-ACCESS read-create STATUS current DESCRIPTION "In the case where there is more than one IP address for a given `ifIndex', this object is used to specify the IP address that will become the `vrrpOperMasterIpAddr', should the virtual router transition from backup to master. If this object is set to 0.0.0.0, the IP address which is numerically lowest will be selected." DEFVAL { '00000000'H } -- 0.0.0.0 ::= { vrrpOperEntry 8 } vrrpOperAuthType OBJECT-TYPE SYNTAX INTEGER { noAuthentication(1), -- VRRP protocol exchanges are not -- authenticated. simpleTextPassword(2), -- Exchanges are authenticated by a -- clear text password. ipAuthenticationHeader(3) -- Exchanges are authenticated using -- the IP authentication header. } MAX-ACCESS read-create STATUS current DESCRIPTION "Authentication type used for VRRP protocol exchanges between virtual routers. This value of this object is the same for a given ifIndex. New enumerations to this list can only be added via a new RFC on the standards track." DEFVAL { noAuthentication } ::= { vrrpOperEntry 9 } vrrpOperAuthKey OBJECT-TYPE SYNTAX OCTET STRING (SIZE (0..16)) MAX-ACCESS read-create STATUS current DESCRIPTION "The Authentication Key. This object is set according to the value of the 'vrrpOperAuthType' object ('simpleTextPassword' or 'ipAuthenticationHeader'). If the length of the value is less than 16 octets, the agent will left adjust and zero fill to 16 octets. The value of this object is the same for a given ifIndex. When read, vrrpOperAuthKey always returns an Octet String of length zero." ::= { vrrpOperEntry 10 } vrrpOperAdvertisementInterval OBJECT-TYPE SYNTAX Integer32 (1..255) UNITS "seconds" MAX-ACCESS read-create STATUS current DESCRIPTION "The time interval, in seconds, between sending advertisement messages. Only the master router sends VRRP advertisements." DEFVAL { 1 } ::= { vrrpOperEntry 11 } vrrpOperPreemptMode OBJECT-TYPE SYNTAX TruthValue MAX-ACCESS read-create STATUS current DESCRIPTION "Controls whether a higher priority virtual router will preempt a lower priority master." DEFVAL { true } ::= { vrrpOperEntry 12 } vrrpOperVirtualRouterUpTime OBJECT-TYPE SYNTAX TimeStamp MAX-ACCESS read-only STATUS current DESCRIPTION "This is the value of the `sysUpTime' object when this virtual router (i.e., the `vrrpOperState') transitioned out of `initialized'." ::= { vrrpOperEntry 13 } vrrpOperProtocol OBJECT-TYPE SYNTAX INTEGER { ip (1), bridge (2), decnet (3), other (4) } MAX-ACCESS read-create STATUS current DESCRIPTION "The particular protocol being controlled by this Virtual Router. New enumerations to this list can only be added via a new RFC on the standards track." DEFVAL { ip } ::= { vrrpOperEntry 14 } vrrpOperRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "The row status variable, used in accordance to installation and removal conventions for conceptual rows. The rowstatus of a currently active row in the vrrpOperTable is constrained by the operational state of the corresponding virtual router. When `vrrpOperRowStatus' is set to active(1), no other objects in the conceptual row, with the exception of `vrrpOperAdminState', can be modified. Prior to setting the `vrrpOperRowStatus' object from `active' to a different value, the `vrrpOperAdminState' object must be set to `down' and the `vrrpOperState' object be transitioned to `initialize'. To create a row in this table, a manager sets this object to either createAndGo(4) or createAndWait(5). Until instances of all corresponding columns are appropriately configured, the value of the corresponding instance of the `vrrpOperRowStatus' column will be read as notReady(3). In particular, a newly created row cannot be made active(1) until (minimally) the corresponding instance of `vrrpOperVrId' has been set and there is at least one active row in the `vrrpAssoIpAddrTable' defining an associated IP address for the virtual router." ::= { vrrpOperEntry 15 } -- ******************************************************************* -- VRRP Associated IP Address Table -- ******************************************************************* vrrpAssoIpAddrTable OBJECT-TYPE SYNTAX SEQUENCE OF VrrpAssoIpAddrEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "The table of addresses associated with this virtual router." ::= { vrrpOperations 4 } vrrpAssoIpAddrEntry OBJECT-TYPE SYNTAX VrrpAssoIpAddrEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry in the table contains an IP address that is associated with a virtual router. The number of rows for a given ifIndex and VrId will equal the number of IP addresses associated (e.g., backed up) by the virtual router (equivalent to 'vrrpOperIpAddrCount'). Rows in the table cannot be modified unless the value of `vrrpOperAdminState' is `disabled' and the `vrrpOperState' has transitioned to `initialize'." INDEX { ifIndex, vrrpOperVrId, vrrpAssoIpAddr } ::= { vrrpAssoIpAddrTable 1 } VrrpAssoIpAddrEntry ::= SEQUENCE { vrrpAssoIpAddr IpAddress, vrrpAssoIpAddrRowStatus RowStatus } vrrpAssoIpAddr OBJECT-TYPE SYNTAX IpAddress MAX-ACCESS not-accessible STATUS current DESCRIPTION "The assigned IP addresses that a virtual router is responsible for backing up." ::= { vrrpAssoIpAddrEntry 1 } vrrpAssoIpAddrRowStatus OBJECT-TYPE SYNTAX RowStatus MAX-ACCESS read-create STATUS current DESCRIPTION "The row status variable, used according to installation and removal conventions for conceptual rows. Setting this object to active(1) or createAndGo(4) results in the addition of an associated address for a virtual router. Destroying the entry or setting it to notInService(2) removes the associated address from the virtual router. The use of other values is implementation-dependent." ::= { vrrpAssoIpAddrEntry 2 } -- ******************************************************************* -- VRRP Router Statistics -- ******************************************************************* vrrpRouterChecksumErrors OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of VRRP packets received with an invalid VRRP checksum value." ::= { vrrpStatistics 1 } vrrpRouterVersionErrors OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of VRRP packets received with an unknown or unsupported version number." ::= { vrrpStatistics 2 } vrrpRouterVrIdErrors OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of VRRP packets received with an invalid VRID for this virtual router." ::= { vrrpStatistics 3 } -- ******************************************************************* -- VRRP Router Statistics Table -- ******************************************************************* vrrpRouterStatsTable OBJECT-TYPE SYNTAX SEQUENCE OF VrrpRouterStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "Table of virtual router statistics." ::= { vrrpStatistics 4 } vrrpRouterStatsEntry OBJECT-TYPE SYNTAX VrrpRouterStatsEntry MAX-ACCESS not-accessible STATUS current DESCRIPTION "An entry in the table, containing statistics information about a given virtual router." AUGMENTS { vrrpOperEntry } ::= { vrrpRouterStatsTable 1 } VrrpRouterStatsEntry ::= SEQUENCE { vrrpStatsBecomeMaster Counter32, vrrpStatsAdvertiseRcvd Counter32, vrrpStatsAdvertiseIntervalErrors Counter32, vrrpStatsAuthFailures Counter32, vrrpStatsIpTtlErrors Counter32, vrrpStatsPriorityZeroPktsRcvd Counter32, vrrpStatsPriorityZeroPktsSent Counter32, vrrpStatsInvalidTypePktsRcvd Counter32, vrrpStatsAddressListErrors Counter32, vrrpStatsInvalidAuthType Counter32, vrrpStatsAuthTypeMismatch Counter32, vrrpStatsPacketLengthErrors Counter32 } vrrpStatsBecomeMaster OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of times that this virtual router's state has transitioned to MASTER." ::= { vrrpRouterStatsEntry 1 } vrrpStatsAdvertiseRcvd OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of VRRP advertisements received by this virtual router." ::= { vrrpRouterStatsEntry 2 } vrrpStatsAdvertiseIntervalErrors OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of VRRP advertisement packets received for which the advertisement interval is different than the one configured for the local virtual router." ::= { vrrpRouterStatsEntry 3 } vrrpStatsAuthFailures OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of VRRP packets received that do not pass the authentication check." ::= { vrrpRouterStatsEntry 4 } vrrpStatsIpTtlErrors OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of VRRP packets received by the virtual router with IP TTL (Time-To-Live) not equal to 255." ::= { vrrpRouterStatsEntry 5 } vrrpStatsPriorityZeroPktsRcvd OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of VRRP packets received by the virtual router with a priority of '0'." ::= { vrrpRouterStatsEntry 6 } vrrpStatsPriorityZeroPktsSent OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of VRRP packets sent by the virtual router with a priority of '0'." ::= { vrrpRouterStatsEntry 7 } vrrpStatsInvalidTypePktsRcvd OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The number of VRRP packets received by the virtual router with an invalid value in the 'type' field." ::= { vrrpRouterStatsEntry 8 } vrrpStatsAddressListErrors OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of packets received for which the address list does not match the locally configured list for the virtual router." ::= { vrrpRouterStatsEntry 9 } vrrpStatsInvalidAuthType OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of packets received with an unknown authentication type." ::= { vrrpRouterStatsEntry 10 } vrrpStatsAuthTypeMismatch OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of packets received with 'Auth Type' not equal to the locally configured authentication method (`vrrpOperAuthType')." ::= { vrrpRouterStatsEntry 11 } vrrpStatsPacketLengthErrors OBJECT-TYPE SYNTAX Counter32 MAX-ACCESS read-only STATUS current DESCRIPTION "The total number of packets received with a packet length less than the length of the VRRP header." ::= { vrrpRouterStatsEntry 12 } -- ******************************************************************* -- Trap Definitions -- ******************************************************************* vrrpNotifications OBJECT IDENTIFIER ::= { vrrpMIB 0 } vrrpTrapPacketSrc OBJECT-TYPE SYNTAX IpAddress MAX-ACCESS accessible-for-notify STATUS current DESCRIPTION "The IP address of an inbound VRRP packet. Used by vrrpTrapAuthFailure trap." ::= { vrrpOperations 5 } vrrpTrapAuthErrorType OBJECT-TYPE SYNTAX INTEGER { invalidAuthType (1), authTypeMismatch (2), authFailure (3) } MAX-ACCESS accessible-for-notify STATUS current DESCRIPTION "Potential types of configuration conflicts. Used by vrrpAuthFailure trap." ::= { vrrpOperations 6 } vrrpTrapNewMaster NOTIFICATION-TYPE OBJECTS { vrrpOperMasterIpAddr } STATUS current DESCRIPTION "The newMaster trap indicates that the sending agent has transitioned to 'Master' state." ::= { vrrpNotifications 1 } vrrpTrapAuthFailure NOTIFICATION-TYPE OBJECTS { vrrpTrapPacketSrc, vrrpTrapAuthErrorType } STATUS current DESCRIPTION "A vrrpAuthFailure trap signifies that a packet has been received from a router whose authentication key or authentication type conflicts with this router's authentication key or authentication type. Implementation of this trap is optional." ::= { vrrpNotifications 2 } -- ******************************************************************* -- Conformance Information -- ******************************************************************* vrrpMIBCompliances OBJECT IDENTIFIER ::= { vrrpConformance 1 } vrrpMIBGroups OBJECT IDENTIFIER ::= { vrrpConformance 2 } -- ................................................................... -- Compliance Statements -- ................................................................... vrrpMIBCompliance MODULE-COMPLIANCE STATUS current DESCRIPTION "The core compliance statement for all VRRP implementations." MODULE -- this module MANDATORY-GROUPS { vrrpOperGroup, vrrpStatsGroup } OBJECT vrrpOperPriority WRITE-SYNTAX Integer32 (1..255) DESCRIPTION "SETable values are from 1 to 255." ::= { vrrpMIBCompliances 1 } -- ................................................................... -- Conformance Groups -- ................................................................... vrrpOperGroup OBJECT-GROUP OBJECTS { vrrpNodeVersion, vrrpNotificationCntl, vrrpOperVirtualMacAddr, vrrpOperState, vrrpOperAdminState, vrrpOperPriority, vrrpOperIpAddrCount, vrrpOperMasterIpAddr, vrrpOperPrimaryIpAddr, vrrpOperAuthType, vrrpOperAuthKey, vrrpOperAdvertisementInterval, vrrpOperPreemptMode, vrrpOperVirtualRouterUpTime, vrrpOperProtocol, vrrpOperRowStatus, vrrpAssoIpAddrRowStatus } STATUS current DESCRIPTION "Conformance group for VRRP operations." ::= { vrrpMIBGroups 1 } vrrpStatsGroup OBJECT-GROUP OBJECTS { vrrpRouterChecksumErrors, vrrpRouterVersionErrors, vrrpRouterVrIdErrors, vrrpStatsBecomeMaster, vrrpStatsAdvertiseRcvd, vrrpStatsAdvertiseIntervalErrors, vrrpStatsAuthFailures, vrrpStatsIpTtlErrors, vrrpStatsPriorityZeroPktsRcvd, vrrpStatsPriorityZeroPktsSent, vrrpStatsInvalidTypePktsRcvd, vrrpStatsAddressListErrors, vrrpStatsInvalidAuthType, vrrpStatsAuthTypeMismatch, vrrpStatsPacketLengthErrors } STATUS current DESCRIPTION "Conformance group for VRRP statistics." ::= { vrrpMIBGroups 2 } vrrpTrapGroup OBJECT-GROUP OBJECTS { vrrpTrapPacketSrc, vrrpTrapAuthErrorType } STATUS current DESCRIPTION "Conformance group for objects contained in VRRP notifications." ::= { vrrpMIBGroups 3 } vrrpNotificationGroup NOTIFICATION-GROUP NOTIFICATIONS { vrrpTrapNewMaster, vrrpTrapAuthFailure } STATUS current DESCRIPTION "The VRRP MIB Notification Group." ::= { vrrpMIBGroups 4 } END keepalived-2.3.1/doc/samples/0000775000175000017500000000000014166546704013057 500000000000000keepalived-2.3.1/doc/samples/keepalived.conf.fwmark0000664000175000017500000000066111260075324017233 00000000000000! Sample configuration for use Linux FWMARK global_defs { router_id io } virtual_server fwmark 1 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 900 protocol TCP real_server 192.168.201.100 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 192.168.201.101 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } } keepalived-2.3.1/doc/samples/keepalived.conf.vrrp.lvs_syncd0000664000175000017500000000204012620473233020733 00000000000000! Configuration File for keepalived vrrp_sync_group VG1 { VI_2 VI_3 } vrrp_instance VI_1 { state MASTER interface eth0 lvs_sync_daemon_interface eth1 virtual_router_id 51 priority 150 advert_int 1 authentication { auth_type PASS auth_pass grr02 } virtual_ipaddress { 192.168.200.16 192.168.200.17 192.168.200.18 } } vrrp_instance VI_2 { interface eth0 virtual_router_id 52 priority 100 advert_int 1 virtual_ipaddress { 192.168.200.19 192.168.200.20 192.168.200.21 } } vrrp_instance VI_3 { interface eth1 virtual_router_id 53 priority 100 advert_int 1 virtual_ipaddress { 192.168.201.19 192.168.201.20 192.168.201.21 } } virtual_server 192.168.200.19 80 { delay_loop 20 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.201.100 80 { weight 1 TCP_CHECK { connect_timeout 3 } } } keepalived-2.3.1/doc/samples/keepalived.conf.SMTP_CHECK0000664000175000017500000000531313167617056017437 00000000000000! Configuration File for keepalived ! ! The SMTP_CHECK connects to a smtp server ! and checks with the following dialogue: ! ! 220 mta1.somecompany.com ESMTP ! HELO foo.bar.com ! 250 mta1.somecompany.com Hello foo.bar.com [192.168.1.45], pleased to meet you ! QUIT ! 221 2.0.0 mta1.somecompany.com closing connection ! ! It specifically checks the numeric codes returned (220, 250, and 221). ! global_defs { notification_email { acassen } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL } virtual_server 192.168.200.100 25 { delay_loop 60 lb_algo rr lb_kind NAT protocol TCP ! In this real_server example we will simply check ! the ip address of the real_server. This could be ! the case where the real server only has a single ! interface that keepalived is balancing traffic ! to. real_server 172.16.1.10 25 { weight 1 SMTP_CHECK { connect_timeout 30 retry 2 delay_before_retry 5 helo_name "foo.bar.com" } } ! In this complex example, the real_server has ! multiple interfaces. Keepalived is sending traffic ! to 172.16.1.11 but the smtp server also routes ! traffic to some additional subnets. We do not ! want to dispatch traffic unless all the interfaces ! appear to be up. Note: The main ip of the real ! server that we are dispatching traffic to must ! explicitly be checked by a host directive. real_server 172.16.1.11 25 { weight 1 SMTP_CHECK { connect_timeout 10 retry 2 delay_before_retry 5 helo_name foo.bar.com host { connect_ip 172.16.1.11 } host { connect_ip 192.168.155.10 } host { connect_ip 64.233.167.99 } } } ! Final example showing some of the more extended ! features. ! ! Use connect_port to provide an alternate port ! other than the default 25. ! ! Use bindto to force the connection to originate ! from a specific interface. real_server 172.16.1.12 25 { weight 1 SMTP_CHECK { connect_timeout 10 retry 2 delay_before_retry 5 helo_name "foo.bar.com" host { connect_ip 172.16.1.12 connect_port 25 bindto 172.16.1.2 } host { connect_ip 192.168.155.11 connect_port 25 bindto 192.168.155.2 } host { connect_ip 64.233.167.100 connect_port 587 } } } } keepalived-2.3.1/doc/samples/keepalived.conf.vrrp.localcheck0000664000175000017500000000635114070347771021040 00000000000000! Configuration File for keepalived # Note: The " /dev/null` if [ -z "$SAMBA_BIN" ] ; then exit 2 fi if [ -z "$1" ] ; then echo "Usage: $0 " exit 2 fi ($SAMBA_BIN -N -L $1 -W CENTRALB -U nobody) \ | egrep '^Domain=\[[A-Za-z0-9_-]+\]' > /dev/null 2>&1 keepalived-2.3.1/doc/samples/keepalived.conf.vrrp.scripts0000664000175000017500000000217112511211300020403 00000000000000! Configuration File for keepalived ! extra script call demonstration ! scripts are supported in Instance and groups ! declarations. vrrp_sync_group G1 { group { VI_2 VI_3 } notify_backup "/usr/local/bin/vrrp.back arg1 arg2" notify_master "/usr/local/bin/vrrp.mast arg1 arg2" notify_fault "/usr/local/bin/vrrp.fault arg1 arg2" } vrrp_instance VI_1 { state MASTER interface eth0 smtp_alert virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.200.16 192.168.200.17 192.168.200.18 } notify_backup "/usr/local/bin/vrrp.sh BACKUP VI_1" notify_master "/usr/local/bin/vrrp.sh MASTER VI_1" notify_fault "/usr/local/bin/vrrp.sh FAULT VI_1" } vrrp_instance VI_2 { interface eth0 state MASTER virtual_router_id 52 priority 150 virtual_ipaddress { 192.168.200.100/27 } } vrrp_instance VI_3 { interface eth0 state MASTER virtual_router_id 53 priority 150 virtual_ipaddress { 192.168.200.101/27 } } keepalived-2.3.1/doc/samples/keepalived.conf.vrrp.static_ipaddress0000664000175000017500000000111711260075324022256 00000000000000! Configuration File for keepalived global_defs { router_id LVS_DEVEL } static_ipaddress { 192.168.200.16 dev eth0 scope link 192.168.200.17 dev eth1 scope link 192.168.200.18 dev eth2 } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 virtual_ipaddress { 192.168.200.20 } virtual_routes { src 192.168.100.1 192.168.109.0/24 via 192.168.200.254 dev eth1 192.168.110.0/24 via 192.168.200.254 dev eth1 192.168.111.0/24 dev eth2 192.168.112.0/24 via 192.168.100.254 } } keepalived-2.3.1/doc/samples/keepalived.conf.quorum0000664000175000017500000000464311260075326017302 00000000000000! Sample configuration for quorum/hysteresis setup. ! The server pool below consists of 10 servers. After ! start, the quorum will not be reached until 9 (7+2) ! live servers are present in the pool (all servers are ! equally weighted, and quorum is the sum of weights). ! Once this happens, a custom script will be executed, ! which supposedly invokes some actions to start ! announcing IP address of the virtual server to the ! world. After that the quorum will not break until ! the pool has 5 (7-2) or more live servers. Pool size ! change from 7 to 6 and back will not trigger a quorum ! flap this way. Once there are less than 5 servers, ! the quorum is considered lost and corresponding ! script is executed, supposedly propagating the ! failure, so necessary actions can be taken. ! ! Due to the alpha mode, all real servers are considered ! down on server start, so the quorum is initially lost. ! Due to the omega mode, quorum_down notifier is executed ! on keepalived shutdown as well (see keepalived.conf ! manpage for details). virtual_server 10.0.1.1 80 { delay_loop 6 lb_algo wrr lb_kind NAT persistence_timeout 900 protocol TCP alpha omega quorum 7 hysteresis 2 quorum_up /usr/local/sbin/quorum-up.sh quorum_down /usr/local/sbin/quorum-down.sh real_server 10.0.0.1 8080 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 10.0.0.2 8080 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 10.0.0.3 8080 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 10.0.0.4 8080 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 10.0.0.5 8080 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 10.0.0.6 8080 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 10.0.0.7 8080 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 10.0.0.8 8080 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 10.0.0.9 8080 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 10.0.0.10 8080 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } } keepalived-2.3.1/doc/samples/sample_notify_fifo.sh0000775000175000017500000001026714144521453017206 00000000000000#!/bin/bash # To use this script, copy it to directory /etc/keepalived/scripts # and add one or more of the following to the keepalived configuration # file in the global_defs section: # notify_fifo /etc/keepalived/scripts/notify_fifo # vrrp_notify_fifo /etc/keepalived/scripts/vrrp_notify_fifo # lvs_notify_fifo /etc/keepalived/scripts/lvs_notify_fifo # This script will then need to be executed, passing it the name of the # fifo. # # As an alternative to executing this script manually, add one or more of # the following in the global_defs section of the config: # notify_fifo_script /etc/keepalived/scripts/sample_notify_fifo.sh # vrrp_notify_fifo_script /etc/keepalived/scripts/sample_notify_fifo.sh # lvs_notify_fifo_script /etc/keepalived/scripts/sample_notify_fifo.sh # If run this way, Keepalived will terminate the script with SIGTERM when # it exits. CREATED_FIFO=0 SHUTDOWN=0 TIMEOUT=10 FIFO=$1 [[ -z $FIFO ]] && echo "A FIFO name must be specified" && exit 1 LOG_FILE=/tmp/${FIFO##*/}.log if [[ -d /run ]]; then PID_DIR=/run elif [[ -d /var/run ]]; then PID_DIR=/var/run else PID_DIR=/tmp fi PID_FILE=$PID_DIR/${FIFO##*/}.pid exiting() { # When this script exists, this function is always executed because # it is associated to the bash EXIT signal. [[ $CREATED_FIFO -eq 1 ]] && rm -f $FIFO flock -u $FD } reload_terminate() { exit 0 } stopping() { PROLOGUE=$(echo "$(date +"%a %b %e %X %Y")": \[$PPID:$$\]) echo "$PROLOGUE" STOPPING >>$LOG_FILE exit 0 } start_shutdown() { SHUTDOWN=1 # When keepalived terminates, it sends a TERM signal to this script before # sending the fifo notifies. We catch the SIGTERM here, and after a short # delay send a SIGALRM to the main script process ( sleep 0.5 kill -ALRM $$ 2>/dev/null ) & } trap stopping HUP INT QUIT USR1 USR2 PIPE ALRM trap reload_terminate QUIT trap start_shutdown TERM trap exiting EXIT exec {FD}>>"$PID_FILE" if ! flock -e -n $FD; then # Send SIGQUIT signal to the previous instance of this script. # The previous script waits for its current executed command to end # before actually calling reload_terminate(). The TIMEOUT value must # take this constraint into account. OLD_PID=$(cat $PID_FILE) if ls -l /proc/$OLD_PID/fd | grep -qw "$(readlink -f "$PID_FILE")" then kill -QUIT $OLD_PID fi flock -e --timeout $TIMEOUT $FD || exit 1 fi echo $$ >"$PID_FILE" if [[ ! -p $FIFO ]]; then mkfifo $FIFO if [[ $? -eq 0 ]]; then CREATED_FIFO=1 else echo "Unable to create fifo $FIFO" >>$LOG_FILE exit 1 fi fi # If keepalived terminates, the FIFO will be closed, so # read the FIFO in a loop. It keepalived hasn't opened the # FIFO, the script will be blocked until it has been opened. # When keepalived reloads, it sends the script a SIGTERM, and # then closes the FIFO. Since keepalived removes the FIFO, # creates a new one and runs the (possibly changed) FIFO script # again, we need to terminate if the FIFO is closed and we have # received a SIGTERM. # When keepalived stops it sends SIGTERM to the script and # afterwards send STOPPING messages, so we need to continue # reading the FIFO until it is closed. FIFO_INODE=$(stat -c "%i" $FIFO) [[ $? -ne 0 ]] && echo FIFO $FIFO not accessible >>$LOG_FILE && exit 1 while [[ $SHUTDOWN -eq 0 ]] do [[ ! -p $FIFO ]] && echo FIFO $FIFO missing >>$LOG_FILE && exit 1 exec <$FIFO [[ $? -ne 0 || $(stat -c "%i" $FIFO 2>/dev/null) -ne $FIFO_INODE ]] && break while read line; do PROLOGUE=$(echo "$(date +"%a %b %e %X %Y")": \[$PPID:$$\]) set $line TYPE=$1 if [[ $TYPE = INSTANCE || $TYPE = GROUP ]]; then VRRP_INST=${2//\"/} STATE=$3 PRIORITY=$4 # Now take whatever action is required echo "$PROLOGUE" $TYPE $VRRP_INST $STATE $PRIORITY >>$LOG_FILE elif [[ $TYPE = VS ]]; then VS=$2 STATE=$3 # Now take whatever action is required echo "$PROLOGUE" $TYPE $VS $STATE >>$LOG_FILE elif [[ $TYPE = RS ]]; then RS=$2 VS=$3 STATE=$4 # Now take whatever action is required echo "$PROLOGUE" $TYPE $RS $VS $STATE >>$LOG_FILE else echo "$PROLOGUE" $TYPE - unknown "($*)" >>$LOG_FILE fi done [[ $SHUTDOWN -eq 0 ]] && echo "$PROLOGUE" FIFO CLOSED >>$LOG_FILE done stopping keepalived-2.3.1/doc/samples/keepalived.conf.conditional_conf0000664000175000017500000000103713220013273021243 00000000000000# Run keepalived with either '-i high' or '-i low' @high net_namespace high @low net_namespace low vrrp_script check_VI_0 { @high script /etc/keepalived/scripts/check_high_VI_0.sh @low script /etc/keepalived/scripts/check_low_VI_0.sh interval 1 timeout 10 rise 3 fall 3 } vrrp_instance VI_0 { state BACKUP interface eth0 virtual_router_id 1 @high priority 170 @low priority 85 advert_int 12 version 3 use_vmac track_script { check_VI_0 } track_interface { eth3 eth2 weight 20 } virtual_ipaddress { 10.1.0.254/32 } } keepalived-2.3.1/doc/samples/keepalived.conf.status_code0000664000175000017500000000170113471774662020276 00000000000000! Configuration File for keepalived ! This example demonstrates status_code, a component of LVS configuration. global_defs { notification_email { acassen } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL } virtual_server 192.168.200.100 443 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.201.100 443 { weight 1 SSL_GET { url { path / status_code 200-299 400-499 503 505 # Can specify a HTTP status_code or a section separated by '-' or both } url { path /mrtg/ digest 9b3a0c85a887a256d6939da88aabd8cd status_code 200 # Can mix digest and status_code } connect_timeout 3 retry 3 delay_before_retry 3 } } } keepalived-2.3.1/doc/samples/keepalived.conf.virtualhost0000664000175000017500000000155513167617067020351 00000000000000! Configuration File for keepalived global_defs { notification_email { acassen } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL } virtual_server 192.168.200.100 80 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP virtualhost www.firewall.loc # The VirtualHost string to use # in the GET query. real_server 192.168.201.100 80 { weight 1 SSL_GET { url { path / digest ff20ad2481f97b1754ef3e12ecd3a9cc } url { path /mrtg/ digest 9b3a0c85a887a256d6939da88aabd8cd } connect_timeout 3 retry 3 delay_before_retry 3 } } } keepalived-2.3.1/doc/samples/keepalived.conf.UDP_CHECK0000664000175000017500000000112113612172632017264 00000000000000! Configuration File for keepalived ! This example demonstrates UDP_CHECK, a component of LVS configuration. global_defs { notification_email { acassen } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL } virtual_server 10.10.10.2 1358 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol UDP real_server 192.168.200.6 1358 { weight 1 UDP_CHECK { connect_timeout 3 retry 3 delay_before_retry 3 ! require_reply } } } keepalived-2.3.1/doc/samples/keepalived.conf.virtual_server_group0000664000175000017500000000205613167617067022252 00000000000000! Configuration File for keepalived global_defs { notification_email { acassen } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL } virtual_server_group VSG_1 { 10.0.0.1 8080 10.0.0.2 80 192.168.200.1 1358 192.168.200.3-10 80 fwmark 1 fwmark 2 } virtual_server group VSG_1 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.200.1 1358 { weight 1 HTTP_GET { url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 retry 3 delay_before_retry 3 } } real_server 192.168.200.2 1358 { weight 1 HTTP_GET { url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 retry 3 delay_before_retry 3 } } } keepalived-2.3.1/doc/samples/keepalived.conf.sample0000664000175000017500000000161613167617067017244 00000000000000! Configuration File for keepalived global_defs { notification_email { acassen } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL } vrrp_instance VI_1 { interface eth0 virtual_router_id 50 nopreempt priority 100 advert_int 1 virtual_ipaddress { 192.168.200.11 192.168.200.12 192.168.200.13 } } virtual_server 10.10.10.2 1358 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP sorry_server 192.168.200.200 1358 real_server 192.168.200.2 1358 { weight 1 HTTP_GET { url { path /testurl3/test.jsp digest 640205b7b0fc66c1ea91c463fac6334d } connect_timeout 3 retry 3 delay_before_retry 3 } } } keepalived-2.3.1/doc/samples/keepalived.conf.track_interface0000664000175000017500000000134013064432030021056 00000000000000! Configuration File for keepalived global_defs { router_id LVS_DEVEL } static_routes { 192.168.210.0/24 via 192.168.200.254 dev eth0 192.168.211.0/24 via 192.168.200.254 dev eth0 192.168.212.0/24 dev eth3 192.168.213.0/24 dev eth1 } vrrp_instance VI_1 { state MASTER interface eth0.1 # Vlaned interface track_interface { # Interface state we monitor eth0 eth1 } virtual_router_id 51 priority 100 virtual_ipaddress { 192.168.200.16 192.168.200.17 dev eth1 192.168.200.18 dev eth2 } virtual_routes { 192.168.110.0/24 via 192.168.200.254 dev eth1 192.168.111.0/24 dev eth2 192.168.112.0/24 via 192.168.100.254 } } keepalived-2.3.1/doc/samples/keepalived.conf.misc_check_arg0000664000175000017500000000077613220013273020665 00000000000000! Configuration File for keepalived global_defs { notification_email { acassen } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL } virtual_server 10.10.10.2 1358 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol TCP real_server 192.168.200.6 1358 { weight 1 MISC_CHECK { misc_path "/usr/local/bin/script.sh arg1 arg2" } } } keepalived-2.3.1/doc/samples/keepalived.conf.vrrp.sync0000664000175000017500000000331413167617065017722 00000000000000! Configuration File for keepalived vrrp_sync_group G1 { group { VI_1 VI_2 VI_5 VI_6 VI_7 VI_8 VI_9 } notify_backup "/usr/local/bin/vrrp.back arg1 arg2" notify_master "/usr/local/bin/vrrp.mast arg1 arg2" notify_fault "/usr/local/bin/vrrp.fault arg1 arg2" } vrrp_sync_group G2 { group { VI_3 VI_4 } } vrrp_instance VI_1 { interface eth0 state MASTER virtual_router_id 51 priority 100 virtual_ipaddress { 192.168.200.18/25 } } vrrp_instance VI_2 { interface eth1 state MASTER virtual_router_id 52 priority 100 virtual_ipaddress { 192.168.201.18/26 } } vrrp_instance VI_3 { interface eth0 virtual_router_id 53 priority 100 virtual_ipaddress { 192.168.200.19/27 } } vrrp_instance VI_4 { interface eth1 virtual_router_id 54 priority 100 virtual_ipaddress { 192.168.201.19/28 } } vrrp_instance VI_5 { state MASTER interface eth0 virtual_router_id 55 priority 100 virtual_ipaddress { 192.168.200.20/27 } } vrrp_instance VI_6 { state MASTER interface eth0 virtual_router_id 56 priority 100 virtual_ipaddress { 192.168.200.21/27 } } vrrp_instance VI_7 { state MASTER interface eth0 virtual_router_id 57 priority 100 virtual_ipaddress { 192.168.200.22/27 } } vrrp_instance VI_8 { state MASTER interface eth0 virtual_router_id 58 priority 100 virtual_ipaddress { 192.168.200.23/27 } } vrrp_instance VI_9 { state MASTER interface eth0 virtual_router_id 59 priority 100 virtual_ipaddress { 192.168.200.24/27 } } keepalived-2.3.1/doc/samples/keepalived.conf.PING_CHECK0000664000175000017500000000101113612172632017367 00000000000000! Configuration File for keepalived ! This example demonstrates PING_CHECK, a component of LVS configuration. global_defs { notification_email { acassen } notification_email_from Alexandre.Cassen@firewall.loc smtp_server 192.168.200.1 smtp_connect_timeout 30 router_id LVS_DEVEL } virtual_server 10.10.10.2 1358 { delay_loop 6 lb_algo rr lb_kind NAT persistence_timeout 50 protocol UDP real_server 192.168.200.6 1358 { weight 1 PING_CHECK { retry 4 } } } keepalived-2.3.1/doc/man/0000775000175000017500000000000014624033727012161 500000000000000keepalived-2.3.1/doc/man/man5/0000775000175000017500000000000014624033727013021 500000000000000keepalived-2.3.1/doc/man/man5/keepalived.conf.50000664000175000017500000040660714624033726016100 00000000000000.TH keepalived.conf 5 2024-04-29 "Keepalived" "Keepalived Configuration's Manual" .SH NAME keepalived.conf - configuration file for Keepalived .br .PP .SH Note: This documentation MUST be considered as THE exhaustive source of information in order to configure Keepalived. This documenation is supported and maintained by Keepalived Core-Team. .PP .SH DESCRIPTION \fBkeepalived.conf\fR is the configuration file which describes all the Keepalived keywords. Keywords are placed in hierarchies of blocks and subblocks, each layer being delimited by '{' and '}' pairs. .PP Comments start with '#' or '!' to the end of the line and can start anywhere in a line. .PP The keyword 'include' and variants allow inclusion of other configuration files from within the main configuration file, or from subsequently included files. .PP The format of the include directive is: \fBinclude\fR FILENAME .PP FILENAME can be a fully qualified or relative pathname, and can include wildcards, including csh style brace expressions such as "{foo/{,cat,dog},bar}" if glob() supports them. .PP After opening an included file, the current directory is set to the directory of the file itself, so any relative paths included from a file are relative to the directory of the including file itself. The include variants add additional include checks to the current include_check level (see below) The variants are: .br \fBincluder\fR FILENAME - same as include_check readable .br \fBincludem\fR FILENAME - same as include_check match .br \fBincludew\fR FILENAME - same as include_check wildcard_match .br \fBincludeb\fR FILENAME - same as include_check brace_match .br \fBincludea\fR FILENAME - all include_check checks .PP NOTE: If the libc glob() function does not support GLOB_ALTDIRFUNC (e.g. Musl libc as on Alpine Linux etc.), then only includea, includer and includew of the above options will work. .PP Why do we want to allow errors? Suppose a configuration has optional files in /etc/keepalived/conf.d, then \fIinclude_/etc/keepalived/conf.d/*\fR could be specified, but it should not error if there are no files in the directory; in this case \fIincluder\fR should be used. Otherwise it is sensible to use \fIincludea\fR. include handling will not work with if the include line uses conditional configuration or parameter substitution, since the detection of the include keywords is done before the processing on conditional configuration and parameter substitution. The basic \fIinclude\fR keyword is retained for backward compatibility, since it does not produce config errors if files could not be opened etc. .PP .SH PARAMETER SYNTAX \fB\fR is one of on|off|true|false|yes|no .br \fB\fR is a time value in seconds, including fractional seconds, e.g. 2.71828 or 3; resolution of timer is micro-seconds. .SH SCRIPTS There are three classes of scripts can be configured to be executed. (a) Notify scripts that are run when a vrrp instance or vrrp group changes state, or a virtual server quorum changes between up and down. (b) vrrp tracking scripts that will cause vrrp instances to go down if they exit a non-zero exist status, or if a weight is specified will add or subtract the weight to/from the priority of that vrrp instance. (c) LVS checker misc scripts that will cause a real server to be configured down if they exit with a non-zero status. By default the scripts will be executed by user keepalived_script if that user exists, or if not by root, but for each script the user/group under which it is to be executed can be specified. There are significant security implications if scripts are executed with root privileges, especially if the scripts themselves are modifiable or replaceable by a non root user. Consequently, security checks are made at startup to ensure that if a script is executed by root, then it cannot be modified or replaced by a non root user. All scripts should be written so that they will terminate on receipt of a SIGTERM signal. Scripts will be sent SIGTERM if their parent terminates, or it is a script that keepalived is awaiting its exit status and it has run for too long. .PP .SH Quoted strings Quoted strings are specified between " or ' characters and strings are delimited by whitespace. In the examples below the \' characters are not part of the strings and should not be specified: .nf .RS \'abcd" efg h jkl "mnop\' .RE .fi will be the single string: .nf .RS \'abcd efg h jkl mnop\' .RE whereas: .nf .RS \'abcd "efg h jkl" mnop\' .RE .fi will be the three strings: .nf .RS \'abcd\', \'efg h jkl\' and \'mnop\' .RE i.e. the " and ' characters are removed and any intervening whitespace is retained. .PP Quoted strings can also have escaped characters, like the shell. \\a, \\b, \\E, \\f, \\n, \\r, \\t, \\v, \\nnn and \\xXX (where nnn is up to 3 octal digits, and XX is any sequence of hex digits) and \\cC (which produces the control version of character C) are all supported. \\C for any other character C is just treated as an escaped version of character C, so \\\\ is a \\ character and \\" will be a " character, but it won't start or terminate a quoted string. .PP For specifying scripts with parameters, unquoted spaces will separate the parameters. If it is required for a parameter to contain a space, it should be enclosed in single quotes ('). .PP .SH CONFIGURATION PARSER Traditionally the configuration file parser has not been one of the strengths of keepalived. Lot of efforts have been put to correct this even if this is not the primal goal of the project. .SH TOP HIERACHY .PP Keepalived configuration file is articulated around a set of configuration blocks. Each block is focusing and targetting a specific daemon family feature. These features are: .PP \fBGLOBAL CONFIGURATION\fR .PP \fBBFD CONFIGURATION\fR .PP \fBVRRPD CONFIGURATION\fR .PP \fBLVS CONFIGURATION\fR .SH GLOBAL CONFIGURATION contains subblocks of \fBGlobal definitions, Linkbeat interfaces, Interface up/down transition delays, Static track groups, Static addresses, Static routes,\fR and \fBStatic rules\fR .PP .SH Global definitions .PP .nf # Following are global daemon facilities for running # keepalived in a separate network namespace: # -- # Set the network namespace to run in. # The directory /run/keepalived will be created as an # unshared mount point, for example for pid files. # syslog entries will have _NAME appended to the ident. # Note: the namespace cannot be changed on a configuration reload. \fBnet_namespace \fRNAME # Add the IPVS configuration in the specified net namespace. It allows to easily # split the VIP traffic on a given namespace and keep the healthchecks traffic # in another namespace. If NAME is not specified, then the default namespace # will be used. \fBnet_namespace_ipvs \fRNAME # ipsets wasn't network namespace aware until Linux 3.13, and so # if running with an earlier version of the kernel, by default # use of ipsets is disabled if using a namespace and vrrp_ipsets # has not been specified. This options overrides the default and # allows ipsets to be used with a namespace on kernels prior to 3.13. \fBnamespace_with_ipsets\fR # If multiple instances of keepalived are run in the same namespace, # this will create pid files with NAME as part of the file names, # in /run/keepalived. # Note: the instance name cannot be changed on a configuration reload \fBinstance \fRNAME # Create pid files in /run/keepalived \fBuse_pid_dir\fR # Poll to detect media link failure using ETHTOOL, MII or ioctl interface # otherwise uses netlink interface. \fBlinkbeat_use_polling\fR # Time for main process to allow for child processes to exit on termination # in seconds. This can be needed for very large configurations. # (default: 5) \fBchild_wait_time \fRSECS Note: All processes/scripts run by keepalived are run with parent death signal set to SIGTERM. All such processes/scripts should either not change the action for SIGTERM, or ensure that the process/script terminates once SIGTERM is received, possibly following any cleanup actions needed. # Global definitions configuration block \fBglobal_defs \fR{ # In order to ensure that all processes read exactly the same configuration, # while the config is first read it is written, by default, to a memory based # file (or to an anonymous file in /tmp/ if memfd_create() is not supported). # If your configuration is very large, you may not want the copy to be # held in memory, in which case specifing the \fItmp_config_directory\fR causes the # configuration to be written to an anonymous file on the filesystem on which # the specified directory resides, which must be writeable by keepalived. # This setting cannot be changed on a reload, and it should be specified as # early as possible in the configuration. \fBtmp_config_directory\fR DIRECTORY # config_save_dir causes keepalived to save configuration state and # configuration files before and after each reload. This is used for debugging # purposes if there appear to be problems related to repeated reloads. # The directory will be created if it does not exist, but all parent # directories must exist. \fBconfig_save_dir\fR DIRECTORY # Set the process names of the keepalived processes to the default values: # keepalived, keepalived_vrrp, keepalived_ipvs, keepalived_bfd \fBprocess_names\fR # Specify the individual process names \fBprocess_name\fR NAME \fBvrrp_process_name\fR NAME \fBchecker_process_name\fR NAME \fBbfd_process_name\fR NAME # keepalived by default resolves script path names to remove symlinks. # To keep symlinks in pathnames, specify use_syslink_paths. \fBuse_symlink_paths \fR[] # The startup and shutdown scripts are run once, when keepalived starts # before any child processes are run, and when keepalived stops after # all child processes have terminated, respectively. # The original motivation for adding this feature was that although # keepalived can setup IPVS configuration using firewall marks, there # was no mechanism for adding configuration to set the firewall marks # (or for removing it afterwards). # This feature can also be used to setup the iptables framework required # if using iptables (see vrrp_iptables option below), modify interface # settings, or anything else that can be done from a script or program. # Only one startup script and one shutdown script can be specified. # The timeouts (in seconds default 10 seconds) are the time allowed for # scripts to run; if the timeout expires the scripts will be killed (this # is to stop keepalived hanging waiting for the scripts to terminate). \fBstartup_script\fR SCRIPT_NAME [username [groupname]] \fBstartup_script_timeout\fR SECONDS # range [1,1000] \fBshutdown_script\fR SCRIPT_NAME [username [groupname]] \fBshutdown_script_timeout\fR SECONDS # range [1,1000] # Set of email To: notify. To include a display name, the whole email address # must be included in double quotes("). \fBnotification_email \fR{ admin@example1.com "My admin " ... } # email from address that will be in the header (see comment above for # including a display name). # (default: keepalived@local_host_name) \fBnotification_email_from \fRadmin@example.com # Remote SMTP server used to send notification email. # IP address or domain name with optional port number. # (default port number: 25) \fBsmtp_server \fR127.0.0.1 [] # Name to use in HELO messages. # (default: local host name) \fBsmtp_helo_name \fR # SMTP server connection timeout in seconds. \fBsmtp_connect_timeout \fR30 # Sets default state for all smtp_alerts \fBsmtp_alert \fR # Sets default state for vrrp smtp_alerts \fBsmtp_alert_vrrp \fR # Sets default state for checker smtp_alerts \fBsmtp_alert_checker \fR # Logs every failed real server check in syslog # (nevertheless, SMTP alert is only sent when all retry checks failed # and real server transitions to DOWN state) \fBchecker_log_all_failures \fR # Don't send smtp alerts for fault conditions \fBno_email_faults\fR # String identifying the machine (doesn't have to be hostname). # (default: local host name) \fBrouter_id \fR # Multicast Group to use for IPv4 VRRP adverts # Defaults to the RFC5798 IANA assigned VRRP multicast address 224.0.0.18 # which You typically do not want to change. \fBvrrp_mcast_group4 \fR224.0.0.18 # Multicast Group to use for IPv6 VRRP adverts # (default: ff02::12) \fBvrrp_mcast_group6 \fRff02::12 # sets the default interface for static addresses. # (default: eth0) \fBdefault_interface \fRp33p1.3 # The sync daemon as provided by the IPVS kernel code only supports # one master and one backup daemon instance at a time to synchronize # the IPVS connection table. # See ipvsadm(8) man page for more details of the sync daemon. # Parameters are binding interface, and optional: # inst VRRP_INSTANCE (inst can be omitted for backward compatibility) # syncid (0 to 255) for lvs syncd, default is the VRID of vrrp instance, # or 0 if no vrrp instance # maxlen (1..65507) maximum packet length (limit is mtu - 20 - 8) # port (1..65535) UDP port number to use, default 8848 # ttl (1..255) # group - multicast group address(IPv4 or IPv6), default 224.0.0.81 # If VRRP_INSTANCE is not specified, both the master and backup sync daemons # will be run as long as keepalived is running, otherwise the sync daemon # master/backup state tracks the state of the specified vrrp instance: if # the vrrp instance is in master state, only the master sync daemon will run, # if the vrrp instance is not master, only the backup sync daemon will run. # NOTE: maxlen, port, ttl and group are only available on Linux 4.3 or later. # See kernel source doc/Documentation/networking/ipvs-sysctl.txt for details of # parameters controlling IPVS and the sync daemon. # /proc/net/ip_vs* provide some details about the state of IPVS. \fBlvs_sync_daemon \fR [[inst] ] [id ] \e [maxlen ] [port ] [ttl ] [group ] # lvs_timeouts specifies the tcp, tcp_fin and udp connection tracking timeouts # in seconds. At least one value must be specified; not setting a value leaves # it unchanged from when keepalived started. \fBlvs_timeouts\fR [tcp SECS] [tcpfin SECS] [udp SECS] # flush any existing LVS configuration at startup \fBlvs_flush\fR # flush remaining LVS configuration at shutdown (for large configurations # this is much faster than the default approach of deleting each RS and # each VS individually). # If VS is specified, remove each keepalived managed virtual # server without explicitly removing the real servers (the kernel will # remove them). \fBlvs_flush_on_stop [VS]\fR # delay for second set of gratuitous ARPs after transition to MASTER. # in seconds, 0 for no second set. # (default: 5) \fBvrrp_garp_master_delay \fR10 # number of gratuitous ARP messages to send at a time after # transition to MASTER. # (default: 5) \fBvrrp_garp_master_repeat \fR1 # delay for second set of gratuitous ARPs after lower priority # advert received when MASTER. # (default: vrrp_garp_master_delay) \fBvrrp_garp_lower_prio_delay \fR10 # Default value for vrrp down_timer_adverts. \fBvrrp_down_timer_adverts \fR[1:100] # number of gratuitous ARP messages to send at a time after # lower priority advert received when MASTER. # (default: vrrp_garp_master_repeat) \fBvrrp_garp_lower_prio_repeat \fR1 # minimum time interval for refreshing gratuitous ARPs while MASTER. # in seconds (resolution seconds). # (default: 0 (no refreshing)) \fBvrrp_garp_master_refresh \fR60 # number of gratuitous ARP messages to send at a time while MASTER # (default: 1) \fBvrrp_garp_master_refresh_repeat \fR2 # Delay between gratuitous ARP messages sent on an interface # decimal, seconds (resolution usecs). # (default: 0) \fBvrrp_garp_interval \fR0.001 # Delay between unsolicited NA messages sent on an interface # decimal, seconds (resolution usecs). # (default: 0) \fBvrrp_gna_interval \fR0.000001 # By default keepalived sends 5 gratuitions ARP/NA messages at a # time, and after transitioning to MASTER sends a second block of # 5 messages 5 seconds later. # With modern switches this is unnecessary, so setting vrrp_min_garp # causes only one ARP/NA message to be sent, with no repeat 5 seconds # later. \fBvrrp_min_garp \fR[] # The following option causes periodic GARP/NA messages to be sent on # interfaces of VIPs/eVIPs that are not the interface of the VRRP # instance, in order to ensure that switch MAC caches are maintained # (specified in seconds). # Many switches have a default cache timeout of 300 seconds, and so # a garp repeat rate of 1/3rd of that would be sensible. The maximum # permitted value is 1 day (86400 seconds); # By default, it will only send on VMAC interfaces; specifying \fBall\fR # will cause it to send GARP/NA on each interface used by the VRRP instance. \fBvrrp_garp_extra_if [all] \fR100 # If a lower priority advert is received, don't send another advert. # This causes adherence to the RFCs. Defaults to false, unless # strict_mode is set. \fBvrrp_lower_prio_no_advert \fR[] # If we are master and receive a higher priority advert, send an advert # (which will be lower priority than the other master), before we # transition to backup. This means that if the other master has # garp_lower_priority_repeat set, it will resend garp messages. # This is to get around the problem of their having been two simultaneous # masters, and the last GARP messages seen were from us. \fBvrrp_higher_prio_send_advert \fR[] # Set the default VRRP version to use # (default: 2, but IPv6 instances will use version 3) \fBvrrp_version \fR<2 or 3> # See vrrp_instance description of V3_checksum_as_V2 \fBv3_checksum_as_v2\fR [] # keepalived uses a firewall (either nftables or iptables) for two purposes: # i) To implement no_accept mode # ii) To stop IGMP/MLD/Router-Solicit packets being sent on VMAC interfaces, # and to move IGMP/MLD messages onto the underlying interface. # If both vrrp_iptables and vrrp_nftables are specified, keepalived will use # nftables and not iptables. Similarly, if the iptables command is generating # nftables configuration, or there is no iptables command installed, # keepalived will use nftables rather than iptables. # If neither vrrp_nftables or vrrp_iptables are specified but VMACs are in use # or no_accept is specified, keepalived will use nftables if it is available. # Use nftables as the firewall. # TABLENAME must not exist, and must be different for each # instance of keepalived running in the same network namespace. # Default tablename is keepalived, and priority is -1. # keepalived will create base chains in the table. # counters means counters are added to the rules (primarily for # debugging purposes). # ifindex means create IPv6 link local sets using ifindex rather # than ifnames. This is the default unless the vrrp_instance has # set dont_track_primary. The alternative is to use interface names # as part of the set key, but the nft utility prior to v0.8.3 will # then not output interface names properly. \fBnftables \fR[TABLENAME] \fBnftables_priority \fRPRIORITY \fBnftables_counters\fR \fBnftables_ifindex\fR # Similarly for IPVS iptables - used for setting fwmarks for virtual # server groups. keepalived will allocate a fwmark for each virtual # server group, so that only one virtual server for each group needs # to be configured in IPVS, by using a fwmark, and nftables will be # used to set the fwmark for each of the virtual server # address/protocol/port combinations specified. # nftables_ipvs_start_fwmark specifies the first fwmark for keepalived # to use (default 1000). This will be incremented for each subsequent # virtual server group. \fBnftables_ipvs \fR[TABLENAME] \fBnftables_ipvs_priority \fRPRIORITY \fBnftables_ipvs_start_fwmark \fRNUMBER # Use iptables as the firewall. # Note: it is necessary for the specified chain to exist in # the iptables and/or ip6tables configuration, and for the chain # to be called from an appropriate point in the iptables configuration. # It will probably be necessary to have this filtering after accepting # any ESTABLISHED,RELATED packets, because IPv4 might select the VIP as # the source address for outgoing connections. # Note: although the default chains that are used are INPUT and OUTPUT, # since those are the only chains that will always exist, it is not safe # or sensible to use those chains and specific chains should be created # and called from appropriate points in the iptables configuration. The # chains used for keepalived should not be used for any other purpose, and # should have no rules configured, other than the rules that keepalived # manages. # A startup_script (see above) can be used to create the chains and to # add rules to call them. A shutdown_script can be used to remove the # iptables configuration added by the startup_script. # Note2: If using ipsets, the iptables VIP rules are appended to the end # of the specified chains; if not using ipsets, the VIP rules are inserted # at the beginning of the chains. Any IGMP rules are always appended to # the end of the chains. # (default: INPUT) \fBvrrp_iptables \fRkeepalived # or for outbound filtering as well # Note, outbound filtering won't work with IPv4, since the VIP can be # selected as the source address for an outgoing connection. With IPv6 # this is unlikely since the addresses are deprecated. \fBvrrp_iptables \fRkeepalived_in keepalived_out # or to to use default chains (INPUT and OUTPUT) \fBvrrp_iptables\fR # Keepalived may have the option to use ipsets in conjunction with # iptables. If so, then the ipset names can be specified, defaults # as below. If no names are specified, ipsets will not be used, # otherwise any omitted names will be constructed by adding "_if" # and/or "6" and _igmp/_mld/_nd to previously specified names. \fBvrrp_ipsets \fR[keepalived [keepalived6 [keepalived_if6 [keepalived_igmp [keepalived_mld [keepalived_vmac_nd]]]]]] # An alternative to moving IGMP messages from VMACs to their parent interfaces # is to disable them altogether in the kernel by setting # igmp_link_local_mcast_reports false. # This stops IGMP join etc messages for 224.0.0.0/24, since they should # always be forwarded to all interfaces (see RFC4541). # This is available from Linux 4.3 onwards. disable_local_igmp # The following enables checking that when in unicast mode, the # source address of a VRRP packet is one of our unicast peers. \fBvrrp_check_unicast_src\fR # Checking all the addresses in a received VRRP advert can be time # consuming. Setting this flag means the check won't be carried out # if the advert is from the same master router as the previous advert # received. # (default: don't skip) \fBvrrp_skip_check_adv_addr\fR # Enforce strict VRRP protocol compliance. This currently includes # enforcing the following. Please note that other checks may be # added in the future if they are found to be missing: # 0 VIPs not allowed # unicast peers not allowed # IPv6 addresses not allowed in VRRP version 2 # First IPv6 VIP is link local # State MASTER can be configured if and only if priority is 255 # Authentication is not supported # Preempt delay is not supported # Accept mode cannot be set for VRRPv2 # If accept/no accept is not specified, accept is set if priority # is 255 aand cleared otherwise # Gratuitous ARP repeats cannot be enabled # Cannot clear lower_prio_no_advert # Cannot set higher_prio_send_advert # Cannot use vmac_xmit_base # Cannot have no VIPs with VRRPv3 \fBvrrp_strict\fR # Send vrrp instance priority notifications on notify FIFOs. \fBvrrp_notify_priority_changes\fR # The following options can be used if vrrp, checker or bfd processes # are timing out. This can be seen by a backup vrrp instance becoming # master even when the master is still running, because the master or # backup system is too busy to process vrrp packets. # -- # keepalived can, if it detects that it is not running sufficiently # soon after a timer should expire, increase its priority, first # of all switching to realtime scheduling, and if that is not # sufficient, it will then increase its realtime priority by one each # time it detects a further delay in running. If the event that realtime # scheduling is enabled, RLIMIT_RTTIME will be set, using the values for # {bfd,checker,vrrp}_rlimit_rttime (see below). These values may need # to be increased for slower processors. # -- # To limit the maximum increased automatic priority, specify the following # (0 doesn't use automatic priority increases, and is the default. -1 disables # the warning message at startup). Omitting the priority sets the maximum value. \fBmax_auto_priority\fR [<-1 to 99>] # 99 is really sched_get_priority_max(SCHED_RR) # Minimum delay in microseconds after timer expires before keeplalived is # scheduled after which the process priority will be auto incremented # (default is 1000000 usecs (1 second), maximum is 10000000 (10 seconds)) \fBmin_auto_priority_delay\fR # Set the vrrp child process priority (Negative values increase priority) \fBvrrp_priority \fR<-20 to 19> # Set the checker child process priority \fBchecker_priority \fR<-20 to 19> # Set the BFD child process priority \fBbfd_priority \fR<-20 to 19> # Set the vrrp child process non swappable \fBvrrp_no_swap\fR # Set the checker child process non swappable \fBchecker_no_swap\fR # Set the BFD child process non swappable \fBbfd_no_swap\fR # The following options can be used to force vrrp, checker and bfd # processes to run on a restricted CPU set. # You can either bind processes to a single CPU or define a set of # cpu. In that last case Linux kernel will be restricted to that cpu # set during scheduling. Forcing process binding to single CPU can # increase performances on heavy loaded box. # INTEGER following configuration keyword are representing cpu_id # as shown in /proc/cpuinfo on line "processor:" # -- # Set CPU Affinity for the vrrp child process \fBvrrp_cpu_affinity\fR []...[] # Set CPU Affinity for the checker child process \fBchecker_cpu_affinity\fR []...[] # Set CPU Affinity for the bfd child process \fBbfd_cpu_affinity\fR []...[] # Set the vrrp child process to use real-time scheduling # at the specified priority \fBvrrp_rt_priority \fR<1..99> # Set the checker child process to use real-time scheduling # at the specified priority \fBchecker_rt_priority \fR<1..99> # Set the BFD child process to use real-time scheduling # at the specified priority \fBbfd_rt_priority \fR<1..99> # Set the limit on CPU time between blocking system calls, # in microseconds # (default: 10000) \fBvrrp_rlimit_rttime \fR>=2 \fBchecker_rlimit_rttime \fR>=2 \fBbfd_rlimit_rttime \fR>=2 # If Keepalived has been build with SNMP support, the following # keywords are available. # Note: Keepalived, checker and RFC support can be individually # enabled/disabled # -- # Specify socket to use for connecting to SNMP master agent # (see source module keepalived/vrrp/vrrp_snmp.c for more details) # (default: unix:/var/agentx/master) \fBsnmp_socket \fRudp:1.2.3.4:705 # enable SNMP handling of vrrp element of KEEPALIVED MIB \fBenable_snmp_vrrp\fR # enable SNMP handling of checker element of KEEPALIVED MIB \fBenable_snmp_checker\fR # enable SNMP handling of RFC2787 and RFC6527 VRRP MIBs \fBenable_snmp_rfc\fR # enable SNMP handling of RFC2787 VRRP MIB \fBenable_snmp_rfcv2\fR # enable SNMP handling of RFC6527 VRRP MIB \fBenable_snmp_rfcv3\fR # enable SNMP traps \fBenable_traps\fR # When SNMP requests are made, the checker process only updates the # virtual and real server stats from the kernel if the last time the # stats for that virtual server were read was more than this configured # interval (in seconds). The default interval is 5 seconds, and the # valid range is 0.001 (1 milli-second) to 30 seconds. \fBsnmp_vs_stats_update_interval\fR # Like snmp_vs_stats_update_interval but for real servers. Stats for # real servers are only read if there is an SNMP request for real server # stats. \fBsnmp_rs_stats_update_interval\fR # If Keepalived has been build with DBus support, the following # keywords are available. # -- # Enable the DBus interface \fBenable_dbus\fR # Name of DBus service # Useful if you want to run multiple keepalived processes with DBus enabled # (default: org.keepalived.Vrrp1) \fBdbus_service_name \fRSERVICE_NAME # String to use for DBus path when VRRP instance has no interface configured # Useful if your system has an interface named "none"! # (default: "none") \fBdbus_no_interface_name \fRNAME # Specify the default username/groupname to run scripts under. # If this option is not specified, the user defaults to keepalived_script # if that user exists, otherwise the uid/gid under which keepalived is running. # If groupname is not specified, it defaults to the user's group. \fBscript_user \fRusername [groupname] # Don't run scripts configured to be run as root if any part of the path # is writable by a non-root user. Also, enforce the default script_user is # keepalived_script, and don't default to the user under which keepalived # is running (usually root). \fBenable_script_security\fR # Rather than using notify scripts, specifying a fifo allows more # efficient processing of notify events, and guarantees that they # will be delivered in the correct sequence. # NOTE: the FIFO names must all be different # -- # FIFO to write notify events to # See vrrp_notify_fifo and lvs_notify_fifo for format of output # For further details, see the description under vrrp_sync_group. # see doc/samples/sample_notify_fifo.sh for sample usage. \fBnotify_fifo \fRFIFO_NAME [username [groupname]] # script to be run by keepalived to process notify events # The FIFO name will be passed to the script as the last parameter \fBnotify_fifo_script \fRSTRING|QUOTED_STRING [username [groupname]] # FIFO to write vrrp notify events to. # The string written will be a line of the form: INSTANCE "VI_1" MASTER 100 # and will be terminated with a new line character. # For further details of the output, see the description under vrrp_sync_group # and doc/samples/sample_notify_fifo.sh for sample usage. \fBvrrp_notify_fifo \fRFIFO_NAME [username [groupname]] # script to be run by keepalived to process vrrp notify events # The FIFO name will be passed to the script as the last parameter \fBvrrp_notify_fifo_script \fRSTRING|QUOTED_STRING [username [groupname]] # FIFO to write notify healthchecker events to # The string written will be a line of the form: # VS [192.168.201.15]:tcp:80 {UP|DOWN} # RS [1.2.3.4]:tcp:80 [192.168.201.15]:tcp:80 {UP|DOWN} # and will be terminated with a new line character. \fBlvs_notify_fifo \fRFIFO_NAME [username [groupname]] # script to be run by keepalived to process healthchecher notify events # The FIFO name will be passed to the script as the last parameter \fBlvs_notify_fifo_script \fRSTRING|QUOTED_STRING [username [groupname]] # By default, when keepalived reloads the vrrp instance and sync group states # are not written to the relevant FIFOs. Setting this option will cause the # states to be sent to the FIFO(s) when keepalived reloads. \fBfifo_write_vrrp_states_on_reload\fR # Allow configuration to include interfaces that don't exist at startup. # This allows keepalived to work with interfaces that may be deleted and restored # and also allows virtual and static routes and rules on VMAC interfaces. # allow_if_changes allows an interface to be deleted and recreated with a # different type or underlying interface, eg changing from vlan to macvlan # or changing a macvlan from eth1 to eth2. This is predominantly used for # reporting duplicate VRID errors at startup if allow_if_changes is not set. \fBdynamic_interfaces [allow_if_changes]\fR # The following options are only needed for large configurations, where either # keepalived creates a large number of interface, or the system has a large # number of interface. These options only need using if # "Netlink: Receive buffer overrun" messages are seen in the system logs. # If the buffer size needed exceeds the value in /proc/sys/net/core/rmem_max # the corresponding force option will need to be set. # -- # Set netlink receive buffer size. This is useful for # very large configurations where a large number of interfaces exist, and # the initial read of the interfaces on the system causes a netlink buffer # overrun. \fBvrrp_netlink_cmd_rcv_bufs \fRBYTES \fBvrrp_netlink_cmd_rcv_bufs_force \fR \fBvrrp_netlink_monitor_rcv_bufs \fRBYTES \fBvrrp_netlink_monitor_rcv_bufs_force \fR # The vrrp netlink command and monitor socket the checker command and # and monitor socket and process monitor buffer sizes can be independently set. # The force flag means to use SO_RCVBUFFORCE, so that the buffer size # can exceed /proc/sys/net/core/rmem_max. \fBlvs_netlink_cmd_rcv_bufs \fRBYTES \fBlvs_netlink_cmd_rcv_bufs_force \fR \fBlvs_netlink_monitor_rcv_bufs \fRBYTES \fBlvs_netlink_monitor_rcv_bufs_force \fR # As a guide for process_monitor_rcv_bufs for 1400 processes terminating # simultaneously, 212992 (the default on some systems) is insufficient, whereas # 500000 is sufficient. \fBprocess_monitor_rcv_bufs \fRBYTES \fBprocess_monitor_rcv_bufs_force \fR # When a socket is opened, the kernel configures the max rx buffer size for # the socket to /proc/sys/net/core/rmem_default. On some systems this can be # very large, and even generally this can be much larger than necessary. # This isn't a problem so long as keepalived is reading all queued data from # it's sockets, but if rmem_default was set sufficiently large, and if for # some reason keepalived stopped reading, it could consume all system memory. # The vrrp_rx_bufs_policy allows configuring of the rx bufs size when the # sockets are opened. If the policy is MTU, the rx buf size is configured # to the total of interface's MTU * vrrp_rx_bufs_multiplier for each vrrp # instance using the socket. Likewise, if the policy is ADVERT, then it is # the total of each vrrp instances advert packet size * multiplier. # (default: use system default) \fBvrrp_rx_bufs_policy \fR[MTU|ADVERT|NUMBER] # (default: 3) \fBvrrp_rx_bufs_multiplier \fRNUMBER # Send notifies at startup for real servers that are starting up \fBrs_init_notifies\fR # Don't send an email every time a real server checker changes state; # only send email when a real server is added or removed \fBno_checker_emails\fR # The umask to use for creating files. The number can be specified in hex, octal # or decimal. BITS are I{R|W|X}{USR|GRP|OTH}, e.g. IRGRP, separated by '|'s. # IRWX{U|G|O} can also be specified. # The default umask is IXUSR | IRWXG | IRWXO. This option cannot override the # command-line option. \fBumask \fR[NUMBER|BITS] # On some systems when bond interfaces are created, they can start passing traffic # and then have a several second gap when they stop passing traffic inbound. This # can mean that if keepalived is started at boot time, i.e. at the same time as # bond interfaces are being created, keepalived doesn't receive adverts and hence # can become master despite an instance with higher priority sending adverts. # This option specifies a delay in seconds before vrrp instances start up after # keepalived starts, \fBvrrp_startup_delay \fR5.5 # The following will cause logging of receipt of VRRP adverts for VRIDs not configured # on the interface on which they are received. \fBlog_unknown_vrids\fR # Specify the prefix for generated VMAC names (default "vrrp") \fBvmac_prefix \fRSTRING # Specify the prefix for generated VMAC names for VIPs which use a VMAC but are not # on the VRRP instance's interface (default vmac_prefix value) \fBvmac_addr_prefix \fRSTRING # Specify random seed for ${_RANDOM}, to make configurations repeatable (default # is to use a seed based on the time, so that each time a different configuration # will be generated). \fBrandom_seed \fRUNSIGNED_INT # If a configuration reload is attempted with an updated configuration file that has # errors, keepalived may terminate, and possibly enter a loop indefinitely restarting # and terminating. If reload_check_config is set, then keepalived will attempt to # validate the configuration before initiating a reload, and only initiate the reload # if the configuration is valid. \fBreload_check_config \fR[LOG_FILE] # Treat any missing include file as an error. The OPTIONS can be any combination of # readable - error if a match is not a readable file # match - error if no file matches (unless wildcard specified) # wildcard_match - error if no file matches (even if wildcard specified) # brace_match - error if a brace expansion does not match a file # Note: match, wildcard_match and brace_match include the readable check. # The setting of include_check is saved when a new include file is opened, and restored # when the file is closed. This means that the include_check setting when reading a # file cannot be changed by a subsequently included file. To change the setting for all # included files, include_check should be set at the beginning of the configuration file # specified in the command line (default /etc/keepalived/keepalived.conf). # Note2: If the libc glob() function does not support GLOB_ALTDIRFUNC (e.g. Musl libc as # on Alpine Linux etc.), then only readable and wildcard_match of the above options will work. # It is possible to add or remove individual settings; '+' means add the following # checks, '-' means remove the following checks. For example # \fIinclude_check +match -wildcard_match\fR # adds the requirement that there is a matching file, and removes the requirement for # wildcard matches. # If no option is specified, it is the same as specifying all options. \fBinclude_check \fR[OPTIONS] # reload_time_file allows a reload of keepalived to be scheduled in the future. This is # particularly useful if there is a master keepalived and one or more backup keepalived # instances and the new configuration is incompatible with the previous configuration, # e.g. adding or removing VIPs which would cause adverts to be rejected. # All the instances can be scheduled to reload at the same time, thereby ensuring that # no mismatching adverts are received by the backup instances. # The configuration specifies a file which keepalived will monitor. The first line of # the file must contain a valid time or date/time exactly in the formats specified below. # When keepalived starts up, it reads the file if it exists, and schedules a reload at # the specified time. If the file does not exist, then when it is subsequently created # a reload will be scheduled. If the file is updated, the reload time will be modified # accordingly. If the file is deleted, the reload is cancelled. # Normally when the reload occurs the specified file is deleted, since the reload has # been done; if the file included a date then the reload will be in the past and so # ignored. However, if there is no date, then if the file were reread following the # reload, a reload would be scheduled for 24 hours time. In order to stop this, the # file is deleted (unlinked) by default. If reload_repeat is specified, then the # file is not deleted, and if the file contains a time only with no date, then # keepalived will keep reloading at that time every day until the file is removed or # modified. # If the directory containing the file does not exist at startup/reload, or if the # directory is removed or renamed, then no future scheduled reloads will occur until # a manual (SIGHUP) reload is done or keepalived restarts. # The permitted formats of the entry in the timer file are precisely: # HH:MM:SS # YY-MM-DD HH:MM:SS # YYYY-MM-DD HH:MM:SS # each with an optional 'Z' at the end. # There must be no leading or trailing whitespace, and only one space between the date # and the time. # If there is a 'Z' at the end of the time, the time is parsed as UTC, otherwise the # time is the localtime for the environment in which keepalived is running. If the # systems which are being reloaded are in different timezones, it is probably safer to # use UTC. # If using local time with daylight savings, beware that some times don't exist and # some times are duplicated and hence ambiguous. \fBreload_time_file\fR ABSOLUTE-PATHNAME-OF-FILE \fBreload_repeat\fR # Some users frequently update their configurations and reload keepalived. reload_file # provides a mechanism that allows the configuration update processes not to update the # configuration files while keepalived is reading them. # The reload file will be created by keepalived before it starts reading configuration # files, unless the file exists. If the file already exists, it will be truncated. Once # keepalived has completed reading the files it will remove the reload file. # If reload_file with no file name is specified, the default filename keepalived.reload # in the PID directory will be used. # The best way to use the reload file is for the configuration update process to touch # the reload file before it signals keepalived to reload, and then wait for the file # to be deleted, which indicates that keepalived has finished reading the config files. # When keepalived starts reading the configuration files, since it truncates the reload # file, if update process creates the reload_file with non-zero size, it can detect # the reloading starting by the reload_file becoming zero length. \fBreload_file\fR [ABSOLUTE-PATHNAME-OF-FILE] # Sending SIGUSR1 to keepalived causes it to dump its data structures # for debugging purposes, although some users use this feature and # process the output. Please note that the format of the .data files # produced is not guaranteed to maintain backward compatibility. # The standard file names are keepalived_parent.data, keepalived.data, # keepalived_check.data and keepalived_bfd.data. This causes a problem # if more than one keepalived instance is running on a system. # In order to alleviate this, enabling data_use_instance includes the # instance name and network namespace in the file name of the .data files. \fBdata_use_instance \fR[] # json_version 2 puts the VRRP data in a named array and adds # track_process details. Default is version 1. \fBjson_version \fR{1|2} } .fi .SH Linkbeat interfaces .PP The linkbeat_interfaces block allows specifying which interfaces should use polling via MII, Ethtool or ioctl status rather than rely on netlink status updates. This allows more granular control of global definition \fBlinkbeat_use_polling\fR. .PP This option is preferred over the deprecated use of \fBlinkbeat_use_polling\fR in a vrrp_instance block, since the latter only allows using linkbeat on the interface of the vrrp_instance itself, whereas \fRtrack_interface\fR and virtual_ipaddresses and virtual_iproutes may require monitoring other interfaces, which may need to use linkbeat polling. .PP The default polling type to use is MII, unless that isn't supported in which case ETHTOOL is used, and if that isn't supported then ioctl polling. The preferred type of polling to use can be specified with MII or ETHTOOL or IOCTL after the interface name, but if that type isn't supported, a supported type will be used. .PP The syntax for linkbeat_interfaces is: .nf \fBlinkbeat_interfaces\fR { eth2 enp2s0 ETHTOOL } .fi .SH Static track groups .PP Static track groups are used to allow vrrp instances to track static addresses, routes and rules. If a static address/route/rule specifies a track group, then if the address/route/rule is deleted and cannot be restored, the vrrp instance will transition to fault state. .PP The syntax for a track group is: .nf \fBtrack_group \fRGROUP1 { \fBgroup \fR{ VI_1 VI_2 } } .fi .SH Static routes/addresses/rules .PP Keepalived can configure static addresses, routes, and rules. These addresses, routes and rules are \fBNOT\fR moved by vrrpd, they stay on the machine. If you already have IPs and routes on your machines and your machines can ping each other, you don't need this section. The syntax for rules and routes is the same as for ip rule add/ip route add (except shortened option names are not supported due to ambiguities). The track_group specification refers to a named track_group which lists the vrrp instances which will track the address, i.e. if the address is deleted the vrrp instances will transition to backup. NOTE: since rules without preferences can be added in different orders due to vrrp instances transitioning from master to backup etc, rules need to have a preference. If a preference is not specified, keepalived will assign one, but it will probably not be what you want. .PP The syntax is the same for virtual addresses and virtual routes. If no dev element is specified, it defaults to default_interface (default eth0). Note: the broadcast address may be specified as '-' or '+' to clear or set the host bits of the address. .PP If a route or rule could apply to either IPv4 or IPv6 it will default to IPv4. To force a route/rule to be IPv6, add the keyword "inet6". .PP By default keepalived prepends routes (the kernel's default) which adds the route before any matching routes (this is the same behaviour as the (undocumented) 'ip route prepend' command). If 'add' is specified, the behaviour will be the same as the 'ip route add' command, which only adds the route if there is no matching route. If 'append' is specified, the behaviour is the same as the 'ip route append' command, i.e. the route is added after any matching route. Note: the rules for whether a route matches differ between IPv4 and IPv6; for example specifying a different proto means a matching route can be prepended/appended for IPv4 but not for IPv6. If in doubt, test it using the 'ip route add/prepend/append' commands. .PP .nf \fBstatic_ipaddress \fR{ [/] [brd ] [dev ] [scope ] [label