keepalived源码解析 —— vrrp

阅读: 评论:0

keepalived源码解析 —— vrrp

keepalived源码解析 —— vrrp

功能:
1、分析收到的 vrrp 包。若包分析返回结果:VRRP_PACKET_OK,则直接返回 false;
2、若满足以下任一条件:
1)master 收到一个 priority = 0 的通告;
2)配置文件指定了:higher_prio_send_advert(若 master 收到一个更高优先级的 vrrp,则自身在变成 backup 之前发送一个通告)
且 对端 vrrp 的优先级 > 本端 vrrp 的优先级,或者 两者的优先级相同但ip相同;
则:
发送 vrrp 通告;
3、若对端与本端 vrrp 优先级均为 VRRP_PRIO_OWNER(255),则本端 vrrp 优先级-1;
4、若满足以下任一条件:
1)对端 vrrp 的优先级 < 本端 vrrp 的优先级;
2)两端优先级相同,所使用的的 ip 不同;
则:
1)发送 vrrp 通告(若配置项未指定 lower_prio_no_advert,即:如果收到低优先级的通告,不发送任何通告);
2)发送 ARP 数据包,更新远端 ARP 缓冲区;
5、若对端 vrrp 优先级 > 本端 vrrp 优先级 或者两者优先级相同但地址不同,
则:本端 vrrp 切换为 master

返回值 True:离开 master 状态,false:保留 master 状态

