vrrp协议_要了我老命了|VRRP双主

在一次网络故障中,发现NE路由器的VRRP配置导致双主状态,原因是STP配置不当造成的心跳报文传输问题。通过调整STP配置或启用MSTP+VRRP结构,解决了双主问题,确保了服务器数据采集的正常进行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

信不信还真的会要命,为啥?烦啊,好好的切换就行了,双主还要排错,那不是要命么。(到点下班才是正确打开姿势)
本文关键字:MSTP,VRRP

一、交代前因后果

在一个良辰美景时刻,额,周五了,马上双休,应该算好日子吧。

开了首music,准备到点就溜。

快下班了,收拾东西,在这个即将出门的时刻,电话响起来了,犹豫了几秒钟,接了。

采集不到服务器数据,一波ping,嘿嘿,没通,tracert过不去,登录上设备,display ip route +服务器地址,咦,什么鬼,路由怎么跑到防火墙那边了,额,等我下,先上个拓扑....。

266e78e845a555cf555abbc94ee73790.png

在NE交换机上面display ip route +服务器ip,在NE设备上面显示下一跳是防火墙的地址,查配置,NE和防火墙起来了ospf,并且把直连接口和静态路由import,而在NE上面显示的destination目标网段为全0,说明防火墙那边有默认全0路由,被ne学到了。

说了这么多,其实我想对NE路由器说一句,大哥,你搞错了,你的下一家是华三交换机的地址才对啊,在display cu| include static,好吧,指向服务器的路由存在啊,在华为华三体系里面,静态协议优先级高于ospf,那么问题来了,为什么这条路由不生效,下一跳指向了防火墙呢?

我暂且登录华三交换机一看,原来用的vrrp主备模式,继续看,vrrp状态,双主。。。

好吧,先搞定双主怎么回事再说吧!

恩,使用的是这样子。华为和华三交换机之间走trunk,放行了两个vlan,这两个vlan是服务器对应使用的。

在华

在keepalived的VRRP模块中,`vrrp_check_packet`、`vrrp_send_adv`、`vrrp_update_pkt`和`vrrp_send_pkt`是处理VRRP报文的核心函数。要支持自定义VRRP扩展(如封装故障信息),需要修改这些函数以添加自定义字段并确保其正确传输和解析。以下是具体修改方法: --- ### **1. 修改`vrrp_update_pkt`(构造VRRP报文)** `vrrp_update_pkt`负责填充VRRP报文内容。在此函数中添加自定义字段(如故障代码): #### **修改步骤**: 1. **在VRRP报文结构中添加自定义字段**(如`fault_code`): - 在`keepalived/include/vrrp.h`中扩展`vrrp_packet`结构体: ```c typedef struct _vrrp_packet { uint8_t version; uint8_t type; uint8_t vrid; uint8_t priority; // 其他原有字段... uint8_t fault_code; // 新增:故障代码字段 } vrrp_packet; ``` 2. **在`vrrp_update_pkt`中填充自定义字段**: - 在`keepalived/src/vrrp/vrrp_packet.c`中修改: ```c void vrrp_update_pkt(vrrp_t *vrrp, vrrp_packet *pkt) { // 原有字段填充 pkt->version = VRRP_VERSION; pkt->type = VRRP_TYPE_ADVERTISEMENT; pkt->vrid = vrrp->vrid; pkt->priority = vrrp->effective_priority; // 新增:填充故障代码(MASTER节点在故障时设置) if (vrrp->is_master && vrrp->fault_detected) { pkt->fault_code = vrrp->fault_code; // 例如:0x01=服务崩溃,0x02=硬件故障 } else { pkt->fault_code = 0x00; // 无故障 } } ``` --- ### **2. 修改`vrrp_send_adv`和`vrrp_send_pkt`(发送报文)** 这两个函数负责发送VRRP报文。通常无需直接修改它们,但需确保`vrrp_update_pkt`已正确填充自定义字段,且报文长度足够。 #### **注意事项**: - 如果自定义字段增加了报文长度,需检查`vrrp_send_pkt`中的缓冲区大小是否足够。 - 确保发送的报文符合VRRP协议格式(如IP头部的总长度字段需更新)。 --- ### **3. 修改`vrrp_check_packet`(接收和解析报文)** `vrrp_check_packet`用于解析接收到的VRRP报文。需在此函数中提取自定义字段并处理。 #### **修改步骤**: 1. **解析自定义字段**: - 在`keepalived/src/vrrp/vrrp_packet.c`中修改: ```c int vrrp_check_packet(vrrp_t *vrrp, vrrp_packet *pkt) { // 原有校验逻辑(如版本、VRID匹配) if (pkt->version != VRRP_VERSION || pkt->vrid != vrrp->vrid) { return -1; } // 新增:提取故障代码 if (pkt->fault_code != 0x00) { log_message(LOG_INFO, "Received fault code from MASTER: %d", pkt->fault_code); // 触发BACKUP节点的处理逻辑(如记录日志、切换状态) handle_master_fault(vrrp, pkt->fault_code); } return 0; } ``` 2. **添加故障处理逻辑**: - 在`vrrp_packet.c`中定义`handle_master_fault`函数: ```c void handle_master_fault(vrrp_t *vrrp, uint8_t fault_code) { // 根据故障代码执行操作(如发送告警、强制切换) if (fault_code == 0x01) { log_message(LOG_ERR, "MASTER服务崩溃,准备接管!"); } else if (fault_code == 0x02) { log_message(LOG_ERR, "MASTER硬件故障,立即切换!"); } // 其他处理逻辑... } ``` --- ### **4. 在MASTER节点设置故障代码** 在MASTER节点的故障检测逻辑中,设置`fault_code`并触发报文更新: #### **示例代码**: ```c // 在MASTER节点的故障检测函数中 void detect_master_fault(vrrp_t *vrrp) { if (is_service_down()) { vrrp->fault_code = 0x01; // 服务崩溃 vrrp->fault_detected = 1; vrrp_send_adv(vrrp); // 立即发送带故障信息的报文 } } ``` --- ### **5. 编译和测试** 1. **重新编译keepalived**: ```bash make clean && ./configure && make sudo make install ``` 2. **测试场景**: - 在MASTER节点模拟故障(如停止服务),验证BACKUP节点是否能正确解析`fault_code`并触发预期行为。 - 使用`tcpdump`抓包,检查VRRP报文是否包含自定义字段。 --- ### **关键注意事项** 1. **兼容性**: - 自定义字段应位于VRRP报文的可选部分(如认证字段后),避免破坏协议兼容性。 - 可通过配置选项(如`enable_fault_extension`)控制是否启用扩展。 2. **报文长度**: - 如果自定义字段增加报文长度,需调整`vrrp_send_pkt`中的缓冲区大小和IP头部长度字段。 3. **安全性**: - 确保自定义字段不被篡改(如通过VRRP认证机制)。 --- ### **最终代码结构示例** ```c // vrrp.h typedef struct _vrrp_packet { uint8_t version; uint8_t type; uint8_t vrid; uint8_t priority; uint8_t fault_code; // 自定义字段 } vrrp_packet; // vrrp_packet.c void vrrp_update_pkt(vrrp_t *vrrp, vrrp_packet *pkt) { pkt->fault_code = vrrp->fault_code; } int vrrp_check_packet(vrrp_t *vrrp, vrrp_packet *pkt) { if (pkt->fault_code) handle_master_fault(vrrp, pkt->fault_code); } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值