Skip to content

Commit 0624ca4

Browse files
committed
vrrp: fix vmac creation issue due to race condition
The VMAC interface sometimes does not reappear when its associated link interface is quickly re-added after being deleted, a situation caused by a race condition. This problem manifests during the operations of cleanup_lost_interface() This function checks for VMAC interfaces on top of the removed link interface. It deletes these VMAC interfaces if they are present. Subsequently, Netlink is invoked to refresh the information of all interfaces, and this is followed by the cleaning of the link interface data in memory. The problem occurs when Netlink, queried indirectly by sub-functions of cleanup_lost_interface(), detects that the link interface has reappeared. Although the interface data in memory is updated accordingly, cleanup_lost_interface() unconditionally clears this refreshed information. As a result, the data regarding the link interface is lost, preventing the re-creation of its associated VMAC interfaces. Fix the VMAC creation issue by adding a 'cleaning flag' that is set at the start of the cleanup process. This flag says whether to proceed with the interface data cleanup. If the interface is refreshed during the Netlink polling, the flag is unset, thereby preventing the subsequent clearing of the updated interface information. Signed-off-by: Louis Scalbert <[email protected]>
1 parent 566f44b commit 0624ca4

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

keepalived/core/keepalived_netlink.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1978,6 +1978,8 @@ netlink_if_link_populate(interface_t *ifp, struct rtattr *tb[], struct ifinfomsg
19781978
#endif /* _HAVE_VRF_ */
19791979

19801980
ifp->rp_filter = UINT_MAX; /* We have not read it yet */
1981+
1982+
ifp->cleaning = false;
19811983
#endif /* _HAVE_VRRP_VMAC_ */
19821984

19831985
ifp->ifi_flags = ifi->ifi_flags;

keepalived/include/vrrp_if.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ typedef struct _interface {
161161
otherwise the physical interface */
162162
bool is_ours; /* keepalived created the interface */
163163
bool deleting; /* Set when we are deleting the interface */
164+
bool cleaning; /* Set when we are cleaning the interface */
164165
bool seen_interface; /* The interface has existed at some point since we started */
165166
bool changeable_type; /* The interface type or underlying interface can be changed */
166167
#ifdef _HAVE_VRF_

keepalived/vrrp/vrrp_if.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,6 +1394,11 @@ cleanup_lost_interface(interface_t *ifp)
13941394
tracking_obj_t *top;
13951395
vrrp_t *vrrp;
13961396

1397+
#ifdef _HAVE_VRRP_VMAC_
1398+
ifp->cleaning = true;
1399+
#endif /* _HAVE_VRRP_VMAC_ */
1400+
1401+
13971402
list_for_each_entry(top, &ifp->tracking_vrrp, e_list) {
13981403
vrrp = top->obj.vrrp;
13991404

@@ -1476,12 +1481,19 @@ cleanup_lost_interface(interface_t *ifp)
14761481

14771482
interface_down(ifp);
14781483

1484+
#ifdef _HAVE_VRRP_VMAC_
1485+
if (!ifp->cleaning)
1486+
/* interface has been refreshed. Do not clean */
1487+
return;
1488+
#endif /* _HAVE_VRRP_VMAC_ */
1489+
14791490
ifp->ifindex = 0;
14801491
ifp->ifi_flags = 0;
14811492
ifp->seen_up = false;
14821493
#ifdef _HAVE_VRRP_VMAC_
14831494
if (!ifp->is_ours)
14841495
ifp->base_ifp = ifp;
1496+
ifp->cleaning = false;
14851497
#endif
14861498
#ifdef _HAVE_VRF_
14871499
ifp->vrf_master_ifp = NULL;

0 commit comments

Comments
 (0)