bool
vrrp_state_master_rx(vrrp_t * vrrp, const vrrphdr_t *hd, const char *buf, ssize_t buflen)
{ssize_t ret;
#ifdef _WITH_VRRP_AUTH_const ipsec_ah_t *ah;
#endifunsigned master_adver_int;int addr_cmp;vrrp_t *gvrrp;element e;// TODO - could we get here with wantstate == FAULT and STATE != FAULT?/* return on link failure */
// TODO - not needed???/* vrrp 出现故障 */if (vrrp->wantstate == VRRP_STATE_FAULT) {vrrp->master_adver_int = vrrp->adver_int;vrrp->ms_down_timer = 3 * vrrp->master_adver_int + VRRP_TIMER_SKEW(vrrp);vrrp->state = VRRP_STATE_FAULT;send_instance_notifies(vrrp);vrrp->last_transition = timer_now();return true;}/* 分析收到的数据包 */ret = vrrp_check_packet(vrrp, hd, buf, buflen, true);/* 包无效,直接返回 */if (ret != VRRP_PACKET_OK)return false;/* 比较数据包地址 与 vrrp 地址*/addr_cmp = vrrp_saddr_cmp(&vrrp->pkt_saddr, vrrp);/*若满足以下任一条件:1、master 收到一个 priority = 0 的通告;2、配置文件指定了:higher_prio_send_advert(若 master 收到一个更高优先级的 vrrp,则自身在变成 backup 之前发送一个通告)且 对端 vrrp 的优先级 > 本端 vrrp 的优先级,或者 两者的优先级相同但ip相同;则:发送 vrrp 通告	*/if (hd->priority == 0 ||(vrrp->higher_prio_send_advert &&(hd->priority > vrrp->effective_priority ||(hd->priority == vrrp->effective_priority && addr_cmp > 0)))) {log_message(LOG_INFO, "(%s) Master received priority 0 or lower priority advert", vrrp->iname);vrrp_send_adv(vrrp, vrrp->effective_priority);/* 发送 vrrp 通告 */if (hd->priority == 0)return false;}/* 若对端与本端 vrrp 优先级均为 VRRP_PRIO_OWNER(255),则本端 vrrp 优先级-1 */if (hd->priority == vrrp->effective_priority) {if (addr_cmp == 0)/* 对端使用与本端相同的ip发送优先级一样的 vrrp */log_message(LOG_INFO, "(%s) WARNING - equal priority advert received from remote host with our IP address.", vrrp->iname);else if (vrrp->effective_priority == VRRP_PRIO_OWNER) {/* If we are configured as the address owner (priority == 255), and we receive an advertisement* from another system indicating it is also the address owner, then there is a clear conflict.* Report a configuration error, and drop our priority as a workaround. */log_message(LOG_INFO, "(%s) CONFIGURATION ERROR: local instance and a remote instance are both configured as address owner, please fix - reducing local priority", vrrp->iname);vrrp->effective_priority = VRRP_PRIO_OWNER - 1;vrrp->base_priority = VRRP_PRIO_OWNER - 1;}}/*若满足以下任一条件:1、对端 vrrp 的优先级 < 本端 vrrp 的优先级;2、两端优先级相同,所使用的的 ip 不同;则:1)发送 vrrp 通告(若配置项未指定 lower_prio_no_advert,即:如果收到低优先级的通告,不发送任何通告);2)发送 ARP 数据包,更新远端 ARP 缓冲区;*/if (hd->priority < vrrp->effective_priority ||(hd->priority == vrrp->effective_priority &&addr_cmp < 0)) {/* We receive a lower prio adv we just refresh remote ARP cache */log_message(LOG_INFO, "(%s) Received advert from %s with lower priority %d, ours %d%s",vrrp->iname,inet_sockaddrtos(&vrrp->pkt_saddr),hd->priority,vrrp->effective_priority,!vrrp->lower_prio_no_advert ? ", forcing new election" : "");
#ifdef _WITH_VRRP_AUTH_if (vrrp->auth_type == VRRP_AUTH_AH) {ah = (const ipsec_ah_t *) (buf + sizeof(struct iphdr));log_message(LOG_INFO, "(%s) IPSEC-AH : Syncing seq_num"" - Increment seq", vrrp->iname);
// TODO - why is seq_number taken from lower priority advert?vrrp->ipsecah_counter.seq_number = ntohl(ah->seq_number) + 1;vrrp->le = false;}
#endif/*若配置项未指定 lower_prio_no_advert(如果收到低优先级的通告,不发送任何通告),则发送 vrrp 通告*/if (!vrrp->lower_prio_no_advert)vrrp_send_adv(vrrp, vrrp->effective_priority);/*若指定了 garp_lower_prio_rep(当 master 接收到一个较低优先级的 vrrp 后,一次发送 gratuitous apr 的数量组),则发送 ARP 数据包,更新远端 ARP 缓冲区*/if (vrrp->garp_lower_prio_rep) {vrrp_send_link_update(vrrp, vrrp->garp_lower_prio_rep);if (vrrp->garp_lower_prio_delay)thread_add_timer(master, vrrp_lower_prio_gratuitous_arp_thread,vrrp, vrrp->garp_lower_prio_delay);/* If we are a member of a sync group, send GARP messages* for any other member of the group that has* garp_lower_prio_rep set */if (vrrp->sync) {LIST_FOREACH(vrrp->sync->vrrp_instances, gvrrp, e) {if (gvrrp == vrrp)continue;if (!gvrrp->garp_lower_prio_rep)continue;vrrp_send_link_update(gvrrp, gvrrp->garp_lower_prio_rep);if (gvrrp->garp_lower_prio_delay)thread_add_timer(master, vrrp_lower_prio_gratuitous_arp_thread,gvrrp, gvrrp->garp_lower_prio_delay);}}}/* If a lower priority router has transitioned to master, there has presumably* been an intermittent communications break between the master and backup. It* appears that servers in an Amazon AWS environment can experience this.* The problem then occurs if a notify_master script is executed on the backup* that has just transitioned to master and the script executes something like* a `aws ec2 assign-private-ip-addresses` command, thereby removing the address* from the 'proper' master. Executing notify_master_rx_lower_pri notification* allows the 'proper' master to recover the secondary addresses. */send_event_notify(vrrp, VRRP_EVENT_MASTER_RX_LOWER_PRI);return false;}/*若对端 vrrp 优先级 > 本端 vrrp 优先级 或者两者优先级相同但地址不同,则:本端 vrrp 切换为 master*/if (hd->priority > vrrp->effective_priority ||(hd->priority == vrrp->effective_priority && addr_cmp > 0)) {if (hd->priority > vrrp->effective_priority)log_message(LOG_INFO, "(%s) Master received advert from %s with higher priority %d, ours %d",vrrp->iname,inet_sockaddrtos(&vrrp->pkt_saddr),hd->priority,vrrp->effective_priority);elselog_message(LOG_INFO, "(%s) Master received advert from %s with same priority %d but higher IP address than ours",vrrp->iname,inet_sockaddrtos(&vrrp->pkt_saddr),hd->priority);
#ifdef _WITH_VRRP_AUTH_if (vrrp->auth_type == VRRP_AUTH_AH)vrrp->le = false;
#endifif (vrrp->version == VRRP_VERSION_3) {master_adver_int = (ntohs(hd->v3.adver_int) & 0x0FFF) * TIMER_CENTI_HZ;/* As per RFC5798, set Master_Adver_Interval to Adver Interval contained* in the ADVERTISEMENT*/if (vrrp->master_adver_int != master_adver_int) {log_message(LOG_INFO, "(%s) advertisement interval updated from %u to %u milli-sec from higher priority master",vrrp->iname, vrrp->master_adver_int / (TIMER_HZ / 1000), master_adver_int / (TIMER_HZ / 1000));vrrp->master_adver_int = master_adver_int;}}vrrp->ms_down_timer = 3 * vrrp->master_adver_int + VRRP_TIMER_SKEW(vrrp);vrrp->master_priority = hd->priority;vrrp->wantstate = VRRP_STATE_BACK;vrrp->state = VRRP_STATE_BACK;return true;}return false;
}

本文发布于:2024-02-02 21:12:16,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170687953446469.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:源码   keepalived   vrrp
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23