Isso pode realmente ser causado por um bug. Eu sei porque eu tive que consertar isso sozinho.
De acordo com o RFC, quando as prioridades são iguais em ambos os nós;
If the Priority in the ADVERTISEMENT is equal to the local Priority and the primary IP Address of the sender is greater than the local primary IP Address, then: o Cancel Adver_Timer o Set Master_Down_Timer to Master_Down_Interval o Transition to the {Backup} state
Então, quem tiver o maior endereço IP vencerá.
Em keepalived, a maneira como isso é feito é basicamente errado. Endianness não é considerado adequadamente ao fazer esta comparação.
Vamos imaginar que temos dois roteadores, (A) 10.1.1.200 e (B) 10.1.1.201.
O código deve realizar a seguinte comparação.
Em A:
if (10.1.1.201 > 10.1.1.200) // True
be_backup();
Em B:
if (10.1.1.200 > 10.1.1.201) // False
be_master();
No entanto, como o endianness não é manipulado incorretamente, a seguinte comparação é feita em seu lugar.
Em A:
if (10.1.1.201 > 200.1.1.10) // False
be_master();
Em B:
if (10.1.1.200 > 201.1.1.10) // False
be_master();
Esse patch deve funcionar, mas eu o refiz do meu patch original e não o testou . Nem mesmo testado compila! Então não há reembolso!
--- vrrp/vrrp.c.old 2013-10-13 17:39:29.421000176 +0100
+++ vrrp/vrrp.c 2013-10-13 18:07:57.360000966 +0100
@@ -923,7 +923,7 @@
} else if (vrrp->family == AF_INET) {
if (hd->priority > vrrp->effective_priority ||
(hd->priority == vrrp->effective_priority &&
- ntohl(saddr) > ntohl(VRRP_PKT_SADDR(vrrp)))) {
+ ntohl(saddr) > VRRP_PKT_SADDR(vrrp))) {
log_message(LOG_INFO, "VRRP_Instance(%s) Received higher prio advert"
, vrrp->iname);
if (proto == IPPROTO_IPSEC_AH) {