前段时间帮一个做企业网的朋友做IPv6双栈改造,现场三台思科路由器,一台ISR 4331当核心,两台C8300当分支,原本跑的都是IPv4的OSPF和静态路由,现在要求全网IPv6互通,路由协议必须一并切过来。本以为就是照着手册敲几条命令的事,结果真上手才发现,思科路由器上IPv6路由协议的配置思路和IPv4有明显区别,静态路由、RIPng、OSPFv3、EIGRP for IPv6、BGP4+各有各的坑,尤其是OSPFv3在旧版本IOS上的router-id问题和EIGRP for IPv6默认shutdown这个细节,差点把现场折腾到通宵。
这篇文章就把我在这次改造中实际用到的配置命令、踩过的坑、查错的过程完整整理出来,内容包括接口IPv6地址的配置方式、静态路由的三种写法、RIPng、OSPFv3、EIGRP for IPv6以及BGP4+的完整配置示例,最后附一份排错命令速查表和经典故障实录。不管你是刚接触IPv6的CCNA考生,还是正在做网络割接的运维工程师,这份总结都可以直接拿来对标参考。
1. IPv6路由配置前的三个准备动作
很多人在配置IPv6路由协议之前就栽了跟头,原因是只想着配协议,忽略了IPv6本身和IPv4在接口层面的一些差异。这里先说三个最基础但最容易漏掉的准备动作,这三个动作没做好,后面的路由协议配置全都白搭。
1.1 全局开启IPv6单播路由转发
拿到一台思科路由器,想让它跑IPv6路由协议,第一步不是配接口地址,而是先敲一条全局命令:
Router(config)# ipv6 unicast-routing这条命令的作用是让路由器具备IPv6数据包的转发能力。如果不敲,接口上照样可以配IPv6地址,show ipv6 interface brief也能看到地址状态是up/up,但路由器不会对IPv6报文做路由转发,路由表里也不会出现直连路由之外的任何条目。
我见过不少新手在GNS3里做实验,接口地址配了,OSPFv3也宣告了,但两台路由器之间就是ping不通,最后发现就是漏了这条命令。所以在配置任何IPv6路由协议之前,务必先确认这条命令已经敲了,可以用show running-config | include ipv6 unicast-routing来验证。
1.2 接口地址配置:手动指定与EUI-64的取舍
思科路由器接口配置IPv6地址有两种常用方式。第一种是完全手动指定,这种方式最直观,也最容易维护:
Router(config)# interface GigabitEthernet0/0 Router(config-if)# ipv6 address 2001:db8:1:1::1/64 Router(config-if)# no shutdown第二种是使用EUI-64格式,接口ID部分由接口MAC地址自动生成:
Router(config)# interface GigabitEthernet0/0 Router(config-if)# ipv6 address 2001:db8:1:1::/64 eui-64关于EUI-64有个细节必须强调:EUI-64格式只支持/64前缀,如果你敲了2001:db8:1:1::/126 eui-64这种命令,IOS会直接报错拒绝执行。原因很简单,EUI-64会生成一个64位的接口ID,加上64位前缀才是128位完整地址,前缀长度不是/64就没法在剩余空间里塞下完整的接口ID。
我在实际项目中更倾向于手动指定地址,原因是地址可读性好,便于在排错时快速识别设备。EUI-64虽然自动生成很省事,但生产环境里如果设备换了一块接口板,MAC变了,IPv6地址也会跟着变,这在运维上是个隐形炸弹。
另外强烈建议在接口上手工配置一个链路本地地址,不要用自动生成的:
Router(config-if)# ipv6 address FE80::1 link-local这样做的价值在后面的路由协议配置和排错中会非常明显,尤其是用链路本地地址作为下一跳和路由协议邻居时,固定的地址比自动生成的一长串好记多了。
1.3 链路本地地址:IPv6排错和路由的关键
说到链路本地地址,有必要单独开辟一小节聊聊。IPv6的每个接口无论是否配置全球单播地址,都会自动生成一个以FE80::/10开头的链路本地地址,用于同一链路上的通信。
这个地址在IPv6路由协议里极其重要:OSPFv3的Hello报文源地址是链路本地地址,RIPng的更新报文也是从链路本地地址发出的,BGP的IPv6会话也经常建立在链路本地地址上。这意味着你在排查邻居关系时,看到的对端地址很可能就是FE80::开头的一串。
正因为链路本地地址这么常用,我强烈建议在接口上手工规划,像前面说的那样:
Router(config-if)# ipv6 address FE80::1 link-local一台路由器上多个接口分别用FE80::1、FE80::2、FE80::3这样规划,排错时一眼就能看出是哪个接口的邻居。如果没有手工规划,自动生成的链路本地地址是根据MAC算出来的,不同接口MAC不同,地址也不同,排查问题时要逐一对照show ipv6 interface的输出才能对上号,效率很低。
还有一个容易踩的坑:静态路由如果下一跳写成链路本地地址,必须同时指定出接口,这个在下一节详细说。
2. IPv6静态路由:全网最简但最容易踩坑
静态路由在IPv6环境里依然是不可或缺的,尤其是中小型网络的末端、备份链路或者默认路由。虽然命令不长,但格式上有几个跟IPv4明显不一样的地方,配置时稍不注意就会出错。
2.1 静态路由配置格式与三种写法
IPv6静态路由的基本命令格式是:
ipv6 route 目标前缀/前缀长度 {下一跳地址 | 出接口 | 出接口 下一跳地址}跟IPv4最大的区别在于,IPv6静态路由的下一跳可以写成纯下一跳地址,也可以写成纯出接口,还可以写成出接口加下一跳地址的组合形式。三种写法对应不同场景:
第一种,纯下一跳地址,要求下一跳是IPv6全局单播地址:
Router(config)# ipv6 route 2001:db8:3:0::/64 2001:db8:1:1::2这种写法适合以太网环境,下一跳路由器配了全局单播地址,并且路由可达。
第二种,出接口加链路本地地址,这是以太网链路上最推荐的写法:
Router(config)# ipv6 route 2001:db8:3:0::/64 GigabitEthernet0/0 FE80::2注意,当下一跳写的是链路本地地址时,必须同时指定出接口,否则IOS会提示命令不完整,根本敲不进去。原因是链路本地地址只在本地链路内有意义,路由器必须知道从哪个接口出去才能到达这个地址。
第三种,纯出接口写法:
Router(config)# ipv6 route 2001:db8:3:0::/64 GigabitEthernet0/1这种写法相当于把出接口当作路由的出口,类似IPv4里的ip route ... interface方式。在点到点链路上比较常见,但在以太网这种广播型链路上不推荐,因为如果出接口下有多个设备,路由器无法确定到底是哪个邻居,遇到特殊情况会出现路由黑洞。
2.2 默认路由的配置方法
IPv6的默认路由用::/0表示,相当于IPv4里的0.0.0.0/0,配置命令如下:
Router(config)# ipv6 route ::/0 GigabitEthernet0/0 2001:db8:1:1::2 Router(config)# ipv6 route ::/0 GigabitEthernet0/0 FE80::2注意::/0中间是冒号,不是::0,如果敲成::0就会被解析成地址::加前缀长度0,实际上还是表示默认路由,但不同IOS版本对这种输入的解析可能有差异,最好严格写成::/0。
默认路由在IPv6选路里的行为跟IPv4一样,只有当路由表中没有更精确匹配的路由条目时才会被使用。在双栈改造项目中,通常会把它和动态路由协议配合使用,作为末梢网络的出口路由。
2.3 浮动静态路由的IPv6版本
浮动静态路由这个思路在IPv6下同样适用,而且配置几乎零成本。场景是这样的:核心路由器同时连着主运营商和备份运营商,主链路跑BGP或者OSPFv3,备份链路用一条静态默认路由兜底。正常情况下动态路由协议的管理距离更小,静态路由躺在路由表里不生效;一旦主链路断开,动态路由条目消失,静态路由自动顶上。
命令写法就是在静态路由末尾加上AD值参数:
Router(config)# ipv6 route ::/0 GigabitEthernet0/1 2001:db8:2:2::2 200默认情况下IPv6静态路由的管理距离是1,OSPFv3是110,BGP外部是20。这里把静态路由AD值改成200,比OSPFv3和BGP都大,所以平时静态路由不生效,只有动态路由失效时才会接管转发。
有一个实际项目里的经验:备用链路既然要兜底,建议把IPv4和IPv6的浮动静态路由都配上,并且两条路由的AD值保持一致,否则会出现IPv4走备份、IPv6走主链路这种不对称的尴尬情况。
3. RIPng:小网络的快速选择
RIPng是IPv6环境下的距离矢量路由协议,对应IPv4里的RIPv2。在思科路由器上配置RIPng的思路和RIPv2差别很大,如果不理解底层机制,很容易绕晕。
3.1 RIPng与RIPv2的关键差异
先理清楚RIPng的几个核心参数:它使用UDP端口521发送更新报文,组播地址是FF02::9,最大跳数限制依然是15跳,16跳表示不可达。
跟RIPv2相比,RIPng有几个关键变化:
- RIPv2用network命令宣告网段,RIPng没有network命令,改为在接口下直接启用。
- RIPv2的更新报文源地址是接口IPv4地址,RIPng默认用接口的链路本地地址作为源地址。
- RIPng的进程名是一个自定义标签,比如
ipv6 router rip NG里的NG,这个标签只是本地有意义,不需要和其他设备保持一致。 - RIPv2和RIPng完全不兼容,一个接口要么跑RIPv2要么跑RIPng,不能混着来。
跳数限制决定了RIPng只适合小型网络。网络直径超过15跳就不要考虑它了,老老实实上OSPFv3或者IS-IS。
3.2 三步完成RIPng配置
配置RIPng的流程可以概括为三步:创建进程、接口启用、验证邻居。下面是完整配置示例,以两台路由器为例:
Router A: ! ipv6 unicast-routing ! interface GigabitEthernet0/0 ipv6 address 2001:db8:1:1::1/64 ipv6 address FE80::1 link-local ipv6 rip NG enable ! interface GigabitEthernet0/1 ipv6 address 2001:db8:10:1::1/64 ipv6 address FE80::1 link-local ipv6 rip NG enable ! ipv6 router rip NGRouter B: ! ipv6 unicast-routing ! interface GigabitEthernet0/0 ipv6 address 2001:db8:1:1::2/64 ipv6 address FE80::2 link-local ipv6 rip NG enable ! interface GigabitEthernet0/1 ipv6 address 2001:db8:20:1::1/64 ipv6 address FE80::1 link-local ipv6 rip NG enable ! ipv6 router rip NG注意两台路由器的进程标签都用了NG,其实可以不一样,路由器之间不会因为这个标签不一致而拒绝建立邻居关系,这个标签纯粹是本地管理用途。
配置完成以后,可以用下面几条命令验证:
Router# show ipv6 rip Router# show ipv6 rip database Router# show ipv6 route rip如果邻居关系建立了,路由表里会出现以R开头的IPv6路由条目,表示来自RIPng。
3.3 RIPng的坑:接口多时别全局debug
RIPng配置简单,但有个实际运维中的坑要提一下。有次我在设备上排查一个RIPng路由不更新的问题,敲了debug ipv6 rip,结果那台路由器接了十几个接口,debug输出瞬间把控制台刷到卡死,最后不得不重启设备恢复。
正确做法是如果确实要抓RIPng报文,优先用debug ipv6 rip配合access-list做过滤,或者直接在接口上抓包分析,而不是全局开debug。另外RIPng的更新周期是30秒,如果配置了接口的ipv6 rip hop-count等参数,注意不要调得太激进,否则会加重链路负担。
还有一个常见问题:接口上如果配了IPv4的ACL或者组播过滤策略,可能会导致RIPng的组播报文FF02::9被丢弃,表现为邻居关系始终起不来。排查时优先检查接口下的入向策略,这是现场实测过的一个经典案例。
4. OSPFv3:生产环境最常用的IGP
OSPFv3是目前思科设备上部署IPv6最常用的IGP协议,没有之一。但要注意,OSPFv3并不是简单地把OSPFv2的地址从IPv4换成IPv6,它在协议机制和配置方式上都有实质变化。这一节把OSPFv3的配置拆开揉碎讲清楚。
4.1 OSPFv3与OSPFv2的真正区别
OSPFv2和OSPFv3共享很多核心概念:区域、SPF算法、LSA泛洪、DR/BDR选举,这些都一样。但两者在运行机制上有关键差异:
第一,OSPFv2通过network命令宣告网段,OSPFv3没有network命令,改为在接口上直接挂区域,格式是ospfv3 进程号 ipv6 area 区域号。
第二,OSPFv3的Router ID字段依然是32位,格式沿用了IPv4的点分十进制写法。由于IPv6地址是128位,无法直接作为Router ID,所以必须手工配置Router ID。这是一个非常关键的差异,如果不配置Router ID,OSPFv3进程会直接报错:
%OSPFv3-4-NORTRID: OSPFv3 process could not pick a router-id. Please configure manual router-id.第三,OSPFv3的认证机制改为基于IPsec,接口上没有ipv6 ospf authentication这种简单密码认证命令了。不过这属于高级配置,日常场景可以不用关心。
第四,OSPFv3天然支持多地址族,这也是为什么新版IOS推荐用router ospfv3命名模式,可以把IPv4和IPv6的OSPF配置放在同一个进程下。
4.2 OSPFv3完整配置示例
以经典模式为例,三台路由器组成的简单OSPFv3网络:
Router A(核心): ! ipv6 unicast-routing ! interface GigabitEthernet0/0 ipv6 address 2001:db8:1:1::1/64 ipv6 address FE80::1 link-local ipv6 ospf 1 area 0 ! interface GigabitEthernet0/1 ipv6 address 2001:db8:1:2::1/64 ipv6 address FE80::1 link-local ipv6 ospf 1 area 0 ! ipv6 router ospf 1 router-id 1.1.1.1Router B(分支1): ! ipv6 unicast-routing ! interface GigabitEthernet0/0 ipv6 address 2001:db8:1:2::2/64 ipv6 address FE80::2 link-local ipv6 ospf 1 area 0 ! interface GigabitEthernet0/1 ipv6 address 2001:db8:20:1::1/64 ipv6 address FE80::1 link-local ipv6 ospf 1 area 1 ! ipv6 router ospf 1 router-id 2.2.2.2新版本的IOS XE还支持命名模式的OSPFv3,配置方式有所不同:
Router(config)# router ospfv3 1 Router(config-router)# router-id 1.1.1.1 Router(config-router)# address-family ipv6 unicast Router(config-router-af)# exit-address-family Router(config-router)# exit Router(config)# interface GigabitEthernet0/0 Router(config-if)# ospfv3 1 ipv6 area 0命名模式的好处是OSPFv3进程可以同时管理IPv4和IPv6地址族,未来网络演进空间更大。如果你的设备IOS版本支持,我建议直接用命名模式;如果现场设备还跑着老版本IOS,用ipv6 router ospf经典模式也一样能完成工作,关键是Router ID一定要手工配置。
还有一个小技巧:在点对点以太网链路上,可以在接口下敲ipv6 ospf network point-to-point,把接口类型改成point-to-point,这样可以避免DR/BDR选举,邻居建立速度更快,网络收敛也更快。这个优化在生产环境很实用。
4.3 OSPFv3排错三板斧
OSPFv3排错,我一般按下面这个顺序来:
先看邻居表:
Router# show ipv6 ospf neighbor正常状态下邻居状态应该是FULL/DR、FULL/BDR或者FULL/-。如果看到INIT、EXSTART或者EXCHANGE状态,说明邻居关系建立不完整。
再看接口状态:
Router# show ipv6 ospf interface确认接口处于哪个区域、网络类型是什么、cost值是多少,有没有收到对端Hello报文。
最后用debug抓邻居状态变化:
Router# debug ipv6 ospf adj现场排查时优先看前两步,因为debug输出量大,容易干扰判断。如果前两步都正常,再用debug对着看状态机切换,定位会更准。
5. EIGRP for IPv6:思科私有协议照样能跑
虽然现在很多网络都在规划去思科化,但存量市场里EIGRP的使用量依然不小。EIGRP for IPv6的配置思路和IPv4版本差异很大,有几个细节必须单独提醒。
5.1 EIGRP for IPv6的三大变化
对比IPv4版本的EIGRP,IPv6版本的EIGRP有三个明显变化:
第一,EIGRP for IPv6没有network命令,不需要在进程下宣告网段,改成直接在接口下启用ipv6 eigrp 进程号。
第二,EIGRP for IPv6进程默认处于shutdown状态,必须在进程视图下手动执行no shutdown命令,否则进程不会运行。这个坑非常隐蔽,配置完接口、敲完邻居相关的所有命令,结果邻居死活起不来,查了半天发现进程默认关闭,那种感受谁经历谁知道。
第三,EIGRP for IPv6会自动从本地IPv6地址推导Router ID,默认情况下不需要手工配置。但如果你在配置过程中看到Router ID生成的提示信息,说明当前设备的Router ID可能是从链路本地地址推导出来的,链路本地地址变化会导致Router ID变化,影响邻居稳定性。所以生产环境我依然建议手工指定Router ID,格式同样沿用IPv4点分十进制。
5.2 四条命令拉起EIGRP进程
配置EIGRP for IPv6其实很简单,核心就四条命令:
Router(config)# ipv6 router eigrp 100 Router(config-rtr)# router-id 3.3.3.3 Router(config-rtr)# no shutdown Router(config-rtr)# exit Router(config)# interface GigabitEthernet0/0 Router(config-if)# ipv6 eigrp 100注意进程号100是和IPv4 EIGRP共用的自治系统号,如果同一台设备上IPv4 EIGRP用了100,IPv6 EIGRP建议保持一致,方便维护,互不冲突。
配置完成后验证命令:
Router# show ipv6 eigrp neighbors Router# show ipv6 eigrp topology Router# show ipv6 route eigrp如果邻居状态显示为P(Passive),说明拓扑收敛正常。
5.3 命名模式EIGRP的新写法
新版IOS支持命名模式的EIGRP配置,把IPv4和IPv6地址族统一到一个进程下管理:
Router(config)# router eigrp EXPRESS Router(config-router)# address-family ipv6 Router(config-router-af)# autonomous-system 100 Router(config-router-af)# router-id 3.3.3.3 Router(config-router-af)# exit-address-family Router(config-router)# exit Router(config)# interface GigabitEthernet0/0 Router(config-if)# ipv6 eigrp EXPRESS命名模式的优点是可以给EIGRP进程起一个有意义的名字,而不是用数字编号,同时在同一个进程下管理多个地址族。老设备不支持的话,用经典模式也没问题。
两种模式下,K值、metric计算方式、汇总和过滤机制都和IPv4版本保持一致,工程师上手成本很低。
6. BGP4+:出口和对接场景的主力
如果网络需要和ISP对接或者承载大规模路由,OSPFv3和EIGRP就不够看了,这时候只能用BGP4+。BGP4+是BGP-4的IPv6扩展,在思科路由器上的配置方式和IPv4 BGP差异也比较明显。
6.1 BGP4+基础配置
先看一个最基础的EBGP配置示例。两台路由器直连,AS号分别是65001和65002:
Router A: ! ipv6 unicast-routing ! interface GigabitEthernet0/0 ipv6 address 2001:db8:10:1::1/64 ipv6 address FE80::1 link-local ! router bgp 65001 bgp router-id 1.1.1.1 neighbor 2001:db8:10:1::2 remote-as 65002 address-family ipv6 neighbor 2001:db8:10:1::2 activate network 2001:db8:100::/48 exit-address-familyRouter B: ! ipv6 unicast-routing ! interface GigabitEthernet0/0 ipv6 address 2001:db8:10:1::2/64 ipv6 address FE80::2 link-local ! router bgp 65002 bgp router-id 2.2.2.2 neighbor 2001:db8:10:1::1 remote-as 65001 address-family ipv6 neighbor 2001:db8:10:1::1 activate exit-address-family和IPv4 BGP相比,最关键的差异在于:配置完邻居后,必须在address-family ipv6视图下对这个邻居执行activate命令,否则BGP不会在这个邻居上交换IPv6路由。同理,如果你想在两个IPv6邻居之间同时交换IPv4和IPv6路由,需要在两个地址族下都执行activate。
6.2 双栈BGP同时传递IPv4和IPv6路由
双栈环境下,两个邻居之间往往既要传IPv4路由,又要传IPv6路由。配置思路是这样的:
Router(config)# router bgp 65001 Router(config-router)# bgp router-id 1.1.1.1 Router(config-router)# neighbor 2001:db8:10:1::2 remote-as 65002 Router(config-router)# address-family ipv4 Router(config-router-af)# neighbor 2001:db8:10:1::2 activate Router(config-router-af)# exit-address-family Router(config-router)# address-family ipv6 Router(config-router-af)# neighbor 2001:db8:10:1::2 activate Router(config-router-af)# exit-address-family在这个场景里,IPv6地址既是BGP会话的传输地址,又同时承载IPv4和IPv6两个地址族的路由。要注意的是IPv4单播地址族默认会把所有邻居自动激活,而IPv6地址族不会。所以配置的重点是要确保在ipv4地址族下没有多余激活、在ipv6地址族下显式激活。
验证命令:
Router# show bgp ipv6 unicast summary Router# show bgp ipv6 unicast在输出里可以看到邻居的AS号、收发报文计数以及IPv6前缀数量。
6.3 BGP在IPv6下的选路和策略
BGP4+的选路原理和IPv4 BGP完全一致:Weight、Local Preference、AS Path、Origin、MED、EBGP优于IBGP,依次比较。所以在IPv6地址族下做路径控制,用的也是set local-preference、set as-path prepend这些route-map工具。
举个实际例子,在边界路由器上只允许接收某一段IPv6前缀,可以用前缀列表:
Router(config)# ipv6 prefix-list FILTER_V6 seq 5 permit 2001:db8:200::/40 le 48 Router(config)# ipv6 prefix-list FILTER_V6 seq 10 deny ::/0 le 128 Router(config)# router bgp 65001 Router(config-router)# address-family ipv6 Router(config-router-af)# neighbor 2001:db8:10:1::2 prefix-list FILTER_V6 in Router(config-router-af)# exit-address-family关于BGP还有一个容易忽略的点:IPv6的下一跳属性是128位地址,在EBGP场景下默认会把下一跳改成通告者自己的地址;在IBGP场景下,如果路由是从EBGP学来的,默认不修改下一跳,可能需要配合next-hop-self来修正。这个和IPv4行为一致,容易忽视但很关键。
7. 多协议重分发:别把生产环境搞成环路
很多网络不是单一协议跑到底的,尤其是改造期,核心跑OSPFv3,分支可能还残留RIPng,出口接了BGP,这时候就需要重分发把不同协议的路由互相引进来。IPv6环境下的重分发命令和IPv4的思路相通,但有几个细节要特别留意。
7.1 IPv6重分发配置示例
把静态路由重分发进OSPFv3:
Router(config)# router ospfv3 1 Router(config-router)# address-family ipv6 unicast Router(config-router-af)# redistribute static metric 20 Router(config-router-af)# exit-address-family把BGP路由重分发进OSPFv3:
Router(config-router-af)# redistribute bgp 65001 metric 20把RIPng路由重分发进OSPFv3:
Router(config-router-af)# redistribute ripng NG metric 20OSPFv3的重分发和OSPFv2有个区别:OSPFv2里重分发进OSPF需要带subnets关键字才能宣告非主网段路由,但OSPFv3本身就没有子网掩码这个说法,所以不需要带subnets关键字,直接写metric就行。
把OSPFv3重分发进RIPng的写法:
Router(config)# ipv6 router rip NG Router(config-rtr)# redistribute ospf 1 metric 3这里的ospf 1对应的是OSPFv3进程号1。注意RIPng的种子metric直接影响跳数,如果OSPF域直径比较大,重分发进来的路由很容易在RIPng域内超过15跳限制,配置前务必估算好网络直径。
7.2 重分发后的管理距离与选路影响
重分发之后最容易出现的问题是路由回灌导致环路。比如核心路由器同时跑OSPFv3和RIPng,两边都重分发,如果两边都学到了同一条前缀,路由器会根据管理距离选路。IPv6下各协议的管理距离和IPv4一致:
- 直连路由:0
- 静态路由:1
- EIGRP内部:90
- OSPFv3:110
- IS-IS:115
- RIPng:120
- EIGRP外部:170
- BGP内部:200
- BGP外部:20
这个表在排错时非常重要。比如在同时运行OSPFv3和RIPng的边界设备上,OSPFv3的管理距离更小,路由器会优先选OSPFv3的路由;如果这条OSPFv3路由又是通过重分发从RIPng学来的,就可能出现路由优先级倒挂和回灌的隐患。真实项目中,这种问题往往表现为数据包绕远路甚至时通时不通,排查起来很费劲。
7.3 重分发的三条经验建议
第一,能用单一协议就不要上重分发。改造期间临时用一下可以,正式运行环境尽量收敛到单一IGP协议。
第二,重分发方向要单向控制。比如只允许OSPFv3重分发进BGP,不允许BGP主动重分发进OSPFv3,全靠默认路由兜底,这样可以避免大范围路由震荡。
第三,所有重分发点必须做路由过滤。用route-map配合ipv6 prefix-list精确控制哪些前缀能进来。比如只允许内部前缀进入BGP,外部前缀用默认路由覆盖。过滤规则宁紧勿松,这是生产环境的铁律。
8. 排错速查:IPv6路由协议排查工具与经典故障
这一节把我常用的IPv6排错命令和这次改造中遇到的几个经典故障整理成速查手册,平时配置的时候也可以对照着用。
8.1 常用show命令速查表
下面的表格是我在排障时最常用的一组命令,按场景分类,方便快速定位:
| 排查目标 | 命令 | 输出重点 |
|---|---|---|
| 接口IPv6状态 | show ipv6 interface brief | 每个接口的地址和状态 |
| IPv6邻居表 | show ipv6 neighbors | 链路层地址和IPv6地址映射 |
| IPv6路由表 | show ipv6 route | 各协议路由条目及来源编码 |
| IPv6转发状态 | show ipv6 unicast-routing | 确认IPv6转发是否全局开启 |
| RIPng状态 | show ipv6 rip database | RIPng路由数据库 |
| OSPFv3邻居 | show ipv6 ospf neighbor | 邻居状态和Router ID |
| OSPFv3链路状态 | show ipv6 ospf database | LSDB内容 |
| EIGRP邻居 | show ipv6 eigrp neighbors | EIGRP邻居关系 |
| EIGRP拓扑 | show ipv6 eigrp topology | EIGRP拓扑表 |
| BGP邻居 | show bgp ipv6 unicast summary | BGP邻居状态和前缀数 |
| BGP路由 | show bgp ipv6 unicast | BGP IPv6路由表 |
| IPv6协议配置 | show ipv6 protocols | 各路由协议运行状态汇总 |
8.2 五个经典故障实录
这里挑五个实际项目中遇到的典型问题,每个都给了排查思路和解决方案。
故障一:OSPFv3邻居无法建立,日志报NORTRID
现象:OSPFv3进程起来之后邻居一直停留在DOWN状态,设备日志出现%OSPFv3-4-NORTRID报错。
原因:OSPFv3的Router ID是32位字段,不能从IPv6地址自动生成,必须手工配置。设备上没有配置router-id,进程无法正常工作。
解决:在OSPFv3进程中配置router-id 1.1.1.1,注意选择全网唯一且稳定的ID。
故障二:OSPFv3邻居状态卡在EXSTART/EXCHANGE
现象:邻居状态始终停在EXSTART或EXCHANGE,无法达到FULL。
原因:绝大部分情况是链路两端MTU不一致。OSPFv3的Hello报文交互时,如果对端发出的Database Description报文超过本端MTU,报文被丢弃,邻居关系就卡在数据库描述阶段。
解决:检查接口MTU配置,保证链路两端一致。临时可以用ipv6 ospf mtu-ignore绕过,但生产环境不建议长期开启,正确做法是统一MTU规划。
故障三:RIPng邻居起来了,但路由不更新
现象:show ipv6 rip database看到部分路由缺失,但邻居状态正常。
原因:RIPng使用组播地址FF02::9发送更新,链路上如果有组播过滤或者ACL把FF02::9丢弃,就会导致更新报文收不到。
解决:检查接口下的ACL和组播策略,确认没有过滤FF02::9。如果开了IPv4的组播路由,也要确认不会影响IPv6组播。
故障四:IPv6静态路由配完却不生效
现象:show ipv6 route能看到静态路由条目,但状态一直是standby或者完全不转发流量。
原因:最常见的原因是漏配了ipv6 unicast-routing。没有这条命令,路由器不会查找IPv6路由表转发报文。还有一个可能:静态路由的下一跳不可达,比如下一跳写了对端设备的链路本地地址但没给出接口。
解决:先确认ipv6 unicast-routing已开启,再用ping ipv6测试下一跳可达性,最后检查静态路由的下一跳和出接口是否匹配。
故障五:BGP邻居建立不起来
现象:show bgp ipv6 unicast summary显示邻居IDLE状态。
原因:排查步骤比较多,按顺序来:先确认基础连通性能不能ping通对端IPv6地址;再确认AS号配置是否正确;然后确认在address-family ipv6下对邻居执行了activate;最后检查是否配置了ebgp-multihop(非直连EBGP场景才需要)。
解决:三步走完之后,用debug bgp ipv6 unicast观察收发的Open报文,基本能定位问题。
8.3 日常运维的几条经验小结
最后分享几条我在这类项目中沉淀下来的实践经验,不一定写在官方文档里,但很管用。
第一,链路本地地址一定要规划。不管是OSPFv3、RIPng还是BGP4+,邻居报文大量使用链路本地地址,规划好后排错效率翻倍。
第二,部署IPv6前先画好地址规划表。哪些段分配给业务、哪些段分配给网络设备互联、哪些段分配给管理,都要提前定好。否则现场一边配地址一边查表,效率很低。
第三,配置完一个功能就立刻验证,不要攒着一起测。我在现场的习惯是接口配完马上ping,协议起来马上看邻居表,路由学过来马上traceroute。实践证明这样能最快定位是配置问题还是链路问题。
第四,保存配置并留档。IPv6改造项目涉及的命令多、细节多,每台设备配置完成后务必write memory保存,并把配置文档归档,方便后续变更和排错。
第五,千万别忽略日志。很多邻居起不来的问题,设备日志里写得明明白白,比如OSPFv3的NORTRID提示,一眼就能定位。养成看日志的习惯能省下大量时间。
这次改造项目最终顺利交付,网络切到双栈后,IPv4业务和IPv6业务都稳定运行。回到开头那句话,配置IPv6路由协议本身不难,难的是理解每个协议在IPv6下的思路差异和那些不起眼的细节。希望这份配置和排错总结,能帮你在做IPv6改造时少踩几个坑。