
做Datacom方向认证的人基本都会做到这样一个进阶实验在通过非广播网络互联的多台路由器之间用MGRE把分散站点拉成一张虚拟网再在这张虚拟网上跑OSPF。听起来不难实际配置下去你会发现Hello包发不出去、邻居卡在init、路由学到了却Ping不通……每个报错都能让人怀疑人生。这篇文章不打算复述说明书而是把整个实验从拓扑规划、隧道配置、OSPF网络类型选择到排错链路完整讲一遍。适合正在备考Datacom方向认证、或者刚接手站点间互联项目的人。1. 为什么MGRE上跑OSPF会让人头疼1.1 MGRE不是普通的点对点GRE普通GRE是point-to-point隧道两端地址固定配置很简单。MGRE是multipoint GRE一台设备可以同时和多个对端建立隧道但不需要为每个对端单独创建一个隧道接口。它靠NHRP动态维护“隧道IP地址→公网地址”的映射。用生活类比普通GRE就像两个人约定好的固定电话拨过去就能通MGRE更像一个总机加分机系统每个分机向总机注册自己的分机号和所在直线号码其他分机要找它时先问总机总机返回号码然后两分机之间直接通话。这个类比能帮你在脑子里搭出Hub-Spoke的模型。MGRE里的“总机”是Hub路由器上通过NHRP登记所有Spoke的映射。Spoke之间如果流量触发NHRP可以返回对方映射动态建立Spoke-to-Spoke隧道如果不需要流量可以继续走Hub转发。这一点直接影响后面OSPF的路由设计。1.2 OSPF的组播Hello遇上了“没有广播”的虚拟网络OSPF靠组播Hello报文发现邻居组播地址是224.0.0.5和224.0.0.6。在以太网里组播有真实广播域支撑在普通点对点GRE里链路只有两端组播发出去只会拷贝给唯一对端等价于单播。但MGRE不是广播网络而且Spoke数量可能是几十上百没有天然的组播复制机制。NHRP提供了一个“组播列表”的概念凡是注册过或者手工指定为组播目的地的地址隧道接口发送组播报文时会把报文复制成多份逐一跳转封装发给列表里的每个对端。如果不把这个组播列表配好OSPF的Hello根本到不了对端邻居关系自然起不来。这是MGRE加OSPF实验里第一个、也是最常见的坑。很多人把OSPF配置反复检查了几遍实际上问题出在隧道层没有“广播能力”。1.3 OSPF网络类型带来的连带反应OSPF在很多主流设备的Tunnel接口上默认网络类型是NBMA。NBMA的特点是不支持广播和组播邻居要手工指定Hello定时器默认30秒而不是10秒。如果不知道这一点就会觉得配置没生效OSPF邻居永远卡在initDR也选不出来。即便把网络类型改成broadcast第二个问题又来了广播网络需要DR和BDR选举而选举结果会直接影响整张MGRE网络的路由学习路径。MGRE不是真实广播域DR的“广播”是通过Hub的组播复制替大家做的。如果DR选错到某个不稳定的Spoke全网路由同步就会出问题。所以网络类型的选择和OSPF运行机制必须放在一起想不能像在以太网交换机上那样随手就配。2. 实验拓扑与地址规划先把底子打稳2.1 拓扑与角色这个实验我用三台设备搭R1当Hub也就是中心节点R2和R3当Spoke也就是分支节点。三台设备各自有一个物理接口接在同一个模拟公网的交换环境里物理地址互相可达。三台设备还各有一个Loopback0模拟站点侧私网。这样做的目的很清晰底层物理网络是“不相关的一个IP网段”上层隧道是“10.1.1.0/24的虚拟网”最上层是“三个站点的Loopback网段”。路由协议要做的就是让三个Loopback网段通过隧道自动互通。Loopback0为什么要单独建因为它是稳定存在的接口用来做OSPF Router-ID和测试目标地址不会因为公网接口抖动而消失。生产环境中站点侧的真实业务网段就相当于这里的Loopback。2.2 地址规划表设备角色物理接口地址模拟公网Tunnel地址Loopback0R1Hub203.0.113.1/2410.1.1.1/241.1.1.1/32R2Spoke203.0.113.2/2410.1.1.2/242.2.2.2/32R3Spoke203.0.113.3/2410.1.1.3/243.3.3.3/32这里用203.0.113.0/24是文档示例地址段不会跟现实的公网地址冲突放在实验里模拟公网互通很合适。隧道地址用一个独立网段所有站点统一规划OSPF才能把它当作同一个广播域、多路访问网络来处理。如果各站点的Tunnel地址不连续后面OSPF的网络模型就乱了。2.3 物理接口基础配置R1的物理口配置如下R2、R3类似只是IP不同interface GigabitEthernet0/0/1 ip address 203.0.113.1 255.255.255.0R2配置203.0.113.2/24R3配置203.0.113.3/24。配置完在R1上ping通另外两个地址确认底层没有障碍。这一步别跳过后面隧道起不来的话光靠看隧道接口状态是很迷惑的。先确认底层三层可达能省一半排查时间。2.4 Loopback和路由器身份绑定Loopback0接口配置interface LoopBack0 ip address 1.1.1.1 255.255.255.255R2用2.2.2.2/32R3用3.3.3.3/32。OSPF的Router-ID只要唯一就行我习惯直接用Loopback地址这样看路由表和邻居表时一眼能认出是哪台设备不用去翻地址对应表。生产环境里Router-ID最好也来自稳定Loopback别让设备随机取物理接口地址否则接口重拨或故障会导致Router-ID变化OSPF邻居全部重建影响很大。3. 隧道层配置NHRP才是MGRE的灵魂3.1 Hub端Tunnel接口配置逐行拆解R1作为Hub核心配置是interface Tunnel0/0/0 ip address 10.1.1.1 255.255.255.0 tunnel-protocol gre p2mp source GigabitEthernet0/0/1 nhrp network-id 100 nhrp entry multicast dynamictunnel-protocol gre p2mp把Tunnel口从默认点对点GRE改成多点GRE。少了这句后面所有NHRP和MGRE都不生效。source GigabitEthernet0/0/1指定隧道封装源地址。GRE封装时外层源IP用这个接口的地址。这个地址必须稳定而且能被所有Spoke路由到。nhrp network-id 100NHRP的域标识。network-id相同的设备才能互相注册和解析它不是OSPF进程号大家约好一个值即可。nhrp entry multicast dynamic自动登记组播列表。任何Spoke一旦向Hub注册成功Hub就会把这个Spoke放进组播转发列表。之后OSPF在Tunnel口发送组播Hello时Hub会复制给所有已注册Spoke。这一句就是MGRE网络能“假装”支持广播的关键。注意Hub上不要写destination。MGRE的Hub逻辑上要对所有Spoke开放而不是固定一个对端。3.2 Spoke端Tunnel接口配置R2的Tunnel配置interface Tunnel0/0/0 ip address 10.1.1.2 255.255.255.0 tunnel-protocol gre p2mp source GigabitEthernet0/0/1 destination 203.0.113.1 nhrp network-id 100 nhrp entry multicast 203.0.113.1R3类似把IP和source换成203.0.113.3。Spoke端和Hub端有两个明显区别。一是多了destination 203.0.113.1Spoke必须知道向谁注册所以固定目的地址指向Hub物理地址。二是组播列表用nhrp entry multicast 203.0.113.1而不是dynamic。意思是Spoke上所有组播、广播报文都交给Hub去复制。Spoke不需要动态组播列表因为它不会替别人转发组播只要能把组播送到Hub就算完成。这两行是MGRE隧道能建起来的基础也是最容易漏的地方。3.3 注册与组播映射验证配完隧道后先不要急着开OSPF优先确认NHRP注册。在R2上执行display nhrp peer能看到R1的10.1.1.1对应203.0.113.1的映射。在R1上执行同样命令能看到R2和R3两条动态注册记录。如果Hub上能看到Spoke记录说明NHRP注册成功。如果看不到接下来先排查network-id是否一致、destination是不是Hub物理地址、底层物理口是否互通。还要在R1上看组播列表display nhrp multicast正常情况下能列出R2和R3的公网地址。这个列表决定了OSPF组播Hello能不能被复制出去后面OSPF邻居能不能起来全看这一步。隧道接口本身的状态有时候会骗人。如果source配错Tunnel口可能显示Down但即便Spoke还没注册Hub的Tunnel口也可能是Up状态。所以不要只看Up或者Down直接看NHRP表才是最准的。3.4 一个需要提前想清楚的参数Tunnel接口的MTU默认可能是1500而GRE封装要额外占用24字节左右。如果底层链路的MTU就是1500那么超过1476字节的报文会被分片。OSPF和NHRP控制报文通常不大不容易触发问题但后面业务流量如果带大包就可能出现“路由通、普通Ping通、大包Ping不通、TCP卡住”的怪现象。实验阶段可以不管生产部署一定要检查链路MTU必要时在Tunnel口下调MTU或者在底层接口统一调整MTU避免分片重组造成的性能损耗和丢包。4. OSPF开启后的三种演进从默认NBMA到两种推荐4.1 默认NBMA为什么直接做反而麻烦在很多设备的默认配置里Tunnel接口的OSPF网络类型是NBMA。NBMA的意思是“非广播多路访问”本质上最贴近MGRE的物理能力不是一个广播域但可以有多台设备。OSPF对NBMA的处理方式是不发送组播Hello只能手工指定邻居Hello间隔也变成30秒。如果不在Tunnel口下改OSPF网络类型又不配置peer那OSPF邻居会一直起不来。你可以自己试一下R1上配完OSPF后查看邻居状态大概率是init或attempt。这不是OSPF没配置对而是它根本没有找到一个可以发送单播Hello的对象。NBMA方案不是不能用但它把“动态”变成了“全手工”Spoke一多配置量很大还容易漏设备。所以我不推荐在这个实验里用默认NBMA硬扛。4.2 方案一broadcast加DR优先级调整最直观的做法是把Tunnel口伪装成一个广播网络。在R1、R2、R3的Tunnel口下执行ospf network-type broadcast然后通过DR优先级确保Hub成为唯一的DR让Spoke的优先级为0R1的Tunnel口ospf dr-priority 200R2、R3的Tunnel口ospf dr-priority 0OSPF广播网络的DR选举规则是优先级高的优先优先级相同比Router-ID已经当选的DR不会因为后来者优先级更高而自动切换。所以把Hub设成200、Spoke设成0是最保险的组合。Spoke为0意味着它永远不能成为DR也不能成为BDRHub自然是DR。为什么非要让Hub当DR因为MGRE上只有Hub有组播复制能力只有它能把LSU可靠转发给所有Spoke。如果某个Spoke意外当上DR而这个Spoke又没有组播列表没法把LSU复制给其他Spoke全网路由同步就会中断。Hub当DR等于把整张虚拟网络的“广播”能力集中到唯一有能力广播的节点上。OSPF配置部分R1: ospf 1 router-id 1.1.1.1 area 0 network 10.1.1.0 0.0.0.255 network 1.1.1.1 0.0.0.0R2: ospf 1 router-id 2.2.2.2 area 0 network 10.1.1.0 0.0.0.255 network 2.2.2.2 0.0.0.0R3类似用3.3.3.3做Router-ID。配置完后在所有设备上执行reset ospf process确认重新选举DR。强制重置的原因DR选举不是实时的。如果先启动的Spoke已经把自己选成了DRHub后启动也不会抢。不重置一遍会在邻居表里看到一个奇怪的DR而它其实没有能力承担广播复制。4.3 方案二p2mp网络类型如果不想跟DR选举纠缠可以把Tunnel口的OSPF网络类型改成p2mpR1/R2/R3的Tunnel口下 ospf network-type p2mpp2mp即Point-to-MultiPoint不选举DR和BDROSPF邻居关系建立逻辑更简单。但要注意p2mp的Hello默认仍然用组播地址224.0.0.5发送所以Hub端仍然需要配置nhrp entry multicast dynamicSpoke仍需要nhrp entry multicast指向Hub。只有这样才能保证组播Hello到达对端。p2mp模式下OSPF把所有邻居都当作点对点链路看待不需要2-way状态直接进入ExStart收敛路径更简单。这种方式适合对DR机制不放心、希望尽量减少特殊状态影响的场景。缺点是如果设备不支持自动组播复制或者想控制Hello流量就需要手工指定邻居。在实验设备上只要前面NHRP组播列表配置没问题p2mp基本可以无缝工作。4.4 两种方案对比对比维度broadcast DR优先级调整p2mp邻居建立靠DR/BDR机制状态机有2-way无2-way邻居状态更少DR选举需要且必须保证Hub是DR不需要组播依赖依赖Hub组播复制同样依赖手工指定邻居不需要缺组播复制时可手工指定peer适合场景需要走标准以太网逻辑网管熟悉DR分支数量多、希望协议状态最少两边都做一遍是最好的你会对OSPF在不同网络类型下的表现有直观感受。实际生产环境里我更偏向p2mp少一个DR角色就少一类故障。但如果内部习惯用标准广播网络模型做监控和排查broadcast方案也没问题关键是要把Hub的DR优先级稳住。4.5 Spoke到Spoke的下一跳与现实数据流OSPF路由学完之后R3看到的去2.2.2.2/32的路由下一跳很可能是R2的隧道地址10.1.1.2而不是Hub。这不是故障而是OSPF的正常行为在广播网络或p2mp网络中去往对端Loopback的最优路径会解析到通告路由器的隧道接口地址。R3要往10.1.1.2发数据时查自己的直连路由表发现有10.1.1.0/24于是认为“同一网段直接封装”。但MGRE的真实二层需要NHRP映射。此时R3会向NHRP服务器也就是Hub发起解析请求询问10.1.1.2对应哪个公网地址。Hub查自己的注册表把203.0.113.2返回给R3R3随即建立到203.0.113.2的动态GRE隧道。这个过程由数据首包触发所以第一次Ping可能会超时第二次开始就正常了。如果想强制所有站点间流量都绕行Hub也可以做但那是另一套NHRP重定向和短路策略涉及“不允许Spoke间直接解析”的配置实验里一般不展开。这个实验只要保证路由表完整、数据可达就已经达到了进阶训练目标。5. 验证与排错把“路由学到但Ping不通”治得明明白白5.1 分三层验证MGRE加OSPF的链路有三层物理层公网IP互相Ping通隧道层NHRP注册成功、Tunnel IP互相Ping通路由层OSPF邻居Full、私网路由完整。排错时必须从下往上验证任何一层有问题上面的现象都会变得很奇怪。我自己习惯的验证顺序是在R3上ping R1的Tunnel地址10.1.1.1再ping R2的Tunnel地址10.1.1.2。这里允许第一次丢包因为NHRP解析要现学。在R1上display nhrp peer确认R2、R3都注册了。在R3上display ospf peer确认邻居状态稳定为Full。在R3上display ip routing-table确认能学到2.2.2.0/32和1.1.1.0/32记录下一跳。最后才ping 2.2.2.2。这个顺序不是死板的但它能帮你快速定位是哪一层出了问题。5.2 故障1OSPF邻居一直卡在init现象是display ospf peer看到R1与R2之间的邻居状态一直是init始终不变成2-way或者Full。我的排查链路先看NHRP表而不是看OSPF。R2上display nhrp peer确认有没有R1的记录。如果有再看R1上display nhrp multicast确认R2是否在组播列表里。如果R2不在列表说明R2没有成功注册或者注册后被清掉了这时候回头检查R2的destination、network-id和物理网络连通性。如果NHRP表完整再看Tunnel口上OSPF网络类型是不是broadcast或p2mp。如果还是默认NBMA并且没有在任何地方指定单播邻居Hello发不出去邻居自然卡在init。改完网络类型后记得reset ospf process再观察。另外有一个很隐蔽的坑Hub上只配了nhrp entry multicast dynamic但Spoke上没有配nhrp entry multicast。这时Hub发给Spoke的组播能发出去因为Hub动态登记过Spoke但Spoke发给Hub的组播没有明确出口丢在隧道里。现象往往是一边是Full另一边卡在init。所以Spoke上的nhrp entry multicast指向Hub一定不能漏。5.3 故障2OSPF邻居Full路由表也有但Ping不通这个故障最经典。R3上能看到去2.2.2.2/32的OSPF路由下一跳是10.1.1.2但ping 2.2.2.2就是不通。我的排查顺序先在R3上ping 10.1.1.2如果第一次不通、第二次通说明NHRP动态解析在工作隧道本身没问题。接着看NHRP映射表确认有没有10.1.1.2对应的公网地址。如果没有说明R3向Hub发起的解析请求没被响应回到Hub上用display nhrp peer确认R2是否还在注册表里。如果Hub这边一切正常就看R2的回报路由。R3到R2的隧道能通不代表R2到R3也能通。R2收到来自R3隧道源203.0.113.3的数据包后要查路由表把响应报文通过GRE隧道送回去。如果OSPF同步正常R2路由表里肯定有3.3.3.3/32。如果R2上没有说明OSPF区域配置不完整或者有过滤策略拦截了LSA。还有一些情况是底层ACL或安全策略拦截了GRE协议号47导致隧道包半路被丢但实验环境一般不涉及。如果路由表都有、NHRP表都有还是Ping不通把OSPF里的MTU问题纳入怀疑清单。某些设备在OSPF数据库描述报文里比较MTU不一致会导致邻居卡在ExStart或者Exchange。可以在接口下强制MTU一致或检查隧道MTU配置确保三台设备Tunnel口MTU完全一样。5.4 故障3DR选错了导致路由部分不通现象是R1和R2邻居FullR1和R3邻居Full但R2和R3之间互相学不到Loopback或者某台设备上路由表时有时无。这种问题多半是DR被某个Spoke抢去了。如果没有把Spoke的dr-priority设置成0而某个Spoke先启动并当上了DRHub后启动时不会抢它的位置。DR没有组播复制能力LSU只能发给它自己或Hub其他Spoke就收不全。处理办法把Hub优先级调高、Spoke优先级设为0然后reset ospf process让DR重新选举。重置之后立刻在Hub上看display ospf peer第一行的DR地址应该是Hub自己的隧道地址。如果DR不对说明Tunnel口下的ospf dr-priority没有生效检查是不是写在了Tunnel接口下而不是OSPF进程下。5.5 常用检查命令清单目的命令查看NHRP对端映射display nhrp peer查看NHRP组播列表display nhrp multicast查看隧道接口状态display tunnel-info / display interface Tunnel0/0/0查看OSPF邻居display ospf peer查看OSPF接口网络类型display ospf interface Tunnel0/0/0查看路由表display ip routing-table抓包确认Hellodebugging ospf packet / display ospf interface这些命令都是在设备本地执行。实验时给每台设备开一个日志终端把OSPF事件打出来能省去很多猜谜时间。5.6 做完这个实验我留下的三个习惯第一凡是涉及MGRE我永远不会跳过NHRP表验证。第二凡是把OSPF配置在隧道接口上我都会主动确认接口的网络类型而不是默认它正常。第三凡是Ping不通我习惯把所有设备的OSPF进程重置一遍再看因为DR、接口网络类型这类参数改了以后OSPF进程不会自动重算很多状态。这三个习惯帮我少踩了很多网工项目里的暗坑。你在自己的实验环境里做一遍也会慢慢形成类似的反射条件。