From db6859f67cedbbdf73117ce79af0b7af4351215f Mon Sep 17 00:00:00 2001 From: Quentin Armitage Date: Sun, 8 Nov 2015 15:44:36 +0000 Subject: Allow gratuitious ARP parameters to be configured globally It is likely that the gratuitions ARP parameters will want to be the same for all interfaces, so allow the defaults to be set globally. Also allow vrrp_garp_delay to be set to 0 to indicate not to send further garp messages after a delay (to emulate how the kernel sends gratuitous ARPs). Signed-off-by: Quentin Armitage (cherry picked from commit eb7c4b57e074f4ce8b143d4abf3f1e4b855dc5ed) --- doc/keepalived.conf.SYNOPSIS | 27 ++++++++++++++++++--------- doc/man/man5/keepalived.conf.5 | 20 ++++++++++++++++++-- keepalived/core/global_data.c | 18 ++++++++++++++++++ keepalived/core/global_parser.c | 28 ++++++++++++++++++++++++++++ keepalived/include/global_data.h | 5 +++++ keepalived/vrrp/vrrp.c | 12 +++++++----- keepalived/vrrp/vrrp_data.c | 6 ++++-- keepalived/vrrp/vrrp_print.c | 4 ++++ keepalived/vrrp/vrrp_scheduler.c | 7 +++---- 9 files changed, 105 insertions(+), 22 deletions(-) diff --git a/doc/keepalived.conf.SYNOPSIS b/doc/keepalived.conf.SYNOPSIS index 6837892..7f0d279 100644 --- a/doc/keepalived.conf.SYNOPSIS +++ b/doc/keepalived.conf.SYNOPSIS @@ -34,6 +34,16 @@ global_defs { # Block identification router_id # String identifying router vrrp_mcast_group4 # optional, default 224.0.0.18 vrrp_mcast_group6 # optional, default ff02::12 + vrrp_garp_master_delay # delay in seconds for second set of gratuitous ARP + # messages after MASTER state transition, default 5 + vrrp_garp_master_repeat # how many gratuitous ARP messages after MASTER + # state transition should be sent, default 5 + vrrp_garp_master_refresh # Periodic delay in seconds sending + # gratuitous ARP while in MASTER state + # Default: 0 (no refreshing) + vrrp_garp_master_refresh_repeat # how many gratuitous ARP messages shoule be sent + # at each periodic repeat + # Default: once (per period) } linkbeat_use_polling # Use media link failure detection polling fashion @@ -175,15 +185,14 @@ vrrp_instance { # VRRP instance declaration ... # in unicast design fashion } lvs_sync_daemon_interface # Binding interface for lvs syncd - garp_master_delay # delay for gratuitous ARP after MASTER - # state transition - garp_master_repeat # how often the gratuitous ARP after MASTER - # state transition should be repeated? - garp_master_refresh # Periodic delay in seconds sending - # gratuitous ARP while in MASTER state - garp_master_refresh_repeat # how often the periodically repeated gratuitous ARP - # should be repeated? - # Default: once (per period) + + # The following garp parameters take their defaults from the global config for vrrp_garp_master_... + # See their descriptions for the meaning of the parameters. + garp_master_delay + garp_master_repeat + garp_master_refresh + garp_master_refresh_repeat + virtual_router_id # VRRP VRID priority # VRRP PRIO advert_int # VRRP Advert interval (use default) diff --git a/doc/man/man5/keepalived.conf.5 b/doc/man/man5/keepalived.conf.5 index 82bc353..e40440d 100644 --- a/doc/man/man5/keepalived.conf.5 +++ b/doc/man/man5/keepalived.conf.5 @@ -43,6 +43,19 @@ and # (doesn't have to be hostname). vrrp_mcast_group4 224.0.0.18 # optional, default 224.0.0.18 vrrp_mcast_group6 ff02::12 # optional, default ff02::12 + + # delay for second set of gratuitous ARPs after transition to MASTER + vrrp_garp_master_delay 10 # secs, default 5, 0 for no second set + + # number of gratuitous ARP messages to send at a time after transition to MASTER + vrrp_garp_master_repeat 1 # default 5 + + # minimum time interval for refreshing gratuitous ARPs while MASTER + vrrp_garp_master_refresh 60 # secs, default 0 (no refreshing) + + # number of gratuitous ARP messages to send at a time while MASTER + vrrp_garp_master_refresh_repeat 2 # default 1 + enable_traps # enable SNMP traps } @@ -181,8 +194,11 @@ which will transition together on any state change. # Binding interface for lvs syncd lvs_sync_daemon_interface eth1 - # delay for gratuitous ARP after transition to MASTER - garp_master_delay 10 # secs, default 5 + # interface specific settings, same as global parameters; default to global parameters + garp_master_delay 10 + garp_master_repeat 1 + garp_master_refresh 60 + garp_master_refresh_repeat 2 # arbitrary unique number 0..255 # used to differentiate multiple instances of vrrpd diff --git a/keepalived/core/global_data.c b/keepalived/core/global_data.c index 87a6c77..0c2abce 100644 --- a/keepalived/core/global_data.c +++ b/keepalived/core/global_data.c @@ -29,6 +29,7 @@ #include "list.h" #include "logger.h" #include "utils.h" +#include "vrrp.h" /* global vars */ data_t *global_data = NULL; @@ -84,6 +85,14 @@ set_default_mcast_group(data_t * data) inet_stosockaddr("ff02::12", 0, &data->vrrp_mcast_group6); } +static void +set_vrrp_defaults(data_t * data) +{ + data->vrrp_garp_rep = VRRP_GARP_REP; + data->vrrp_garp_refresh_rep = VRRP_GARP_REFRESH_REP; + data->vrrp_garp_delay = VRRP_GARP_DELAY; +} + /* email facility functions */ static void free_email(void *data) @@ -119,6 +128,7 @@ alloc_global_data(void) new->email = alloc_list(free_email, dump_email); set_default_mcast_group(new); + set_vrrp_defaults(new); return new; } @@ -182,6 +192,14 @@ dump_global_data(data_t * data) log_message(LOG_INFO, " VRRP IPv6 mcast group = %s" , inet_sockaddrtos(&data->vrrp_mcast_group6)); } + if (data->vrrp_garp_delay) + log_message(LOG_INFO, " Gratuitous ARP delay = %d", + data->vrrp_garp_delay/TIMER_HZ); + if (!timer_isnull(data->vrrp_garp_refresh)) + log_message(LOG_INFO, " Gratuitous ARP refresh timer = %lu", + data->vrrp_garp_refresh.tv_sec); + log_message(LOG_INFO, " Gratuitous ARP repeat = %d", data->vrrp_garp_rep); + log_message(LOG_INFO, " Gratuitous ARP refresh repeat = %d", data->vrrp_garp_refresh_rep); #ifdef _WITH_SNMP_ if (data->enable_traps) log_message(LOG_INFO, " SNMP Trap enabled"); diff --git a/keepalived/core/global_parser.c b/keepalived/core/global_parser.c index cb613bf..8b354ff 100644 --- a/keepalived/core/global_parser.c +++ b/keepalived/core/global_parser.c @@ -104,6 +104,30 @@ vrrp_mcast_group6_handler(vector_t *strvec) , FMT_STR_VSLOT(strvec, 1)); } } +static void +vrrp_garp_delay_handler(vector_t *strvec) +{ + global_data->vrrp_garp_delay = atoi(vector_slot(strvec, 1)) * TIMER_HZ; +} +static void +vrrp_garp_refresh_handler(vector_t *strvec) +{ + global_data->vrrp_garp_refresh.tv_sec = atoi(vector_slot(strvec, 1)); +} +static void +vrrp_garp_rep_handler(vector_t *strvec) +{ + global_data->vrrp_garp_rep = atoi(vector_slot(strvec, 1)); + if ( global_data->vrrp_garp_rep < 1 ) + global_data->vrrp_garp_rep = 1; +} +static void +vrrp_garp_refresh_rep_handler(vector_t *strvec) +{ + global_data->vrrp_garp_refresh_rep = atoi(vector_slot(strvec, 1)); + if ( global_data->vrrp_garp_refresh_rep < 1 ) + global_data->vrrp_garp_refresh_rep = 1; +} #ifdef _WITH_SNMP_ static void trap_handler(vector_t *strvec) @@ -126,6 +150,10 @@ global_init_keywords(void) install_keyword("notification_email", &email_handler); install_keyword("vrrp_mcast_group4", &vrrp_mcast_group4_handler); install_keyword("vrrp_mcast_group6", &vrrp_mcast_group6_handler); + install_keyword("vrrp_garp_master_delay", &vrrp_garp_delay_handler); + install_keyword("vrrp_garp_master_repeat", &vrrp_garp_rep_handler); + install_keyword("vrrp_garp_master_refresh", &vrrp_garp_refresh_handler); + install_keyword("vrrp_garp_master_refresh_repeat", &vrrp_garp_refresh_rep_handler); #ifdef _WITH_SNMP_ install_keyword("enable_traps", &trap_handler); #endif diff --git a/keepalived/include/global_data.h b/keepalived/include/global_data.h index 3e429da..9ea0867 100644 --- a/keepalived/include/global_data.h +++ b/keepalived/include/global_data.h @@ -27,6 +27,7 @@ #include #include #include +#include /* local includes */ #include "list.h" @@ -53,6 +54,10 @@ typedef struct _data { list email; struct sockaddr_storage vrrp_mcast_group4; struct sockaddr_storage vrrp_mcast_group6; + int vrrp_garp_delay; + timeval_t vrrp_garp_refresh; + int vrrp_garp_rep; + int vrrp_garp_refresh_rep; #ifdef _WITH_SNMP_ int enable_traps; #endif diff --git a/keepalived/vrrp/vrrp.c b/keepalived/vrrp/vrrp.c index dcf4ed1..22ae856 100644 --- a/keepalived/vrrp/vrrp.c +++ b/keepalived/vrrp/vrrp.c @@ -272,7 +272,9 @@ vrrp_in_chk_vips(vrrp_t * vrrp, ip_address_t *ipaddress, unsigned char *buffer) /* * VRRP incoming packet check. - * return 0 if the pkt is valid, != 0 otherwise. + * return VRRP_PACKET_OK if the pkt is valid, or + * VRRP_PACKET_KO if packet invalid or + * VRRP_PACKET_DROP if packet not relevant to us */ static int vrrp_in_chk(vrrp_t * vrrp, char *buffer) @@ -984,11 +986,11 @@ vrrp_send_update(vrrp_t * vrrp, ip_address_t * ipaddress, int idx) if (!IP_IS6(ipaddress)) { msg = "gratuitous ARPs"; - inet_ntop(AF_INET, &ipaddress->u.sin.sin_addr, addr_str, 41); + inet_ntop(AF_INET, &ipaddress->u.sin.sin_addr, addr_str, sizeof(addr_str)); send_gratuitous_arp(ipaddress); } else { msg = "Unsolicited Neighbour Adverts"; - inet_ntop(AF_INET6, &ipaddress->u.sin6_addr, addr_str, 41); + inet_ntop(AF_INET6, &ipaddress->u.sin6_addr, addr_str, sizeof(addr_str)); ndisc_send_unsolicited_na(ipaddress); } @@ -1308,8 +1310,8 @@ vrrp_saddr_cmp(struct sockaddr_storage *addr, vrrp_t *vrrp) int vrrp_state_master_rx(vrrp_t * vrrp, char *buf, int buflen) { - vrrphdr_t *hd = NULL; - int ret = 0, proto = 0; + vrrphdr_t *hd; + int ret, proto = 0; ipsec_ah_t *ah; /* return on link failure */ diff --git a/keepalived/vrrp/vrrp_data.c b/keepalived/vrrp/vrrp_data.c index 99a9303..1235aac 100644 --- a/keepalived/vrrp/vrrp_data.c +++ b/keepalived/vrrp/vrrp_data.c @@ -20,6 +20,7 @@ * Copyright (C) 2001-2012 Alexandre Cassen, */ +#include "global_data.h" #include "vrrp_data.h" #include "vrrp_index.h" #include "vrrp_sync.h" @@ -367,8 +368,9 @@ alloc_vrrp(char *iname) new->stats = alloc_vrrp_stats(); memcpy(new->iname, iname, size); new->quick_sync = 0; - new->garp_rep = VRRP_GARP_REP; - new->garp_refresh_rep = VRRP_GARP_REFRESH_REP; + new->garp_rep = global_data->vrrp_garp_rep; + new->garp_refresh_rep = global_data->vrrp_garp_refresh_rep; + new->garp_delay = global_data->vrrp_garp_delay; list_add(vrrp_data->vrrp, new); } diff --git a/keepalived/vrrp/vrrp_print.c b/keepalived/vrrp/vrrp_print.c index 455accb..ff4b925 100644 --- a/keepalived/vrrp/vrrp_print.c +++ b/keepalived/vrrp/vrrp_print.c @@ -130,6 +130,10 @@ vrrp_print(FILE *file, void *data) if (vrrp->garp_delay) fprintf(file, " Gratuitous ARP delay = %d\n", vrrp->garp_delay/TIMER_HZ); + fprintf(file, " Gratuitous ARP refresh = %lu\n", + vrrp->garp_refresh.tv_sec/TIMER_HZ); + fprintf(file, " Gratuitous ARP repeat = %d\n", vrrp->garp_rep); + fprintf(file, " Gratuitous ARP refresh repeat = %d\n", vrrp->garp_refresh_rep); fprintf(file, " Virtual Router ID = %d\n", vrrp->vrid); fprintf(file, " Priority = %d\n", vrrp->base_priority); fprintf(file, " Advert interval = %d %s\n", diff --git a/keepalived/vrrp/vrrp_scheduler.c b/keepalived/vrrp/vrrp_scheduler.c index 74be027..47e6cd8 100644 --- a/keepalived/vrrp/vrrp_scheduler.c +++ b/keepalived/vrrp/vrrp_scheduler.c @@ -805,10 +805,9 @@ vrrp_master(vrrp_t * vrrp) * register a gratuitous arp thread delayed to 5 secs. */ if (vrrp_state_master_tx(vrrp, 0)) { - thread_add_timer(master, vrrp_gratuitous_arp_thread, - vrrp, - (vrrp->garp_delay) ? - vrrp->garp_delay : VRRP_GARP_DELAY); + if (vrrp->garp_delay) + thread_add_timer(master, vrrp_gratuitous_arp_thread, + vrrp, vrrp->garp_delay); vrrp_smtp_notifier(vrrp); } } -- 1.7.12.1