先查 EVPN 路由器 MAC,再怀疑 underlay
Type 5 路由同时携带 L3 VNI 和路由器 MAC,用于内层帧。在改动一条从来不是问题的 underlay MAC 之前,先核对这两项。
同一个 VXLAN 报文里会出现两个 MAC 地址,其中只有一个是目的主机的。在 EVPN VXLAN 的 IP-VRF 到 IP-VRF 设计中,内层目的 MAC 是出口路由器通告的路由器 MAC,而外层目的 MAC 属于在下一段 underlay 链路上投递该报文的那台设备。把两者混为一谈,就会让人跑到 underlay 去找一个并不存在的故障。按顺序做完这几项检查。
每一步只回答一个问题,而第一个答案决定了后面的步骤是否还有意义。
1. 先读前缀路由及其 community
从路由入手,而不是从抓包入手:
show bgp l2vpn evpn route type prefix 10.20.0.0/24Type 5 路由通告一个 IP 前缀。在无接口的 IP-VRF 模型中,它还携带 L3 VNI 和扩展的 router MAC community,而正是这个 community 标明了出口路由端点。应当去读 community,而不是假设 MAC 已嵌入前缀 NLRI 之中——它并没有。如果路由存在且 community 已附上,控制面该做的就已经做完了。
2. 确认使用的是哪种转发模型
无接口模型与 overlay 索引递归是两种不同的受支持做法。无接口模型会对报文做路由,为远端路由端点构造内层帧,再朝出口 VTEP 封装。
而在 overlay 索引递归下,入口路由器需要多查一次表来解析下一跳,之后才能转发。两种模型都成立,适用哪套流程取决于你的 fabric 用的是哪一种。把直连下一跳的推理套到另一种方式搭建的 fabric 上,会得出一个在抓包里看着对、在设计评审里却是错的结论。
3. 预期有两个不同的 MAC 角色
内层目的 MAC 是出口路由器通告的路由器 MAC。外层目的 MAC 是本地投递的下一跳,它可能是某台 underlay 路由器,并且每跳都可能变化。两者不同是正常的,两者相同只是巧合而不是要求。抓包里内侧像一个机箱地址、外侧是物理下一跳地址,这恰恰描述的正是设计想要的封装。
4. 把机箱派生的取值当作实现选择
平台可能从系统或机箱标识派生出它所通告的路由器 MAC,这是实现层面的决定,而不是协议规定。在下结论之前,先查清厂商的分配与冗余模型,再判断地址格式说明了什么。
两个都合规的实现完全可以通告看起来不一样的路由器 MAC,所以拿它们跨厂商对比,能证明的东西很少。
5. 在状态出现分歧之前什么也别改
做评审时,把选中的前缀路由、它的扩展 community、BGP 下一跳、L3 VNI 以及由此得到的转发表状态放在一起对比,然后在抓包里标注内层与外层的头部。
如果这五项都对得上,那个看起来奇怪的 MAC 正在履行职责,改掉它只会弄坏一个路由端点,而不是修正地址错误。如果对不上,你现在已经知道是哪个字段错了,改动就是有的放矢而不是猜测。EVPN IP 前缀规范 正是那场讨论中应当引用的依据,因为它既描述了模型,也描述了承载该值的 community。