commit 97429b3b7e6ec2f5b9c93a5d507b152bab30f919 Author: Quentin Armitage Date: Wed Sep 16 15:35:44 2020 +0100 vrrp: Fix using VMACs with unicast peers Signed-off-by: Quentin Armitage diff --git a/doc/man/man5/keepalived.conf.5 b/doc/man/man5/keepalived.conf.5 index e6b230c6..83a5915f 100644 --- a/doc/man/man5/keepalived.conf.5 +++ b/doc/man/man5/keepalived.conf.5 @@ -1359,6 +1359,8 @@ The syntax for vrrp_instance is : # all.rp_filter, as will default.rp_filter, and all.rp_filter # will be set to 0. # The original settings are restored on termination. + # \fBNOTE 2\fR: If using use_vmac with unicast peers, + # vmac_xmit_base must be set. \fBuse_vmac \fR[] # Send/Recv VRRP messages from base interface instead of diff --git a/keepalived/vrrp/vrrp_parser.c b/keepalived/vrrp/vrrp_parser.c index 5cf1eea1..d1e2d8ea 100644 --- a/keepalived/vrrp/vrrp_parser.c +++ b/keepalived/vrrp/vrrp_parser.c @@ -416,9 +416,14 @@ vrrp_end_handler(void) #ifdef _HAVE_VRRP_VMAC_ if (!list_empty(&vrrp->unicast_peer) && vrrp->vmac_flags) { - report_config_error(CONFIG_GENERAL_ERROR, "(%s): Cannot use VMAC/ipvlan with unicast peers - clearing use_vmac", vrrp->iname); - vrrp->vmac_flags = 0; - vrrp->vmac_ifname[0] = '\0'; + if (!vrrp->ifp) { + report_config_error(CONFIG_GENERAL_ERROR, "(%s): Cannot use VMAC/ipvlan with unicast peers and no interface - clearing use_vmac", vrrp->iname); + vrrp->vmac_flags = 0; + vrrp->vmac_ifname[0] = '\0'; + } else if (!__test_bit(VRRP_VMAC_XMITBASE_BIT, &vrrp->vmac_flags)) { + report_config_error(CONFIG_GENERAL_ERROR, "(%s) unicast with use_vmac requires vmac_xmit_base - setting", vrrp->iname); + __set_bit(VRRP_VMAC_XMITBASE_BIT, &vrrp->vmac_flags); + } } #endif diff --git a/keepalived/vrrp/vrrp_scheduler.c b/keepalived/vrrp/vrrp_scheduler.c index 2fb859e1..d9271720 100644 --- a/keepalived/vrrp/vrrp_scheduler.c +++ b/keepalived/vrrp/vrrp_scheduler.c @@ -459,17 +459,17 @@ vrrp_create_sockpool(list_head_t *l) struct sockaddr_storage *unicast_src; list_for_each_entry(vrrp, &vrrp_data->vrrp, e_list) { - if (list_empty(&vrrp->unicast_peer)) { - ifp = -#ifdef _HAVE_VRRP_VMAC_ - (__test_bit(VRRP_VMAC_XMITBASE_BIT, &vrrp->vmac_flags)) ? vrrp->configured_ifp : -#endif - vrrp->ifp; + if (list_empty(&vrrp->unicast_peer)) unicast_src = NULL; - } else { + else unicast_src = &vrrp->saddr; - ifp = vrrp->ifp; - } + + ifp = +#ifdef _HAVE_VRRP_VMAC_ + (__test_bit(VRRP_VMAC_XMITBASE_BIT, &vrrp->vmac_flags)) ? vrrp->configured_ifp : +#endif + vrrp->ifp; + proto = IPPROTO_VRRP; #if defined _WITH_VRRP_AUTH_ if (vrrp->auth_type == VRRP_AUTH_AH) @@ -607,13 +607,6 @@ vrrp_lower_prio_gratuitous_arp_thread(thread_ref_t thread) vrrp_send_link_update(vrrp, vrrp->garp_lower_prio_rep); } -static void -vrrp_master(vrrp_t * vrrp) -{ - /* Send the VRRP advert */ - vrrp_state_master_tx(vrrp); -} - void try_up_instance(vrrp_t *vrrp, bool leaving_init) { @@ -802,7 +795,7 @@ vrrp_dispatcher_read_timeout(sock_t *sock) vrrp_goto_master(vrrp); } else if (vrrp->state == VRRP_STATE_MAST) - vrrp_master(vrrp); + vrrp_state_master_tx(vrrp); /* handle instance synchronization */ #ifdef _TSM_DEBUG_