From 4248ed359a6ce740e887c0093bcef0b2eb10a4fb Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Sat, 2 Jul 2016 14:18:39 +0100 Subject: [PATCH] Add new lvs sync daemon options Linux 4.3 added support for sync-maxlen, mcast-group (IP address), mcast-ttl and mcast-port. This commit allows setting of those options. This should allow the sync daemon to now run over IPv6 as well as IPv4. The lastest released version of ipvsadm(8) does not yet support these options. To support these options fetch ipvsadm source from https://git.kernel.org/cgit/utils/kernel/ipvsadm/ipvsadm.git/ The Linux kernel doesn't yet handle setting the backup daemon with a link local IPv6 address. In order to support that, the patch at https://git.kernel.org/cgit/linux/kernel/git/horms/ipvs.git/commit/ ?id=370a8107e7883634c2c333c0e1b4ebd62dcf9fe6 must be applied to the kernel source until it is incorporated upstream. Signed-off-by: Quentin Armitage --- configure | 106 +++++++---------- configure.ac | 26 ++++- doc/KEEPALIVED-MIB | 140 +++++++++++++++++++++-- doc/keepalived.conf.SYNOPSIS | 7 +- doc/man/man5/keepalived.conf.5 | 8 +- keepalived/check/Makefile.in | 1 - keepalived/check/check_snmp.c | 107 +++++++++++++++++ keepalived/check/ipvswrapper.c | 55 ++++++--- keepalived/core/global_data.c | 29 +++-- keepalived/core/global_parser.c | 113 +++++++++++++++--- keepalived/core/main.c | 2 +- keepalived/include/global_data.h | 11 +- keepalived/include/ipvswrapper.h | 24 +++- keepalived/include/vrrp_ipset.h | 1 + keepalived/libipvs-2.6/ip_vs.h | 39 ++++++- keepalived/libipvs-2.6/ip_vs_nl_policy.c | 10 +- keepalived/libipvs-2.6/libipvs.c | 67 ++++++++++- keepalived/vrrp/vrrp.c | 48 ++++---- keepalived/vrrp/vrrp_daemon.c | 20 ++-- keepalived/vrrp/vrrp_ipset.c | 5 +- keepalived/vrrp/vrrp_parser.c | 10 +- keepalived/vrrp/vrrp_scheduler.c | 16 +-- keepalived/vrrp/vrrp_snmp.c | 10 +- keepalived/vrrp/vrrp_sync.c | 4 + lib/parser.h | 2 +- 25 files changed, 682 insertions(+), 179 deletions(-) diff --git a/configure b/configure index f2967ba6e..267e1dea5 100755 --- a/configure +++ b/configure @@ -648,6 +648,7 @@ VRRP_VMAC FIB_ROUTING_SUPPORT SOCK_CLOEXEC_SUPPORT SOCK_NONBLOCK_SUPPORT +IPVS_SYNCD_ATTRIBUTES IPVS_SYNCD KERN USE_LIBIPSET @@ -3085,68 +3086,6 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. -# Expand $ac_aux_dir to an absolute path. -am_aux_dir=`cd "$ac_aux_dir" && pwd` - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5 -$as_echo_n "checking whether $CC understands -c and -o together... " >&6; } -if ${am_cv_prog_cc_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF - # 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 { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5 - ($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } \ - && 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 -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5 -$as_echo "$am_cv_prog_cc_c_o" >&6; } -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_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: @@ -4624,6 +4563,7 @@ if test "$IPVS_SUPPORT" = "_WITHOUT_LVS_" -a "$enable_vrrp" = "no"; then fi IPVS_SYNCD="_WITHOUT_IPVS_SYNCD_" +IPVS_SYNCD_ATTRIBUTES="_WITHOUT_IPVS_SYNCD_ATTRIBUTES_" if test "$IPVS_SUPPORT" = "_WITH_LVS_"; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IPVS syncd support" >&5 $as_echo_n "checking for IPVS syncd support... " >&6; } @@ -4646,10 +4586,50 @@ $as_echo "yes" >&6; } { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi + + if test "$IPVS_SYNCD" = "_HAVE_IPVS_SYNCD_"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for IPVS syncd attributes" >&5 +$as_echo_n "checking for IPVS syncd attributes... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + int value; + +int +main () +{ + + value = IPVS_DAEMON_ATTR_SYNC_MAXLEN; + value = IPVS_DAEMON_ATTR_MCAST_GROUP; + value = IPVS_DAEMON_ATTR_MCAST_GROUP6; + value = IPVS_DAEMON_ATTR_MCAST_PORT; + value = IPVS_DAEMON_ATTR_MCAST_TTL; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + IPVS_SYNCD_ATTRIBUTES=yes + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext; + if test "$IPVS_SYNCD_ATTRIBUTES" = "yes"; then + IPVS_SYNCD_ATTRIBUTES="_HAVE_IPVS_SYNCD_ATTRIBUTES_" + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + fi + fi fi + VRRP_SUPPORT="_WITHOUT_VRRP_" if test "$enable_vrrp" != "no"; then VRRP_SUPPORT="_WITH_VRRP_" @@ -5507,7 +5487,7 @@ fi -APP_DEFS="-D${KERN} -D${IPVS_SUPPORT} -D${IPVS_SYNCD} -D${VRRP_SUPPORT} -D${VRRP_VMAC} -D${ADDR_GEN_MODE} -D${SNMP_SUPPORT} -D${SNMP_KEEPALIVED_SUPPORT} -D${SNMP_CHECKER_SUPPORT} -D${SNMP_RFC_SUPPORT} -D${SNMP_RFCV2_SUPPORT} -D${SNMP_RFCV3_SUPPORT} -D${IPVS_USE_NL} -D${USE_NL3} -D${VRRP_AUTH_SUPPORT} -D${SO_MARK_SUPPORT} -D${USE_LIBIPTC} -D${USE_LIBIPSET} -D${IPV4_DEVCONF} -D${IF_H_LINK_H_COLLISION} -D${LINUX_NET_IF_H_COLLISION} -D${SOCK_NONBLOCK_SUPPORT} -D${SOCK_CLOEXEC_SUPPORT} -D${FIB_ROUTING_SUPPORT} -D${MEM_CHECK} -D${MEM_CHECK_LOG} -D${PIPE2_SUPPORT} ${DFLAGS}" +APP_DEFS="-D${KERN} -D${IPVS_SUPPORT} -D${IPVS_SYNCD} -D${IPVS_SYNCD_ATTRIBUTES} -D${VRRP_SUPPORT} -D${VRRP_VMAC} -D${ADDR_GEN_MODE} -D${SNMP_SUPPORT} -D${SNMP_KEEPALIVED_SUPPORT} -D${SNMP_CHECKER_SUPPORT} -D${SNMP_RFC_SUPPORT} -D${SNMP_RFCV2_SUPPORT} -D${SNMP_RFCV3_SUPPORT} -D${IPVS_USE_NL} -D${USE_NL3} -D${VRRP_AUTH_SUPPORT} -D${SO_MARK_SUPPORT} -D${USE_LIBIPTC} -D${USE_LIBIPSET} -D${IPV4_DEVCONF} -D${IF_H_LINK_H_COLLISION} -D${LINUX_NET_IF_H_COLLISION} -D${SOCK_NONBLOCK_SUPPORT} -D${SOCK_CLOEXEC_SUPPORT} -D${FIB_ROUTING_SUPPORT} -D${MEM_CHECK} -D${MEM_CHECK_LOG} -D${PIPE2_SUPPORT} ${DFLAGS}" BUILD_OPTS=`echo ${APP_DEFS} | sed -e 's/ "$//' -e 's/.*"//' -e 's/-D//g' -e 's/_ / /g' -e 's/ _/ /g' -e 's/^_//' -e 's/_$//'` diff --git a/configure.ac b/configure.ac index 09b728b00..fba78680d 100644 --- a/configure.ac +++ b/configure.ac @@ -310,6 +310,7 @@ fi dnl ----[ IPVS syncd support probe ]--- IPVS_SYNCD="_WITHOUT_IPVS_SYNCD_" +IPVS_SYNCD_ATTRIBUTES="_WITHOUT_IPVS_SYNCD_ATTRIBUTES_" if test "$IPVS_SUPPORT" = "_WITH_LVS_"; then AC_MSG_CHECKING([for IPVS syncd support]) if test "$KERN" = "_KRNL_2_6_"; then @@ -329,9 +330,32 @@ if test "$IPVS_SUPPORT" = "_WITH_LVS_"; then else AC_MSG_RESULT([no]) fi + + if test "$IPVS_SYNCD" = "_HAVE_IPVS_SYNCD_"; then + AC_MSG_CHECKING([for IPVS syncd attributes]) + AC_TRY_COMPILE([ + #include + int value; + ], [ + value = IPVS_DAEMON_ATTR_SYNC_MAXLEN; + value = IPVS_DAEMON_ATTR_MCAST_GROUP; + value = IPVS_DAEMON_ATTR_MCAST_GROUP6; + value = IPVS_DAEMON_ATTR_MCAST_PORT; + value = IPVS_DAEMON_ATTR_MCAST_TTL; + ], [ + IPVS_SYNCD_ATTRIBUTES=yes + ], []); + if test "$IPVS_SYNCD_ATTRIBUTES" = "yes"; then + IPVS_SYNCD_ATTRIBUTES="_HAVE_IPVS_SYNCD_ATTRIBUTES_" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + fi fi AC_SUBST(IPVS_SYNCD) +AC_SUBST(IPVS_SYNCD_ATTRIBUTES) dnl ----[ Checks for kernel netlink support ]---- VRRP_SUPPORT="_WITHOUT_VRRP_" @@ -631,7 +655,7 @@ AC_CHECK_FUNCS(gettimeofday select socket strerror strtol uname) AC_CHECK_FUNC([pipe2], [PIPE2_SUPPORT=_HAVE_PIPE2_], [PIPE2_SUPPORT=_WITHOUT_PIPE2_]) AC_SUBST([PIPE2_SUPPORT]) -APP_DEFS="-D${KERN} -D${IPVS_SUPPORT} -D${IPVS_SYNCD} -D${VRRP_SUPPORT} -D${VRRP_VMAC} -D${ADDR_GEN_MODE} -D${SNMP_SUPPORT} -D${SNMP_KEEPALIVED_SUPPORT} -D${SNMP_CHECKER_SUPPORT} -D${SNMP_RFC_SUPPORT} -D${SNMP_RFCV2_SUPPORT} -D${SNMP_RFCV3_SUPPORT} -D${IPVS_USE_NL} -D${USE_NL3} -D${VRRP_AUTH_SUPPORT} -D${SO_MARK_SUPPORT} -D${USE_LIBIPTC} -D${USE_LIBIPSET} -D${IPV4_DEVCONF} -D${IF_H_LINK_H_COLLISION} -D${LINUX_NET_IF_H_COLLISION} -D${SOCK_NONBLOCK_SUPPORT} -D${SOCK_CLOEXEC_SUPPORT} -D${FIB_ROUTING_SUPPORT} -D${MEM_CHECK} -D${MEM_CHECK_LOG} -D${PIPE2_SUPPORT} ${DFLAGS}" +APP_DEFS="-D${KERN} -D${IPVS_SUPPORT} -D${IPVS_SYNCD} -D${IPVS_SYNCD_ATTRIBUTES} -D${VRRP_SUPPORT} -D${VRRP_VMAC} -D${ADDR_GEN_MODE} -D${SNMP_SUPPORT} -D${SNMP_KEEPALIVED_SUPPORT} -D${SNMP_CHECKER_SUPPORT} -D${SNMP_RFC_SUPPORT} -D${SNMP_RFCV2_SUPPORT} -D${SNMP_RFCV3_SUPPORT} -D${IPVS_USE_NL} -D${USE_NL3} -D${VRRP_AUTH_SUPPORT} -D${SO_MARK_SUPPORT} -D${USE_LIBIPTC} -D${USE_LIBIPSET} -D${IPV4_DEVCONF} -D${IF_H_LINK_H_COLLISION} -D${LINUX_NET_IF_H_COLLISION} -D${SOCK_NONBLOCK_SUPPORT} -D${SOCK_CLOEXEC_SUPPORT} -D${FIB_ROUTING_SUPPORT} -D${MEM_CHECK} -D${MEM_CHECK_LOG} -D${PIPE2_SUPPORT} ${DFLAGS}" BUILD_OPTS=`echo ${APP_DEFS} | sed -e 's/ "$//' -e 's/.*"//' -e 's/-D//g' -e 's/_ / /g' -e 's/ _/ /g' -e 's/^_//' -e 's/_$//'` AC_SUBST(APP_DEFS) AC_SUBST(BUILD_OPTS) diff --git a/doc/KEEPALIVED-MIB b/doc/KEEPALIVED-MIB index 90dde4515..748d6857e 100644 --- a/doc/KEEPALIVED-MIB +++ b/doc/KEEPALIVED-MIB @@ -22,12 +22,16 @@ IMPORTS FROM SNMPv2-TC; keepalived MODULE-IDENTITY - LAST-UPDATED "201606290000Z" + LAST-UPDATED "201607020000Z" ORGANIZATION "Keepalived" CONTACT-INFO "http://www.keepalived.org" DESCRIPTION "This MIB describes objects used by keepalived, both for VRRP and health checker." + REVISION "201607020000Z" + DESCRIPTION + "added LVS sync daemon parameters and deprecated + LVS sync daemon objects within VRRP instance" REVISION "201606290000Z" DESCRIPTION "add lvs_flush" REVISION "201606030000Z" @@ -526,17 +530,19 @@ vrrpInstanceAuthType OBJECT-TYPE vrrpInstanceLvsSyncDaemon OBJECT-TYPE SYNTAX INTEGER { enabled(1), disabled(2) } MAX-ACCESS read-only - STATUS current + STATUS deprecated DESCRIPTION - "Is LVS sync daemon enabled for this VRRP instance?" + "Is LVS sync daemon enabled for this VRRP instance? + Deprecated in favour of lvsSyncDaemonEnabled." ::= { vrrpInstanceEntry 16 } vrrpInstanceLvsSyncInterface OBJECT-TYPE SYNTAX DisplayString MAX-ACCESS read-only - STATUS current + STATUS deprecated DESCRIPTION - "If LVS sync daemon is enabled, which interface to use for syncing?" + "If LVS sync daemon is enabled, which interface to use for syncing? + Deprecated in favour of lvsSyncDaemonInterface." ::= { vrrpInstanceEntry 17 } vrrpInstanceSyncGroup OBJECT-TYPE @@ -2018,6 +2024,85 @@ realServerRateOutBPS OBJECT-TYPE "Current outgoing rate for this real server." ::= { realServerEntry 26 } +lvsSyncDaemon OBJECT IDENTIFIER ::= { check 6 } + +lvsSyncDaemonEnabled OBJECT-TYPE + SYNTAX INTEGER { enabled(1), disabled(2) } + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Is LVS sync daemon enabled?" + ::= { lvsSyncDaemon 1 } + +lvsSyncDaemonInterface OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "If LVS sync daemon is enabled, which interface to use for syncing?" + ::= { lvsSyncDaemon 2 } + +lvsSyncDaemonVrrpInstance OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "If LVS sync daemon is enabled, which VRRP instance is it tracking?" + ::= { lvsSyncDaemon 3 } + +lvsSyncDaemonSyncId OBJECT-TYPE + SYNTAX Integer32 (0..255) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "LVS sync daemon id?" + ::= { lvsSyncDaemon 4 } + +lvsSyncDaemonMaxLen OBJECT-TYPE + SYNTAX Integer32 (0..65517) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "LVS sync daemon payload maximum length, 0 means default setting. + Only available on Linux >= 4.3." + ::= { lvsSyncDaemon 5 } + +lvsSyncDaemonPort OBJECT-TYPE + SYNTAX Integer32 (0..65535) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "LVS sync daemon UDP port, 0 means default setting. + Only available on Linux >= 4.3." + ::= { lvsSyncDaemon 6 } + +lvsSyncDaemonTTL OBJECT-TYPE + SYNTAX Integer32 (0..255) + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "LVS sync daemon packet TTL, 0 means default setting. + Only available on Linux >= 4.3." + ::= { lvsSyncDaemon 7 } + +lvsSyncDaemonMcastGroupAddrType OBJECT-TYPE + SYNTAX InetAddressType + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "LVS sync daemon multicast group address type. + Only available on Linux >= 4.3." + ::= { lvsSyncDaemon 8 } + +lvsSyncDaemonMcastGroupAddrValue OBJECT-TYPE + SYNTAX InetAddress + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "LVS sync daemon multicast group IP address. + Only available on Linux >= 4.3." + ::= { lvsSyncDaemon 9 } + -- Traps checkTrap OBJECT IDENTIFIER ::= { check 5 } @@ -2103,10 +2188,23 @@ checkCompliances MODULE-COMPLIANCE virtualServerGroupGroup, virtualServerGroup, realServerGroup, - checkTrapsGroup + checkTrapsGroup, + lvsSyncDaemonGroup } ::= { compliances 3 } +vrrpLvsSyncGroupCompliances MODULE-COMPLIANCE + STATUS deprecated + DESCRIPTION + "The compliance statement for LVS sync group associated + with a VRRP instance. This is deprecated in favour of + lvsSyncDaemonGroup." + MODULE -- this module + MANDATORY-GROUPS { + vrrpLvsSyncGroup + } + ::= { compliances 4 } + globalGroup OBJECT-GROUP OBJECTS { version, @@ -2161,8 +2259,6 @@ vrrpInstanceGroup OBJECT-GROUP vrrpInstancePreempt, vrrpInstancePreemptDelay, vrrpInstanceAuthType, - vrrpInstanceLvsSyncDaemon, - vrrpInstanceLvsSyncInterface, vrrpInstanceSyncGroup, vrrpInstanceGarpDelay, vrrpInstanceSmtpAlert, @@ -2237,6 +2333,17 @@ vrrpTrapsGroup NOTIFICATION-GROUP "Conformance group for VRRP traps." ::= { vrrpGroups 4 } +vrrpLvsSyncGroup OBJECT-GROUP + OBJECTS { + vrrpInstanceLvsSyncDaemon, + vrrpInstanceLvsSyncInterface + } + STATUS deprecated + DESCRIPTION + "The deprecated LVS sync daemon configuration + objects associated with a VRRP instance." + ::= { vrrpGroups 5 } + checkGroups OBJECT IDENTIFIER ::= { groups 3 } virtualServerGroupGroup OBJECT-GROUP @@ -2342,4 +2449,21 @@ checkTrapsGroup NOTIFICATION-GROUP "Conformance group for check traps." ::= { checkGroups 4 } +lvsSyncDaemonGroup OBJECT-GROUP + OBJECTS { + lvsSyncDaemonEnabled, + lvsSyncDaemonInterface, + lvsSyncDaemonVrrpInstance, + lvsSyncDaemonSyncId, + lvsSyncDaemonMaxLen, + lvsSyncDaemonPort, + lvsSyncDaemonTTL, + lvsSyncDaemonMcastGroupAddrType, + lvsSyncDaemonMcastGroupAddrValue + } + STATUS current + DESCRIPTION + "Conformance group for LVS sync daemon." + ::= { checkGroups 5 } + END diff --git a/doc/keepalived.conf.SYNOPSIS b/doc/keepalived.conf.SYNOPSIS index 637a90930..fe94bcbce 100644 --- a/doc/keepalived.conf.SYNOPSIS +++ b/doc/keepalived.conf.SYNOPSIS @@ -47,9 +47,14 @@ global_defs { # Block identification # (in seconds, resolution microseconds) vrrp_mcast_group4 # optional, default 224.0.0.18 vrrp_mcast_group6 # optional, default ff02::12 - lvs_sync_daemon [] + lvs_sync_daemon [id ] [maxlen ] [port ] [ttl ] [group ] # Binding interface, vrrp instance and optional # syncid (0 to 255) for lvs syncd + # maxlen (1..65507) maximum packet length + # port (1..65535) UDP port number to use + # ttl (1..255) + # group - multicast group address (IPv4 or IPv6) + # NOTE: maxlen, port, ttl and group are only available on Linux 4.3 or later. lvs_flush # flush any existing LVS configuration at startup vrrp_garp_master_delay # delay in seconds for second set of gratuitous ARP # messages after MASTER state transition, default 5 diff --git a/doc/man/man5/keepalived.conf.5 b/doc/man/man5/keepalived.conf.5 index bb4721ae6..1b149eb07 100644 --- a/doc/man/man5/keepalived.conf.5 +++ b/doc/man/man5/keepalived.conf.5 @@ -55,9 +55,15 @@ and vrrp_mcast_group4 224.0.0.18 # optional, default 224.0.0.18 vrrp_mcast_group6 ff02::12 # optional, default ff02::12 - lvs_sync_daemon [] + lvs_sync_daemon [id ] [maxlen ] [port ] [ttl ] [group ] # Binding interface, vrrp instance and optional # syncid for lvs syncd + # syncid (0 to 255) for lvs syncd + # maxlen (1..65507) maximum packet length + # port (1..65535) UDP port number to use + # ttl (1..255) + # group - multicast group address (IPv4 or IPv6) + # NOTE: maxlen, port, ttl and group are only available on Linux 4.3 or later. lvs_flush # flush any existing LVS configuration at startup # delay for second set of gratuitous ARPs after transition to MASTER diff --git a/keepalived/check/Makefile.in b/keepalived/check/Makefile.in index 95d6fc7b5..4bcb4932a 100644 --- a/keepalived/check/Makefile.in +++ b/keepalived/check/Makefile.in @@ -1,4 +1,3 @@ - # Makefile # # Keepalived OpenSource project. diff --git a/keepalived/check/check_snmp.c b/keepalived/check/check_snmp.c index feee5b3e0..0699f1bc6 100644 --- a/keepalived/check/check_snmp.c +++ b/keepalived/check/check_snmp.c @@ -112,6 +112,22 @@ #define STATE_RS_REGULAR_NEXT 3 #define STATE_RS_END 4 +#ifdef _HAVE_IPVS_SYNCD_ +enum check_snmp_lvs_sync_daemon { + CHECK_SNMP_LVSSYNCDAEMONENABLED, + CHECK_SNMP_LVSSYNCDAEMONINTERFACE, + CHECK_SNMP_LVSSYNCDAEMONVRRPINSTANCE, + CHECK_SNMP_LVSSYNCDAEMONSYNCID, +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + CHECK_SNMP_LVSSYNCDAEMONMAXLEN, + CHECK_SNMP_LVSSYNCDAEMONPORT, + CHECK_SNMP_LVSSYNCDAEMONTTL, + CHECK_SNMP_LVSSYNCDAEMONMCASTGROUPADDRTYPE, + CHECK_SNMP_LVSSYNCDAEMONMCASTGROUPADDRVALUE, +#endif +}; +#endif + /* Macro */ #define RETURN_IP46ADDRESS(entity) \ do { \ @@ -810,6 +826,74 @@ check_snmp_realserver(struct variable *vp, oid *name, size_t *length, return NULL; } +#ifdef _HAVE_IPVS_SYNCD_ +static u_char* +check_snmp_lvs_sync_daemon(struct variable *vp, oid *name, size_t *length, + int exact, size_t *var_len, WriteMethod **write_method) +{ + static unsigned long long_ret; + + if (header_generic(vp, name, length, exact, var_len, write_method)) + return NULL; + + switch (vp->magic) { + case CHECK_SNMP_LVSSYNCDAEMONENABLED: + long_ret = global_data->lvs_syncd.syncid != -1 ? 1 : 2; + return (u_char *)&long_ret; + case CHECK_SNMP_LVSSYNCDAEMONINTERFACE: + if (global_data->lvs_syncd.syncid == -1) + return NULL; + *var_len = strlen(global_data->lvs_syncd.ifname); + return (u_char *)global_data->lvs_syncd.ifname; + case CHECK_SNMP_LVSSYNCDAEMONVRRPINSTANCE: + if (global_data->lvs_syncd.syncid == -1) + return NULL; + *var_len = strlen(global_data->lvs_syncd.vrrp_name); + return (u_char *)global_data->lvs_syncd.vrrp_name; + case CHECK_SNMP_LVSSYNCDAEMONSYNCID: + if (global_data->lvs_syncd.syncid == -1) + return NULL; + long_ret = global_data->lvs_syncd.syncid; + return (u_char *)&long_ret; +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + case CHECK_SNMP_LVSSYNCDAEMONMAXLEN: + if (global_data->lvs_syncd.syncid == -1) + return NULL; + long_ret = global_data->lvs_syncd.sync_maxlen; + return (u_char *)&long_ret; + case CHECK_SNMP_LVSSYNCDAEMONPORT: + if (global_data->lvs_syncd.syncid == -1) + return NULL; + long_ret = global_data->lvs_syncd.mcast_port; + return (u_char *)&long_ret; + case CHECK_SNMP_LVSSYNCDAEMONTTL: + if (global_data->lvs_syncd.syncid == -1) + return NULL; + long_ret = global_data->lvs_syncd.mcast_ttl; + return (u_char *)&long_ret; + case CHECK_SNMP_LVSSYNCDAEMONMCASTGROUPADDRTYPE: + if (global_data->lvs_syncd.syncid == -1) + return NULL; + long_ret = (global_data->lvs_syncd.mcast_group.ss_family == AF_INET6) ? 2:1; + return (u_char *)&long_ret; + case CHECK_SNMP_LVSSYNCDAEMONMCASTGROUPADDRVALUE: + if (global_data->lvs_syncd.syncid == -1) + return NULL; + if (global_data->lvs_syncd.mcast_group.ss_family == AF_INET6) { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&global_data->lvs_syncd.mcast_group; + *var_len = 16; + return (u_char *)&addr6->sin6_addr; + } else { + struct sockaddr_in *addr4 = (struct sockaddr_in *)&global_data->lvs_syncd.mcast_group; + *var_len = 4; + return (u_char *)&addr4->sin_addr; + } +#endif + } + return NULL; +} +#endif + static oid check_oid[] = {CHECK_OID}; static struct variable8 check_vars[] = { /* virtualServerGroupTable */ @@ -960,6 +1044,29 @@ static struct variable8 check_vars[] = { {CHECK_SNMP_RSRATEOUTBPS, ASN_GAUGE, RONLY, check_snmp_realserver, 3, {4, 1, 26}}, #endif +#ifdef _HAVE_IPVS_SYNCD_ + /* LVS sync daemon configuration */ + {CHECK_SNMP_LVSSYNCDAEMONENABLED, ASN_INTEGER, RONLY, + check_snmp_lvs_sync_daemon, 2, {6, 1}}, + {CHECK_SNMP_LVSSYNCDAEMONINTERFACE, ASN_OCTET_STR, RONLY, + check_snmp_lvs_sync_daemon, 2, {6, 2}}, + {CHECK_SNMP_LVSSYNCDAEMONVRRPINSTANCE, ASN_OCTET_STR, RONLY, + check_snmp_lvs_sync_daemon, 2, {6, 3}}, + {CHECK_SNMP_LVSSYNCDAEMONSYNCID, ASN_INTEGER, RONLY, + check_snmp_lvs_sync_daemon, 2, {6, 4}}, +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + {CHECK_SNMP_LVSSYNCDAEMONMAXLEN, ASN_INTEGER, RONLY, + check_snmp_lvs_sync_daemon, 2, {6, 5}}, + {CHECK_SNMP_LVSSYNCDAEMONPORT, ASN_INTEGER, RONLY, + check_snmp_lvs_sync_daemon, 2, {6, 6}}, + {CHECK_SNMP_LVSSYNCDAEMONTTL, ASN_INTEGER, RONLY, + check_snmp_lvs_sync_daemon, 2, {6, 7}}, + {CHECK_SNMP_LVSSYNCDAEMONMCASTGROUPADDRTYPE, ASN_INTEGER, RONLY, + check_snmp_lvs_sync_daemon, 2, {6, 8}}, + {CHECK_SNMP_LVSSYNCDAEMONMCASTGROUPADDRVALUE, ASN_OCTET_STR, RONLY, + check_snmp_lvs_sync_daemon, 2, {6, 9}}, +#endif +#endif }; void diff --git a/keepalived/check/ipvswrapper.c b/keepalived/check/ipvswrapper.c index 0ffbb6186..ada08bbd6 100644 --- a/keepalived/check/ipvswrapper.c +++ b/keepalived/check/ipvswrapper.c @@ -117,7 +117,7 @@ ipvs_talk(int cmd, bool ignore_error) } void -ipvs_syncd_cmd(int cmd, char *ifname, int state, int syncid, bool ignore_error) +ipvs_syncd_cmd(int cmd, const struct lvs_syncd_config *config, int state, bool ignore_interface, bool ignore_error) { #ifdef _HAVE_IPVS_SYNCD_ @@ -125,9 +125,13 @@ ipvs_syncd_cmd(int cmd, char *ifname, int state, int syncid, bool ignore_error) /* prepare user rule */ urule->state = state; - urule->syncid = syncid; - if (ifname != NULL) - strncpy(urule->mcast_ifn, ifname, IP_VS_IFNAME_MAXLEN); + if (config) { + urule->syncid = config->syncid; + if (!ignore_interface) + strncpy(urule->mcast_ifn, config->ifname, IP_VS_IFNAME_MAXLEN); + } + else + urule->syncid = 0; /* Talk to the IPVS channel */ ipvs_talk(cmd, ignore_error); @@ -480,16 +484,37 @@ ipvs_talk(int cmd, bool ignore_error) return result; } +/* Note: This function is called in the context of the vrrp child process, not the checker process */ void -ipvs_syncd_cmd(int cmd, char *ifname, int state, int syncid, bool ignore_error) +ipvs_syncd_cmd(int cmd, const struct lvs_syncd_config *config, int state, bool ignore_interface, bool ignore_error) { memset(daemonrule, 0, sizeof(ipvs_daemon_t)); /* prepare user rule */ daemonrule->state = state; - daemonrule->syncid = syncid; - if (ifname != NULL) - strncpy(daemonrule->mcast_ifn, ifname, IP_VS_IFNAME_MAXLEN); + if (config) { + daemonrule->syncid = config->syncid; + if (!ignore_interface) + strncpy(daemonrule->mcast_ifn, config->ifname, IP_VS_IFNAME_MAXLEN); +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + if (cmd == IPVS_STARTDAEMON) { + if (config->sync_maxlen) + daemonrule->sync_maxlen = config->sync_maxlen; + if (config->mcast_port) + daemonrule->mcast_port = config->mcast_port; + if (config->mcast_ttl) + daemonrule->mcast_ttl = config->mcast_ttl; + if (config->mcast_group.ss_family == AF_INET) { + daemonrule->mcast_af = AF_INET; + daemonrule->mcast_group.ip = ((struct sockaddr_in *)&config->mcast_group)->sin_addr.s_addr; + } + else if (config->mcast_group.ss_family == AF_INET6) { + daemonrule->mcast_af = AF_INET6; + memcpy(&daemonrule->mcast_group.in6, &((struct sockaddr_in6 *)&config->mcast_group)->sin6_addr, sizeof(daemonrule->mcast_group.in6)); + } + } +#endif + } /* Talk to the IPVS channel */ ipvs_talk(cmd, ignore_error); @@ -1040,18 +1065,20 @@ ipvs_update_stats(virtual_server_t *vs) /* * Common IPVS functions */ +/* Note: This function is called in the context of the vrrp child process, not the checker process */ void -ipvs_syncd_master(char *ifname, int syncid) +ipvs_syncd_master(const struct lvs_syncd_config *config) { - ipvs_syncd_cmd(IPVS_STOPDAEMON, ifname, IPVS_BACKUP, syncid, false); - ipvs_syncd_cmd(IPVS_STARTDAEMON, ifname, IPVS_MASTER, syncid, false); + ipvs_syncd_cmd(IPVS_STOPDAEMON, config, IPVS_BACKUP, false, false); + ipvs_syncd_cmd(IPVS_STARTDAEMON, config, IPVS_MASTER, false, false); } +/* Note: This function is called in the context of the vrrp child process, not the checker process */ void -ipvs_syncd_backup(char *ifname, int syncid) +ipvs_syncd_backup(const struct lvs_syncd_config *config) { - ipvs_syncd_cmd(IPVS_STOPDAEMON, ifname, IPVS_MASTER, syncid, false); - ipvs_syncd_cmd(IPVS_STARTDAEMON, ifname, IPVS_BACKUP, syncid, false); + ipvs_syncd_cmd(IPVS_STOPDAEMON, config, IPVS_MASTER, false, false); + ipvs_syncd_cmd(IPVS_STARTDAEMON, config, IPVS_BACKUP, false, false); } /* diff --git a/keepalived/core/global_data.c b/keepalived/core/global_data.c index 4988fc24a..26760d7d4 100644 --- a/keepalived/core/global_data.c +++ b/keepalived/core/global_data.c @@ -156,7 +156,10 @@ alloc_global_data(void) new->enable_snmp_checker = true; #endif } - new->lvs_syncd_syncid = -1; + new->lvs_syncd.syncid = -1; +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + new->lvs_syncd.mcast_group.ss_family = AF_UNSPEC; +#endif if (snmp_socket) { new->snmp_socket = MALLOC(strlen(snmp_socket + 1)); @@ -209,8 +212,8 @@ free_global_data(data_t * data) #ifdef _WITH_SNMP_ FREE_PTR(data->snmp_socket); #endif - FREE_PTR(data->lvs_syncd_if); - FREE_PTR(data->lvs_syncd_vrrp_name); + FREE_PTR(data->lvs_syncd.ifname); + FREE_PTR(data->lvs_syncd.vrrp_name); FREE(data); } @@ -238,14 +241,24 @@ dump_global_data(data_t * data) , data->email_from); dump_list(data->email); } - if (data->lvs_syncd_vrrp) { + if (data->lvs_syncd.vrrp) { log_message(LOG_INFO, " LVS syncd vrrp instance = %s" - , data->lvs_syncd_vrrp->iname); - if (data->lvs_syncd_if) + , data->lvs_syncd.vrrp->iname); + if (data->lvs_syncd.ifname) log_message(LOG_INFO, " LVS syncd interface = %s" - , data->lvs_syncd_if); + , data->lvs_syncd.ifname); log_message(LOG_INFO, " LVS syncd syncid = %d" - , data->lvs_syncd_syncid); + , data->lvs_syncd.syncid); +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + if (data->lvs_syncd.sync_maxlen) + log_message(LOG_INFO, " LVS syncd maxlen = %d", data->lvs_syncd.sync_maxlen); + if (data->lvs_syncd.mcast_group.ss_family != AF_UNSPEC) + log_message(LOG_INFO, " LVS mcast group %s", inet_sockaddrtos(&data->lvs_syncd.mcast_group)); + if (data->lvs_syncd.mcast_port) + log_message(LOG_INFO, " LVS syncd mcast port = %d", data->lvs_syncd.mcast_port); + if (data->lvs_syncd.mcast_ttl) + log_message(LOG_INFO, " LVS syncd mcast ttl = %d", data->lvs_syncd.mcast_ttl); +#endif } log_message(LOG_INFO, "LVS flush = %s", data->lvs_flush ? "true" : "false"); if (data->vrrp_mcast_group4.ss_family) { diff --git a/keepalived/core/global_parser.c b/keepalived/core/global_parser.c index 11ad07661..bfc41061b 100644 --- a/keepalived/core/global_parser.c +++ b/keepalived/core/global_parser.c @@ -23,6 +23,7 @@ */ #include +#include #include "global_parser.h" #include "global_data.h" #include "check_data.h" @@ -106,30 +107,114 @@ email_handler(vector_t *strvec) static void lvs_syncd_handler(vector_t *strvec) { - int syncid; + int val; + int i; + char *endptr; - if (global_data->lvs_syncd_if) { - log_message(LOG_INFO, "lvs_sync_daemon has already been specified as %s %s - ignoring", global_data->lvs_syncd_if, global_data->lvs_syncd_vrrp_name); + if (global_data->lvs_syncd.ifname) { + log_message(LOG_INFO, "lvs_sync_daemon has already been specified as %s %s - ignoring", global_data->lvs_syncd.ifname, global_data->lvs_syncd.vrrp_name); return; } - if (vector_size(strvec) < 3 || vector_size(strvec) > 4) { - log_message(LOG_INFO, "lvs_sync_daemon requires interface, VRRP instance and optional syncid"); + if (vector_size(strvec) < 3) { + log_message(LOG_INFO, "lvs_sync_daemon requires interface, VRRP instance"); return; } - global_data->lvs_syncd_if = set_value(strvec); + global_data->lvs_syncd.ifname = set_value(strvec); - global_data->lvs_syncd_vrrp_name = MALLOC(strlen(vector_slot(strvec, 2)) + 1); - if (!global_data->lvs_syncd_vrrp_name) + global_data->lvs_syncd.vrrp_name = MALLOC(strlen(vector_slot(strvec, 2)) + 1); + if (!global_data->lvs_syncd.vrrp_name) return; - strcpy(global_data->lvs_syncd_vrrp_name, vector_slot(strvec, 2)); - if (vector_size(strvec) >= 4) { - syncid = atoi(vector_slot(strvec,3)); - if (syncid < 0 || syncid > 255) - log_message(LOG_INFO, "Invalid syncid - defaulting to vrid"); + strcpy(global_data->lvs_syncd.vrrp_name, vector_slot(strvec, 2)); + + /* This is maintained for backwards compatibility, prior to adding "id" option */ + if (vector_size(strvec) >= 4 && isdigit(FMT_STR_VSLOT(strvec, 3)[0])) { + log_message(LOG_INFO, "Please use keyword \"id\" before lvs_sync_daemon syncid value"); + val = strtol(vector_slot(strvec,3), &endptr, 10); + if (*endptr || val < 0 || val > 255) + log_message(LOG_INFO, "Invalid syncid (%s) - defaulting to vrid", FMT_STR_VSLOT(strvec, 3)); else - global_data->lvs_syncd_syncid = syncid; + global_data->lvs_syncd.syncid = val; + i = 4; + } + else + i = 3; + + for ( ; i < vector_size(strvec); i++ ) { + if (!strcmp(vector_slot(strvec, i), "id")) { + if (i == vector_size(strvec) - 1) { + log_message(LOG_INFO, "No value specified for lvs_sync_daemon id, defaulting to vrid"); + continue; + } + val = strtol(vector_slot(strvec, i+1), &endptr, 10); + if (*endptr != '\0' || val < 0 || val > 255) + log_message(LOG_INFO, "Invalid syncid (%s) - defaulting to vrid", FMT_STR_VSLOT(strvec, i+1)); + else + global_data->lvs_syncd.syncid = val; + i++; /* skip over value */ + continue; + } +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + if (!strcmp(vector_slot(strvec, i), "maxlen")) { + if (i == vector_size(strvec) - 1) { + log_message(LOG_INFO, "No value specified for lvs_sync_daemon maxlen - ignoring"); + continue; + } + val = strtol(vector_slot(strvec, i+1), &endptr, 10); + if (*endptr != '\0' || val < 1 || val > 65535 - 20 - 8) + log_message(LOG_INFO, "Invalid lvs_sync_daemon maxlen (%s) - ignoring", FMT_STR_VSLOT(strvec, i+1)); + else + global_data->lvs_syncd.sync_maxlen = val; + i++; /* skip over value */ + continue; + } + if (!strcmp(vector_slot(strvec, i), "port")) { + if (i == vector_size(strvec) - 1) { + log_message(LOG_INFO, "No value specified for lvs_sync_daemon port - ignoring"); + continue; + } + val = strtol(vector_slot(strvec, i+1), &endptr, 10); + if (*endptr != '\0' || val < 1 || val > 65535) + log_message(LOG_INFO, "Invalid lvs_sync_daemon port (%s) - ignoring", FMT_STR_VSLOT(strvec, i+1)); + else + global_data->lvs_syncd.mcast_port = val; + i++; /* skip over value */ + continue; + } + if (!strcmp(vector_slot(strvec, i), "ttl")) { + if (i == vector_size(strvec) - 1) { + log_message(LOG_INFO, "No value specified for lvs_sync_daemon ttl - ignoring"); + continue; + } + val = strtol(vector_slot(strvec, i+1), &endptr, 10); + if (*endptr != '\0' || val < 1 || val > 255) + log_message(LOG_INFO, "Invalid lvs_sync_daemon ttl (%s) - ignoring", FMT_STR_VSLOT(strvec, i+1)); + else + global_data->lvs_syncd.mcast_ttl = val; + i++; /* skip over value */ + continue; + } + if (!strcmp(vector_slot(strvec, i), "group")) { + if (i == vector_size(strvec) - 1) { + log_message(LOG_INFO, "No value specified for lvs_sync_daemon group - ignoring"); + continue; + } + + if (inet_stosockaddr(vector_slot(strvec, i+1), NULL, &global_data->lvs_syncd.mcast_group) < 0) + log_message(LOG_INFO, "Invalid lvs_sync_daemon group (%s) - ignoring", FMT_STR_VSLOT(strvec, i+1)); + + if ((global_data->lvs_syncd.mcast_group.ss_family == AF_INET && !IN_MULTICAST(htonl(((struct sockaddr_in *)&global_data->lvs_syncd.mcast_group)->sin_addr.s_addr))) || + (global_data->lvs_syncd.mcast_group.ss_family == AF_INET6 && !IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)&global_data->lvs_syncd.mcast_group)->sin6_addr))) { + log_message(LOG_INFO, "lvs_sync_daemon group address %s is not multicast - ignoring", FMT_STR_VSLOT(strvec, i+1)); + global_data->lvs_syncd.mcast_group.ss_family = AF_UNSPEC; + } + + i++; /* skip over value */ + continue; + } +#endif + log_message(LOG_INFO, "Unknown option %s specified for lvs_sync_daemon", FMT_STR_VSLOT(strvec, i)); } } static void diff --git a/keepalived/core/main.c b/keepalived/core/main.c index dcafa6723..914bf241f 100644 --- a/keepalived/core/main.c +++ b/keepalived/core/main.c @@ -32,7 +32,7 @@ #define CHILD_WAIT_SECS 5 /* global var */ -char *conf_file = CONF; /* Configuration file */ +char *conf_file = KEEPALIVED_CONFIG_FILE; /* Configuration file */ int log_facility = LOG_DAEMON; /* Optional logging facilities */ pid_t vrrp_child = -1; /* VRRP child process ID */ pid_t checkers_child = -1; /* Healthcheckers child process ID */ diff --git a/keepalived/include/global_data.h b/keepalived/include/global_data.h index 631c0fd3a..2d1afcfff 100644 --- a/keepalived/include/global_data.h +++ b/keepalived/include/global_data.h @@ -44,6 +44,10 @@ #include "list.h" #include "timer.h" #include "vrrp.h" +#ifdef _HAVE_IPVS_SYNCD_ +#include "ipvswrapper.h" +#endif + /* constants */ #define DEFAULT_SMTP_SERVER 0x7f000001 @@ -65,10 +69,9 @@ typedef struct _data { list email; struct sockaddr_storage vrrp_mcast_group4; struct sockaddr_storage vrrp_mcast_group6; - char *lvs_syncd_if; /* handle LVS sync daemon state using this */ - vrrp_t *lvs_syncd_vrrp; /* instance FSM & running on specific interface */ - int lvs_syncd_syncid; /* => eth0 for example. */ - char *lvs_syncd_vrrp_name; /* Only used during configuration */ +#ifdef _HAVE_IPVS_SYNCD_ + struct lvs_syncd_config lvs_syncd; +#endif bool lvs_flush; /* flush any residual LVS config at startup */ int vrrp_garp_delay; timeval_t vrrp_garp_refresh; diff --git a/keepalived/include/ipvswrapper.h b/keepalived/include/ipvswrapper.h index 47aea681f..21b1da23d 100644 --- a/keepalived/include/ipvswrapper.h +++ b/keepalived/include/ipvswrapper.h @@ -45,6 +45,9 @@ #elif _KRNL_2_6_ #include "../libipvs-2.6/ip_vs.h" #include "../libipvs-2.6/libipvs.h" +#ifdef _HAVE_IPVS_SYNCD_ +#include "vrrp.h" +#endif #endif // #include #endif @@ -91,6 +94,21 @@ do { \ UNSET_ALIVE((V)); \ } while (0) +#ifdef _HAVE_IPVS_SYNCD_ +struct lvs_syncd_config { + char *ifname; /* handle LVS sync daemon state using this */ + vrrp_t *vrrp; /* instance FSM & running on specific interface */ + int syncid; /* 0 .. 255 */ +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + int sync_maxlen; + struct sockaddr_storage mcast_group; + int mcast_port; + int mcast_ttl; +#endif + char *vrrp_name; /* used during configuration and SNMP */ +}; +#endif + /* prototypes */ extern int ipvs_start(void); extern void ipvs_stop(void); @@ -99,9 +117,9 @@ extern virtual_server_group_t *ipvs_get_group_by_name(char *, list); extern void ipvs_group_sync_entry(virtual_server_t *vs, virtual_server_group_entry_t *vsge); extern void ipvs_group_remove_entry(virtual_server_t *, virtual_server_group_entry_t *); extern int ipvs_cmd(int, virtual_server_t *, real_server_t *); -extern void ipvs_syncd_cmd(int, char *, int, int, bool); -extern void ipvs_syncd_master(char *, int); -extern void ipvs_syncd_backup(char *, int); +extern void ipvs_syncd_cmd(int, const struct lvs_syncd_config *, int, bool, bool); +extern void ipvs_syncd_master(const struct lvs_syncd_config *); +extern void ipvs_syncd_backup(const struct lvs_syncd_config *); #ifdef _KRNL_2_6_ /* Refresh statistics at most every 5 seconds */ diff --git a/keepalived/include/vrrp_ipset.h b/keepalived/include/vrrp_ipset.h index bcc2ef306..b8d590a86 100644 --- a/keepalived/include/vrrp_ipset.h +++ b/keepalived/include/vrrp_ipset.h @@ -23,6 +23,7 @@ #ifndef _VRRP_IPSET_H #define _VRRP_IPSET_H +#define LIBIPSET_NFPROTO_H #include #include "vrrp_ipaddress.h" diff --git a/keepalived/libipvs-2.6/ip_vs.h b/keepalived/libipvs-2.6/ip_vs.h index dc467c221..d3413fdec 100644 --- a/keepalived/libipvs-2.6/ip_vs.h +++ b/keepalived/libipvs-2.6/ip_vs.h @@ -10,6 +10,7 @@ #include #include #include /* For __beXX types in userland */ +#include /* For nf_inet_addr */ #ifdef LIBIPVS_USE_NL #include @@ -104,6 +105,7 @@ #define IP_VS_PEDATA_MAXLEN 255 +/* union nf_inet_addr { __u32 all[4]; __be32 ip; @@ -111,6 +113,7 @@ union nf_inet_addr { struct in_addr in; struct in6_addr in6; }; +*/ /* * The struct ip_vs_service_user and struct ip_vs_dest_user are @@ -348,7 +351,7 @@ struct ip_vs_timeout_user { /* The argument to IP_VS_SO_GET_DAEMON */ -struct ip_vs_daemon_user { +struct ip_vs_daemon_kern { /* sync daemon state (master/backup) */ int state; @@ -359,6 +362,33 @@ struct ip_vs_daemon_user { int syncid; }; +struct ip_vs_daemon_user { + /* sync daemon state (master/backup) */ + int state; + + /* multicast interface name */ + char mcast_ifn[IP_VS_IFNAME_MAXLEN]; + + /* SyncID we belong to */ + int syncid; + +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + /* UDP Payload Size */ + int sync_maxlen; + + /* Multicast Port (base) */ + u_int16_t mcast_port; + + /* Multicast TTL */ + u_int16_t mcast_ttl; + + /* Multicast Address Family */ + u_int16_t mcast_af; + + /* Multicast Address */ + union nf_inet_addr mcast_group; +#endif +}; /* * @@ -488,6 +518,13 @@ enum { IPVS_DAEMON_ATTR_STATE, /* sync daemon state (master/backup) */ IPVS_DAEMON_ATTR_MCAST_IFN, /* multicast interface name */ IPVS_DAEMON_ATTR_SYNC_ID, /* SyncID we belong to */ +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + IPVS_DAEMON_ATTR_SYNC_MAXLEN, /* UDP Payload Size */ + IPVS_DAEMON_ATTR_MCAST_GROUP, /* IPv4 Multicast Address */ + IPVS_DAEMON_ATTR_MCAST_GROUP6, /* IPv6 Multicast Address */ + IPVS_DAEMON_ATTR_MCAST_PORT, /* Multicast Port (base) */ + IPVS_DAEMON_ATTR_MCAST_TTL, /* Multicast TTL */ +#endif __IPVS_DAEMON_ATTR_MAX, }; diff --git a/keepalived/libipvs-2.6/ip_vs_nl_policy.c b/keepalived/libipvs-2.6/ip_vs_nl_policy.c index c300d84e6..c93342b78 100644 --- a/keepalived/libipvs-2.6/ip_vs_nl_policy.c +++ b/keepalived/libipvs-2.6/ip_vs_nl_policy.c @@ -66,6 +66,14 @@ struct nla_policy ipvs_daemon_policy[IPVS_DAEMON_ATTR_MAX + 1] = { [IPVS_DAEMON_ATTR_MCAST_IFN] = { .type = NLA_STRING, .maxlen = IP_VS_IFNAME_MAXLEN }, [IPVS_DAEMON_ATTR_SYNC_ID] = { .type = NLA_U32 }, -}; +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + [IPVS_DAEMON_ATTR_SYNC_MAXLEN] = { .type = NLA_U16 }, + [IPVS_DAEMON_ATTR_MCAST_GROUP] = { .type = NLA_U32 }, + [IPVS_DAEMON_ATTR_MCAST_GROUP6] = { .type = NLA_UNSPEC, + .maxlen = sizeof(struct in6_addr) }, + [IPVS_DAEMON_ATTR_MCAST_PORT] = { .type = NLA_U16 }, + [IPVS_DAEMON_ATTR_MCAST_TTL] = { .type = NLA_U8 }, +#endif + }; #endif /* LIBIPVS_USE_NL */ diff --git a/keepalived/libipvs-2.6/libipvs.c b/keepalived/libipvs-2.6/libipvs.c index 5b3fda90b..f08c4e43d 100644 --- a/keepalived/libipvs-2.6/libipvs.c +++ b/keepalived/libipvs-2.6/libipvs.c @@ -527,6 +527,8 @@ int ipvs_set_timeout(ipvs_timeout_t *to) int ipvs_start_daemon(ipvs_daemon_t *dm) { + struct ip_vs_daemon_kern dmk; + ipvs_func = ipvs_start_daemon; #ifdef LIBIPVS_USE_NL if (try_nl) { @@ -541,6 +543,18 @@ int ipvs_start_daemon(ipvs_daemon_t *dm) NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_STATE, dm->state); NLA_PUT_STRING(msg, IPVS_DAEMON_ATTR_MCAST_IFN, dm->mcast_ifn); NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_SYNC_ID, dm->syncid); +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + if (dm->sync_maxlen) + NLA_PUT_U16(msg, IPVS_DAEMON_ATTR_SYNC_MAXLEN, dm->sync_maxlen); + if (dm->mcast_port) + NLA_PUT_U16(msg, IPVS_DAEMON_ATTR_MCAST_PORT, dm->mcast_port); + if (dm->mcast_ttl) + NLA_PUT_U8(msg, IPVS_DAEMON_ATTR_MCAST_TTL, dm->mcast_ttl); + if (dm->mcast_af == AF_INET6) + NLA_PUT(msg, IPVS_DAEMON_ATTR_MCAST_GROUP6, sizeof(dm->mcast_group.in6), &dm->mcast_group.in6); + else if (dm->mcast_af == AF_INET) + NLA_PUT_U32(msg, IPVS_DAEMON_ATTR_MCAST_GROUP, dm->mcast_group.ip); +#endif nla_nest_end(msg, nl_daemon); @@ -551,13 +565,19 @@ int ipvs_start_daemon(ipvs_daemon_t *dm) return -1; } #endif + memset(&dmk, 0, sizeof(dmk)); + dmk.state = dm->state; + strcpy(dmk.mcast_ifn, dm->mcast_ifn); + dmk.syncid = dm->syncid; return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_STARTDAEMON, - (char *)dm, sizeof(*dm)); + (char *)&dmk, sizeof(dmk)); } int ipvs_stop_daemon(ipvs_daemon_t *dm) { + struct ip_vs_daemon_kern dmk; + ipvs_func = ipvs_stop_daemon; #ifdef LIBIPVS_USE_NL if (try_nl) { @@ -582,8 +602,10 @@ int ipvs_stop_daemon(ipvs_daemon_t *dm) return -1; } #endif + memset(&dmk, 0, sizeof(dmk)); + dmk.state = dm->state; return setsockopt(sockfd, IPPROTO_IP, IP_VS_SO_SET_STOPDAEMON, - (char *)dm, sizeof(*dm)); + (char *)&dmk, sizeof(dmk)); } #ifdef LIBIPVS_USE_NL @@ -1114,6 +1136,9 @@ static int ipvs_daemon_parse_cb(struct nl_msg *msg, void *arg) struct nlattr *attrs[IPVS_CMD_ATTR_MAX + 1]; struct nlattr *daemon_attrs[IPVS_DAEMON_ATTR_MAX + 1]; ipvs_daemon_t *u = (ipvs_daemon_t *)arg; +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + struct nladdr *a; +#endif int i = 0; /* We may get two daemons. If we've already got one, this is the second */ @@ -1138,14 +1163,43 @@ static int ipvs_daemon_parse_cb(struct nl_msg *msg, void *arg) IP_VS_IFNAME_MAXLEN); u[i].syncid = nla_get_u32(daemon_attrs[IPVS_DAEMON_ATTR_SYNC_ID]); +#ifdef _HAVE_IPVS_SYNCD_ATTRIBUTES_ + a = daemon_attrs[IPVS_DAEMON_ATTR_SYNC_MAXLEN]; + if (a) + u[i].sync_maxlen = nla_get_u16(a); + + a = daemon_attrs[IPVS_DAEMON_ATTR_MCAST_PORT]; + if (a) + u[i].mcast_port = nla_get_u16(a); + + a = daemon_attrs[IPVS_DAEMON_ATTR_MCAST_TTL]; + if (a) + u[i].mcast_ttl = nla_get_u8(a); + + a = daemon_attrs[IPVS_DAEMON_ATTR_MCAST_GROUP]; + if (a) { + u[i].mcast_af = AF_INET; + u[i].mcast_group.ip = nla_get_u32(a); + } else { + a = daemon_attrs[IPVS_DAEMON_ATTR_MCAST_GROUP6]; + if (a) { + u[i].mcast_af = AF_INET6; + memcpy(&u[i].mcast_group.in6, nla_data(a), + sizeof(u[i].mcast_group.in6)); + } + } +#endif + return NL_OK; } #endif ipvs_daemon_t *ipvs_get_daemon(void) { + struct ip_vs_daemon_kern dmk[2]; ipvs_daemon_t *u; socklen_t len; + int i; /* note that we need to get the info about two possible daemons, master and backup. */ @@ -1157,7 +1211,7 @@ ipvs_daemon_t *ipvs_get_daemon(void) #ifdef LIBIPVS_USE_NL if (try_nl) { struct nl_msg *msg; - memset(u, 0, len); + msg = ipvs_nl_message(IPVS_CMD_GET_DAEMON, NLM_F_DUMP); if (msg && (ipvs_nl_send_message(msg, ipvs_daemon_parse_cb, u) == 0)) return u; @@ -1166,10 +1220,15 @@ ipvs_daemon_t *ipvs_get_daemon(void) return NULL; } #endif - if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_DAEMON, (char *)u, &len)) { + if (getsockopt(sockfd, IPPROTO_IP, IP_VS_SO_GET_DAEMON, (char *)dmk, &len)) { FREE(u); return NULL; } + for (i = 0; i < 2; i++) { + u[i].state = dmk[i].state; + strncpy(u[i].mcast_ifn, dmk[i].mcast_ifn, IP_VS_IFNAME_MAXLEN); + u[i].syncid = dmk[i].syncid; + } return u; } #endif diff --git a/keepalived/vrrp/vrrp.c b/keepalived/vrrp/vrrp.c index 21b72c523..0b76d1a96 100644 --- a/keepalived/vrrp/vrrp.c +++ b/keepalived/vrrp/vrrp.c @@ -1224,8 +1224,8 @@ vrrp_state_become_master(vrrp_t * vrrp) #ifdef _HAVE_IPVS_SYNCD_ /* Check if sync daemon handling is needed */ - if (global_data->lvs_syncd_vrrp == vrrp) - ipvs_syncd_master(global_data->lvs_syncd_if, global_data->lvs_syncd_syncid); + if (global_data->lvs_syncd.vrrp == vrrp) + ipvs_syncd_master(&global_data->lvs_syncd); #endif vrrp->last_transition = timer_now(); } @@ -1313,8 +1313,8 @@ vrrp_state_leave_master(vrrp_t * vrrp) if (VRRP_VIP_ISSET(vrrp)) { #ifdef _HAVE_IPVS_SYNCD_ /* Check if sync daemon handling is needed */ - if (global_data->lvs_syncd_vrrp == vrrp) - ipvs_syncd_backup(global_data->lvs_syncd_if, global_data->lvs_syncd_syncid); + if (global_data->lvs_syncd.vrrp == vrrp) + ipvs_syncd_backup(&global_data->lvs_syncd); #endif } @@ -1831,12 +1831,10 @@ shutdown_vrrp_instances(void) * stop stalled syncd thread according to last * VRRP instance state. */ - if (global_data->lvs_syncd_vrrp == vrrp) - ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, - (vrrp->state == VRRP_STATE_MAST) ? IPVS_MASTER: - IPVS_BACKUP, - global_data->lvs_syncd_syncid, - false); + if (global_data->lvs_syncd.vrrp == vrrp) + ipvs_syncd_cmd(IPVS_STOPDAEMON, &global_data->lvs_syncd, + (vrrp->state == VRRP_STATE_MAST) ? IPVS_MASTER: IPVS_BACKUP, + true, false); #endif } } @@ -2413,30 +2411,32 @@ vrrp_complete_init(void) } /* Set up the lvs_syncd vrrp */ - if (global_data->lvs_syncd_vrrp_name) { + if (global_data->lvs_syncd.vrrp_name) { for (e = LIST_HEAD(vrrp_data->vrrp); e; ELEMENT_NEXT(e)) { vrrp = ELEMENT_DATA(e); - if (!strcmp(global_data->lvs_syncd_vrrp_name, vrrp->iname)) { - global_data->lvs_syncd_vrrp = vrrp; + if (!strcmp(global_data->lvs_syncd.vrrp_name, vrrp->iname)) { + global_data->lvs_syncd.vrrp = vrrp; break; } } - if (!global_data->lvs_syncd_vrrp) { - log_message(LOG_INFO, "Unable to find vrrp instance %s for lvs_syncd - clearing lvs_syncd config", global_data->lvs_syncd_vrrp_name); - FREE(global_data->lvs_syncd_if); - global_data->lvs_syncd_if = NULL; + if (!global_data->lvs_syncd.vrrp) { + log_message(LOG_INFO, "Unable to find vrrp instance %s for lvs_syncd - clearing lvs_syncd config", global_data->lvs_syncd.vrrp_name); + FREE_PTR(global_data->lvs_syncd.ifname); + global_data->lvs_syncd.ifname = NULL; + global_data->lvs_syncd.syncid = -1; + } + else if (global_data->lvs_syncd.syncid == -1) { + /* If no syncid configured, use vrid */ + global_data->lvs_syncd.syncid = global_data->lvs_syncd.vrrp->vrid; } - FREE(global_data->lvs_syncd_vrrp_name); - global_data->lvs_syncd_vrrp_name = NULL; + /* vrrp_name is no longer used */ + FREE_PTR(global_data->lvs_syncd.vrrp_name); + global_data->lvs_syncd.vrrp_name = NULL; } - /* If no sycnid configured, use vrid */ - if (global_data->lvs_syncd_vrrp && global_data->lvs_syncd_syncid == -1) - global_data->lvs_syncd_syncid = global_data->lvs_syncd_vrrp->vrid; - alloc_vrrp_buffer(max_mtu_len); return 1; @@ -2445,7 +2445,7 @@ vrrp_complete_init(void) int vrrp_ipvs_needed(void) { - return !!(global_data->lvs_syncd_if); + return !!(global_data->lvs_syncd.ifname); } /* Try to find a VRRP instance */ diff --git a/keepalived/vrrp/vrrp_daemon.c b/keepalived/vrrp/vrrp_daemon.c index ceacb3f75..fade16600 100644 --- a/keepalived/vrrp/vrrp_daemon.c +++ b/keepalived/vrrp/vrrp_daemon.c @@ -192,8 +192,8 @@ start_vrrp(void) /* If we are managing the sync daemon, then stop any * instances of it that may have been running if * we terminated abnormally */ - ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, IPVS_MASTER, 0, true); - ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, IPVS_BACKUP, 0, true); + ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, IPVS_MASTER, true, true); + ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, IPVS_BACKUP, true, true); #endif } #endif @@ -319,11 +319,11 @@ reload_vrrp_thread(thread_t * thread) thread_cleanup_master(master); #ifdef _HAVE_IPVS_SYNCD_ /* TODO - Note: this didn't work if we found ipvs_syndc on vrrp before on old_vrrp */ - if (global_data->lvs_syncd_if) - ipvs_syncd_cmd(IPVS_STOPDAEMON, NULL, - (global_data->lvs_syncd_vrrp->state == VRRP_STATE_MAST) ? IPVS_MASTER: + if (global_data->lvs_syncd.ifname) + ipvs_syncd_cmd(IPVS_STOPDAEMON, &global_data->lvs_syncd, + (global_data->lvs_syncd.vrrp->state == VRRP_STATE_MAST) ? IPVS_MASTER: IPVS_BACKUP, - global_data->lvs_syncd_syncid, false); + true, false); #endif free_global_data(global_data); free_vrrp_buffer(); @@ -349,11 +349,11 @@ reload_vrrp_thread(thread_t * thread) start_vrrp(); #ifdef _HAVE_IPVS_SYNCD_ - if (global_data->lvs_syncd_if) - ipvs_syncd_cmd(IPVS_STARTDAEMON, NULL, - (global_data->lvs_syncd_vrrp->state == VRRP_STATE_MAST) ? IPVS_MASTER: + if (global_data->lvs_syncd.ifname) + ipvs_syncd_cmd(IPVS_STARTDAEMON, &global_data->lvs_syncd, + (global_data->lvs_syncd.vrrp->state == VRRP_STATE_MAST) ? IPVS_MASTER: IPVS_BACKUP, - global_data->lvs_syncd_syncid, false); + true, false); #endif /* free backup data */ diff --git a/keepalived/vrrp/vrrp_ipset.c b/keepalived/vrrp/vrrp_ipset.c index 4bfad1b61..af83469ff 100644 --- a/keepalived/vrrp/vrrp_ipset.c +++ b/keepalived/vrrp/vrrp_ipset.c @@ -29,9 +29,10 @@ */ #include +#define LIBIPSET_NFPROTO_H +#define LIBIPSET_NF_INET_ADDR_H #include -#include -#include +//#include #include #include diff --git a/keepalived/vrrp/vrrp_parser.c b/keepalived/vrrp/vrrp_parser.c index 66a55d2ec..2deda1571 100644 --- a/keepalived/vrrp/vrrp_parser.c +++ b/keepalived/vrrp/vrrp_parser.c @@ -457,15 +457,15 @@ vrrp_lvs_syncd_handler(vector_t *strvec) vrrp_t *vrrp = LIST_TAIL_DATA(vrrp_data->vrrp); log_message(LOG_INFO, "(%s): Specifying lvs_sync_daemon_interface against a vrrp is deprecated.", vrrp->iname); /* Deprecated after v1.2.19 */ - log_message(LOG_INFO, " %*sPlease use global lvs_sync_daemon_interface and lvs_sync_daemon_vrrp", (int)strlen(vrrp->iname) - 2, ""); + log_message(LOG_INFO, " %*sPlease use global lvs_sync_daemon", (int)strlen(vrrp->iname) - 2, ""); - if (global_data->lvs_syncd_if) { - log_message(LOG_INFO, "(%s): lvs_sync_daemon_interface has already been specified as %s - ignoring", vrrp->iname, global_data->lvs_syncd_if); + if (global_data->lvs_syncd.ifname) { + log_message(LOG_INFO, "(%s): lvs_sync_daemon_interface has already been specified as %s - ignoring", vrrp->iname, global_data->lvs_syncd.ifname); return; } - global_data->lvs_syncd_if = set_value(strvec); - global_data->lvs_syncd_vrrp = vrrp; + global_data->lvs_syncd.ifname = set_value(strvec); + global_data->lvs_syncd.vrrp = vrrp; } static void vrrp_garp_delay_handler(vector_t *strvec) diff --git a/keepalived/vrrp/vrrp_scheduler.c b/keepalived/vrrp/vrrp_scheduler.c index 8b938c79c..015f1f77a 100644 --- a/keepalived/vrrp/vrrp_scheduler.c +++ b/keepalived/vrrp/vrrp_scheduler.c @@ -247,12 +247,12 @@ vrrp_init_state(list l) || vrrp->wantstate == VRRP_STATE_GOTO_MASTER) { #ifdef _HAVE_IPVS_SYNCD_ /* Check if sync daemon handling is needed */ - if (global_data->lvs_syncd_if && - global_data->lvs_syncd_vrrp == vrrp) + if (global_data->lvs_syncd.ifname && + global_data->lvs_syncd.vrrp == vrrp) ipvs_syncd_cmd(IPVS_STARTDAEMON, - global_data->lvs_syncd_if, + &global_data->lvs_syncd, IPVS_MASTER, - global_data->lvs_syncd_syncid, + false, false); #endif #ifdef _WITH_SNMP_RFCV3_ @@ -264,12 +264,12 @@ vrrp_init_state(list l) + VRRP_TIMER_SKEW(vrrp); #ifdef _HAVE_IPVS_SYNCD_ /* Check if sync daemon handling is needed */ - if (global_data->lvs_syncd_if && - global_data->lvs_syncd_vrrp == vrrp) + if (global_data->lvs_syncd.ifname && + global_data->lvs_syncd.vrrp == vrrp) ipvs_syncd_cmd(IPVS_STARTDAEMON, - global_data->lvs_syncd_if, + &global_data->lvs_syncd, IPVS_BACKUP, - global_data->lvs_syncd_syncid, + false, false); #endif log_message(LOG_INFO, "VRRP_Instance(%s) Entering BACKUP STATE", diff --git a/keepalived/vrrp/vrrp_snmp.c b/keepalived/vrrp/vrrp_snmp.c index aea3c4ccd..7a4fc37ab 100644 --- a/keepalived/vrrp/vrrp_snmp.c +++ b/keepalived/vrrp/vrrp_snmp.c @@ -52,8 +52,10 @@ MIBS="+KEEPALIVED-MIB:VRRP-MIB:VRRPV3-MIB" snmptrapd -f -M "+$HOME/.snmp/mibs" -Lo * Enable SNMP in config file, by adding some or all of the following, depending on which configure options were chosen + enable_snmp (enables enable_snmp_keepalived and enable_snmp_checker) enable_snmp_keepalived enable_snmp_checker + enable_snmp_rfc (enables enable_snmp_rfcv2 enable_snmp_rfcv3) enable_snmp_rfcv2 enable_snmp_rfcv3 enable_snmp_traps @@ -1127,12 +1129,12 @@ vrrp_snmp_instance(struct variable *vp, oid *name, size_t *length, return (u_char *)&long_ret; case VRRP_SNMP_INSTANCE_USELVSSYNCDAEMON: - long_ret = (global_data->lvs_syncd_vrrp == rt)?1:2; + long_ret = (global_data->lvs_syncd.vrrp == rt)?1:2; return (u_char *)&long_ret; case VRRP_SNMP_INSTANCE_LVSSYNCINTERFACE: - if (global_data->lvs_syncd_vrrp == rt) { - *var_len = strlen(global_data->lvs_syncd_if); - return (u_char *)global_data->lvs_syncd_if; + if (global_data->lvs_syncd.vrrp == rt) { + *var_len = strlen(global_data->lvs_syncd.ifname); + return (u_char *)global_data->lvs_syncd.ifname; } break; case VRRP_SNMP_INSTANCE_SYNCGROUP: diff --git a/keepalived/vrrp/vrrp_sync.c b/keepalived/vrrp/vrrp_sync.c index 2ab1cdff3..7fb45bd9f 100644 --- a/keepalived/vrrp/vrrp_sync.c +++ b/keepalived/vrrp/vrrp_sync.c @@ -40,6 +40,10 @@ vrrp_init_instance_sands(vrrp_t * vrrp) vrrp->state == VRRP_STATE_GOTO_MASTER || vrrp->state == VRRP_STATE_GOTO_FAULT || vrrp->wantstate == VRRP_STATE_GOTO_MASTER) { +// TIMER - GOTO_MASTER shouldn't be adver_int. Look at circumstances to set GOTO_MASTER +// i) backup and expire timer +// ii) backup and receive prio 0 +// iii) master and receive higher prio advert vrrp->sands = timer_add_long(time_now, vrrp->adver_int); return; } diff --git a/lib/parser.h b/lib/parser.h index 0cbdd8174..5a0d96646 100644 --- a/lib/parser.h +++ b/lib/parser.h @@ -36,7 +36,7 @@ #include "vector.h" /* Global definitions */ -#define CONF "/etc/keepalived/keepalived.conf" +#define KEEPALIVED_CONFIG_FILE "/etc/keepalived/keepalived.conf" #define BOB "{" #define EOB "}" #define MAXBUF 1024