carp: deal with negative net.inet.carp.demotion

Given nodes 1 and 2, where node 1 has an advskew of 0 and node 2 has an
advskew of 100, making them master and backup respectively.

If net.inet.carp.demotion is set to a negative value on node 1, node 2
might become master while node 1 still retains it master status. Wether
or not node 2 becomes master seems to depend on the nodes advskew and
what the demotion sysctl was set to on node 1.

The reason for node 2 becoming master seems to be that the calculated
advskew taking demotion into account is truncated to a single unsigned
byte when copied into the carp header for sending, and node 1 stays
master since it takes uses the whole non-truncated calculated advskew
when deciding wether to stay master.

PR:		259528
Reviewed by:	donner, glebius
MFC after:	3 weeks
Sponsored by:	Modirum MDPay
Differential Revision:	https://reviews.freebsd.org/D32759
This commit is contained in:
Marius Halden 2021-10-31 21:18:42 +01:00 committed by Kristof Provost
parent dde6071adc
commit 1019354b54

View File

@ -304,7 +304,9 @@ SYSCTL_VNET_PCPUSTAT(_net_inet_carp, OID_AUTO, stats, struct carpstats,
#define DEMOTE_ADVSKEW(sc) \
(((sc)->sc_advskew + V_carp_demotion > CARP_MAXSKEW) ? \
CARP_MAXSKEW : ((sc)->sc_advskew + V_carp_demotion))
CARP_MAXSKEW : \
(((sc)->sc_advskew + V_carp_demotion < 0) ? \
0 : ((sc)->sc_advskew + V_carp_demotion)))
static void carp_input_c(struct mbuf *, struct carp_header *, sa_family_t);
static struct carp_softc