From 84c2806e3ceba9bb164b6367ffb1f8d882f07c83 Mon Sep 17 00:00:00 2001 From: Louis Scalbert Date: Mon, 3 Apr 2023 17:38:36 +0200 Subject: [PATCH] vrrp: fix persistent FAULT state with use_vmac on a down base interface If the base interface of VMAC is down at startup, the VRRP instance will remain on FAULT state even if the base interface is set up. keepalived uses a vrrp->num_script_if_fault fault counter that is incremented when there is a new fault and decremented when the fault is recovered. When the counter equals to zero, it considers there is no fault. try_up_instance() is used to decrease the counter. Since 4c7a94a409 ("vrrp: Make VMAC IPv6 link local address mirror parent interface"), it was not called anymore when a IPv6 link-local was back on the VMAC interface. Increment vrrp->num_script_if_fault when an IPv6 appears on the VMAC. Fixes: 4c7a94a409 ("vrrp: Make VMAC IPv6 link local address mirror parent interface") Signed-off-by: Louis Scalbert --- keepalived/core/keepalived_netlink.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/keepalived/core/keepalived_netlink.c b/keepalived/core/keepalived_netlink.c index 4b9058caa0..d9cc381eb9 100644 --- a/keepalived/core/keepalived_netlink.c +++ b/keepalived/core/keepalived_netlink.c @@ -1027,22 +1027,25 @@ netlink_if_address_filter(__attribute__((unused)) struct sockaddr_nl *snl, struc !__test_bit(VRRP_VMAC_XMITBASE_BIT, &vrrp->flags) && ifa->ifa_family == AF_INET6 && vrrp->ifp->is_ours) { - inet_ip6tosockaddr(addr.in6, &vrrp->saddr); + if (vrrp->saddr.ss_family == AF_UNSPEC) { + inet_ip6tosockaddr(addr.in6, &vrrp->saddr); + if ( #if 0 - if (IN6_IS_ADDR_UNSPECIFIED(&vrrp->ifp->sin6_addr)) { - /* This should never happen with the current code since we always - * create a link local address on the VMAC interface. - * However, if in future it is decided not to automatically create - * a link local address on the VMAC interface if the parent interface - * does not have one, then we will need the following code - */ - if (add_link_local_address(vrrp->ifp, addr.in6) && + /* This should never happen with the current code since we always + * create a link local address on the VMAC interface. + * However, if in future it is decided not to automatically create + * a link local address on the VMAC interface if the parent interface + * does not have one, then we will need the following code + */ + add_link_local_address(vrrp->ifp, addr.in6) && +#endif vrrp->num_script_if_fault && (!__test_bit(VRRP_FLAG_SADDR_FROM_CONFIG, &vrrp->flags) || is_tracking_saddr)) try_up_instance(vrrp, false); - } else -#endif + } else { + inet_ip6tosockaddr(addr.in6, &vrrp->saddr); reset_link_local_address(&vrrp->ifp->sin6_addr, vrrp); + } } #endif }