TCP/IP路由技术(第2卷)(全新翻译版) (CCIE职业发展系列)
Author: Jeff Doyle; chenjin5.com
Date: 2009-04-30T16:00:00+00:00
Keywords: chenjin5.com
Publisher: chenjin5.com 海量电子书免费下载

图书在版编目（C I P）数据

TCP/IP路由技术．第2卷/（美）多伊尔（Doyle, J.），（美）卡罗尔（Carroll, J. D.）著；夏俊杰译．—北京：人民邮电出版社，2009.6（2011.8重印）

（CCIE职业发展系列）

ISBN 978-7-115-19822-8

I．T… II．①多… ②卡… ③夏… III．计算机网络—通信协议—路由选择 IV．TN915. 04

中国版本图书馆CIP数据核字（2009）第025505号

版 权 声 明

Routing TCP/IP, Volume 2 (ISBN: 1578700892)

Copyright © 2001 Cisco Systems, Inc.

Authorized translation from the English language edition published by Cisco Press.

All rights reserved.

本书中文简体字版由美国Cisco Press授权人民邮电出版社出版。未经出版者书面许可，对本书任何部分不得以任何方式复制或抄袭。

版权所有，侵权必究。

CCIE职业发展系列

TCP/IP路由技术（第二卷）

♦　著　［美］Jeff Doyle，CCIE#1919

Jennifer DeHaven Carroll, CCIE#1402

译　　　　夏俊杰

责任编辑　李　际

♦　人民邮电出版社出版发行　北京市崇文区夕照寺街14号

邮编　100061　电子邮件　315@ptpress.com.cn

网址　http://www.ptpress.com.cn

北京鑫正大印刷有限公司印刷

♦　开本：787×1092　1/16

印张：41.5

字数：1042千字　2009年6月第1版

印数：11501 - 13 000册　2011年8月北京第7次印刷

著作权合同登记号　图字：01-2009-2442号

ISBN 978-7-115-19822-8/TP

定价：89.00元

读者服务热线：（010）67132705　印装质量热线：（010）67129223

反盗版热线：（010）67171154

内容提要

本书在《TCP/IP路由技术（第一卷）》的基础上，深入系统地阐述了TCP/IP相关高级路由技术，包括BGP、多播、IPv6以及网络管理等内容。为便于读者深入掌握各章所学知识，本书提供了大量的案例分析材料，内容涵盖协议配置、故障检测与排除等方方面面。并且，在各章结束时都提供了大量的复习题和练习题，以加强读者对所学知识的记忆与理解。

本书除了面向众多备考的准CCIE以及需要通过再认证的CCIE之外，还非常适合从事大型IP网络规划、设计和实施工作的工程技术人员及网络管理员参考。

关于作者

Jeff Doyle（CCIE #1919）是科罗拉多州丹佛市Juniper Networks公司的专业服务咨询师，其主要研究方向是IP路由协议和MPLS流量工程技术。Jeff曾经设计和实现的大规模Internet服务提供商网络遍及北美、欧洲和亚洲，并且在NANOG（North American Network Operators’ Group，北美网络运营团体）和 APRICOT（Asia Pacific Regional Internet Conference on Operational Technologies，亚太地区互联网运营技术协会）等服务提供商论坛讲授高级网络互联技术。在加入Juniper Neworks公司之前，Jeff曾经是INS（International Network Services，国际网络服务）公司的高级网络系统咨询师。

Jennifer DeHaven Carroll是朗讯技术公司的首席咨询师和Cisco认证互联网专家（CCIE #1402）。在过去的13年间，她负责规划、设计和实现过许多大型网络，还开发和讲授有关IP路由协议的所有理论知识以及Cisco实现课程。

关于技术审校人

Henry Benjamin（CCIE #469, CCNA, CCDA, B.Eng.）先生是Cisco认证Internet专家和Cisco Systems公司的IT网络设计工程师。他有着8年以上Cisco网络工作经验，包括规划、设计和实施运行IGRP、EIGRP和OSPF的大规模IP网络，目前正在位于澳大利亚悉尼的Cisco IT设计团队工作。Henry拥有悉尼大学的工程学士学位。

Peter J. Moyer（CCIE #3286）先生是Juniper Networks公司的专业服务咨询师，专门从事大规模ISP网络的设计和实施工作。除了咨询工作之外，Peter还向Juniper的客户及合作伙伴讲授高级IP路由课程以及举办IP网络设计讲座，还主持过类似于MPLS等高级主题的网络大会。在加入Juniper之前，Peter是INS（International Network Services，国际网络服务）公司的高级网络咨询师，曾经设计并实现过大量的大型企业网。Peter拥有马里兰大学计算机和信息科学的理学学士学位。

献词

Jeff Doyle：谨将本书献给我的妻子Sara和我的孩子们——Anna、Carol、James及Katherine，她们是我的避风港，让我始终保持健康、谦逊和快乐。

Jennifer DeHaven Carroll：谨将本书献给我的丈夫Mike和我的儿子Mitchell，是他们一直在背后鼓励着我。

致谢

Jeff Doyle：技术书籍的作者就像是一群才华横溢的专业人士的名誉负责人，本书也毫不例外，就像大家在接受奥斯卡大奖时的演说一样，我也要感谢诸多人士。

首先特别感谢Jenny Carroll，她为编辑《TCP/IP路由技术（第一卷）》而付出的辛勤劳动让人肃然起敬。她不仅将自己的技术专长奉献给了本书第二卷，而且在我几近绝望地落后于本书写作计划之时，在我的请求下她伸出了无私的援助之手，成为本书的合著者，并编写了本卷的最后两章内容。如果没有她那极具价值的建议和关注，本书的任何一卷都将无法达到现在的实现程度。

我还要感谢我的朋友兼同事Pete Moyer，他是本书第二卷的技术编辑。Moyer对我生命所产生的影响已远远超越了本书，我将永远感谢他。

我要感谢Laurie McGuire和Chris Cleveland，感谢他们作为开发编辑所提供的大量专业指导，是他们让本书精益求精，也让我成为了一名更优秀的作者。

感谢Brett Bartow以及Cisco Press的全体同仁在本书写作期间表现出来的耐心，他们永不言弃的决心是本书得以顺利出版的重要力量。在整个编撰项目的过程中，当我认为他们应该拿着我的第一本书敲打我的脑袋的时候，他们仍一如既往地表现出莫大的友善之情。

最后，我还要感谢你们——我的好读者，是你们让第一本书变得如此成功，并一直耐心地等待我完成第二卷。我期望本卷内容值得你们的期待。

Jennifer DeHaven Carroll：我要感谢Jeff Doyle给予我合作编写本书的机会，整个过程不但有趣而且充满挑战性。

译者的话

经过10多年的快速发展，中国的互联网已经进入了一个崭新的天地，目前的宽带用户数已跃居世界第二（仅次于美国）。互联网在中国的应用正逐步广泛化，越来越多的人接触到了互联网，并从互联网世界中获益。随着互联网规模的不断增大，网络复杂性也日益明显。首先，用户对新业务的发展需求推动了多播等技术的逐步应用；其次，IPv4地址的日益耗尽使得IPv6逐渐步入大家的视线，我国 CNGI在这方面也取得了令世人瞩目的成绩；再加上近年来互联网安全事故的增多，使得大家越来越关注互联网以及信息化的安全性。所有的这一切都对从事互联网工作的工程技术人员提出了更高、更迫切的要求，而TCP/IP相关路由技术是所有互联网技术的核心基础，无论是广大CCIE报考者或CCIE再认证考试的准备者，还是从事大型IP网络方案设计和优化工作的网络管理员、网络咨询师，都应该将该技术透彻理解并加以掌握。

本书作者是互联网通信领域的资深专家，他经验丰富，写作内容精炼实用。在《TCP/IP路由技术（第一卷）》的基础上，他对BGP、多播、IPv6等高级路由技术做了深入地剖析和延展。本书作为Cisco职业发展系列教程，不但紧扣了 CCIE实验室考试要求，还提供了大量CCIE认证之外的重要知识，以及大量的配置示例和案例研究，不但便于读者学习理解，而且也极具使用价值，完全可以应用于实际的大型IP网络之中。译者在翻译过程中更是收获良多，因而相信本书一定可以成为许许多多相关从业人员的最佳案头参考书。此外，本书在编排结构上也非常适合不同读者的阅读和查阅，其各部分内容相对独立，读者可以根据需要有选择地进行跳跃式阅读。

在本书翻译过程中，不仅得到了译者家人、编辑和朋友们的无私支持与帮助，并且与译者在北京电信规划设计院有限公司长期工作的经验密不可分，在此一并表示衷心的感谢。

本书内容涉及面广，虽然在翻译过程中为了尽量准确表达作者原意，特别是某些专有名词术语的译法，译者在多年网络通信工程经验的基础上，查阅了大量的相关书籍及标准规范，但由于时间仓促，加之译者水平有限，译文中仍难免有不当之处，敬请广大读者批评指正。

夏俊杰　xiajunjie@msn.com

2008年12月于北京电信规划设计院有限公司

Table of Contents

前　言

第1部分　外部网关协议

第1章　外部网关协议

1.1　EGP 的起源

1.2　EGP 的操作

1.2.1　EGP 的拓扑结构问题

1.2.2　EGP 功能

1.2.3　EGP 消息格式

1.3　EGP 的不足

1.4　配置 EGP

1.4.1　案例研究：EGP 末梢网关

1.4.2　案例研究：EGP 核心网关

1.4.3　案例研究：间接邻居

1.4.4　案例研究：默认路由

1.5　检测与排除 EGP 故障

1.5.1　邻居表释义

1.5.2　以糖浆般的速度进行收敛

1.6　附注

1.7　展望

1.8　复习题

1.9　配置练习题

1.10　故障检测与排除练习题

第2章　BGP-4 简介

2.1　无类别域间路由

2.1.1　汇总概述

2.1.2　无类别路由

2.1.3　汇总：好处、坏处及不对称流量

2.1.4　Internet：迄今为止依然是分层结构

2.1.5　CIDR：降低路由表爆炸的危险

2.1.6　CIDR：降低B类地址空间被耗尽的危险

2.1.7　CIDR 面临的难题

2.2　谁需要 BGP

2.2.1　单归属自治系统

2.2.2　多归属到单自治系统

2.2.3　多归属到多自治系统

2.2.4　关于“负载均衡”

2.2.5　BGP 的危害

2.3　BGP 基础

2.3.1　BGP 消息类型

2.3.2　BGP 有限状态机

2.3.3　路径属性

2.3.4　管理性权值

2.3.5　AS_SET

2.3.6　BGP 决策进程

2.3.7　路由阻尼

2.4　I BGP 与 IGP 同步

2.5　管理大规模 BGP 对等应用

2.5.1　对等体组

2.5.2　团体

2.5.3　路由反射器

2.5.4　联盟

2.6　BGP 消息格式

2.6.1　Open（打开）消息

2.6.2　Update（更新）消息

2.6.3　Keepalive（保持激活）消息

2.6.4　Notification（通告）消息

2.7　附注

2.8　展望

2.9　推荐读物

2.10　复习题

第3章　BGP-4 的配置及故障检测与排除

3.1　基本的 BGP 配置

3.1.1　案例研究：在 BGP 路由器之间建立对等关系

3.1.2　案例研究：将 IBGP路由注入 BGP

3.1.3　案例研究：将 BGP路由注入 IGP

3.1.4　案例研究：无 IGP时的 IBGP

3.1.5　案例研究：IBGP 作用于 IGP 之上

3.1.6　案例研究：EBGP 多跳

3.1.7　案例研究：聚合路由

3.2　管理 BGP 连接

3.3　路由策略

3.3.1　重置 BGP 连接

3.3.2　案例研究：通过 NLRI 过滤路由

3.3.3　案例研究：通过 AS_PATH 过滤路由

3.3.4　案例研究：通过路由映射过滤路由

3.3.5　案例研究：管理性权值

3.3.6　案例研究：管理性距离和后门路由

3.3.7　案例研究：使用 LOCAL_PREF 属性

3.3.8　案例研究：使用 MULTI_EXIT_DISC 属性

3.3.9　案例研究：预附加 AS_PATH

3.3.10　案例研究：路由标记

3.3.11　案例研究：路由阻尼

3.4　大型 BGP

3.4.1　案例研究：BGP 对等体组

3.4.2　案例研究：BGP 团体

3.4.3　案例研究：私有 AS 号

3.4.4　案例研究：BGP 联盟

3.4.5　案例研究：路由反射器

3.5　推荐读物

3.6　展 望

3.7　命令汇总

3.8　配置练习题

3.9　故障检测及排除练习题

第2部分　高级 IP 路由问题

第4章　网络地址转换

4.1　NAT 操作

4.1.1　NAT 基本概念

4.1.2　NAT 与 IP 地址保护

4.1.3　NAT 与 ISP 迁移

4.1.4　NAT 与多归属自治系统

4.1.5　端口地址转换

4.1.6　NAT 与 TCP 负载分发

4.1.7　NAT 与虚拟服务器

4.2　NAT 存在的问题

4.2.1　头部检验

4.2.2　分段

4.2.3　加密

4.2.4　安全

4.2.5　协议相关问题

4.3　NAT 配置

4.3.1　案例研究:静态NAT

4.3.2　案例研究：动态NAT

4.3.3　案例研究：网络融合

4.3.4　案例研究：通过 NAT多归属到 ISP

4.3.5　端口地址转换

4.3.6　案例研究：TCP 负载均衡

4.3.7　案例研究：服务分发

4.4　NAT 的故障检测与排除

4.5　参考文献

4.6　展 望

4.7　命令汇总

4.8　配置练习题

4.9　故障检测与排除练习题

第5章　IP 多播路由简介

5.1　IP 多播的需求

5.1.1　多播IP地址

5.1.2　组成员概念

5.1.3　IGMP

5.1.4　CGMP

5.2　多播路由存在的问题

5.2.1　多播转发

5.2.2　多播路由

5.2.3　稀疏与密集拓扑结构

5.2.4　隐式加入与显式加入

5.2.5　有源树与共享树

5.2.6　多播定界

5.3　DVMRP 操作

5.3.1　邻居发现和维护

5.3.2　DVMRP 路由表

5.3.3　DVMRP 包转发

5.3.4　DVMRP 消息格式

5.4　MOSPF 操作

5.4.1　MOSPF 基础

5.4.2　区域间 MOSPF

5.4.3　AS 间 MOSPF

5.4.4　MOSPF 扩展格式

5.5　CBT 操作

5.5.1　CBT 基础

5.5.2　发现核心路由器

5.5.3　CBT 指派路由器

5.5.4　成员源和非成员源

5.5.5　CBT 消息格式

5.6　PIM 简介

5.7　PIM-DM 操作

5.7.1　PIM-DM 基础

5.7.2　剪除覆盖

5.7.3　单播路由变化

5.7.4　PIM-DM 指派路由器

5.7.5　PIM 转发路由器选举

5.8　PIM-SM 操作

5.8.1　PIM-SM 基础

5.8.2　发现 RP

5.8.3　PIM-SM 与共享树

5.8.4　源注册

5.8.5　PIM-SM 与最短路径树

5.8.6　PIMv2 消息格式

5.9　附 注

5.10　展 望

5.11　推荐读物

5.12　命令汇总

5.13　复习题

第6章　IP 多播路由的配置及故障检测与排除

6.1　IP 多播路由的配置

6.1.1　案例研究：配置 PIM-DM

6.1.2　配置 PIM-SM

6.1.3　案例研究：多播负载均衡

6.2　IP 多播路由的故障检测与排除

6.2.1　使用 mrinfo

6.2.2　使用 mtrace和 mstat

6.3　展 望

6.4　配置练习题

6.5　故障检测与排除练习题

第7章　大规模多播路由

7.1　多播定界

7.2　案例研究：穿越非多播域的多播技术

7.3　连接到DVMP网络

7.4　域间多播

7.4.1　MBGP

7.4.2　MSDP 的操作

7.4.3　MSDP 消息格式

7.5　案例研究：配置M BGP

7.6　案例研究：配置MSDP

7.7　案例研究：MDSP网状多播组

7.8　案例研究：任播RP

7.9　案例研究：MSDP默认对等体

7.10　命令汇总

7.11　附 注

7.12　展望

7.13　复习题

第8章　IPv6

8.1　IPv6 设计目的

8.1.1　提高扩展能力

8.1.2　简化配置

8.1.3　提高安全性

8.2　IPv6 当前状态

8.2.1　IPv6 规范（RFC）

8.2.2　厂商支持情况

8.2.3　实现情况

8.3　IPv6 包格式

8.3.1　IPv6 地址

8.3.2　地址结构

8.3.3　IPv6 头部

8.4　IPv6 功能

8.4.1　在 Cisco路由器上启用 IPv6 能力

8.4.2　ICMPv6

8.4.3　邻居发现

8.4.4　自动配置

8.4.5　路由

8.4.6　任播进程

8.4.7　多播

8.4.8　QoS

8.5　从 IPv4 向 IPv6 的迁移

8.5.1　双栈

8.5.2　DNS

8.5.3　在 IPv4中隧道化 IPv6

8.5.4　NAT-PT

8.6　附注

8.7　展 望

8.8　推荐读物

8.9　复习题

8.10　参考文献

第9章　路由器管理

9.1　策略及规程定义

9.1.1　SLA

9.1.2　变更管理

9.1.3　上报规程

9.1.4　更新策略

9.2　SNMP

9.2.1　SNMP 概述

9.2.2　CiscoWorks

9.2.3　路由器的 SNMP 配置

9.3　RMON

9.3.1　RMON 概述

9.3.2　路由器的 RMON 配置

9.4　日志记录

9.5　Syslog

9.5.1　Syslog 概述

9.5.2　路由器的 Syslog 配置

9.6　NTP

9.6.1　NTP 概述

9.6.2　路由器的 NTP 配置

9.7　记账

9.7.1　IP 记账

9.7.2　NetFlow

9.8　配置管理

9.9　故障管理

9.10　性能管理

9.11　安全管理

9.11.1　密码类型和加密

9.11.2　控制交互式访问

9.11.3　最小化 DoS 攻击的风险

9.11.4　TACACS+

9.11.5　RADIUS

9.11.6　SSH

9.12　支撑管理进程的服务器设计

9.13　网络健壮性

9.14　实验室

9.15　命令汇总

9.16　附注

9.17　展 望

9.18　推荐读物

9.19　复习题

9.20　配置练习题

9.21　参考文献

第3部分　附　录

附录A　命令 show ip bgp neighbors 的显示内容

附录B　正则表达式教程

B.1　直接量和元字符

B.2　描述：匹配行起始和行结束

B.3　括入括号：匹配一组字符

B.4　求反：匹配除某组字符之外的所有内容

B.5　通配符：匹配任意单个字符

B.6　求或：匹配一组字符中的某个字符

B.7　可选字符：匹配一个可能在也可能不在的字符

B.8　重复：匹配许多重复字符

B.9　边界：描述直接量

B.10　组成在一起：一个复杂的案例

B.11　推荐读物

附录C　保留的多播地址

C.1　Internet 多播地址

C.2　引用

C.3　人 员

附录D　复习题答案

附录E　配置练习题答案

附录F　故障检测与排除练习题答案

前　言

自从出版了《TCP/IP路由技术（第一卷）》之后，虽然 Cisco Press “CCIE职业发展系列”中增加了大量新书，而且 CCIE计划本身也被扩展到多个专业领域，但IP路由协议仍然是所有准CCIE们的核心基础。因此，必须透彻地对其加以理解和掌握，否则基础不牢，大厦将倾。

我在《TCP/IP路由技术（第一卷）》的前言中曾经说过，“……随着互联网络规模和复杂性的不断增大，路由问题也随即变得庞大且错综复杂”。由于本书重点从IGP转移到了自治系统间的路由问题以及多播和IPv6等诸多特殊路由问题，因而可扩展性和管理性仍然是本书第二卷的核心主题。

本书的写作目的不仅是要帮助读者轻松通过CCIE实验室考试，而且还要帮助读者不断增进知识和技巧，以使读者无愧于CCIE的称号。正如我在《TCP/IP路由技术（第一卷）》中曾经说过的一样，我希望读者成为真正的CCIE，而不仅仅是一名能够通过CCIE实验室考试的技术人员，因而本书所提供的信息要远远多于通过CCIE实验室考试所需的知识。当然，所有信息对一名受人尊敬的互联网络专家的职业生涯都是至关重要的。

当我获得CCIE称号时，CCIE实验室还主要是由AGS+路由器组成的，与那个时代相比，现在的CCIE实验室和考试内容已经发生了翻天覆地的变化。当前的实验室难度变得越来越高，而且CCIE计划增加了再认证要求，在我第一次参加再认证考试之前，有人曾告诉过我《TCP/IP路由技术（第一卷）》对他们准备该考试起到了很大的作用，特别是IS-IS（该协议几乎没有用在服务提供商的网络之外）。因而，我决定写作本书的第二卷，不仅面向众多准CCIE们，也面向那些需要通过再认证的CCIE们，有关多播路由和IPv6的章节就是面向这样的读者群。

我努力遵照《TCP/IP路由技术（第一卷）》的结构来编写第二卷，即首先从通用角度来描述某种协议，然后再以Cisco IOS软件为例给出相应的协议配置示例，最后再给出利用Cisco IOS软件工具检测与排除协议故障的示例。但是对于BGP和IP多播来说，如果按照这种结构来编写会让单章内容变得极其冗长，因而我将其分解成了多个章节。

最后，衷心希望大家阅读本书所获得的知识丝毫不亚于我写作本书所获得的知识。

命令语法约定

本书在介绍命令语法时使用与IOS命令参考一致的约定。本书涉及的命令参考约定如下：

•　需要逐字输入的命令和关键字用粗体表示，在配置示例和输出结果（而不是命令语法）中，需要用户手工输入的命令用粗体表示（如show命令）；

•　必须提供实际值的参数用斜体表示；

•　互斥元素用竖线（｜）隔开；

•　中括号[]表示可选项；

•　大括号表示{}必选项；

•　中括号内的大括号[{}]表示可选项中的必选项。

本书中使用的图标

第1部分
外部网关协议

第1章　外部网关协议

第2章　BGP-4简介

第3章　BGP-4的配置及故障检测与排除

本章将主要讨论以下主题。

•　EGP的起源：本节将讨论在RFC 827（1982）中定义的外部网关协议的发展历史。

•　EGP的操作：本节将讨论EGP的基本操作机制，重点是EGP拓扑结构、EGP功能及EGP消息格式。

•　EGP的不足：本节将探讨为什么EGP不再是一种可行的外部网关协议解决方案。

•　配置EGP：本节将通过4个独立的案例研究——EGP末梢网关、EGP核心网关、间接邻居和默认路由，来说明不同类型的EGP配置方法。

•　检测和排除EGP故障：本节将分析如何解读EGP邻居表，并通过案例研究来展现EGP网络的慢速收敛问题，也说明了EGP为什么不再是一种可行的外部网关协议解决方案。

读累了记得休息一会哦~

公众号：古德猫宁李

- 电子书搜索下载
- 书单分享
- 书友学习交流

网站：沉金书屋 https://www.chenjin5.com

- 电子书搜索下载
- 电子书打包资源分享
- 学习资源分享

第1章
外部网关协议

聪明的读者一定会问（也应该问）：“为什么要浪费纸张专门花一个章节来描述像EGP（Exterior Gateway Protocol，外部网关协议）这样一种已经被废除了的协议？”毕竟EGP已经被BGP（Border Gateway Protocol，边界网关协议）协议广泛替代了。该问题的答案有二。

首先，虽然目前已经很少有人在用EGP了，但某些特殊场合仍然会遇到。例如，在写作本书时仍然可以在某些美国军用互联网络中见到EGP的影子。因而作为一名CCIE，仍然应该为这种罕见应用做好知识储备。

其次，本章内容作为一种历史铺垫，其目的是解释外部网关协议的发展驱动力，并说明最初的外部网关协议存在的不足，以便引出后面两章的内容。而且，在了解了BGP的演进根源之后，可以更好地认识到BGP的重要性。

1.1　EGP 的起源

在20世纪80年代早期，构成ARPANET（现代互联网的前身）的路由器（网关）设备上都运行了一种距离向量路由协议——GGP（Gateway-to-Gateway Protocol，网关到网关协议）。但是随着ARPANET的不断发展，与当今许多负责管理日益增长的互联网络的网管员一样，ARPANET的架构师们也预见到了相同的问题：现在运行的路由协议没有很好的扩展性。

Eric Rosen在RFC 827中阐述了以下扩展性问题。

•　由于所有的网关都要知道所有的路由器，所以带来的问题是“路由算法的开销将变得异常巨大”。任何时候网络拓扑结构发生变化时（而且随着网络规模的扩大，这种可能性会越来越大），所有的网关设备都要相互交换路由信息并重新计算路由表，即便互联网络处于一种稳定状态，路由表的规模和路由更新量也是一个越来越大的负担。

•　随着GGP软件实现数量的增多，以及GGP软件所运行的硬件平台的多样化，“已越来越无法将Internet认为是一个统一的通信系统”。特别是，网络维护和故障检测及排除将变得“几乎不可能。”

•　随着网关数量的逐渐增多，网关管理员也将越来越多，软件升级的阻力也将随之加大：“任何被提议的软件变化都需要在太多的地点由太多的人员来实施。”

RFC 827中提出的解决方案就是ARPANET从一个单一互联网络迁移到一个相互连接的、自治控制的互联网络系统所使用的方案。对每个互联网络（被称为AS[Autonomous System，自治系统]）来说，AS的管理权限是完全开放的，可以任意选择管理本互联网络的方式。自治系统的概念扩展了网络互连的范围，并增加了一个新的分级层次。只要有一个单一互联网络（由多个网络组成的一个网络）就有一个自治系统，每个自治系统本身都是一个互联网络。与利用IP地址来标识一个网络类似，AS也需要通过自治系统号来加以标识，AS号是一组16位的数字，由负责分配IP地址的编址机构分配。

注意：与IP地址类似，AS号也有一些用于私有用途的保留号，这些保留的AS为64512~65535。具体信息详见RFC 1930（www.isi.edu/in-notes/rfc1930.txt）。

在AS所有可选的管理权限中，最主要的就是可以任意选择网关所运行的路由协议。由于网关设备位于AS内部，因而它们运行的路由协议也被称为IGP（Interior Gateway Protocol，内部网关协议）。由于GGP是ARPANET的路由协议，因而其理所当然地被默认为是第一个IGP，不过1982年人们的兴趣集中在更现代（也更简单）的RIP（Routeing Information Protocol，路由信息协议）协议，并且认为各种各样至今仍未规划的路由协议将被应用于许多自治系统中。目前，GGP已完全被RIP、RIP-2、IGRP（Interior Gateway Routing Protocol，内部网关路由协议）、EIGRP（Enhanced IGRP，增强型IGRP）、OSPF（Open Shortest Path First，开放最短路径优先）和IS-IS（Integrated Intermediate System-to-Intermediate System，集成式中间系统到中间系统）所取代。

每个AS都通过一个或多个外部网关与其他AS互连在一起，RFC 827提出外部网关之间通过EGP协议来共享路由信息。与大众流行的认识不同，尽管EGP是一种距离向量协议，但并不是一种路由协议，因为EGP没有在网络之间选择最优路径的路由算法。更准确地来说，EGP是一种通用语言，外部网关之间利用该语言来相互交换可达性信息。其中，可达性信息是一个包含了主网（major network）地址（而不是子网）和网关的简单列表，通过该列表可以到达所有网络和网关。

1.2　EGP 的操作

RFC 827中定义的是EGP版本1。EGP版本2对版本1做了少量修改，并在RFC 888中首次被提出，正式的EGPv2则由RFC 904进行定义。

1.2.1　EGP 的拓扑结构问题

EGP邻居（也被称为对等体）之间需要交换EGP消息。如果邻居位于同一个AS之内，就被称为内部邻居（interior neighbours）；如果邻居位于不同的AS之内，则被称为外部邻居（exterior neighbours）。EGP无邻居自动发现功能，需要用手工方式来配置邻居地址，邻居间交换的消息采用单播方式被传送到手工配置的邻居地址。

由于EGP消息只应该被传送给单一邻居，因而RFC 888建议将EGP消息的TTL（time-to-live，生存时间）设置为低值。不过，没有任何一种EGP功能需要EGP邻居共享同一条数据链路。例如，图1-1显示了两个被某台仅运行RIP的路由器所分隔的EGP邻居，由于EGP消息采用单播方式被传送到邻居，因而可以穿越该路由器边界。Cisco路由器将EGP消息的TTL设置为255。

图1-1　EGP邻居无需连接在同一个网络上

EGP网关既可以是核心网关（core gateway），也可以是末梢网关（stub gateway）。这两种类型的网关都能接受来自其他自治系统中的网络信息，但末梢网关只能发送其自身AS的网络信息，只有核心网关才能发送从其他AS学习到的网络信息。

为了理解EGP为何要定义核心网关和末梢网关，需要先来了解EGP体系结构方面的局限性。如前所述，EGP并不是一种路由协议，其更新信息中仅列出了可达网络，并没有包含确定最短路径或防止路由环路的足够信息，因而建立起来的EGP拓扑结构必须没有环路。

图1-2显示的EGP拓扑结构中只有一个核心AS，其他自治系统（末梢自治系统）必须连接在该核心AS上。这种两级树状拓扑结构与OSPF的两级拓扑结构需求非常相似，而且作用也完全相同。《TCP/IP路由技术（第一卷）》中曾提到，域间OSPF路由在本质上属于距离向量路由，因而很容易形成路由环路。为此，OSPF要求所有非主干OSPF域之间的流量都必须经过主干域，利用这种强制性的无环路域间拓扑结构，可以大大降低路由环路的可能性。与此类似，要求末梢自治系统间的所有EGP可达性信息都必须经过核心AS，可以大大降低EGP拓扑结构潜在的路由环路可能性。

图1-2　为防止出现路由环路，仅允许核心网关将学习自某个AS的网络信息发送给其他AS

1.2.2　EGP 功能

EGP由以下3种协议机制组成。

•　邻居获取协议（Neighbor Acquisition Protocol）

•　邻居可达性协议（Neighbor Reachability Protocol）

•　网络可达性协议（Network Reachability Protocol）

这3种协议机制利用10种消息类型来建立邻居关系，维护邻居关系，与邻居交换网络可达性信息，并向邻居通告程序或格式化差错。表1-1列出了所有的EGP消息类型以及使用每种消息类型的协议机制。

下面将逐一讨论上述3种EGP机制。1.2.3小节将详细讨论上述消息。

1．邻居获取协议

EGP邻居在正常交换可达性信息之前，必须首先确认兼容性问题。该功能由一个简单的双向握手过程来完成，由其中一个邻居发送Neighbor Acquisition Request（邻居获取请求）消息，而另一个邻居则响应Neighbor Acquisition Confirm（邻居获取确认）消息。

没有任何一个RFC说明了两个EGP邻居是如何初次发现对方的。在实际应用中，EGP网关都是通过手工配置邻居的IP地址来获知其邻居的。之后，该网关将向该手工配置的邻居发送一条单播Neighbor Acquisition Request（邻居获取请求）消息，该消息申明了一个Hello间隔（即该网关同意从其邻居接受的两条Hello消息之间的最小间隔）和Poll间隔（即该网关同意因路由更新而被其邻居轮询的最小间隔）。该邻居的响应消息Neighbor Acquisition Confirm（邻居获取确认）中也将包含其Hello间隔和轮询间隔，如果邻居双方就这两个间隔值达成一致，那么就可以交换网络可达性信息了。

当网关学习到邻居之后，将认为邻居处于Idle（空闲）状态；在发送第一条Neighbor Acquisition Request（邻居获取请求）消息之前，网关会将邻居的状态转换为Acquire（获取）状态，当网关接收到Neighbor Acquisition Confirm（邻居获取确认）消息之后，则将邻居的状态转换为Down（停用）状态。

注意：RFC 904中详细解释了EGP的有限状态机。

如果网关的响应消息不是Neighbor Acquisition Confirm（邻居获取确认），而是Neighbor Acquisition Refuse（邻居获取拒绝），则表示拒绝该邻居。Neighbor Acquisition Refuse（邻居获取拒绝）消息中可以包含拒绝理由，如表空间不足，当然，也可以无任何特定理由即可拒绝该邻居。

利用Neighbor Cease（邻居终止）消息，网关可以随时终止已建立的邻居关系。与Neighbor Acquisition Refuse（邻居获取拒绝）消息一样，发起Neighbor Cease（邻居终止）消息的网关既可以在消息中包含终止原因，也可以什么原因都不说。邻居收到Neighbor Cease（邻居终止）消息之后，回应Neighbor Cease Acknowledgment（邻居终止确认）消息。

邻居获取进程的最后一种情况就是网关发送Neighbor Acquisition Request（邻居获取请求）消息，而邻居无任何响应。RFC 888建议“以一个合理的速率（如每隔30s）”来重传Neighbor Acquisition Request（邻居获取请求）消息，但Cisco的EGP实现并不仅仅在固定周期内重传未确认的消息，而是在初次发送Neighbor Acquisition Request（邻居获取请求）消息之后的30s重传未确认的Acquisition（获取）消息，之后在再次重传之前需要等待60秒钟的时间。如果在第三次重传之后的30s之内仍未收到响应消息，网关就将邻居的状态由Acquire（获取）转换为Idle（空闲），如例1-1所示。网关将Idle（空闲）状态保持到300秒（5分钟）之后，将Idle（空闲）状态转换到Acquire（获取）状态，并重新开始上述邻居获取进程。

例1-1：命令debug ip egp transactions的输出结果显示了EGP的状态转换过程。

需要注意的是，例1-1中的每条EGP消息都有一个序列号，利用该序列号可以表示EGP消息对（如Neighbor Acquisition Request/Confirm、Request/Refusal以及Cease/Cease-Ack消息对）。后面“网络可达性协议”部分将详细解释序列号的使用方式。

当两个EGP网关成为邻居之后，其中一个为active（主动）邻居，另一个是passive（被动）邻居。总是由主动网关发送Neighbor Acquisition Request（邻居获取请求）消息来发起邻居关系，被动网关从不发送Neighbor Acquisition Request（邻居获取请求）消息，它们仅响应主动网关发出的Neighbor Acquisition Request（邻居获取请求）消息。Hello/I-Heard-you消息对也是如此，由主动邻居发送Hello消息，而被动邻居则回应I-Heard-You（I-H-U）消息。不过，被动网关可以发起Neighbor Cease（邻居终止）消息，此时主动网关必须回应Neighbor Cease Acknowledgment（邻居终止确认）消息。

核心网关（可以是位于多个其他自治系统的路由器的邻居）既可能是某个邻居邻接（neighbor adjacency）关系的主动网关，也可能是其他邻居邻接关系的被动网关。Cisco的EGP实现利用AS作为决定因素，即AS号小的邻居成为主动邻居。

2．邻居可达性协议

网关获取到某个邻居之后，就通过发送周期性的Hell消息来维护邻居关系，而邻居则以 I-H-U消息作为Hello消息的回应。RFC 904没有指定Hello消息的标准周期，Cisco使用的默认周期为60秒，也可以使用命令timers egp对其进行修改。

交换完Hello/I-H-U消息对之后，邻居的状态由Down（停用）变为Up（启用）（参见例 1-2），之后邻居之间就可以交换网络可达性信息了，如下所述。

例1-2：命令debug ip egp transactions的输出结果显示了双向握手成功以及EGP的状态转换。

如果主动邻居连续发送了3条消息之后仍未收到响应消息，那么邻居的状态将被转换为 Down（停用）。网关以正常的Hello间隔发送3条以上的Hello消息，如果仍未收到响应消息，那么邻居的状态将被转换为Cease（终止）状态。网关按60秒的间隔时间发送3条Neighbor Cease（邻居终止）消息，如果邻居均回应Neighbor Cease Acknowledgment（邻居终止确认）消息，那么该网关就将邻居的状态转换为Idle（空闲）状态，并等待5分钟，之后再转换回Acquire（获取）状态，并尝试重新获取邻居。例1-3显示了该事件的顺序关系。

例1-3：地址为192.168.16.2的邻居停止回应，每条未被确认的EGP消息的间隔为60秒。

（待续）

例1-4给出了另一个沉寂（dead）邻居的例子，只是本例中处于被动模式下的核心网关（192.168.16.2）正在发现该沉寂邻居（192.168.16.1）。

例1-4：地址为192.168.16.1的邻居停止回应，debug消息来自处于被动模式下的核心网关（192.168.16.2）。

如果网关未在60s的Hello间隔内收到Hello消息，则将尝试“唤醒”其邻居。由于被动模式下的网关无法发送Hello消息，因而发送Poll（轮询）消息，之后该网关将等待一个Poll间隔。（Cisco的默认Poll间隔是180s，即3分钟。）如果网关未收到响应消息，将再次发送另一条Poll消息，并且再等待一个Poll间隔；如果仍未收到响应消息，网关就将邻居的状态更改为Down（停用），随后又更改为Cease（终止）状态。如例1-3所示，发送了3条Cease消息之后，邻居的状态被更改为Idle（空闲）。

3．网络可达性协议

当邻居的状态为Up（启用）时，EGP邻居之间可以开始交换可达性信息。每个网关都周期性地向其邻居发送包含了序列号的Poll（轮询）消息，邻居则以包含了相同序列号和可达网络列表的Update（更新）消息进行响应。例1-5解释了Cisco IOS软件对序列号的使用方式。

例1-5：EGP邻居之间进行周期性地相互轮询，以获得网络可达性更新。

邻居间交换的每对Hello/I-H-U消息中都包含了相同的序列号，直至发送Poll（轮询）消息时为止，Poll/Update消息对也使用相同的序列号。主动邻居每接收到一次Update（更新）消息，就将序列号加1，如例1-5所示，Poll/Update消息对中的序列号为120，之后被加1后变成了121。需要注意的是，本例中两个邻居都发送了Poll（轮询）消息，来自被动邻居（192.168.16.2）的Poll（轮询）消息带有完全不同的序列号（3），而邻居总是以包含了与Poll（轮询）消息中完全相同的序列号的Update（更新）消息作为响应消息。

Cisco IOS软件中的默认Poll间隔为180秒，也可以使用命令timers egp对其进行修改。通常情况下，只有当网关被轮询到时才发送Update（更新）消息，这就意味着拓扑结构的变化可能最多有3分钟时间无法向外部进行宣告。为此，EGP通过允许网关在每个Poll间隔内发送一条主动提供的（unsolicited）Update（更新）消息（即不作为Poll（轮询）响应消息的Update（更新））来解决这个问题，但Cisco不支持这种主动提供的Update（更新）。

注意：也可以使用命令timers egp来修改Hello间隔，命令格式为timers egp hello polltime。

Poll（轮询）和Update（更新）消息中都包含了源网络的地址，例如，例1-5中的Poll（轮询）和Update（更新）消息中显示的源网络地址为192.168.16.0。这里所说的源网络指的是通过该网络可以测量所有的可达性信息——也就是说，通过连接在源网络上的路由器可以到达所有被请求或被宣告的网络。虽然源网络通常就是与两个邻居都相连的网络，但更准确地说法应该是：源网络就是Poll（轮询）正在请求消息的网络以及Update（更新）正在提供信息的网络。EGP完全是一种有类别协议，而且源网络（也就是列在Update中的网络地址）总是主类（major class）网络地址（从来都不会是子网）。

在源网络地址之后是一台或多台路由器以及通过这些路由器可以到达的网络列表，该列表上的路由器的共同特征是都连接在源网络上。如果该列表上的路由器不是发起Update（更新）消息的EGP网关，那么该路由器就是间接（indirect）或第三方（third-party）邻居。

图1-3解释了间接EGP邻居的概念，名为Moe的路由器是一台核心网关，与其他3台网关形成对等关系。

图1-3　间接EGP邻居

例1-5中的调试消息来自AS1中的路由器Shemp。需要注意的是，由路由器Moe（192.168.16.2）发起的Update（更新）消息中，这3个网络都被列为可通过路由器Moe而到达，有4个网络可以通过路由器Larry（192.168.16.4）和Curly（192.168.16.3）而到达，而这2台路由器都是Shemp的间接邻居，需要通过Moe才能通达。AS3中的路由器Joe则不是一个间接邻居，因为该路由器并没有连接到源网络上，其网络仅仅被宣告为可以通过路由器Moe到达该网络。

间接路由器的宣告可以节省公共链路的带宽，但更为重要的是，通过消除不需要的路由器跳数可以大大提高路由效率。如图1-3所示，路由器Shemp仅与Moe形成对等关系，而事实上，路由器Larry并不运行EGP，只是通过RIP将其网络宣告给Moe，路由器Moe通过向Shemp告知有比自己更好的下一跳来执行”抢占重定向（preemptive redirect）”操作。

事实上，EGP的Update（更新）消息中也可以仅包含间接邻居——也就是说，消息发起方可能不将其作为通往其他网络的下一跳。此时，该发起方被称为route server（路由器服务器）。路由服务器通过IGP或静态路由可以学习到可达性信息，并将这些可达性信息宣告给EGP邻居，而自身并不执行任何包转发功能。

从EGP网关的角度来看，邻居既可以是内部网关，也可以是外部网关。如果位于同一个AS中，则邻居为内部网关，如果位于不同的AS中，则邻居为外部网关。图1-3中的所有EGP网关都将其邻居视为外部网关。如果路由器Larry也运行了EGP，而且与Moe形成对等关系，那么这两台路由器都会将对方视为内部网关。

EGP的Update（更新）消息中包含了两个用来描述其列表中的路由器是内部网关还是外部网关的字段（详见1.2.3小节）。下面来看一下例1-5的Update（更新）消息，可以看出这两个字段紧挨着源网络地址字段之前：IntGW=2以及ExtGW=1。这两个字段之和即为Update（更新）消息中列出的路由器数量。首先列出的是所有指定的内部网关，因而，如果IntGW=2以及ExtGW=1，则表示列出的前两个路由器为内部网关，最后一个路由器为外部网关。如果将例1-5中192.168.16.2的Update（更新）消息与图1-3相比较，可以看出，通过路由器Curly可达的3个网络都被列在Update（更新）的最后，并被标记为外部——也就是说，这3个网络可以通过路由器Moe的外部网关到达。由于末梢网关无法将网络宣告到本AS之外，因而只有核心网关的Update（更新）消息中才包含外部网关信息。

EGP的Update（更新）消息为每个列出的网络都关联一个距离值，距离字段为8bit，距离值范围为0〜255。不过，除了将255表示为不可达网络之外，RFC 904并没有具体指定距离值的解析方式，而且也没有RFC定义任何利用该距离值来计算AS间最短路径的算法。Cisco则将距离值理解为跳数，如例1-5所示，其默认规则也非常简单：

•　如果网关在本AS内宣告所有网络，则距离值为0；

•　如果网关在本AS之外宣告所有网络，则距离值为3；

•　如果网关指示某网络不可达，则将其距离值设置为255。

以例1-5和图1-3为例，尽管网络172.20.0.0与路由器Moe之间存在一跳路由，但Moe宣告该网络时的距离值为0，即与其直接连接的网络172.17.0.0的距离值相同。Moe与网络10.0.0.0之间存在一跳路由，与网络172.18.0.0之间存在两跳路由，由于这两个网络与Moe处于不同的AS中，因而Moe宣告这两个网络时的距离值都为3。需要记住的一点是，从本质上来看，EGP所使用的距离值对确定到某个网络的最佳路径毫无用处。

例1-6给出了Shemp的路由表以及例1-5中的Update（更新）所产生的路由项。

例1-6：路由器Shemp的路由表。

例1-6中的路由表有两点值得注意。首先，EGP项的管理距离为140，该管理距离要高于所有的IGP（外部EIGRP除外），因而路由器将总是选择IGP路由，即使EGP宣告的是同一个网络。

其次，每个由EGP宣告的网络的距离值都比例1-5 Update（更新）消息中显示的距离大1。这是因为，跟RIP路由算法一样，Cisco的EGP进程将所有的距离值都加1。

1.2.3　EGP 消息格式

EGP使用5种不同的编码格式来表示表1-1中的10类消息，所有消息的头部格式都一样，如图1-4所示。

图1-4　EGP消息头部

EGP消息的头部字段定义如下。

•　版本（Version）：指定当前的EGP版本号。如果接收到的消息中的版本号与接收方的版本号不一致，则将拒绝该消息。当前所有EGP实现的版本号都是2。

•　类型（Type）：指定头部后面是5种消息格式中的哪一个。表1-2给出了10类EGP消息及其使用的类型编号。

•　代码（Code）：指定子类型。例如，如果类型为5，则代码可以指示消息是Hello还是I-Heard-Youo

•　状态（Status）：根据消息类型的不同而不同（就像代码字段一样）。例如，Neighbor Acquisition（邻居获取）消息可以利用状态字段来表示主动或被动模式，而Neighbor Reachability（邻居可达性）消息可以利用状态字段来表示Up（启用）或Down（停用）状态。

•　校验和（Checksum）：是EGP消息和反码的反码，与IP、TCP和UDP使用的差错校验算法相同。

•　自治系统号（Autonomous System Number）：指定消息发起方的AS号。

•　序列号（Sequence Number）：用于同步消息对（如本章前面所述）。例如，Update（更新）消息中包含的序列号应始终与Poll（轮询）消息中的序列号一致。

1．Neighbor Acquisition（邻居获取）消息（EGP消息类型3）

Neighbor Acquisition（邻居获取）消息属于EGP类型3。表1-3列出了用于指示EGP消息的代码值，源自RFC 904的表1-4给出了状态字段的可能值以及可能使用某特定状态的原因。

表1-3　消息类型3使用的代码

表1-4　消息类型3使用的状态编号

图1-5　给出了Neighbor Acquisition（邻居获取）的格式，Hello间隔和Poll（轮询）间隔字段仅出现在Neighbor Acquisition Request（邻居获取请求，代码0）和Neighbor Acquisition Confirm（邻居获取确认，代码1）消息中，其他Neighbor Reachability（邻居可达性）消息的格式与头部相同，不包含其他字段。

•　Hello间隔（Hello interval）：表示发起方同意接收的两个Hello消息之间的最小间隔，以秒为单位。Cisco的默认Hello间隔为60秒，可以利用命令timers egp对其进行修改。

图1-5　Neighbor Acquisition（邻居获取）消息

•　轮询间隔（Poll interval）：表示发起方同意接收的两个Poll消息之间的最小间隔，以秒为单位。Cisco的默认Hello间隔为180秒，可以利用命令timers egp对其进行修改。

2．Neighbor Reachability（邻居可达性）消息（EGP消息类型5）

如图1-6所示，Neighbor Reachability（邻居可达性）消息就是EGP头部，类型字段为5。由于所有必需信息都包含在代码字段（参见表1-5）和状态字段（参见表1-6）中，因而Neighbor Reachability（邻居可达性）消息中不包含其他字段。

图1-6　Neighbor Reachability（邻居可达性）消息

3．Poll（轮询）消息（EGP消息类型2）

在EGP头部增加一个IP源网络（是指被请求了可达性信息的网络）字段即构成了Poll（轮询）消息（参见图1-7）。该字段中编码的IP地址总是A、B、C类网络地址，代码字段总是为0，所用的状态编号与表1-6相同（RFC 888将Poll（轮询）和Error（差错）消息中的状态字段列为未使用）。

4．Update（更新）消息（EGP消息类型1）

与Poll（轮询）消息一样，Update（更新）消息的代码字段始终为0，表1-7列出了状态字段的可能值，除了Unsolicited（主动提供的）值之外，其余均与表1-6一样。

图1-7　轮询消息

状态字段的最高位是Unsolicited（主动提供的）bit，如果该bit被置位（即该字段值为128），则Update（更新）消息为主动提供的消息。Unsolicited（主动提供的）bit可以与其他各种状态值一起使用。

Update（更新）消息包含一个4级列表的分层结构，图1-8解释了Update（更新）消息的格式以及这些列表分层结构的组织方式。

分层结构的最高一层是所有直接连接到源网络的路由器列表，列表上的网关数量由# of Interior Gateways（内部网关数）和# of Exterior Gateways（外部网关数）字段之和来表示。

接下来的一层将内部网关和外部网关完全区分开来，首先列出的是所有内部网关（包括发起方）；如果有外部网关，则全部列在内部网关之后。

在分层结构的第3层，每个被列出的网关都有一个距离列表，与内部网关和外部网关一样，该层有一个用来指示列表上距离数量的字段。

最后，每个列出的距离值都有一个在该距离下通过该网关可以到达的网络列表，该层有一个用来表示列表上网络数量的字段。

有关Update（更新）消息格式字段的完整描述如下。

•　内部网关数（# of Interior Gateways）：指定列表上内部网关的数量。

•　外部网关数（# of Exterior Gateways）：指定列在内部网关之后的外部网关的数量。本字段与# of Interior Gateways（内部网关数）字段之和（如图1-8所示的N）表示Update（更新）消息中列出的所有网关数。

•　IP源网络（IP Source Network）：指示网络正在提供的是哪种可达性信息。也就是说，通过连接在该网络上的网关可以到达Update（更新）消息中列出的所有网络，该字段中编码的IP地址总是主类（A、B、C类）网络。

•　网关IP地址（Gateway IP Address）：指定连接在源网络上的网关的IP地址，仅列出主类（A、B或C类）地址的主机部分。该字段的长度是可变的，在C类地址时长度为1个8位组，在A类地址时长度为3个8位组，至于IP地址的网络部分，从IP源网络字段即可得知。

图1-8　Update（更新）消息

•　距离数量（# of Distances）：指示所列网关全部被宣告的距离数量。

•　距离（Distance）:指示所列网关被宣告的特定距离值。

•　网络数量（# of Networks）：指示所列网关全部被宣告的网络数量。

•　网络（Network）：指示被宣告的网络的IP地址。如图1-8所示，每个网络都属于某个特定网关、特定距离和网络列表中的特定顺序。与网关IP地址字段一样，网络字段的长度也是可变的，但是与网关IP地址字段不同的是，网络字段列出的是主类（A、 B或C类）地址的网络部分，而不是主机部分。

5．Error（差错）消息（EGP消息类型8）

网关在任何时候都可以发送Error（差错）消息（如图1-9所示），向发送方指示EGP消息错误或字段值无效。Error（差错）消息中的代码字段总是为0，而状态字段的取值则如表1-7所示。

注意： RFC888将ERROR（差错）消息（与Poll（轮询）消息一样）中的状态字段说明为未用，而RFC904说明的状态字段情况如表1-7所示。

图1-9　Error（差错）消息

Error（差错）消息的发起方可以使用任意值作为序列号。表1-8描述了各种可能的原因（Reason）字段（取自RFC 904）,Error（差错）消息头部是EGP消息（提示差错信息）的前12个8位组。

1.3　EGP 的不足

EGP的根本问题是无法检测路由环路。由于EGP使用的距离值存在上限（255），因而有人可能会说，至少计数到无穷大也算是一种环路检测机制。这一点在理论上没错，但是，这种高极限值加上Poll（轮询）间隔，使得计数到无穷大变得毫无实用意义。举例来说，假设Poll（轮询）间隔为180秒，那么EGP对等体需要花费将近13小时才能计数到无穷大。

因此，EGP必须运行在一个设计良好的无环路的拓扑结构上。虽然在1983年的时候这并不是一个问题，因为那时的EGP仅仅被设计用来将末梢网关连接到ARPANET骨干网上，但当时的EGP设计者就已经预见到了这种拓扑结构限制所带来的问题将会很快显现出来。组成Internet的自治系统需要逐渐演变为几乎无结构化的网状拓扑结构，此时很多自治系统都可以充当其他自治系统的转接（transit）系统。

随着NSFnet的出现，EGP的局限性变得日益明显，此时不仅出现了多个骨干网，而且还需要考虑哪些流量可以穿越哪些骨干网等使用策略。由于EGP不支持这种负责的策略路由，因而必须指制定过渡解决方案。

EGP的另一个问题是无法与IGP进行足够的互操作，以确定从一个网络到另一个网络的最短路由。例如，EGP的距离无法确实地转换为RIP的跳数，如果EGP的距离导致跳数超过15，那么RIP将宣告该网络不可达。EGP的其他不足之处还包括在大量网络之间传递信息时容易失败，以及易于有意或无意地错误传达网络信息。

最后（当然并不是最不重要）,EGP不能及时宣告网络的变化情况。1.5节将给出相应的案例，通过该案例可以清楚地看出，位于EGP连接的AS中的某个网络变成不可达网络之后，4跳之外的网关需要花费将近1小时的时间才能确定该网络已不可达。

虽然人们试图创建EGPv3，但毫无成效，最后，EGP被彻底废弃，取而代之的是全新的AS间协议——BGP。因而，外部网关协议（EGP）不再仅仅是一个协议的名称，而且还是一类协议的名称，所有衍生自EGP概念的协议都被称为EGP。但尽管如此，传统的EGP仍然存在于当今的自治系统和AS间路由之中。

1.4　配置 EGP

通过以下4个基本步骤即可完成路由器上的EGP配置。

•　第1步：利用命令autonomous-system指定路由器的AS。

•　第2步：利用命令router egp启动EGP进程并指定邻居的AS。

•　第3步：利用命令neighbor指定EGP邻居。

•　第4步：指定由EGP宣告的网络。

下面的第一个案例研究将详细解释前3个配置步骤，同时也给出了步骤4的多种实现方法。

1.4.1　案例研究：EGP 末梢网关

图1-10给出了一台位于AS 65502的EGP末梢网关，该末梢网关连接在AS 65501的一台核心网关上，末梢AS运行的IGP为RIP。

例1-7给出了末梢网关的初始配置。

例1-7：图1-10中的末梢网关配置。

图1-10　EGP末梢网关将AS 65502的内部网络宣告给核心网关

请注意，语句autonomous-system指定的是本地AS（local AS, LAS），而语句router egp指定的则是远端AS（far AS,FAS），只有配置完LAS之后才能配置EGP进程。通过语句neighbor可以指示EGP进程其对等体的位置。Buster的路由表（详见例1-8）中既包含了从核心网关学习到的EGP路由项，也包含了从内部邻居学习到的RIP路由项。

例1-8：Buster的路由表显示了从EGP邻居和内部RIP邻居学习到的路由项。

从EGP邻居学习到的路由以度量值（metric）5被重分发到RIP中（详见例1-9）。

需要注意的是，直连网络也被重分发到了RIP之中，如果要将网络192.168.16.0宣告到LAS中，那么就需要使用该配置。水平分割机制可以阻止Stan通过EGP将网络分发到Buster。一种可选的配置方法是在RIP配置中增加语句network 192.168.16.0，并利用语句passive interface让RIP广播不用于AS间链路。

例1-9：通过AS 65502内部路由器的路由表显示重分发的EGP路由。

到现在为止，Buster的EGP配置已经从核心网关接收到了网络信息，但还没有将内部网络宣告到核心网关（详见例1-10）。

例1-10：通过Stan的路由表可以看出，没有从Buster学习到任何有关AS 65502中内部网络的信息。

如果需要配置EGP将内部网络宣告出去，那么一种配置选项就是增加redistribute rip语句。但是，进行路由的相互重分发存在一定的风险性，特别是当存在拓扑结构环路或有多个分发点时，这种风险也益发显著。而且，即便是像图1-10那样简单的拓扑结构，重分发也很容易形成路由环回。为安全起见，在配置相互重分发时应配合使用路由过滤器，以确保不接受来自外部网关的内部网络地址，以及不将外部地址宣告到外部网关。有关相互重分发的问题在《TCP/IP路由技术（第一卷）》中有详细描述，而且本书的第2章和第3章中还会做进一步的论述

还有一种更好的配置EGP宣告内部网络的方法，那就是使用network语句。当network语句与EGP或BGP配合使用时，与在IGP配置中使用时的功能有着很大的不同。例如，路由器Buster的RIP配置中，语句network 172.16.0.0的作用是指示路由器在所有IP地址位于172.16.0.0网段中的接口上启用RIP协议。当network与AS间协议协同工作时，其作用则是告诉协议需要宣告哪个网络。例1-11给出了路由器Buster宣告AS 65502中的所有网络的配置情况。

例1-11：配置路由器Buster宣告AS 65502中的所有网络。

例1-12表明将路由器Stan位于network语句之后的路由表全部增加到了Buster的EGP配置中。

例1-12：Buster将AS 65502的内部网络宣告给Stan。

相对于重分发来说，在EGP中使用network语句的好处与使用静态路由而不是动态路由协议相似，即network语句和静态路由都可以精确地控制网络的可达性。对EGP来说，精确度受限于EGP的类别。虽然可以通过不在network语句中指定某个大网段来实现该网络的”私有性”，但同样也就无法再指定其中的各个子网了。下面再来回顾一下例1-8,Buster的路由表中包含了子网172.16.1.0/24和172.16.2.0/24，重新检查一下图1-8中EGP Update（更新）消息的格式，应该记得Update（更新）消息中仅携带IP网络的主类部分：即A类网络的第一个8位组、B类网络的前2个8位组及C类网络的前3个8位组。也就是说，EGP中的network语句只能指定主网。

1.4.2　案例研究：EGP 核心网关

根据定义，一台EGP核心网关可以与多个远端自治系统中的多个邻居建立对等关系，并且可以将网络信息从一个FAS传递到另一个FAS，因此，核心网关的配置与末梢网关有一些不同之处。图1-11给出了一台核心网关Stan,Stan与FAS中的路由器（Buster）及LAS中的路由器（Ollie）形成对等关系。

图1-11　核心路由器Stan必须与远端邻居Buster及本地邻居Ollie建立对等关系

例1-13给出了图1-11中Stan的配置文件。

例1-13：图1-11网络拓扑结构中的核心网关配置。

LAS仍然使用命令autonomous-system来指定，而FAS则没再使用命令router egp，而是使用编号为0的AS来表示任何AS。同样，利用命令neighbor any来指定邻居，以响应发送Acquisition（获取）消息的任何邻居。命令neighbor any是隐式配置邻居，而命令neighbor则是显式配置邻居，虽然核心网关可以釆取显式的邻居配置方式，但隐式配置命令neighbor any更为简单，特别是当核心网关存在大量邻居的时候。

当然，至少有一个邻居需要釆取显式方式进行配置。这是因为如果两个邻居均以命令neighbor any来配置邻居，那么这两个邻居将无法发现对方。例1-14给出了图1-11中邻居 Ollie的配置文件。

例1-14：图1-11网络拓扑结构中邻居Ollie的配置。

由上例可以看出，尽管Ollie使用了命令neighbor any来配置其邻居，但仍显式配置了 Stan的地址，否则Stan和Ollie将无法感知对方的存在。

如例1-14所示，核心网关将本AS之外的网络可达性信息传递给其他外部AS，但并不传递本AS之内的网络可达性信息。例如，例1-8中的Buster路由表中就没有网络192.168.18.0的表项。如果需要宣告内部网络，Stan必须为每个待宣告的网络增加network语句，例子中惟一的一个network语句是针对网络192.168.16.0，作用是允许Ollie接收该网络的信息。重新回顾一下Buster的路由表，可以看到一个关于网络192.168.19.0的路由项，出现该路由项的原因就是在例1-14路由器Ollie的配置文件中的network 192.168.19.0语句。

如果希望核心网关不与每个EGP邻居都建立对等关系，该如何处理？如图1-12所示，AS 65506中的3台路由器都运行了 EGP，但Stan仅与Spanky和Buckwheat建立对等关系，Alfalfa与Ollie建立对等关系。当然，核心网关的网管员可以信任AS 65506的管理员，以便能利用neighbor语句建立正确的对等关系，但信任在AS间的路由选择时一般来说并不是很好。

图1-12　Spanky和Buckwheat必须仅与Stan建立对等关系，而Alfalfa必须仅与Ollie建立对等关系

在这个例子中，AS 65506中的3个网关都有针对Stan和Ollie的neighbor语句。为了控制对等关系，需要使用访问列表并辅以neighbor any语句，如例1-15中Stan的配置文件所示。

例1-15：使用访问列表并辅以neighbor any语句来控制对等关系。

如例1-15所示，neighbor any语句引用了access-list 10，该访问列表拒绝Alfalfa（172.20.1.2）并允许其他所有邻居。Ollie也有类似配置，作用是拒绝Spanky和Buckwheat并允许其他所有邻居。例1-16显示了该配置结果。

例1-16：命令show ip egp显示了EGP邻居的信息。

在路由器Stan和Ollie上使用命令show ip egp可以看出，Ollie与Alfalfa之间为对等关系，而Stan与Spanky和Buckwheat之间为对等关系。

注意：　有关命令show ip egp显示的字段细节将在1.5节中详细描述，现在关注的是邻居的地址。

1.4.3　案例研究：间接邻居

如图1-13所示，3个末梢网关（Groucho、Harpo和Chico）连接在名为Ollie的核心网关上。位于不同的自治系统中的Groucho和Harpo共享同一个以太网，因而可以被配置为间接邻居（indirect neighbors）或第三方邻居（third-party neighbors）。

虽然Groucho与Harpo之间无法直接交换EGP信息，但是，只要Ollie将它们宣告为间接邻居，它们之间就可以直接路由数据包。例1-17显示了Ollie的配置文件。

图1-13　EGP间接邻居

例1-17：相互宣告为间接EGP邻居之后，就可以在间接EGP邻居之间进行数据包的路由选择。

如例1-17所示，Groucho和Harpo被显式地配置为邻居关系，两台路由器的neighbor语句之后都配置了neighbor third-party语句，作用是指定EGP邻居以及位于共享以太网上的网关的间接邻居。请注意，不在共享以太网上的Chico受语句neighbor any的影响。通过例1-18可以看出，核心网关的间接邻居都被标记为Third Party。

通过Ollie的EGP邻居表可以看出，Groucho和Harpo（分别为192.168.19.2和 192.168.19.3）已经被相互配置为间接邻居。

Harbo的路由表（详见例1-19）显示了间接邻居的配置结果，从路由表中可以看出，Harpo去往网络192.168.20.0（位于AS 65503中）的下一跳并没有指向核心网关，而是直接指向了 Groucho（192.168.19.2）。

例1-18：显示核心网关的间接邻居。

例1-19：路由表显示了到达间接邻居的下一跳路由。

例1-19中的Harpo路由表显示了通过下一跳192.168.19.2可以直达网络192.168.20.0。如果没有配置间接邻居，那么Harpo就必须将192.168.19.1设置为下一跳。

1.4.4　案例研究：默认路由

EGP除了可以宣告精确路由之外，还可以宣告一条默认路由。如果某个AS只有单个外部网关，那么一条默认路由将比全部外部路由列表更为有效，这样就可以为路由器节省内存和处理周期，并节省相应的链路带宽。

如图1-13所示，为了将默认路由宣告到AS 65502，需要按照例1-20来配置路由器Stan。

例1-20：宣告默认路由。

命令default-information originate用于生成默认路由，与其他协议不同，EGP中的该命令没有可选语句。需要注意的是，上述配置中增加了路由过滤器，仅允许Stan的SO接口将默认路由向外宣告到AS 65502。如果没有该路由过滤器，默认路由和全部精确路由都会被宣告出去。例1-21显示了该配置结果。

例1-21：通过默认路由网络192.168.20.1为可达网络。

从AS 65502外部网关路由表可以看出，核心网关仅宣告了一条默认路由，通过该默认路由，图1-13中的所有外部网络都可达。

1.5　检测与排除 EGP 故障

在1.3节中已经解释了EGP为何无法应用于复杂的AS间拓扑结构，而强制性的简单拓扑结构带来了一个意外的好处，那就是EGP的故障检测和排除变得非常简单。

与其他路由协议一样，检测与排除EGP故障的第一步工作就是查看路由表。如果所请求的路由缺失或路由表中存在一条非期望路由，通过查看路由表就可以检测到问题的根源。由于EGP的度量值几乎没有任何意义，因而与其他路由协议相比，利用路由表进行EGP故障的检测和排除工作可以得到大大简化。

需要注意的是，在检测EGP配置时，网关必须为每个邻居都配置一个某种形式的neighbor语句（显式配置或使用命令neighbor any）。理解network语句的使用方式以及区分与IGP中使用的network语句的差别也是非常重要的。

命令debug ip egp transactions（在1.2节中已多次用到）是一个非常有用的故障检测和排除工具，该命令的输出结果揭示了在邻居间交换的、所有EGP消息的全部重要信息。

1.5.1　邻居表释义

利用命令show ip egp检查EGP邻居表，可以看出网关邻居的状态和配置情况。例1-18显示了该命令的输出结果。例1-22显示了show ip egp命令作用于Stan的邻居表后的额外输出结果。

例1-22：命令show ip egp的显示结果有助于检测与排除EGP对等体的故障。

通过Stan的路由表可以看出，由于FAS与LAS完全相同（均为65501），因而邻居192.168.18.2是一个内部邻居，而且该邻居处于正常运行状态。同时，192.168.18.2已经正常运行了2小时以上，192.168.16.2已经正常运行了6天17小时。路由表中还显示了网关为每个邻居所使用的当前序列号以及每个邻居所使用的当前序列号。

在Hello和Poll（轮询）间隔之后，记录了过去4个Hello间隔内所收到的邻居可达性信息的数量，利用该数量可以判断邻居是否应该被宣告为Up或Down（基于阈值j、k）o其中，阈值j指定了Down邻居被宣告为Up之前，在4个Hello间隔内接收到的所有邻居可达性消息；阈值k指定了为防止Up邻居被宣告为Down，在4个Hello间隔内接收到的邻居可达性消息的最小数量。表1-9中列出了EGP的阈值j、k，这些阈值对于主动邻居和被动邻居来说是不同的。

表1-9　EGP的阈值j和k

例1-22中的下一个字段Flag（标志）表示该邻居属于永久邻居还是临时邻居。永久邻居指的是被neighbor语句显式配置的邻居，而临时邻居则是被neighbor any语句隐式配置的邻居。如例1-22所示，Stan的两个邻居都是临时邻居，这与前面讨论的Stan配置一致，即只有单条neighbor any语句。对比例1-22和例1-18可以看出，尽管Stan将Ollie（192.168.18.2）视为临时邻居，但Ollie却将Stan（192.168.18.1）视为永久邻居，例1-23显示的Ollie配置解释了原因之所在。

例1-23：路由器Ollie的邻居配置。

由于釆取了显式配置neighbor 192.168.18.1，因而Ollie将Stan归类为永久邻居。

例1-22中的最后一个字段表示本地路由器属于主动邻居还是被动邻居。该例中的Stan是其两个对等关系的主动邻居，因而可以预料Ollie是被动邻居。例1-18则证实了该假设，并显示Ollie是其他所有对等关系的主动邻居。这一点也可以事先预料得到，这是因为AS65501比其他AS号都小。

1.5.2　以糖浆般的速度进行收敛

EGP的一个显著特征就是没有任何操作是快的，不但邻居获取进程慢，而且网络变化的宣告过程也极其缓慢，因而有时可能会错误地认为正常网络存在问题（EGP的自身原因除外）。例如，在图1-13中，假设AS 65503中的用户抱怨无法到达AS 65502中的网络172.17.0.0，检查Groucho的路由表可以发现，路由表中有一条去往172.17.0.0的路由（详见例1-24），但是却无法ping通该网络中的已知地址，此时可能会认为流量去往该网络的路由出现了差错。或黑洞路由（balck hole）。

例1-24：图1-13中的Groucho有一条去往172.17.0.0的路由，但该网络却不可达。

Ollie的路由表（详见表1-25）中显示了解决该问题的一个线索。请注意，在过了16分钟之后仍然未收到网络172.17.0.0新更新消息的情况下，有关该网络的路由项仍然被认为有效，并且仍然被宣告给Ollie的邻居。

在Stan发给Ollie的过去5条更新消息中没有包含网络172.17.0.0。假定此处不存在黑洞路由问题，由于AS 65502中的路由器以太网端口处于断开状态，因而网络172.17.0.0不可达，如果EGP未能连续6次收到某路由的更新消息，那么将会宣告该路由不可用。再加上180秒的更新间隔，可以看出，EGP需要花费18分钟时间才能宣告不可用路由，这之后才会停止在其更新中包含该不可达网络。在图1-13所示的互联网络中，从AS 65502的外部网关宣告网络172.17.0.0不可用到Groucho宣告网络不可用，整整花费了54分钟的时间！

例1-25：新的网络更新未被宣告。

1.6　附　注

1Eric Rosen,“RFC 827：外部网关协议（EGP）”。

2Linda J.Seamonson和Eric C.Rosen “RFC 888:‘末梢’外部网关协议”。

3D.L. Mills,“RFC 904：外部网关协议正式规范”。

4J. Rekhter,“RFC 1092:EGP和新NSFNET骨干网的策略路由”。

1.7　展　望

本章不但说明了AS间路由协议的发明驱动力，也解释了EGP难以胜任该角色的原因。第2章将简要描述EGP的替代协议——边界网关协议及其操作。表1-10汇总了本章用到的所有命令。

表1-10　第一章讨论过的命令小结

续表

1.8　复　习　题

本书附录D中提供了以下复习题的答案。

（1）当前的EGP版本是什么？

（2）什么是EGP内部邻居？什么是EGP外部邻居？

（3）EGP末梢网关与EGP核心网关的主要区别是什么？

（4）EGP为何使用核心或主干AS的概念？

（5）主动EGP邻居与被动EGP邻居之间有何区别？

（6）EGP轮询消息的作用是什么？

（7）什么是间接邻居或第三方邻居？

（8）EGP如何利用度量值计算去往目的地的最佳路径？

1.9　配置练习题

本书附录E中提供了以下配置练习题的答案。

（1）图1-14中的自治系统65531是一个核心AS，请在RTA和RTB上配置EGP，要求如下：

•　不要将AS内的数据链路宣告给任何外部邻居。

•　RTA将连接在其S1接口上的网络宣告给RTB；另外，要求RTA和RTB之间不能宣告其他AS间链路。

•　RTA和RTB向其外部邻居（除了从其他自治系统学习到的网络）宣告默认路由，而且这两个网关都不得将默认路由宣告给其内部邻居。

（2）例1-26给出了图1-15中RTC的路由表。利用重分发机制，配置RTC将所有通过EGP学习到的网络都宣告到AS 65510，将192.168.105.0之外的所有内部网络都宣告到核心AS。通过确保不将AS 65510的内部网络经EGP宣告回去来防止路由环路。配置中的进程ID与本地AS号相同。

图1-14　配置练习题（1）的互联网络

例1-26：图1-15中RTC的路由表。

（3）例1-27显示了图1-15中RTD的路由表。

请根据以下参数配置RTD。

•　仅将192.168.220.0和192.168.230.0宣告到AS 65531；

•　无路由协议被重分发到EGP中；

•　将EGP重分发到AS 65515的IGP中；

•　以度量值1将192.168.3.0从RTC宣告到AS 65515中；

•　以度量值1将192.168.100.0从RTC宣告到AS 65515中；

•　以度量值5将其他路由器宣告到AS 65515中。

图1-15　配置练习题（2）的互联网络

例1-27：图1-15中RTD的路由表。

（4）例1-28给出了图1-15中RTE的路由表。

例1-28：图1-15中RTE的路由表。

（待续）

请根据以下参数配置RTE。

•　无IGP被重分发到EGP中；

•　EGP不被重分发到任何IGP中；

•　AS 65520的所有内部网络都被宣告到AS 65531中；

•　AS 65520的内部路由器可以将数据包转发到经RTA宣告的所有网络；

•　所有的进程ID均与AS号相同；

•　所有的OSPF接口都位于Area 0。

（5）如图1-16所示，在前面的练习题中增加了AS 65525,RTF的以太网接口的IP地址为192.168.1.3/24。

图1-16　配置练习题（5）的互联网络

请配置路由器RTF，使得其仅与RTB建立对等关系，并且支持第三方邻居。

1.10　故障检测与排除练习题

本书附录F中提供了以下故障检测与排除练习题的答案。

（1）如图1-17所示，在互联网络中增加了路由器RTG。

图1-17　故障检测及排除练习题（1）的互联网络

虽然RTG与RTB处于对等关系并相互交换可达性信息，但是却存在一个配置错误。请根据例1-29所提供的信息，找出错误之所在。

例1-29：图1-17中的RTB和RTG的EGP表。

本章主要讨论以下主题。

• 无类别域间路由：本节将介绍CIDR及其优缺点。

•　谁需要BGP？：本节将结合若干个AS间应用场景来探讨BGP的适用场景和不适用场景。

•　BGP基础：本节将讨论边界网关协议的基础知识，包括消息类型和路径属性。

•　IBGP与IGP同步：本节将讨论AS中IBGP与IGP的同步相关问题，解释为何在默认情况下需要同步以及如何避免同步问题。

•　管理大规模BGP对等应用：本节将介绍控制大规模BGP实现的4种工具。

•　BGP消息格式：本节将介绍不同BGP消息的细节内容。

第2章
BGP–4 简介

对所有CCIE来说，BGP（Border Gateway Protocol，边界网关协议）都是一个非常重要的话题，而且在CCIE实验室考试中会得到全面的检验。

通过第1章的学习可以知道，ARPANET的构架师们在20世纪80年代就已经意识到自治系统、AS间的可达性协议对维持快速增长的Internet的可管理性来说是必不可少的。最初的解决方案EGP（Exterior Gateway Protocol，外部网关协议）对基于骨干网的ARPANET来说虽然完全可以胜任，但是从一开始，架构师们就知道网络会逐渐向网状AS互连的拓扑结构方向发展。后来，由于EGP无法检测路由环路、极慢的收敛速度以及缺乏支持路由策略的工具等原因，使得架构师们逐渐认识到EGP无法有效胜任这样拓扑结构下的路由选择工作。

虽然大家尝试对EGP做一些增强性改进，但是最后却发展出一个真正的路由协议（而不是像EGP这样简单的可达性协议）。该AS间路由协议就是由1989年RFC 1105首次引入的BGP，BGP的第一个版本由一年之后的RFC 1163进行更新，后来又在1991年被RFC 1267进行了再次更新，为了表示这3次更新，后来人们习惯性地将这3个版本分别称为BGP-1、BGP-2、BGP-3。

当前的BGP版本BGP-4是由1995年RFC 1771规定的。BGP-4与前面的几个版本有了很大的不同，其最重要的在于BGP-4属于无类别协议，而早期的版本属于有类别协议。这一根本性改变的源动力直指外部网关协议存在的根本原因：保持Internet路由的可管理性和可靠性。为此创建了CIDR（Classless InterDomain Routing，无类别域间路由），CIDR最初由1993年RFC 1517引入，接下来在同一年由RFC 1519最终确定为标准建议，最后在RFC 1520中得到修订，为了支持CIDR，又创建了BGP-4。

2.1　无类别域间路由

自治系统与外部路由协议的创建解决了20世纪80年代Internet的扩展性问题，但是，到了20世纪90年代早期，Internet出现了各种不同的扩展性问题，如下所述：

•　Internet路由表爆炸。以指数增长的路由表开始变得难以管理（包括路由器的处理时间以及管理员），仅仅是路由表尺寸就已经耗用了大量的Internet资源，再加上日复一日的拓扑结构变化以及网络的不稳定性，使得Internet更加不堪重负。

•　B类地址空间的逐渐耗尽。截止到1993年1月，16 382个B类地址已经被分配了7 133个，如果以1993年的地址分配速度，那么整个B类地址空间将在两年不到的时间内被分配完毕（如RFC 1519所述）。

•　全部32位IP地址空间的最终耗尽。

无类别域间路由为前两个问题提供了短期解决方案，另一个短期解决方案就是将在第4章中讨论的NAT（Network Address Translation，网络地址转换）。这些解决方案为Internet架构师们赢得了足够的时间来创建一个拥有足够地址空间的新IP版本，在这一思路下创建的IPng（IP Next Generation，下一代IP）最终形成了IPv6（IPv6采取了128位的地址格式）。将在第8章中讨论的IPv6技术是第三个问题的长期解决方案，但非常有趣的是，CIDR和NAT都取得了巨大的成功，以至于很少再有人像当初那样迫切地希望将网络迁移到IPv6。

CIDR仅仅是一种明智地利用了Internet分层结构的地址汇总方案，因而在进一步讨论CIDR之前，有必要先回顾一下汇总和无类别路由选择，并了解一下当前的Internet发展状况。

2.1.1　汇总概述

汇总（summarization）或路由聚合（route aggregation）（详见《TCP/IP路由技术（第一卷）》）指的是用一个较不精确的地址来宣告一个连续的地址集合。从本质上来看，汇总/路由聚合是通过减小子网掩码的长度直至屏蔽了所有被汇总地址的公共bit来实现的。例如，图2-1中的4个子网（172.16.100.192/28、172.16.100.208/28、172.16.100.224/28和172.16.100.240/ 28）可以被汇总为单个聚合地址172.16.100.192/26。

许多将汇总视为一项艰难工作的网络工程师都会惊诧于他们必须每天都要跟汇总打交道，说到底，什么是与连续主机地址群汇总不一样的子网地址呢？例如，子网地址192.168.5.224/27是主机地址192.168.5.224/32～192.168.5.255/32的聚合地址（当然，”主机地址” 192.168.5.224/32是数据链路本身的地址）。汇总地址的关键特性就是其掩码长度要短于其所要汇总的地址的掩码长度。最极端的汇总地址为默认地址0.0.0.0/0，常写为0/0。如/0所表示的那样，此时的掩码已缩减至无任何网络bit——该地址是所有IP地址的聚合地址。

汇总操作可以穿越类边界，例如，可以将4个C类网络（192.168.0.0,192.168.1.0、192.168.2.0及192.168.3.0）汇总为一个聚合地址192.168.0.0/22。需要注意的是，该聚合地址（使用了22位掩码）不再是一个合法的C类地址，因而为了支持主类网络地址的聚合，整个路由环境必须是无类别的。

图2-1　路由聚合

2.1.2　无类别路由

无类别路由包括以下两个主要特征：

•　无类别是路由协议的特性；

•　无类别是路由器的特性。

作为路由信息的一部分，无类别路由协议携带了每个被宣告地址网络部分的描述信息。网络地址的网络部分通常被称为地址前缀（address prefix），地址前缀可以用一个地址掩码以及一个指示该地址中有多少个bit是前缀bit的长度字段来表示，也可以在其更新中只用前缀 bit来表示（见图2-2）。常见的无类别IP路由协议有RIP-2、EIGRP、OSPF、集成式IS-IS和 BGP-4。

图2-2　利用无类别路由协议宣告一个地址前缀

有类别路由器在其路由表中将目的地址记录为主类网络及这些网络的子网。在执行路由查找时，有类别路由器首先查找主类网络地址，接着再在其主类地址下的子网列表中寻找匹配项。而无类别路由器则会忽略地址类别，仅进行“最长匹配”查找操作，也就是说，对任何目的地址来说，无类别路由器仅选择地址bit匹配最长的路由。以例2-1的路由表为例，例中给出了包含多个可变子网的IP网络，如果路由器是无类别的，那么该路由器将试图为每个目的地址都找到最长匹配项。

例2-1：包含多个可变子网的IP网络的路由表。

如果路由器接收到一个目的地址为192. 168. 1. 75的数据包，那么路由表中会有多个匹配项：192.168.0.0/16、192.168.1.0/24、192.168.1.0/25和192.168.1.64/26。此时，将会选择 192. 168. 1. 64/26（如例2-2所示）作为匹配项，这是因为该地址与目的地址是最长匹配，匹配长度为26bit。

例2-2：目的地址为192.168.1.75的数据包从接口S1被转发出去。

目的地址为192. 168. 1. 217的数据包与192. 168. 1. 64/26或192. 168. 1. 0/25都不匹配，该地址的最长匹配地址应该是192.168.1.0/24，如例2-3所示。

例2-3：路由器无法将192. 168. 1. 217匹配到更精确的子网，因而将其匹配为网络地址192.168.1.0/24。

目的地址192.168.5.3的最长匹配可以是聚合地址192.168.0.0/16（如例2-4所示）。

例2-4：目的地址为192. 168. 5. 3的数据包无法匹配更精确的子网或网络，因而匹配超网 192.168.0.0/16。

最后，目的地址192.168.1.1与路由表中的任何网络项都不匹配（如例2-5所示）。不过，路由器并不会丢弃这类数据包，这是因为例2-1所示的路由表中包含了一条默认路由，这类数据包将会被转发到下一跳路由器192.168.2.130。

例2-5：路由表中无192. 168. 1. 1的匹配项，去往该地址的数据包都将被转发到默认地址，出接口为SO。

从IOS 11. 3开始，Cisco路由器在默认情况下都是无类别的，在该版本之前的IOS都默认为有类别，可以利用命令ip classless来更改默认设置。

例2-1中的路由表及相关示例解释了最长匹配路由选择的一些特性，也就是说，指向聚合地址的路由无需指向聚合地址中的每个成员。图2-3给出了例2-2～例2-5中的路由向量情况。

图2-3　例2-1路由表中的路由向量

考虑一个聚合了其全部子网的网络192.168.1.0/24。图2-3显示指向该网络地址的路由都从接口E0向外转发数据包，但是去往其中的两个子网192. 168. 1.0/25和192.168.1.64/26的路由却指向其他接口S1。

注意：实际上，192. 168. 1. 64/26本身就是192. 168. 1. 0/25的成员，但这两个地址拥有不同的路由（都指向S1），这就暗示了它们是由不同的上游路由器宣告而来的。

同样，192.168.1.0/24是聚合网络192.168.0.0/16的成员，但是指向较不精确地址的路由是通过接口E1向外转发的，而最不精确的路由0.0.0.0/0（是所有其他地址的聚合）是通过接口SO向外转发的。根据最长匹配路由选择原则，去往192. 168. 1. 0/25和192. 168. 1. 64/26的数据包将从接口S1向外转发，而去往网络192.168.1.0/24的其他子网的数据包则将从接口E0向外转发。以192.168（而不是192.168.1）为起始目的地址的数据包都将从接口E1向外转发，而起始目的地址不是192.168的数据包都将从接口SO向外转发。

2.1.3　汇总：好处、坏处及不对称流量

汇总可以大大节约网络资源，包括存储路由表所需的内存容量、网络带宽以及路由器传送和处理路由信息的能力。汇总还可以通过“隐藏”网络的不稳定性来节约网络资源。

例如，图2-4中存在一条翻动路由（flapping route）。这里所说的翻动路由指的是由于物理连接或路由器接口故障而导致不停Up/Down的路由。

如果没有汇总机制，那么子网192.168.1.176/28的每次Up/Down的信息都会被传送到企业互联网络中的每台路由器，反过来，这些路由器又必须处理该信息并相应地调整其路由表。如果路由器Nashville利用聚合地址192. 168. 1. 128/25来宣告所有的上行路由，那么更为精确的子网发生的任何变化都不会通过该路由器被宣告出去，此时的Nashville是聚合点，即便被聚合的某些成员有不稳定状况，聚合路由仍然会保持稳定。

汇总的代价就是牺牲了路由的精确性。如例2-6所示，由于图2-3中的路由器接口S1出现故障，因而导致该接口上从邻居学习到路由无效。但此时并不会丢弃正常情况下从接口S1向外转发的数据包（如目的地址为192. 168. 1. 75的数据包），因为这时的数据包将匹配次最佳路由192.168.1.0/24，并将从接口E0被转发出去（请与例2-2进行对比）。

例2-6：失效路由会导致数据包转发不精确。

路由不精确可能是个问题，也可能不是一个问题，这取决于互联网络的状况。继续前面的例子，假设下一跳路由器192.168.2.2仍有一条经路由器Cleveland到达192. 168. 1. 64/26的路由项（或者是因为该互联网络暂未收敛，或者是该路由为手工录入），那么将会出现路由环路。另一方面，某些通过Cleveland的E0接口可达的路由器可能会有一条去往子网192. 168. 1. 64/26的“后门”路由，只有当主用路由（经Cleveland的S1接口）无效时才会使用该“后门”路由。此时，去往192. 168. 1. 0/24的路由就被设计为备用路由，例2-6所示的路由行为就属于刻意行为。

图2-4　翻动路由使得整个网络变得不稳定

如图2-5所示，失去路由精确性的互联网络会产生不同的问题，图中路由域1通过旧金山和亚特兰大的路由器连接到路由域2。对本例来说，如何定义路由域并不重要，重要的是路由域1中的所有网络都可以被汇总为地址172.16.192.0/18，路由域2中的所有网络都可以被汇总为地址172.16.128.0/18。

相对于宣告单个子网来说，旧金山和亚特兰大的路由器更愿意将汇总地址宣告到两个路由域中。如果达拉斯子网172.16.227.128/26中的某台主机向西雅图子网172.16.172.32/28发送一个数据包，那么该数据包极有可能被路由到亚特兰大（因为亚特兰大路由器是宣告路由域2汇总路由的最近路由器），由亚特兰大将数据包转发到路由域2，并最终到达西雅图。当子网172.16.172.32/28上的主机发送响应信息时，由西雅图将响应数据包转发到旧金山，因为其是宣告汇总路由172.16.192.0/18的最近路由器。

这里出现的问题就是两个子网之间的流量不对称：从172.16.227.128/26到172.16.172.32/ 28的数据包走一条路径，而从172.16.172. 32/28到172.16.227. 128/26的数据包走另一条路径，出现不对称路径的原因是达拉斯和西雅图路由器都没有对方子网的全部路由，它们仅知道去往宣告汇总路由的路由器的路由，因而必须基于该路由转发数据包。换句话说，旧金山和亚特兰大的汇总路由隐藏了这些路由背后的互联网络细节信息。

图2-5　当多台路由器被宣告为同一个聚合地址时，失去路由精确性将会产生问题

不对称流量属于非期望状况，原因主要有3个：首先，不对称流量会使互联网络的流量模型变得难以预测，使得网络基准、容量规划、故障检测及排除变得困难；其次，不对称流量会使链路使用率出现不均衡，某些链路的带宽出现饱和，而其他链路的带宽却得不到有效利用；再次，不对称流量会使出流量和入流量的延时时间出现很大的差异，这种时延变化（也称为抖动）会对某些时延敏感型应用（如语音和直播视频）造成损害。

2.1.4　Internet：迄今为止依然是分层结构

尽管从ARPANET的单骨干网结构（详见第1章）开始，Internet已经经历了巨大的发展变化，但是依然保留了一定的分层架构。分层架构中最低的一级是连接在ISP（Internet Service Provider，互联网服务提供商）上的Internet用户。在很多情况下，ISP都是本地区域范围内的一个或多个小型服务提供商，被称为本地ISP（local ISP），例如，科罗拉多州区号为303的区域内就有200家左右的ISP。这些本地ISP反过来又是某些更大ISP（覆盖整个地区，如一个或多个临近州）的客户，这些更大型的ISP被称为区域服务提供商（regional service provider），如科罗拉多州的CSD Internet和Colorado Supernet。相应地，这些区域服务提供商又连接到拥有覆盖全国或全球区域的高速（DS-3、OC-3或更高）骨干网的大型ISP，这些最大的服务提供商被称为网络服务提供商（network service provider），如MCI/WorldCom（UUNET））、SprintNet、Cable & Wireless、Concentric Network以及PSINet等。更通用地是将这些提供商分别称为Tier III、Tier II和Tier I提供商。

图2-6显示了这些不同类型ISP之间的关系。用户（无论是终端用户还是次一级的服务提供商）都在ISP的POP（Point of Presence，呈现点）处连接到上一级服务提供商，POP实际上就是一个就近的路由器，用户可以通过拨号或专用本地环路连接到该路由器上。在最高级别，网络服务提供商之间通过NAP（Network Access Point，网络接入点）进行互连。NAP实际上就是一个LAN或交换机（通常为以太网、FDDI或ATM），不同的服务提供商可以通过NAP相互交换路由和数据流量。

图2-6　ISP/NAP分层结构

如表2-1所示，某些NAP按名字被称为CIX（Commercial Internet Exchange，商用互联网交换中心）、FIX（Federal Internet Exchange，联邦互联网交换中心）和MAE（Metropolitan Area Exchange，城域交换中心；最初MAE被称为城域以太网（Metropolitan Area Ethernets），由Metropolitan Fiber Systems公司创造）。CIX、FIX和MAE-East都属于早期试验性质的骨干网连接点，根据这些互连点的互连经验，并且作为NSFnet退役计划的一部分，NSF（National Science Foundation，国家科学基金）于1994年建设了首批4个NAP。

表2-1　美国的已知NAP

续表

除了表2-1所示的主要NAP之外，在NSP的互连处还有很多小型NAP，常常用来互连较小的区域服务提供商，如SIX（Seattle Internet eXchange，西雅图互联网交换中心）和新墨西哥网络接入点等都属于区域型NAP。

除了建立NAP之外，NSF还资助了RA（Routing Arbiter，路由仲裁）计划，RA的职责之一就是提升Internet的稳定性和可管理性。迄今为止，RA提出了一个来源于服务提供商的路由（拓扑结构）和策略（优选路径）数据库（即RADB, Routing Arbiter Database，路由仲裁数据库）。该数据库由位于NAP的路由服务器（route server）来维护，而路由服务器实质上就是一台UNIX工作站或运行了BGP的服务器。此时，每个服务提供商的路由器无需与NAP中的其他所有路由器都建立对等关系，而只要与路由服务器建立对等关系即可。各种路由及策略都要与路由服务器进行通信（RA使用一种被称为RIPE-181的复杂数据库语言来处理和维护这些信息），之后由路由服务器将合适的路由传递给其他路由器。

虽然路由服务器运行BGP并处理路由信息，但并不执行包转发功能，而是利用其Update消息通知各路由器，最佳下一跳路由器就是通过NAP直接可达的路由器。经过第1章的学习，读者已经熟悉了EGP第三方邻居的概念，通过实现可行的一对多对等（而不是多对多对等），路由服务器大大提高了网络的稳定性、可管理性以及经由NAP的流量吞吐量。

NAP和RA证明了互相竞争的网络服务提供商之间可以相互合作，从而为Internet提供可管理的网络连接及稳定性。因此，NSF在1997年1月停止了路由服务器和NAP的资助项目，将网络运营交给了商业团体。尽管公共建立的Internet研究仍在继续，如Internet2、GigaPOP及vBNS（very high-speed Backbone Network Service，甚高速骨干网络服务）等计划，但目前的Internet基本实现了商业化运营。

将Internet转移到商业化运营的一个主要原因就是，现在的Internet已经远远偏离了最初的可控性构想。受经济性、竞争性和策略利益等因素的驱动，最大的服务提供商都选择建立直接对等互连，而不是通过路由服务器来实现对等互连，而且对等关系发生在多个级别，而不仅仅局限在图2-6所示的顶级层次。

当两个或多个服务提供商同意通过NAP实现路由共享时，要么直连，要么通过路由服务器进行连接，此时需达成对等协定（peering agreement）。对等协定既可以在两个服务提供商之间直接建立（称为双边对等协定），也可以在一组规模相似的服务提供商之间建立（称为多边对等协定，即MLPA, MultiLateral Peering Agreement）。在确定对等协定中的经济利益时，流量模型起到了决定性作用，如果对等伙伴之间的双方向流量基本平衡，那么一般无需进行相互结算，此时对等伙伴之间属于公平对等互连。但是，如果通过对等互连点的流量出现一方向流量远远大于另一方向流量，如一个小型服务提供商与一个大型服务提供商进行互连时，小型服务提供商通常需要为对等特许支付相应的费用，其原因是小型服务提供商在对等互连时获得的利益要高于大型服务提供商。

偏离最初Internet构想的另ー个因素是对等点的位置。NAP (许多服务提供商互连之处，如表2-1所示）是公共对等站点，除了这些公共对等站点之外，服务提供商们在与其他服务提供商同局址的站点建立了成百上千个NAP,此时签订的对等协定通常是两个或多个服务提供商之间的私有协定。由于私有对等可以大大缓解国家级NAP的网络拥塞，增强路由的灵活性，并降低某些流量的延时，因而得到政府的鼓励。

偏离最初Internet构想还有ー个因素是Internet没有完全按照图2-6所建议的那样去发展，许多全国性、区域性服务提供商也出售本地Internet接入服务，与本地ISP形成了直接竞争。例如，例2-7中路由跟踪的“起始点”就是隶属于Concentric Network (一个骨干网服务提供商）的拨号接入POP。而区域性服务提供商也常常出现在骨干NAP,它们通过NAP与ー个或多个网络服务提供商实现互连，或者通过NAP与其他区域性NAP实现互连，从而绕过了网络服务提供商。

例2-7：从位于丹佛的Concentric Network POP发起路由跟踪。

例2-7中的路由跟踪显示了一部分Internet骨干网结构，两个路由跟踪都从位于丹佛的 Concentric Network POP发起。在第一个路由跟踪中，数据包经Concentric Network的骨干网被转发到MAE-East，进而被连接到BBN Planet骨干网（第3行和第4行），数据包经BBN Planet骨干网被转发到由BBN和US West在明尼阿波利斯共享的TierⅡ NAP（第10行和第11行），最后被传送到目的地US West。

第二次路由跟踪显示数据包在到达目的地（离路由跟踪发起点仅几英里之遥）之前几乎穿越了整个美国。首先，这些数据包沿着Concentric Network骨干网，通过位于加利福利亚的路由器（第4行）到达芝加哥NAP，通过芝加哥NAP连接到Sprint骨干网（第6行），然后又被路由到位于新泽西州彭索金的纽约NAP，接着被转发到ANS骨干网（第11行和第12行），并经由雷斯顿、休斯顿、圣路易斯及芝加哥（第二次经过），最后返回丹佛。

与最后一次路由跟踪相似，我们也是绕了一大圈才又返回到本节所讨论的主题CIDR。

2.1.5　CIDR：降低路由表爆炸的危险

假定Internet具有一定的分层结构，那么可以看出这种分层结构对地址汇总方案有很大的帮助。在顶层，大块连续的C类地址被IANA（Internet Assigned Numbers Authority，互联网编号分配机构）分配给全球范围内的不同地址分配机构。这些地址分配机构被称为区域性IP地址注册管理机构（regional IP registries）。目前一共有3个区域性IP注册管理机构，包括为北美、南美、加勒比海和撒哈拉沙漠以南非洲地区以及全球网络服务提供商分配地址的ARIN（American Registry for Internet Numbers，美洲互联网号码注册管理机构），为欧洲、中东、北非以及部分亚洲地区分配地址的RIPE（Resèaux IP Europèens，欧洲IP资源中心），以及为其余亚太地区分配IP地址的APNIC（Asia Pacific Network Information Center，亚太网络信息中心）。

注意：ARIN是1997年从InterNIC（由Network Solutions公司负责管理）中分离出来的，专门负责IP地址和域名的管理。

表2-2列出了将C类地址分配给这些注册管理机构所服务区域的原始方案，只是其中某些分配方案目前已经过时了。如例2-8所示，标记了“Others”的地址块目前已被分配，区域注册管理机构反过来又将这些地址块分配给大型服务提供商或本地IP注册管理机构。一般来说，在这个级别分配的地址块都不小于32个连续C类地址（通常更多）。例如，Concentric Network曾经被分配给地址块207. 155. 128. 0/17，包括128个连续C类地址（详见例2-8）。

表2-2　按地理区域分配的CIDR地址

例2-8：对例2-7的地址207.155.128.5执行WHOIS时，显示的是分配给Concentric Network的/17 CIDR地址块的一部分。

收到这些地址块的服务提供商将这些地址划分成较小的地址块并分配给其用户，如果这些用户本身就是ISP，那么他们会将这些地址块划分成更小的地址块。按这种方式分配这些C类地址块（被称为CIDR地址块）的一个明显好处就是可以按照分层结构逐级汇总。有关这些地址在Internet中分配的详细情况请参见RFC 2050（www.isi.edu/in-notes/rfc2050.txt）。

为解释清楚，假定Concentric Network将其207. 155. 128. 0/17地址块的一部分（如 207.155.144.0/20）分配给其用户。如果该用户是一个ISP，那么该ISP会将其一部分地址块（如207.155.148.0/22）分配给其自己的用户，此时的用户会将/22（读作“斜杠22”）地址块宣告给ISP,ISP以单个聚合地址207.155.144.0/20将汇总后的用户地址宣告给Concentric Network。最后，Concentric Network又以单个聚合地址207. 155. 128. 0/17将汇总后的用户地址宣告给其所连接的NAP。

很明显，将单个聚合地址宣告给上一级网络域比宣告给成百上千个独立地址要好得多。另一个同样重要的好处是，该地址分配方案大大增强了Internet的稳定性，因为低级网络域的状态变化最多会被传递到第一个聚合点，而不会被进一步传播。

表2-3列出了各种不同CIDR地址块的大小、折合C类网络的大小以及每个地址块可以容纳的主机数量。

表2-3　CIDR地址块大小

续表

2.1.6　CIDR：降低B类地址空间被耗尽的危险

B类地址耗尽的原因就是IP地址类别设计上的固有缺陷：一个C类地址可以提供254个主机地址，而一个B类地址却可以提供65 534个主机地址，两者之间的差距过于悬殊。在出现CIDR之前，如果某公司需要500个主机地址，那么一个C类地址将无法满足该需求，此时就需要申请一个B类地址，而这样就将浪费掉65 000个主机地址。有了CIDR之后，只需要/23地址块就可以满足该公司的需求，从而可以大大节省其他地址分配方式浪费掉的主机地址。

2.1.7　CIDR 面临的难题

虽然CIDR被证明已成功减缓了Internet路由表的快速增长及B类地址的急速耗尽，但是对CIDR地址块的用户来说，仍然存在一些问题。

第一个问题就是可携带性。假设某用户被分配了一个CIDR地址块，而该地址非常有可能属于某个更大的地址块（分配给ISP的地址块）。此时，如果该ISP无法满足该用户的期望或者未能完全履行合约协议，或者该用户收到了其他ISP提供的更为优厚的服务提议，那么更换ISP也就意味着很有可能需要重新编址，而且当用户离开原有ISP、重新选择一个新的ISP时，原有ISP一般也不允许用户保留分配给该用户的IP地址。不但ISP不愿意放弃其地址空间的一部分，而且区域性IP注册管理机构也强烈建议在用户更换ISP时回收已分配给该用户的地址空间。

对终端用户来说，重新编址会带来不同程度的困难，对于那些在自身路由域中使用敌友地址空间、在网络边缘使用NAT（Network Address Translation，网络地址转换，详见第4章）的用户来说，重新编址过程应该是最简单的，此时只需更改“面向公网”部分的地址，对内部用户的影响最小。另一个极端的终端用户场景就是为每个内部网络设备都静态分配了公网地址，这些用户将不得不登录网络中的每台设备进行重新编址。

如果终端用户在整个网络域都使用了CIDR地址块，那么通过DHCP（或BOOTP）可以在一定程度上减轻重新编址所带来的痛苦。此时，除了更改DHCP的地址范围并重启用户机器之外，只需逐个重新编址那些静态分配了IP地址的网络设备，如服务器和路由器。

如果是ISP（而不是终端用户）需要变更上游服务提供商，那么重新编址的问题将变得更加复杂。因为此时不仅需要对自己的互联网络进行重新编址，而且所有被ISP分配了部分CIDR地址块的用户也都需要进行重新编址。

对所有希望连接到多个服务提供商的用户来说，CIDR还会产生另一个问题。多归属（multihoming，将在本章稍后进行详细阐述）的目的是提高冗余性，使得终端用户或ISP可以免受单个上游服务提供商出现故障所带来的网络中断。此时带来的问题就是，用户必须将从第一个服务提供商获得的CIDR地址块宣告到第二个服务提供商。

图2-7解释了多归属带来的问题。如图所示，用户拥有一个属于/23 CIDR地址块（属于 ISP1的更大的/20地址块），当用户连接到ISP2时，希望通过ISP1或ISP2都能接收来自Internet的流量为此，该用户必须将其/23地址块宣告给ISP2，当ISP2将这个/23地址块宣告给其他网络时就会产生问题：所有的“外界”路由器都拥有一条由ISP1宣告的去往205. 113. 48. 0/20的路由和一条由ISP2宣告的去往205.113.50.0/23的路由，所有目的地址为该用户的数据包都将选择相对精确的路由，这样一来，几乎所有来自Internet的流量都将通过ISP2到达用户，包括那些地理位置上更靠近ISP1的流量。

图2-7　Internet入流量匹配最精确的路由

如图2-7所示，路由205.113.50.0/23甚至还有可能通过Internet被宣告给ISP1，但这种情况一般不会发生，因为大多数ISP都会设置路由过滤器，以阻止自己的路由被重新宣告到自己的路由域中。但是，很难确保ISP1设置了正确的路由过滤机制，如果来自Internet的更为精确的路由被泄露到ISP1，那么ISP1的其他用户将跨越Internet和ISP2之后才能到达 205.113.50.0/23，而无法选择更为直接的路径。

对那些实施多归属的用户来说，ISP1除了宣告其CIDR地址块之外，还必须宣告更为精确的路由（如图2-8所示）。但大多数服务提供商都不愿意这么做，因为这样做就好比在其 CIDR地址块中“打孔”（也称为地址泄露），从而大大降低CIDR的有效性，而且在其CIDR地址块中宣告一条更为精确的路由将会给ISP带来管理负担。

图2-8　ISP1在其CIDR地址块中“打孔”

虽然图2-7和例2-8显示的ISP1到Internet只有单一连接，但在大多数情况下，ISP一般都拥有多条连接链接到上层服务提供商及NAP。对每条连接来说，服务提供商都必须重新配置其路由器，除了CIDR地址块之外，还必须宣告更为精确的路由，而且还有可能要修改其所有的入路由过滤器。此外，为了正确宣告用户的/23地址块，还需要ISP1和ISP2进行密切配合，但由于ISP1和ISP2处于竞争状态，双方或某一方不愿意进行紧密合作，从而大大增加了管理复杂度。

即使图2-8中的用户征得ISP1和ISP2的允许，同意宣告其/23地址块，仍然存在其他障碍。因为某些Tier I提供商为了控制骨干网层次的路由表规模，仅接受/19或更小的地址前缀，此时，如果ISP1或ISP2或两者从这样的网络服务提供商获得Internet连接，那么就无法宣告用户的/23地址块。在实际应用中，过滤前缀大于/19的CIDR地址已成为惯例，前缀/19也被称为全局可路由地址（globally routable address）。这就意味着如果宣告了更长的CIDR地址前缀（如/21或/22），那么这些前缀也不会被宣告到整个Internet。请记住，如果Internet的某些网络不知道该如何到达用户的网络，那么用户也将无法到达这些网络。

注意：为了解决日益增加的用户投诉，目前许多Tier I服务提供商已经放松了/19规则。

对图2-8中的多归属用户来说，一种可能的解决方案就是获得一段与提供商相独立（provider-independent）的地址空间（也称为可携带地址空间）。也就是说，用户可以申请不属于ISP1或ISP2的CIDR地址块的独立地址块，这样一来，ISP1和ISP2就可以在不干扰其地址空间的情况下宣告用户的自有地址块。有了ARIN之后，申请一块与提供商相独立的地址空间比从InterNIC申请变得相对容易一些，虽然ARIN也强烈建议用户首选从其提供商申请IP地址，再次从其提供商的提供商申请IP地址，而将从ARIN申请与提供商相独立的地址空间作为最后解决手段。不过，即便如此，仍然要面临很多难题。

首先，准备实施多归属的用户目前的地址空间很可能是从原先的ISP获得的，更改为与提供商相独立的地址空间就需要重新编址，也就会出现上面所描述的所有问题。（当然，如果在应用CIDR之前就已经取得了属于自己的IP地址空间，那么就已经是与提供商相独立的地址空间了，也就不存在上述问题了。）

其次，注册管理机构是根据正当需求而不是长期预测需求来分配地址空间，在该分配策略下，也就意味着可能仅分配满足当前及三个月预测需求的地址空间，而且在下次申请时，必须证明已经有效地使用了原先分配的地址空间。例如，ARIN需要用户证明使用了SWIP（Shared WHOIS Project，共享式WHOIS方案）或RWHOIS（Referral WHOIS Server，参考WHOIS服务器）。其中最常用的是SWIP，做法是将WHOIS信息加入到SWIP模板当中并用电子邮件的方式发送给ARIN。要想使用RWHOIS，必须在网络前端增加RWHOIS服务器，以便ARIN能访问WHOIS信息。无论采取哪种方式，这些WHOIS信息都可以证明用户是否有效使用了地址空间、目前是否己处于即将耗尽状态以及当前的地址空间。

当然，如果用户无法证明申请一个全局可路由（/19）地址空间的正当性的话，将也是一个问题。CIDR分配规则至少会为小用户和ISP的多归属带来难题，接下来的章节将详细讨论多归属问题，并提供一些可替代的拓扑结构。

2.2　谁需要 BGP

许多互联网络并不像想象的那样需要BGP，一个错误的观念就是，如果需要将一个互联网络分为多个路由域，那么就应该在不同的路由域之间运行BGP。当然，BGP的确是一种可行选择，但并不一定要在不必要的情况下通过增加其他路由协议而使事情变得复杂不堪。

以一个包含3 000多台路由器、150 000个用户的跨国企业网为例，图2-9显示了这样一个庞大网络的可能构建方式。整个网络采用OSPF进行路由寻址，为了便于管理，根据地理位置关系将整个网络划分为8个OSPF路由域（routing domain），虽然图中显示的每个OSPF域只有一个骨干区域（area），但是每个域都被划分为多个OSPF区域（根据地理位置的亚区域进行划分）。

虽然BGP可以在多个OSPF域之间提供连接性，但这并不是必需的。8个OSPF骨干区域都可以将路由重分发到单个全局骨干区域中，全局骨干是另一个OSPF域，包括多个OSPF区域，虽然全局骨干一般都是由处理包交换负荷的高端路由器组成，但这些路由器在路由表和OSPF方面的处理负荷却非常小。由于整个网络采用了上述寻址方式，因而8个OSPF域都只需向全局骨干宣告一条聚合路由。实际上，聚合对上述网络设计来说非常必不可少。据估算，如果一个包含了大量子网的互联网络中没有聚合OSPF机制的话，路由处理将变得异常困难，结果就是极差的网络性能和可能的路由器故障。

在使图2-9所示的互联网络保持简单性的三个要素中，物理拓扑结构和地址空间的层次化建设是其中的两个，另一个要素是整个互联网络要有一个统一的管理团队，单一管理团队可以保持全网路由策略的统一性和一致性。在这个案例中，路由策略可以指定每个OSPF区域使用的地址范围以及所有OSPF进程都只能通过OSPF 1进行互连。

图2-9　即便是一个超大型网络也可以仅使用多IGP域来构建

注意：路由策略实际上就是通过控制路由及其特性来控制互联网络中的流量模型的设计和配置方法。重分发、路由过滤器、路由映射都是Cisco IOS Software中最常见的路由策略实施工具。

当然，在实际应用中，几乎没有哪个如图2-9所示这么大规模的企业互联网络从一开始就按照如此协调、如此有逻辑的方式进行设计。很多（即便不是大多数）大型互联网络都是从较小的互联网络逐渐演化而来的（一般都是随着部门和公司的合并而发展演化），这样一来，不同的网络管理员在互联网络中的各个部分都会做出不同的设计选择，当这些不同的网络部分相互融合时，首先要做的就是保证基本的互操作性。

其次要做的事情可能就是实施路由策略，例如，要求来自互联网络中某些域的某些流量在去往其他路由域时，必须优选某些链路或路由，或者仅在域之间宣告某些特定路由。在大部分场合下，所需的路由策略都可以通过IGP之间的重分发以及路由过滤器和路由映射等工具来实现。因而，除非有必要的工程原因（如IGP无法提供相应的工具来实施所需的路由策略，或路由表的规模无法通过汇总来加以控制），否则不建议部署BGP。实践证明，当域内运行了多种IGP时，BGP非常有用，因为此时在所有的IGP之间实施路由重分发的难度要远大于BGP。

在考虑是否需要在互联网络设计中使用BGP时，首先应该考虑的就是发明外部路由协议的缘由，外部路由协议的作用是在自治系统（也就是不同管理机构下的不同互联网络域）之间传递路由。如果是单一企业网，即使该网络大到拥有多个不同的路由域且归不同的本地管理机构管理，也完全可以通过内部路由协议提供的路由工具，以集权方式来实施路由策略。只有在互连各个独立的自治系统时，才需要使用BGP。本节的后续内容将详细说明典型的AS间拓扑结构，并说明何处需要/不需要BGP。

2.2.1　单归属自治系统

如图2-10所示，某用户通过单链路连接到ISP，这种拓扑结构下无需BGP或任何其他类型的路由协议。当这条单链路失效时，无需做出任何路由选择决定，因为不存在其他可选路由，这样一来即使有路由协议也做不了什么。在这种拓扑结构下，用户只需向边界路由器增加一条静态路由并将该路由重分发到其AS中即可。

与此类似，ISP也会增加一条指向用户地址空间的静态路由并宣告到自己的AS之中。当然，如果用户的地址空间属于ISP更大的地址空间的一部分，那么由ISP路由器宣告的这条静态路由不会被传播到该ISP的AS之外。“其余网络世界”要想到达该用户，只能通过该ISP所宣告的地址空间，只有在ISP的AS之内才能知道到达该用户的精确路由。

在处理AS间流量时，需要记住的一个重要法则是：每条物理链路实际上代表的是两条逻辑链路，一条用于入站流量，另一条用于出站流量（如图2-11所示）。

图2-10　单归属拓扑结构下只需配置静态路由即可

图2-11　自治系统间的每条物理链路代表两条逻辑链路，分别承载入站数据包和出站数据包

在每个方向上宣告的路由仅影响相应方向上的流量，曾经撰写过很多优秀的、关于ISP问题文章的Avi Freedman将路由宣告称为承载数据包到达路由中所表示的地址空间的允诺。在图2-10中，用户路由器将默认路由宣告到本地AS中，即一个将数据包分发到所有目的地（没有其他精确路由）的允诺；同样，宣告了路由205. 110. 32. 0/20的ISP路由器也是允诺将流量转发给用户AS。这样一来，来自用户AS的出站流量得益于默认路由，而去往用户AS的入站流量则得益于由ISP路由器宣告的路由。虽然这个概念对本例来说可能显得有些显而易见，但对今后检查更复杂的拓扑结构来说却至关重要。

图2-10所示的拓扑结构有一个非常明显的脆弱性，那就是整个网络连接都要经受很多单点故障的影响，如果图中的单数据链路出现故障，如果路由器或路由器的某个接口出现故障，如果某台路由器的配置出现故障，如果路由器的某个进程出现故障，或者是如果某个过于人性化的路由器管理员犯了错误，都将会导致用户的整个Internet连接出现故障，这种拓扑结构所缺的就是冗余性（redundancy）。

2.2.2　多归属到单自治系统

图2-12给出了一个改良后的拓扑结构，用户拥有到同一个服务提供商的两条冗余链路，至于入站流量和出站链路如何通过冗余链路则取决于这两条链路的使用方式。例如，典型的多归属到同一个提供商的设置方式是一条链路为主用（专用Internet接入链路，如T1），另一条链路为备用，此时备用链路一般为低速链路。

图2-12　多归属到单自治系统

如果冗余链路仅用作备份，那么也不需要使用BGP，此时的路由宣告方式与单归属应用场景一样，只是需要将与备用链路相关的路由距离设置得高一些，以便在主用链路失效时作为备用链路使用。

例2-9显示了带有主用和备用链路情况下的路由器配置情况。

例2-9：多归属到单自治系统的主用和备用链路配置。

在例2-9的配置中，备用路由器有一条管理距离被设置为150的默认路由。这样一来，仅当主用路由器的默认路由不可用时，该备用路由器的默认路由才会进入路由表。而且，备用默认路由以较高的度量值（metric）（大于主用默认路由的度量值）进行宣告，以确保OSPF域中的其他路由器优选主用默认路由。这两条路由的OSPF度量类型均为E2，因而所宣告的度量值在整个OSPF域中保持一致。这种一致性可以保证无论到每台边界路由器的内部代价（cost）是多少，每台路由器上的主用默认路由的度量值都低于备用默认路由的度量值。例2-10给出了某路由器OSPF域内的默认路由情况。

例2-10：首先显示的是主用外部路由，其次显示的是主用路由失效后使用的备用路由。

虽然主用/备用设计方式满足了冗余性的需求，但无法有效地利用可用带宽。一种更好的设计方式是同时使用这两条路径，在链路或路由器出现故障时，这两条路径可以互为备份。此时这两台路由器的配置情况如例2-11所示。

例2-11：多归属到同一AS时的负载共享配置。

上述配置中的两条静态路由的管理距离完全相同，而且默认路由也都以相同的度量值（10）向外宣告。请注意，此时的默认路由以OSPF度量值类型E1向外宣告。对该类型度量值来说，OSPF域中的每台路由器除了要考虑默认路由本身的代价之外，还要考虑到边界路由器的内部代价，因而，每台路由器在选取默认路由时都会选择最近的出口点（见图2-13）。

在大多数情况下，从多个出口点将默认路由宣告到AS中并在相同的出口点对离开AS的地址空间进行汇总，可以实现很好的互联网络性能。需要考虑的一个问题是，非对称流量模式是否会成为一个关注点。如果两个（或多个）出口点的地理间隔足够大，以至于时延变化变得很重要时，就有可能需要进行更好的路由控制，此时就可以考虑是否使用BGP了。

例如，假设图2-12中的两台出口点路由器分别位于洛杉矶和伦敦，并且用户希望所有去往东半球的出流量都使用伦敦路由器，而所有去往西半球的出流量都使用洛杉矶路由器。请记住，入站路由宣告会影响出站流量。如果提供商通过BGP将路由宣告到用户AS中，那么用户的内部路由器将拥有关于外部目的地的更为精确的路由信息。此外，BGP还可以提供相应的工具为外部目的地设置路由策略。

与此相似，出站路由宣告会影响入站流量。如果内部路由通过BGP被宣告给提供商，那么用户就可以决定在哪个出口点宣告哪条路由，并且在将流量发送到用户AS时，可以利用 BGP提供的工具（在一定程度上）影响提供商的选择。

图2-13　边界路由器以度量值10和OSPF度量值类型E1宣告一条默认路由

在考虑是否使用BGP时，需要仔细权衡所得到的好处与增加路由复杂度所带来的代价。只有在对流量控制有益时才应该使用BGP，而且应该分别考虑出站和入站流量，如果仅需要控制用户的入站流量，那么可以通过BGP将路由宣告给提供商，而提供商仍然仅将默认路由宣告给用户AS。

另一方面，如果仅需要控制用户的出站流量，可以使用BGP仅接受提供商的路由，但一定要仔细考虑该从提供商接收哪些路由，“接收全部BGP路由”意味着提供商将会将整个Internet路由表宣告给用户。截至本书写作之时，大约有88 000条路由项（如例2-12所示）。要想存储和处理这么大规模的路由表，需要相当强大的路由器和最少64MB的内存（一般推荐为128MB）。另一方面，也可以利用低端路由器和适当的内存容量轻松实现相对简单的默认路由方案。

例2-12：全Internet路由表汇总信息显示一共有57 624条BGP项。

注意：　例2-12中的路由表汇总信息来源于route-server.ip.att.net公共可访问的路由服务器，另一台可以通过Telnet访问的路由服务器位于route-server.cerf.net。虽然每台服务器上的BGP项数量不完全相同，但其数量规模类似。

接收全路由和不接收任何路由的折衷点是“接收部分BGP路由”。顾名思义，部分路由指的是全部Internet路由的子集，例如，提供商可能仅宣告到达该提供商的其他用户的路由以及到达Internet其余网络的默认路由。后面章节中的内容将证明部分路由是非常有用的。

运行BGP时的另一个考虑因素就是需要利用一个自治系统号来标识用户的路由域。与 IP地址类似，自治系统号也是有限的，并且由区域性地址注册管理机构根据需要进行分配。跟IP地址一样，自治系统号也有一部分被保留用作私有用途：AS号64152～65535。几乎毫无例外，连接到单个服务提供商（无论是单归属还是多归属）的用户都使用保留范围之外的自治系统号，由服务提供商负责将私有AS号从所宣告的BGP路径上过滤掉。

尽管图2-12的拓扑结构已经在图2-10拓扑结构的基础上进行了改进（增加了冗余路由器和数据链路），但是仍然存在单点故障问题——ISP本身。如果该ISP失去了与Internet的连接，那么该用户也将失去与Internet的连接。而且，如果该ISP遭遇了严重的内部故障，那么单归属情况下的用户也将受到拖累。

2.2.3　多归属到多自治系统

如图2-14所示，当用户归属到多个服务提供商时，该用户不但具备了前面所讨论的多归属优势，而且还能防止单ISP故障导致的Internet连接丢失。

图2-14　多归属到多自治系统

对一个小型企业或小型ISP来说，多归属到多个服务提供商有很多实质性的困难。当用户的地址空间属于服务提供商较大地址空间一部分时，将衍生出来如下的问题。

•　必须说服起端的提供商在其CIDR地址块中“打个洞”；

•　必须说服第二个提供商宣告属于不同提供商的地址空间；

•　两个提供商必须都愿意紧密合作，宣告用户的地址空间；

•　如果用户的地址空间小于/19（一般小用户的地址空间都是如此），某些骨干提供商可能会拒收该路由。

最佳的多归属到多个提供商的用户是那些大到能获得（或者已经获得）与提供商相独立的地址空间以及公有自治系统号的企业和ISP。

图2-14中的用户在使用BGP之前仍然可以考虑其他解决方案。一种可选方式就是选取某个ISP作为主用Internet连接，而将另一个ISP作为备用连接；另一种可选方式是将默认路由设置为两个提供商，让路由选择进程自行选择相应的连接。但是，如果用户已经为多归属花了钱并且与多个提供商签订了相应的合约，那么上述两种解决方案都不可用，此时最好的解决方案就是BGP。

此外，需要分别考虑出站和入站流量。对入站流量来说，如果能将全部内部路由都同时宣告给两个提供商，那么将是最可靠的实现方式。此时，可以确保通过任一个AS都能到达用户AS内的所有目的地，即使两个提供商都宣告相同的路由，入站流量也会优选其中的某一条路径，BGP为此通过了相应的路径优选工具。

对出站流量来说，应仔细考虑从提供商接收到的路由。如果从两个提供商都接收了全部路由，那么就可以为每个Internet连接选择最佳路由。但是，在某些情况下，某个提供商可能是所有Internet连接的优选提供商，而另一个提供商仅是少量目的地的优选提供商，此时可以从优选的提供商处获取全部路由，而仅从另一个提供商获取少量部分路由。例如，如果仅希望通过第二提供商去往其他用户并作为主用Internet提供商的备份时（如图2-15所示），第二提供商会发送其客户路由，而用户则需要配置一条去往第二ISP的默认路由，以在主用ISP失效时使用。

图2-15　ISP1是去往大多数Internet连接的优选提供商，而ISP2仅用于去往其他顾客的互联网络并作为备用Internet连接

需要注意的是，ISP1发送的全部路由中可能会包含ISP2的客户路由。但是，由于用户又会从 ISP2处接收到相同的路由，而用户路由器通常都会优选经ISP2的较短路径，因而，如果到ISP2的链路出现故障，那么用户将使用经ISP1及其他Internet网络的较长路径去往ISP2的客户。

与此类似，用户通常都会选择经ISP1去往除ISP2的客户之外的所有目的地，但是，如果经ISP1的部分或全部精确路由出现丢失情况，那么用户将选择经ISP2的默认路由。

如果路由器因CPU和内存的限制而无法接收全部路由的话，也可以从两个提供商处接收部分路由。每个提供商都会发送其自身的客户路由，而用户则可以将默认路由指向两个提供商。此时，用户将以牺牲路由的精确性来换取路由器硬件的节省。

在其他接收部分路由的应用场合，每个ISP除了发送其自身的客户路由之外，还有可能发送其上游提供商的客户路由。如图2-16所示，ISP1连接到Sprint, ISP2连接到MCI，由ISP1发送给用户的部分路由就包含了ISP1的客户路由和Sprint的全部客户路由，由ISP2发送给用户的部分路由就包含了ISP2的客户路由和MCI的全部客户路由，而用户的默认路由则同时指向两个提供商。由于这两个骨干服务提供商的网络规模都非常大，因而用户将拥有足够的路由对大量目的地做出有效的路由决定。同时，比起Internet全路由表来说，部分路由要小得多。

图2-16　用户从两个ISP处接收的部分路由包括每个ISP的客户路由以及相应上游提供商的客户路由

从2.3节开始将解释BGP的操作，以及为入站和出站流量设置优先级和路由策略的工具。

2.2.4　关于“负载均衡”

多归属的主要好处就是冗余性，而且还能在一定程度上增加带宽。但增加带宽并不意味着能平均有效地使用这两条链路的带宽，而且也不应该期望能以50/50的方式完全平均地将流量分布到两条链路上。在实际中，流量占用某ISP的带宽总是比另一个ISP要多得多，该 ISP本身或上游提供商可能拥有更好的路由器、更优的物理链路或更多的NAP连接，或者该 ISP在拓扑结构上有更多的节点靠近用户经常访问的目的地。

当然，这并不是说通过大量的时间及精力也无法控制路由的优先级，让路由流量在两条链路上进行平均分配。不过问题在于，如果为了所谓的负载均衡而强制将某些流量引导到非最优路由时，实质上会导致Internet性能的劣化。在大多数情况下，实际上所实现的负载均衡都是非完全均衡地使用两条ISP链路，不用太在意某条链路占用了75%，而另一条链路只占用了25%。多归属的主要目的是提供冗余性并增加路由选择的效率，而不是负载均衡。

2.2.5　BGP 的危害

创建BGP对等关系涉及一个有趣的信任与非信任问题。一方面，由于BGP对等体是另一个AS，因而必须信任对端的网络管理员，以便了解他正在做些什么；另一方面，如果足够聪明，还应该检查每个操作，以防止对端网络管理员的错误操作而对本网造成损害。在实施BGP对等连接的时候，偏执一点也许更好。

回顾前面有关路由宣告的描述，路由宣告实质上是一个将数据包分发到所宣告目的地的承诺。对外宣告的路由会直接影响所接收到的数据包，而接收到的路由会直接影响所发送的数据包。对一个好的BGP对等方案来说，双方都应该完全了解每个方向上所宣告的路由，而且必须分别考虑入站流量和出站流量；每个对等体都要确保仅传送正确路由，同时还要使用路由过滤器或其他路由策略工具（如将在第3章描述的AS_PATH过滤器）确保仅接收正确路由。

ISP一般都不会容忍用户的BGP配置差错，最糟糕的情况是双方的BGP对等方案都出现了故障。举例来说，假如用户因某种错误配置而将207.46.0.0/16宣告给了ISP，对接收方来说，ISP不但没有过滤掉该条错误路由，而且还将该路由宣告给了外部Internet，该特定CIDR地址块属于微软，但用户却对外申明拥有去往该目的地的路由。这样一来，大量的Internet团体可能都会认为通过该用户路由域去往微软是最佳路由，导致该用户将接收大量来自Internet的非期望数据包，更为严重的是，该用户接收了应该去往微软的大量黑洞流量。此时，该用户和ISP不但烦恼，而且无法理解。

图2-17给出了另一个BGP路由错误案例。该互联网络与图2-15类似，区别在于本例中用户从ISP2学习到的客户路由因疏忽而被宣告给了ISP1。

图2-17　用户将学习自ISP2的路由宣告给了ISP1，从而引导去往ISP2及其客户的数据包通过该用户路由器进行转接

在各种可能性当中，ISP1及其客户将用户的路由域视为去往ISP2及其客户的最佳路径。由于该用户确实有一条去往ISP2的路由，因而这些流量并没有被黑洞化，只是此时的用户域将成为自ISP1去往ISP2的数据包的转接域，对自身的流量不利。由于从ISP2到ISP1的路由仍然要通过Internet，因而该用户会导致ISP2出现不对称路由。

从本质上来说，本节讨论的核心是BGP被设计用来在自主控制的系统之间进行通信。一个成功的、可靠的BGP对等方案不仅需要深入了解每个方向上所宣告的路由，还要深入了解每个对等方的路由策略。

2.3　BGP 基础

与EGP一样，BGP也为每个BGP对等体建立一条惟一的、基于单播的连接。为了提高对等连接的可靠性，BGP使用TCP（端口179）作为底层传送机制，由于将确认、重传和序列化等工作交由TCP层处理，因而BGP的更新机制也得到了大大简化。由于BGP建立在 TCP之上，因而需要为每个对等体建立一个独立的点到点连接。

BGP是一种距离矢量协议，每个BGP节点都依赖下游邻居从其路由表中传递路由；BGP节点基于它们所宣告的路由来进行路由计算，并将计算结果传递给上游邻居。但是，其他距离矢量协议都是以单一数值来量化距离，用来表示跳数或IGRP和RIGRP中所表示的全部接口时延之和及最低带宽，而BGP却使用数据包到达特定目的地所要经过的一个AS号列表（如图2-18所示）。由于该列表完全描述了数据包所要经过的路径，因而为了与其他传统距离矢量协议相区别，也将BGP称为路径矢量（path vector）路由协议。与BGP路由相关联的AS号列表被称为AS_PATH，他属于与每条路由相关联的多个路径属性之一。有关路径属性的内容将在随后章节详细阐述。

图2-18　BGP根据被称为AS_PATH属性的AS号列表来确定最短无环路AS间路径

第1章中曾经说过，由于EGP并没有一个完整的算法来计算最短路径，而且也无法检测路由环路，因而EGP并不是一个真正的路由协议。与此相反，AS_PATH属性使得BGP在这两方面都同时满足了作为路由协议的要求。首先，可以通过最小AS号来确定最短的AS间路径。在图2-18中，AS7收到两条去往207. 126. 0. 0/16的路由，其中一条路由的AS跳数为4，另一条路由的AS跳数为3，因而AS7将选择最短路径（4，2，1）。

利用AS_PATH属性可以非常容易地检测出路由环路。路由器在接收到路由更新后，如果发现在AS_PATH中包含了自己的本地AS号，那么该路由器就知道出现了路由环路。如图2-19所示，AS7向AS8宣告了一条路由，AS8将该路由宣告给了AS9, AS9又将该路由宣告回了AS7, AS7发现自己的AS号在AS_PATH中，因而拒绝接受该更新，从而避免了潜在的路由环路问题。

图2-19　如果BGP路由器发现自己的AS号位于其他AS路由器发送来的路由的AS_PATH中，则拒绝该更新

BGP并不显示每个AS中的详细拓扑信息。由于BGP看到的仅仅是一个自治系统树，而 IGP看到的是AS内部的拓扑情况，因而也可以说BGP比IGP看到是更高层次的Internet视图。由于该更高层次的视图与IGP看到的视图并不兼容，因而Cisco路由器维护了一个独立的路由表以承载BGP路由。例2-13给出了一个利用命令show ip bgp看到的典型BGP路由表。

例2-13：命令show ip bgp显示的BGP路由表。

虽然例2-13中显示的BGP路由表与利用命令show ip route显示的AS内部路由表有些不同，但其中的元素仍然一致。BGP路由表中显示了目的网络、下一跳路由器以及用于选择最短路径的度量值。Metric、LocPrf和Weight列的内容将在本节后面的内容中进行详细阐述，现在关注的主要是Path列的内容，该列列出了每个网络的AS_PATH属性。需要注意的是，每个AS_PATH都以一个i作为结尾，表示该路径终结在由Origin codes所指示的IGP。

请注意，路由表中列出了每个目的网络的多个下一跳。与AS内部路由表仅列出当前在用路由不同的是，BGP路由表列出了所有已知路径。最左列的*（有效）后紧跟一个>，表示该路径是路由器当前使用的路由，该最佳路径是拥有最短AS_PATH的路径。在存在多条拥有等价路径的路由时（如例2-13所示），路由器必须有某种确定最佳路径的准则，有关路径确定的过程将在本节后续内容中进行阐述。

如例2-13所示，如果去往某特定目的地时存在多条并行等价路径，Cisco的默认EBGP实现是仅选择一条路径——这一点与其他IP路由协议不同，其他IP路由协议在默认情况下是通过这4条等价路径做负载均衡。与其他IP路由协议一样，命令maximum-paths用于更改并行路径的默认最大值，其取值范围是1～6。需要注意的是，负载均衡仅能用于EBGP, IBGP只能使用一条链路。

与BGP发言方对等的邻居既可以在不同AS中，也可以在同一AS中。如果邻居位于不同AS中，则该邻居为外部对等体（external peer），此时的BGP被称为EBGP（external BGP，外部BGP）。如果邻居位于同一AS中，则该邻居为内部对等体（internal peer），此时的BGP被称为IBGP（internal BGP，内部BGP）。在配置IBGP时会遇到很多问题，这些问题将在2. 4节中进行详细讨论。

两个邻居在首次建立BGP对等连接时，会交换各自的全部BGP路由表，之后则仅交换增量的部分路由更新。也就是说，仅当网络出现变动时才相互交换路由信息，并且仅交换变动信息。由于BGP并不使用周期性的路由更新机制，因而对等体之间必须交换保持激活（keepalive）消息，以维护该对等连接。Cisco的默认Keepalive消息间隔是60秒（RFC 1771并没有指定标准的保持激活间隔时间），如果在3个间隔时间内对等体未收到Keepalive消息，那么该对等体将宣告其邻居停用（down）。也可以通过命令timers bgp来修改间隔时间。

2.3.1　BGP 消息类型

在建立BGP对等连接之前，两个邻居必须执行标准的TCP三向握手进程，并在端口179打开TCP连接。TCP为一条可靠连接提供了分段、重传、确认以及排序等功能，从而将BGP从这些功能中解放出来。所有的BGP消息都采取单播方式经TCP连接传递给邻居。

BGP使用以下4种消息类型。

•　Open（打开）消息

•　Keepalive（保持激活）消息

•　Update（更新）消息

•　Notification（通告）消息

本小节将解释如何使用这些消息。有关这些消息的格式及每个消息字段的变量情况请参见2.6节。

1．Open（打开）消息

TCP会话建立之后，两个邻居都要发送Open消息，每个邻居都利用该消息标识自己并指定其BGP操作参数。Open消息包括以下信息。

•　BGP版本号（BGP version number）：该字段指定发起方正在运行的BGP版本号（2、 3或4）。除非使用命令neighbour version来强制要求路由器运行早期版本，否则默认值为BGP-4。如果邻居运行的是早期版本的BGP，则该邻居将拒绝指定了版本4的Open消息；此时，BGP-4路由器将更改到BGP-3并再次发送一条指定该版本号的Open消息。该协商过程将持续到邻居双方都同意的相同版本时为止。

•　自治系统号（Autonomous system number）：该字段表示会话发起路由器的AS号，该消息可以确定该BGP会话是EBGP（与邻居的AS号不同）或IBGP（邻居的AS号相同）。

•　保持时间（Hold time）：该字段表示路由器在收到Keepalive消息或Update消息之前可以等待的最长时间（以秒为单位）。保持时间必须是0秒（此时必须不发送Keepalive消息）或至少3秒，Cisco的默认保持时间为180秒。如果邻居双方的保持时间不一致，那么将以较短的时间作为双方接受的保持时间。

•　BGP标识符（BGP identifier）：该字段标识邻居的IP地址。Cisco IOS确定BGP标识符的过程与确定OSPF路由器ID的过程完全一致——使用数值最大的环回（loopback）地址；如果环回接口没有配置IP地址，则使用数值最大的物理接口上的IP地址。

•　可选参数（Optional parameters）：该字段用来宣告支持验证、多协议支持和路由刷新等可选能力。

2．Keepalive（保持激活）消息

如果路由器接受其邻居发送来的Open消息中指定的参数，则响应一条Keepalive消息。此后，Cisco在默认情况下每60秒发送一条Keepalive消息，或者以已协商一致的保持时间的1/3为周期发送Keepalive消息。

3．Update（更新）消息

Update消息用于宣告可行路由、已撤销路由或两者。Update消息包括以下信息。

•　NLRI（Network Layer Reachability Information，网络层可达性信息）：该字段是一个或多个宣告IP地址前缀及其长度的（长度，前缀）二元组。例如，如果宣告的是206.193.160.0/19，那么其长度部分为/19，前缀部分为206.193.160。

•　路径属性（Path Attributes）：将在2. 3. 3节详细描述的路径属性是所宣告NLRI的特性，该属性提供了允许BGP选择最短路径、检测路由环路、确定路由策略的相关信息。

•　已撤销路由（Withdrawn Routes）：描述那些已变为不可达且退出服务的目的地的（长度，前缀）二元组。

请注意，虽然NLRI字段中可能会包含多个前缀，但是每条Update消息仅描述单条BGP路由（这是因为路径属性仅描述单条路径，不过该路径可能会通往多个目的地）。这里再次强调一下，BGP比IGP看到是更高层次的互联网络视图，IGP路由总是指向单个目的IP地址。

4．Notification（通告）消息

路由器只要检测到差错，就会发送Notification消息并关闭BGP连接。2.6节详细列出了会导致发送Notification消息的各种差错情况。

使用Notification消息的一个例子就是在邻居之间协商BGP版本号。建立了TCP连接之后，如果BGP-3发言者接收到一个指定版本号为4的Open消息，则会响应一条申明不支持该版本的Notification消息。

2.3.2　BGP 有限状态机

可以利用有限状态机来描述BGP连接的建立和维护阶段，图2-20和表2-4给出了完整的BGP有限状态机以及触发状态迁移的输入事件。

图2-20　BGP有限状态机

表2-4　图2-20的输入事件（IE）

下面将逐一简要介绍图2-20中出现的6种状态。

1．Idle（空闲）状态

BGP总是以Idle状态为起始点，该状态拒绝所有入站连接。启动事件（IE 1）发生后，BGP进程会初始化所有BGP资源，启动连接重试定时器，初始化去往邻居的TCP连接，侦听来自邻居的TCP初始化并将状态更改为连接状态。启动事件由配置BGP进程或重置现有进程的操作员发起，或者由重置BGP进程的路由器软件发起。

如果发生差错，BGP进程将迁移到空闲状态。此时，路由器可能会自动尝试发起另一个启动事件，但应对路由器的这种行为做一定的限制——这是因为在持续性地差错条件下，经常性地重启会导致波动。因而，在第一次迁移到空闲状态之后，路由器会设置连接重试定时器，在定时器到期时才会重新再启BGP。Cisco的初始连接重试时间为60秒，以后每次连接重试时间都是之前的两倍，也就是说，连续等待时间呈指数关系递增。

2. Connect（连接）状态

该状态下，BGP进程一直等待TCP连接的完成。如果TCP连接建立成功，BGP进程将会向邻居发送Open消息并进入OpenSent（打开发送）状态。如果TCP连接建立不成功，BGP进程将继续侦听由邻居初始化的连接，重置连接重试定时器，并迁移到Active（激活）状态。

如果连接重试定时器到期时仍处于连接状态，则重置定时器，并再次尝试与邻居建立TCP连接，进程也将继续维持在连接状态，其他输入事件将会让BGP进程迁移到空闲状态。

3．Active（激活）状态

该状态下，BGP进程会尝试与其邻居初始化TCP连接。如果TCP连接建立成功，BGP进程会清除连接重试定时器，完成初始化过程，向其邻居发送Open消息，并迁移到打开发送状态。保持定时器被设置为4分钟。

如果连接重试定时器到期时BGP进程仍处于激活状态，则进程将返回到连接状态并重置连接重试定时器，而且还要与对等体进行TCP连接的初始化并继续侦听来自对等体的连接。如果邻居试图以非期望的IP地址建立TCP会话，则重置连接重试定时器，拒绝该连接且继续维持在激活状态。其他输入事件（启动事件除外，因为激活状态会忽略该事件）将会让BGP进程迁移到空闲状态。

4．OpenSent（打开发送）状态

该状态下，已经发送了Open消息，BGP会一直等待直至侦听到来自邻居的Open消息。接收到Open消息后，会检查该消息的每个字段，如果存在差错，则会发送Notification消息并迁移到空闲状态。

如果接收到的Open消息没有差错，则发送Keepalive消息并设置Keepalive定时器。此外，还要协商保持时间，以便确定一个较小的保持时间值。如果协商后的保持时间为0，则不启动保持定时器和Keepalive定时器。根据对等体的AS号，可以确定对等连接是内部连接还是外部连接，并迁移到OpenConfirm（打开确认）状态。

如果收到断开TCP连接的请求，则本地进程将关闭BGP连接，重置连接重试定时器，开始侦听由邻居发起的新连接，并迁移到激活状态。其他输入事件（启动事件除外，因为该状态会忽略该事件）将会让BGP进程迁移到空闲状态。

5．OpenConfirm（打开确认）状态

该状态下，BGP进程将等待Keepalive消息或Notification消息。如果接收到的是Keepalive消息，则迁移到Established（建立）状态；如果接收到的是Notification消息或断开TCP连接请求，则迁移到空闲状态。

如果保持定时器到期、检测到差错或者发生了终止事件，则向邻居发送一条Notification消息，关闭BGP连接并将状态更改为空闲状态。

6．Established（建立）状态

该状态下，BGP对等连接已完全建立，对等体之间可以相互交换Update、Keepalive和Notification消息。如果接收到的是Update或Keepalive消息，则重新启动保持定时器（如果协商好的保持时间不为0）；如果接收到的是Notification消息，则迁移到空闲状态。其他事件（启动事件除外，因为该状态会忽略该事件）将会让BGP进程发送一条Notification消息并迁移到空闲状态。

2.3.3　路径属性

路径属性是所宣告BGP路由的特性。读者对某些路径属性可能非常熟悉（如目的IP地址和下一跳路由器），因为它们是所有路由的公共特性，而某些属性（如ATOMIC_AGGREGATE）则是BGP的特有属性。比较常见的路径属性如表2-5所示。除了为基本的路由选择功能提供必要的信息，路径属性还允许BGP设置并沟通路由策略。

所有的路径属性都可以归入以下4类。

•　周知强制属性；

•　周知自选属性；

•　可选传递性属性；

•　可选非传递性属性。

顾名思义，上述4类属性可以归类为两个子类，而每个子类又包括自己的子类。首先是周知属性，也就是说，所有BGP实现都必须能识别这些属性；其次是可选属性，也就是说，并不要求BGP实现支持这些属性。

周知属性包括强制属性（即必须包含在所有BGP Update消息中）或自选属性（即可以包含在特定Update消息中，也可以不包含在特定Update消息中）。

如果可选属性是传递性的，那么BGP进程应该接受该属性中包含的路径（即使不支持该属性），并将该路径传递给对等体。

如果可选属性是非传递性的，那么无法识别该属性的BGP进程可以忽略Update消息中包括的该属性，并且不将该路径传递给对等体。

表2-5　路径属性*

*实际上，除了上面列出的之外，BGP还有很多路径属性。不过，要么这些路径属性未在RFC 1771中加以规定，要么就是Cisco不支持，因而都超出了本书写作范围。

1．ORIGIN属性

ORIGIN是周知强制属性，指定了路由更新的来源。当BGP存在多条路由时，ORIGIN属性就是BGP用来确定优选路由的因素之一。ORIGIN属性指定的路由来源有如下几种。

•　IGP: NLRI是从源AS的协议中学到的。IGP源拥有ORIGIN值的最高优先级。如果路由是通过network语句从IGP路由表中学习到的（详见第3章），那么该BGP路由的源就是IGP。

•　EGP: NLRI是从外部网关协议中学到的。EGP的优先级次于IGP。

•　不完全的（Incomplete）：NLRI是从其他渠道学习到的。路由来源不完全的路由拥有最低优先级的ORIGIN值。不完全路由并不是说该路由有何缺陷，只是确定该路由来源的信息不完全而已。BGP通过重分发机制学习到的路由将携带不完全路由来源属性，这是因为没有办法确定该路由的来源。

2．AS_PATH属性

AS_PATH属性为周知强制属性，该属性利用一串AS号来描述去往由NLRI指定的目的地的AS间路径或路由。当BGP发言者发起一条路由（在其AS内宣告目的地的NLRI）时，将在AS_PATH中增加自己的AS号。同样，后续的BGP发言者在将路由宣告给外部对等体时，都会将自己的AS号加入到AS_PATH中（如图2-21所示）。其结果就是，AS_PATH描述了该路由所经过的全部自治系统，从最近到达的AS开始，到发起该路由的源AS结束。

图2-21　在AS_PATH中追加AS号（加在最前面）

请注意，仅当Update消息被发送到其他AS时，BGP路由器才会将其AS号追加在 AS_PATH中。也就是说，只有在EBGP对等体之间宣告路由时，才会在AS_PATH中追加 AS号。如果是在IBGP对等体（位于同一个AS中的对等体）之间宣告路由时，就不会追加 AS号。

通常情况下，在一个列表中存在多个同一AS号的多个实例是毫无意义的，而且还会破坏AS_PATH属性的作用。不过，在某个特定场合下，在AS_PATH属性中添加某特定AS号的多个实例也是非常有用的。请注意，出站路由宣告将直接影响入站流量。一般来说，在图2-21中，从NAP去往AS 100的路由将穿过AS 300，这是因为该路由的AS_PATH较短。但是，如果AS 100的入站流量的优选路径是到AS 200的链路时又该如何呢？举例来说，如果（500，200，100）路径上的链路均为DS3，而（300，100）路径上的链路为DS1，或者说，假设AS 200是主用提供商，而AS 300是备用提供商，则出站流量将被发送到AS 200，此时，同样也希望入站流量能走相同的路径。

AS 100可以通过更改其所宣告路由的AS_PATH属性来影响其入站流量（如图2-22所示）。通过在发送到AS 300的列表中增加其AS号的多个实例，AS 100可以让NAP中的路由器认为路径（500，200，100）是最短路径。这种在AS_PATH中增加额外的AS号的操作被称为AS路径预附加（path prepending）。

图2-22　AS 100在宣告给AS 300的AS_PATH中增加其AS号的多个实例

如前所述，AS_PATH属性的另一个功能是预防环路，其实现机制非常简单：如果某台BGP路由器从其外部对等体接收到的某条路由的AS_PATH中包含有自己的AS号，那么该路由器就知道该路由出现了环路，因而丢弃该路由。

3．NEXT_HOP属性

顾名思义，该周知属性描述了下一跳路由器（位于所宣告目的地的路径之上）的IP地址。BGP NEXT_HOP属性所描述的IP地址并不总是邻居路由器的IP地址，规则如下。

•　如果宣告路由器与接收路由器位于不同的自治系统中（外部对等体），那么NEXT_HOP是宣告路由器的接口IP地址；

•　如果宣告路由器与接收路由器位于同一自治系统中（内部对等体），且Update消息的NLRI指向的是同一AS内的目的地，那么NEXT_HOP是宣告该路由的邻居的IP地址；

•　如果宣告路由器和接收路由器是内部对等体，且Update消息的NLRI指向的是不同AS内的目的地，那么NEXT_HOP是外部对等体（通过该对等体学习到该路由）的IP地址。

图2-23解释了第一条规则，图中的宣告路由器和接收路由器位于不同的自治系统中，此时，NEXT_HOP是外部对等体的接口地址。到目前为止，该操作行为仍然与任何路由协议的期望结果一致。

图2-24解释了第二条规则，图中的宣告路由器和接收路由器位于同一AS中，而且正被宣告的路由器也位于同一AS中。此时，与NLRI相关的NEXT_HOP是发起路由器的IP地址。

图2-23　如果BGP的Update消息通过EBGP进行宣告，那么NEXT_HOP属性将是外部对等体的IP地址

图2-24　如果BGP的Update消息通过IBGP进行宣告，且所宣告的目的地位于同一AS，那么NEXT_HOP属性将是发起路由器的IP地址

请注意，虽然宣告路由器和接收路由器并不共享相同的数据链路，但IBGP TCP连接是通过IGP发话（IGP-speaking）路由器进行传递的，这部分内容将在“内部BGP”一节进行详细阐述。目前最重要的关注点是，接收路由器必须执行递归路由查找（有关递归查找的相关知识请参阅《TCP/IP路由技术（第一卷）》），以便将数据包发送到所宣告的目的地。首先，接收路由器会查找目的地172.16.5.30，该路由指示的下一跳是172.16.83.2。由于该IP地址并不属于与该路由器直连的任何子网，因而路由器必须再查找去往172.16.83.2的路由，该路由（通过IGP学习到的）指示的下一跳是172.16.101.1，此时就可以转发数据包了。通过这个例子，可以很好地理解IBGP对IGP的依存关系。

图2-25解释了第三条规则，图中的路由是通过EBGP学习到的，且被传递给内部对等体。由于目的地在其他AS中，因而通过IBGP连接传递的该路由的NEXT_HOP是外部路由器（该路由是通过该路由器学习到的）的接口地址。

图2-25　如果BGP的Update消息通过IBGP进行宣告，且所宣告的目的地位于不同AS，那么NEXT_HOP属性将是外部对等体（通过该路由器学习该路由）的IP地址

在图2-25中，IBGP对等体必须执行递归路由查找，以便将数据包转发到207. 135. 64. 0/19。不过却存在一个潜在的问题，下一跳地址所归属的网络192.168.5.0并不是AS 509的一部分，除非AS边界路由器将该网络宣告到AS 509，否则IGP（甚而内部对等体）将无法知道该网络。此外，如果该网络不在路由表中，那么去往207.135.64.0/19的下一跳地址将不可达，去往该目的地的数据包也都将被丢弃。事实上，尽管去往207.135.64.0/19的路由已经安装在内部对等体的BGP路由表中了，但却没有安装到IGP路由表中，这是因为对该路由器来说，下一跳地址是无效的。

当然，首先要解决的问题是要确保连接到两个自治系统上的外部网络要为内部路由器所知晓。尽管可以使用静态路由，但实用的方式是在外部接口上运行被动模式下的IGP，但在某些场合下，这种方式可能并不适用。第二种解决手段就是利用配置选项让AS 509中的AS边界路由器在NEXT_HOP属性中设置自己的IP地址，而不是外部对等体的IP地址。之后，内部对等体将拥有172.16.83.2的下一跳路由器地址（该地址为IGP所知晓），这种被称为next-hop-self的配置选项将在第3章中进行详细阐述。

4．LOCAL_PREF属性

LOCAL_PREF是本地优先级的缩写，该周知自选属性仅用于内部对等体之间的Update消息，而不会被传递给其他自治系统。该属性用来向BGP路由器通告某被宣告路由的优先等级。如果内部BGP发言者接收到多条去往同一目的地的路由，那么将比较这些路由的LOCAL_PREF属性，LOCAL_PREF最高的路由将被选中。

图2-26解释了LOCAL_PREF的使用方法。AS 2101可以从两个ISP获取路由，但ISP1为优选服务提供商。连接在ISP1上的路由器在宣告来自ISP1的路由时，设置LOCAL_PREF为200；而连接在ISP2上的路由器在宣告来自ISP2的路由时，设置LOCAL_PREF为100（为默认值）。因而，所有的内部对等体（包括连接在ISP2上的路由器）都将优选学习自ISP1的路由，而次选学习自ISP2的路由。

图2-26　LOCAL_PREF属性用于向内部对等体说明路由的优先等级，值越大的优先级越高

5．MULTI_EXIT_DISC属性

LOCAL_PREF属性仅影响离开AS的流量，为了对入站流量施加影响，就需要用到MULTI_EXIT_DISC属性（通常简写为MED）。该可选非传递性属性承载在EBGP Update消息中，可以让某AS向其他AS说明其优选的入口点。在其他条件均相同的情况下，AS在接收到多条去往同一目的地的路由时，就会比较这些路由的MED，与LOCAL_PREF不同（优选LOCAL_PREF值最大的路由）的是，优选MED值最小的路由，这是因为MED被视为一种度量值，所以理所当然地就要优选度量值最低（也就是距离最短）的路由了。

注意：　在BGP-2和BGP-3中，MULTI_EXIT_DISC属性被称为INTER_AS度量值。

图2-27解释了MED的使用方法。如图所示，某用户双归属到单一ISP, AS 525希望其入站流量使用DS-3链路，而将DS-1链路作为备份链路。此时就可以将通过DS-3链路传递的Update消息中的MED值设为0（默认值），而将通过DS-1链路传递的Update消息中的MED值设为100。如果这两条路由的其他条件完全一致，那么ISP将优选MED值较小的DS-3链路。

图2-27　通过DS-3链路传递的路由拥有较低的MED值，则ISP将优选该链路

请注意，ISP在两台路由器之间部署了IBGP, AS 525的MED在这些内部对等体之间进行传递，因而这两台路由器都知道哪条路由是优选路由，但MED并不会被传递到接收AS之外。例如，ISP在将206.25.160.0/19发布给其他AS的时候，并不会将由发起AS设置的MED也传递给其他AS。这就意味着MED仅用于影响两个直连自治系统之间的流量，如果要影响邻居AS之外的路由优先级，就需要使用前面所述的AS_PATH属性。

如果去往同一目的地的两条路由接收自两个不同的自治系统，那么将不会比较这两条路由的MED。例如，如果图2-27中的ISP接收到的206.25.160.0/19路由宣告来自AS 525及其他AS，那么将不会比较来自这两个自治系统的MED值。MED仅仅用于单个AS之内，它在某AS存在多个入口点时用于说明不同入口点的优先等级。

6．ATOMIC_AGGREGATE和AGGREGATOR属性

BGP发话路由器可以向其他BGP发言者发送重叠路由（overlapping route），重叠路由是指那些指向同一目的地的不同路由。例如，路由206.25.192.0/19和206.25.128.0/17就是重叠路由，可以看出，第一条路由包含在第二条路由之内，虽然第二条路由也可以指向除206.25.192.0/19之外的其他更精确的路由。

在确定最佳路径时，路由器总是选择更精确的路径。然而在宣告路由时，BGP发言者可以有多种方式来处理重叠路由，如下所示。

•　同时宣告较精确和较不精确路由；

•　仅宣告较精确路由；

•　聚合两条路由并宣告聚合路由；

•　仅宣告较不精确路由；

•　两条路由都不宣告。

本章在前面已经强调了在进行汇总（路由聚合）时，会丢失某些路由信息，而且路由选择也将变得不够精确。与此相似，在BGP发话路由器上执行路由聚合后会丢失路径的细节信息。图2-28解释了这种路径细节的丢失情况。

图2-28　BGP路由聚合将导致路径信息的丢失

AS 3113正在宣告一个聚合地址，该聚合地址代表了多个自治系统中的地址。由于该AS是该聚合的发起方，因而仅在AS_PATH中包含了自己的AS号。这样一来，有关更精确前缀的路径信息都因为聚合而被丢失了。

ATOMIC_AGGREGATE是一种周知自选属性，用于向下游路由器告知已经出现了路径丢失情况。无论什么时候，BGP发言者在将精确路由汇总到一个较不精确的聚合路由（前面列表中的第5个选项）时，都将丢失路径信息。而且，BGP发言者还必须将ATOMIC_AGGREGATE属性附加到聚合路由上。任何接收到带有ATOMIC_AGGREGATE属性的路由的下游BGP发言者都无法获得该路由更精确的NLRI信息，而且在将该路由宣告给其他对等体时，必须将附加上ATOMIC_AGGREGATE属性。

当设置ATOMIC_AGGREGATE属性时，BGP发言者还可以附加AGGREGATOR属性。由于该可选传递性属性包含了AS号及发起路由聚合的路由器的IP地址，因而提供了路由聚合的相关信息（如图2-29所示）。Cisco的BGP实现将路由器ID作为IP地址插入在该属性中。

7．COMMUNITY属性

COMMUNITY也是一种可选传递性属性，用于简化路由策略的执行。COMMUNITY最初是Cisco专有属性，后来在RFC 1997中实现了标准化。COMMUNITY属性将目的地视为某些共享一个或多个公共特性的目的地的一个成员。例如，ISP可能会为其所有客户的路由都分配一个特定COMMUNITY属性，之后，该ISP就可以基于COMMUNITY值（而不是每条路由）来设置其LOCAL_PREF和MED属性了。

图2-29　ATOMIC_AGGREGATE属性表示已经丢失了路径，而AGGREGATOR属性指示在何处出现路由聚合

COMMUNITY属性是一组4个8位组的数值。RFC 1997规定，前2个8位组表示自治系统，后2个8位组表示出于管理目的而定义的标识符，格式为AA:NN；而Cisco的默认格式为NN:AA，可以利用命令ip bgpcommunity new-format将Cisco的默认格式更改为RFC 1997的标准格式。

例如，假定来自AS 625的某条路由的COMMUNITY标识符为70，则以AA:NN格式表示的COMMUNITY属性为625:70；以十六进制方式表示时为两个连续的数字0x02710046，其中，625=0x0271, 70=0x0046。RFC利用十六进制格式表示COMMUNITY属性值，而Cisco路由器以十进制格式表示COMMUNITY属性值。例如，625:70是40960070（即与0x2710046相等的十进制数值）。

0（0x00000000）〜65535（0x0000FFFF）及4294901760（0xFFFF0000）〜4294967295（0xFFFFFFFF）是保留的团体（community）值，在保留取值范围之外，定义了以下周知团体。

•　INTERNET： Internet团体无任何值，所有路由在默认情况下都属于该团体，如果接收到的路由属于该团体，则可以自由宣告该路由。

•　NO_EXPORT（4294967041或0xFFFFFF01）：如果接收到的路由携带该数值，则不能将该路由宣告为EBGP对等体；如果配置了BGP联盟（confede-ration），则不能将该路由宣告到联盟之外（有关联盟的信息将在2.5节中详细阐述）。

•　NO_ADVERTISE（4294967042或0xFFFFFF02）：如果接收到的路由携带该数值，则根本就不能宣告该路由，包括EBGP或IBGP对等体。

•　LOCAL_AS（4294967043或0xFFFFFF03）：RFC 1997将该属性称为NO_ EXPORT_SUBCONFED。如果接收到的路由携带该数值，那么将不能宣告给EBGP对等体，包括同一联盟内其他自治系统中的对等体。

第3章将给出一些利用团体属性来增强路由策略的例子。

8．ORIGINATOR_ID和CLUSTER_LIST属性

ORIGINATOR_ID和CLUSTER_LIST是由路由反射器使用的可选非传递性属性，有关路由反射器的信息将在2.5节中详细阐述。这两个属性都被用来阻止路由环路。ORIGINATOR_ID是一个由路由反射器创建的32bit数值，该数值是本地AS中路由发起方的路由器ID，如果发起方发现其RID在所接收到的路由的ORIGINATOR_ID中，那么就知道已经出现了路由环路，因而忽略该路由。

CLUSTER_LIST是一串路由传递所经过的路由反射簇（cluster）ID，如果路由反射器发现其本地簇ID在其所接收到的路由的CLUSTER_LIST中，那么就知道已经出现了路由环路，因而忽略该路由。

2.3.4　管理性权值

管理性权值（Administrative Weight）是Cisco的专有BGP参数，仅用于单个路由器内的路由，该数值不与其他路由器进行交换。权值是一种可以分配给路由的数值（取值范围为0〜65 535），权值越高，表示该路由越优。在所有路由特性中，该权值是BGP判定进程在选择最佳路径时最重要的判断要素（显式指定路由除外）。在默认情况下，所有从对等体学习到的路由的权值都为0，而所有由本地路由器生成的路由的权值都为 32 768。

可以为单个路由设置管理性权值，也可以为学习自特定邻居的多条路由设置管理性权值。例如，对等体A和B可能会向同一个BGP发言者宣告相同的路由，通过为接收自对等体A的路由分配较高的权值，BGP发言者就可以优选经过对等体A的路由。需要注意的是，这种优先级仅在本地对单台路由器有效，权值信息既不会被包含在BGP Update消息中，也不会以任何方式告诉BGP发言者的对等体。

2.3.5　AS_SET

如前所述，AS_PATH属性由一组描述去往特定目的地的有序AS号组成，实际上存在如下两种类型的AS_PATH。

•　AS_SEQUENCE：一个有序的AS号列表（与前面描述的一样）。

•　AS_SET：一个去往特定目的地所经路径上的无序AS号列表。

这两种类型是通过AS_PATH属性中的类型代码进行区分的，详细信息请参见2.6节。

注意：　事实上，一共有4种类型的AS_PATH, 2. 5. 4小节将详细阐述另外2种类型：AS_CONFED_SEQUENCE和AS_CONFED_SET。

如前所述，AS_PATH最重要的作用是预防路由环路，如果BGP发言者发现自己的AS号位于接收自外部对等体的路由中，那么就知道出现了路由环路，从而忽略该路由。但是，如果执行了路由聚合（如图2-28所示），则将会丢失某些AS_PATH的细节信息，因而增加路由环路的潜在危险。

例如，假定图2-28中的AS 810有一条可选连接去往其他AS（如图2-30所示），那么来自AS 3113的聚合路由将被宣告给AS 6571，而该聚合路由又将通过AS 6571被宣告回AS810。

图2-30　路由聚合会丢失路径的细节信息，从而导致AS间出现路由环路

由于聚合点“之后”的AS号未能包含在AS_PATH中，因而AS 810无法检测到潜在的路由环路。进一步来说，假定AS 810中的某个网络（如206.25.225.0/24）出现故障，那么该AS中的路由器将匹配来自AS 6571的聚合路由，此时将会出现路由环路。

进一步思考后就可以发现，AS_PATH的环路预防功能并不需要AS号以特定顺序进行排列，所需要的仅仅是接收路由器能够识别出其自身的AS号是否位于AS_PATH中，这就是AS_SET的应用场合。

当BGP发言者从学习自其他自治系统的NLRI创建了一条聚合路由时，可以将AS_PATH中包含的AS号都作为AS_SET。例如，图2-31在图2-28中的聚合路由上增加了AS_SET。

图2-31　通过在聚合路由的AS_PATH中增加AS_SET，就可恢复路由聚合引起的环路预防功能

此时，汇聚路由器仍然以AS_SEQUENCE为起始，接收路由器同样可以沿路径回溯到汇聚路由器，但由于在聚合路由中包含了AS_SET，因而就可以预防路由环路了。通过这个例子还可以看出为什么AS_SET是一个无序的AS号列表，这是因为AS 3113中的汇聚路由器之后是去往各自治系统（位于聚合路由中）的多个分支路径，此时无法用有序的AS号列表来描述这些相互独立的路径。

如果AS_PATH中包含了AS_SET，那么就不需要在聚合路由中包含ATOMIC_AGGR- EGATE了。这是因为，AS_SET不但可以向下行路由器通告已经发生了路由聚合，而且还包含了比ATOMIC_AGGREGATE更多的信息。

与大多数配置选项一样，AS_SET也存在一定的功能妥协。众所周知，路由汇总的好处是可以提高路由的稳定性，也就是说，在某个属于聚合路由的网络出现故障后，该故障将不会跨越聚合点对外进行宣告。但是，如果在聚合路由的AS_PATH中包含了AS_SET，那么该路由的稳定性将会出现一定程度的降低。如图2-31所示，如果去往AS 255的链路出现了故障，那么AS_SET将会出现变化，而这种变化将会跨越聚合点对外进行宣告。

2.3.6　BGP 决策进程

BGP的RIB（Routing Information Base，路由信息库）包括以下3个部分。

•　Adj-RIBs-In：存储了从对等体学习到的路由更新中未经处理的路由信息，这些包含在Adj-RIBs-In中的路由被认为是可行路由。

•　Loc-RIB：包含了BGP发言者对Adj-RIBs-In中的路由应用本地路由策略之后选定的路由。

•　Adj-RIBs-Out：包含了BGP发言者向对等体宣告的路由。

RIB中的这3个部分既可以是3个不同的数据库，也可以是利用指针来区分不同部分的单一数据库。

BGP决策进程通过对Adj-RIBs-In中的路由应用本地路由策略，且向Loc-RIB和Adj- RIBs-Out中输入选定或修改的路由来进行路由选择。BGP决策进程应包括以下3个阶段。

•　第1阶段计算每条可行路由的优先级。无论什么时候，只要路由器到从其邻接AS的对等体处接收到BGP Update消息（包含了新路由、发生变化的路由或撤销某路由），就会激活本决策阶段。该阶段会单独计算每条路由，并为每条路由生成一个用于指示该路由优先级的非负整数。

•　第2阶段从所有可用路由中为特定目的地选出最佳路由，并将其安装到Loc-RIB中。只有完成了第1阶段之后才会激活本决策阶段。

•　第3阶段将相应的路由加入到Adj-RIBs-Out中，以便向对等体进行宣告。只有当Loc-RIB发生变化且第2阶段已经完成之后才会激活本决策阶段。路由聚合就发生在本阶段（如果执行了路由聚合操作）。

除非指定了其他特殊的路由策略，否则第2阶段总是在所有可行路由中为特定目的地选择最精确路由。需要注意的是，如果路由的NEXT_HOP属性所指定的地址不可达，则不会选择该路由。不过这种情况对内部BGP来说存在特例，详细信息将在2.4节中描述。

迄今为止，已经介绍了可以为增强单台路由器、内部对等体、邻接自治系统及自治系统之外的路由策略而赋予BGP路由的多种属性。在对待这些路由属性时，需要注意一定的顺序和规则（特别是当路由器需要在多个属性中进行选择时，这尤为重要），从而公平地为相同的目的地选择特定路由。相应的规则如下。

（1）优选管理性权值最大的路由。由于BGP管理性权值是Cisco的专有参数，因而属于Cisco专有功能。

（2）如果管理性权值相等，则优选LOCAL_PREF值最大的路由。

（3）如果LOCAL_PREF值相等，则优选由该路由器在本地发起的路由。也就是说，优选学习自IGP（运行于该路由器上）的路由。

（4）如果LOCAL_PREF值相等，且没有该路由器在本地发起的路由，则优选AS_PATH最短的路由。

（5）如果AS_PATH长度相等，则优选路由来源编码最低的路径，IGP低于EGP,EGP低于Incomplete（不完全的）。

（6）如果路由来源编码相同，则优选MULTI_EXIT_DISC值最低的路由。仅当所有备选路由的AS号相同时才进行MULTI_EXIT_DISC值的比较。

（7）如果MED相同，则优选EBGP路由，次选联盟EBGP路由，最后选择IBGP路由。

（8）如果路由的上述属性仍相同，则优选到BGP NEXT_HOP最近的路由，该路由是去往下一跳路由器IGP度量值最小的路由。

（9）如果路由的上述属性仍相同，且这些路由均来自于同一个邻接AS，并利用命令maximum-paths启用了BGP多路径功能，则在Loc-RIB中安装所有等价路由。

（10）如果没有启用多路径功能，则优选BGP路由器ID最小的路由。

2.3.7　路由阻尼

路由翻动（route flaps）是Internet（也是所有互联网络）不稳定的首要因素。当有效路由被重复宣告为无效、有效时就会产生路由翻动现象。很显然，每次路由状态发生变化时，都要通过互联网络宣告该变化情况，进而每台路由器都要重新计算路由，从而消耗了大量的网络带宽和路由器的CPU资源。

注意：　经常可能将术语“路由振荡（route oscillation）”与路由翻动混为一谈，实际上，路由振荡属于周期性行为，而路由翻动则不是。

大多数人很快就会想到物理链路不稳定或路由器接口故障是路由翻动的罪魁祸首，这一点完全正确，不过还有其他常见原因（也可能是最常见的原因）会导致路由翻动，那就是人为因素。虽然工程人员在电信局中心机房或用户配线间内进行工程施工时，很有可能出现导致路由翻动的错误，但是不要忘记，缺乏经验的网络管理员可能会对路由器进行错误的配置或错误的故障排查，有可能会重复地增加和删除某条路由、更改接口的状态或拆除BGP会话，如果这些路由变动都被传播给了其ISP，那么该网管员的大意行为将会影响整个Internet。

这种路由不稳定性的影响到底有多坏？以单台有些过载或能力不足的BGP路由器为例，如果上行连接变得不稳定，那么将会使多条路由出现同时性的翻动现象，导致该路由器无法处理这些路由变化，从而出现故障。此时，下游路由器不但要处理原先的翻动路由，还要处理所有源自该故障路由器的不可达路由。如此一来，将在整个互联网络中产生滚雪球效应，从而可能会导致更多的路由器出现故障。因而，这种影响是非常严重的。

路由聚合可以隐藏这种路由的不稳定性，这是因为聚合路由中的某条成员路由失效后，并不会影响聚合路由本身。去往失效路由所指示目的地的数据包仍然会被转发到聚合地址，由于该聚合路由的发起者知道去往目的地的路由无效，因而会丢弃数据包。

不过，在实际情况中，并不总是能进行路由聚合。比方说，某个ISP的用户拥有一个与提供商相独立的IP地址，由于该地址不在提供商的地址块之内，因而就需要在提供商的聚合地址之外再对外宣告该用户的IP地址。另外，通过前面多归属的学习，当用户多归属到多个提供商时，也无法实施路由聚合。

即便ISP可以聚合其用户路由，为Internet提供一条稳定路由，但这种聚合对维护该ISP自己AS内部的稳定性来说仍然毫无用处，路由翻动仍然会影响聚合点之后的所有路由器。

路由阻尼（route dampening）是一种阻止不稳定路由传播到整个互联网络的方法。虽然路由阻尼并不能阻止路由器接收不稳定路由，但是能够阻止路由器继续转发不稳定路由。尽管路由阻尼技术已经出现了一段时间，但在直到最近的RFC 2439（www.isi.edu/in-notes/tr.rfc2439.txt）中才得到了正式规范。

开启路由阻尼机制的路由器会为每条路由分配一个动态的特征值，用以反映该路由的稳定程度。当某条路由出现翻动时，将会给该路由分配一个惩罚值，翻动次数越多，累加的惩罚值就越大。路由阻尼中引入了半衰期（half-life）的时间周期概念，惩罚值以一定的速率衰减到每个半衰期初值的一半，当惩罚值超出了预设的阈值（被称为抑制门限（suppress limit））之后，该路由就被抑制，即不再对外宣告该路由。直到该路由的惩罚值降低至另一个阈值（被称为重用门限（reuse limit））之后，才会再次对外宣告该路由。作为一种可选方式，也可以手工清除路由的惩罚值，这种方式对于矫正了网络中的不稳定性之后需要快速重用该路由时非常有用。

除非抑制门限被设置得非常低，否则单次路由翻动行为并不会抑制该路由。通过半衰期方式，惩罚值会最终减小到零。但是，如果路由翻动的次数足够多，以至于其惩罚值的增加速度大于半衰期的减小速度，那么将会超出抑制门限。尽管路由在被抑制期间，其惩罚值仍然会继续累加，但该路由在超出了最大抑制门限（maximum suppress limit）周期之后将无法被抑制。这样就可以确保某路由在非常短的时间内翻动十几次之后，不会将惩罚值累加到一个很高的、使路由始终保持被抑制状态的值。

Cisco默认的各种路由阻尼变量的情况如下。

•　惩罚值：1000/路由翻动。

•　抑制门限：2000。

•　重用门限：750。

•　半衰期：15分钟。

•　最大抑制时间：60分钟或半衰期的4倍。

有关在Cisco路由器上配置和使用路由阻尼机制的案例研究，参见3.3.11小节。

2.4　I BGP 与 IGP 同步

几乎毫无例外，内部BGP（同一AS中的对等体间的BGP）仅用于多归属场合。IBGP允许边缘路由器共享NLRI及其相关属性，从而增强系统范围内的路由策略。此外，当位于转接（transit）AS中的边缘路由器将学习自外部对等体的路由传递给其他边缘路由器（以便将该路由宣告给外部对等体）时，就可以利用IBGP来作为传递手段。

读者可能会想到，在某些场合下IBGP应该可以被用作IGP。例如，某ISP的AS通常以EBGP方式连接到其他自治系统，且通常承载转接流量，那为什么不在AS内仅运行IBGP，以保持路由协议的一致性呢？问题是每台IBGP路由器都必须与其他IBGP路由器建立全连接的对等关系，也就是说，IBGP互联网络必须是全网状结构。本节将解释为什么必须要有IGP来支持IBGP，以及IGP与IBGP同步的重要性。IBGP必须保持全连接的原因如下。

•　防止在AS内形成BGP路由环路；

•　确保BGP路由路径上的所有路由器都知道如何将数据包转发到目的地。

顾名思义，通过IBGP宣告路由只能在同一个AS内进行宣告，因而AS_PATH并不会发生变化。事实上，只有当路由被宣告给EBGP对等体时，才会在AS_PATH中增加本地AS号。因而，IBGP路由没有EBGP路由所具备的环路预防功能。为了防止路由出现环路，BGP不会将学习自IBGP对等体的路由再宣告给其他IBGP对等体。

图2-32解释了IBGP对等体之间没有建立全连接时的后果。如图所示，在西雅图和塔科马以及塔科马和斯波坎之间配置了IBGP对等会话，西雅图和塔科马之间正在交换各自本地网络的NLRI信息，斯波坎与塔科马也一样，但此时西雅图和斯波坎之间无法相互学习对方的NLRI。

图2-32　在部分网状连接的IBGP环境下，由于学习自某个IBGP对等体的路由不会再被宣告给其他IBGP对等体，因而无法宣告所有NLRI信息

图2-33　显示了如何通过在IBGP对等体之间建立全连接来实现完全的可达性。需要注意的是，尽管西雅图和斯波坎之间不存在直连的数据链路，但它们仍然是对等体，只不过BGP经塔科马用来传递路由的TCP会话是西雅图和斯波坎之间的逻辑点到点会话。这一点非常重要，这是因为，要想建立TCP会话，西雅图和斯波坎就必须了解连接它们的数据链路的地址。

要确保数据链路地址可知看上去似乎非常简单，因为每台路由器的地址都必须包含在BGP的network语句中（将在第3章讨论），但事实并不总是这么简单。

例2-14给出了西雅图的BGP路由表和IGP路由表，对于要转发数据包的路由器来说，目的地必须位于IGP路由表中。

图2-33　在全网状连接的IBGP环境下，每台IBGP路由器都与其他IBGP路由器建立对等关系，并交换全部NLRI信息

例2-14：尽管BGP路由表中存在少量路由，但这些路由无法自动进入路由器的IGP路由表

从例2-14的输出结果可以看出，虽然BGP路由表中包含了几条路由，包括西雅图—塔科马以及斯波坎一塔科马间的数据链路地址（192.168.1.0/24和192.168.2.0/24），但仅有西雅图的直连链路进入了IGP路由表。需要注意的是，斯波坎网络206.25.129.0/24，甚至都没出现在BGP路由表中，表示西雅图和斯波坎之间没有建立正确的对等关系。

注意：请注意，BGP路由表中直连链路的权值与学习自塔科马的路由权值一样。

例2-14解释了同步问题：有关同步状态的规则如下。

学习自IBGP邻居的路由在进入IGP路由表或被宣告给BGP对等体之前，必须首先通过IGP来知晓该路由。

如图2-33所示，由于路由器上未运行IGP，因而BGP路由就不能进入IGP，而且同步机制要求BGP路由在进入IGP之前必须通过IGP来了解该路由。

下面以图2-34中的网络为例，解释同步规则的存在原因。该案例中没有使用IBGP作为内部网关协议，而是使用了OSPF作为IGP。盐湖城和普罗沃被连接在两个独立的自治系统上，并通过IBGP连接相互宣告学习自EBGP的路由，而用来承载IBGP连接的TCP会话则穿过了奥勒姆和奥格登节点。

图2-34　该网络在盐湖城和普罗沃之间运行了部分网状IBGP连接并使用OSPF作为IGP

接下来，假定盐湖城从AS 500学习到了一条去往196.223.18.0/24的路由，在通过IBGP连接将该路由宣告给普罗沃时，利用next-hop-self策略将NEXT_HOP属性更改为自己的路由器ID。之后，普罗沃又将该条路由宣告给AS 700。此时，AS 700中的路由器开始将去往196.223.18.0/24的数据包转发给普罗沃（请记住，路由宣告就是一种传递数据包的承诺），此时将出现差错。普罗沃将查找去往196.223.18.0/24的路由，发现经盐湖城可以到达该网络，之后将查找盐湖城的IP地址，发现可以通过下一跳路由器奥格登到达盐湖城，因而就将去往196.223.18.0/24的数据包转发给奥格登。但是，由于外部路由是通过IBGP在盐湖城和普罗沃之间进行共享的，OSPF路由器无法了解外部路由的信息，因而，当数据包被转发到奥格登之后，奥格登路由器将执行路由查找，但无法发现去往196.223.18.0/24的路由项，则丢弃该数据包以及随后到达的去往该目的地的所有数据包，致使去往网络196.223.18.0/24的流量出现路由黑洞。

当然，如果图2-34中的OSPF路由器知道外部路由，则将不会出现上述的现象——奥格登将知道通过盐湖城可以到达网络196.223.18.0/24，并能正确地转发这些数据包。利用同步机制，就可以防止因IGP信息不足而使得数据包在转接AS中被路由黑洞。

当普罗沃接收到盐湖城发出的196.223.18.0/24路由宣告之后，就将该路由添加到其BGP路由表中，并检查其IGP路由表，以确定IGP路由表中是否存在该路由项。如果该路由项不存在，普罗沃就知道该路由对IGP来说是未知的，那么将无法宣告该路由。如果该路由项存在且IGP在路由表中设置了去往网络196.223.18.0/24的路由项（也就是说，IGP知道该路由），那么普罗沃的BGP路由才与IGP路由实现了同步，此时，路由器才能将该路由宣告给BGP对等体。

回顾图2-33和例2-14所示的案例，即可明白为何同步会让全连接的IBGP无法正确工作。此时塔科马触犯了Catch-22（第22条军规，寓意两难的尴尬境地），它正在接收来自西雅图和斯波坎的路由，但由于这些路由并没有位于塔科马的IGP路由表中，因而塔科马无法让这些路由进入IGP路由表，也就无法对外宣告这些路由。没有任何IGP将这些路由放入到路由表中！

同步属于BGP中较为古老的一种协议机制，可以将路由重分发到IGP中。但是，如上例所示，对全连接的IBGP来说，所有路由器仅通过BGP就能了解所有必需的BGP路由。此时，同步机制将妨碍在BGP中保持BGP路由，并且导致在建立IBGP连接时不能仅使用IGP。

幸运的是，Cisco路由器提供了关闭同步的配置选项。例2-15显示了关闭同步机制之后西雅图的BGP和IGP路由表，此时，塔科马转发了来自斯波坎的路由，数据包也得到了正确转发。

例2-15：图2-33中3台路由器的同步机制被关闭之后，西雅图的BGP和IGP路由表中就有了全部NLRI。

通过上述讨论可以知道，要想保证IBGP能正常工作，就必须实施以下配置选项之一。

•　必须将外部路由重分发到IGP中，以确保IGP能够与BGP实现同步。但该方法的缺陷在于，如果从BGP获取了大量路由（如全部Internet路由表），那么将会给IGP路由器带来巨大的处理和存储负担，在多数情况下，路由器都无法处理如此重负，从而使路由器出现故障。实际上，某些大规模的网络故障就是因疏忽而将全部BGP路由重分发进了OSPF或IS-IS，其中的一次重大事故导致某重要服务提供商的网络曾宕机19个小时。

•　必须在IBGP路由器之间建立全连接关系，且关闭同步机制。此时，每台BGP路由器都可以通过BGP来知晓外部路由，而在关闭了同步机制之后，这些路由在无需首先通过IGP来知晓的情况下即可进入路由表。但该方法的缺陷在于，如果某AS内存在多台IBGP路由器，那么在这些IBGP路由器之间建立全连接关系将是一个非常巨大的管理性挑战。不过即便如此，在处理Internet路由时使用的基本上都是该方法。好在目前有两种措施来控制IBGP的全连接需求，一种是路由反射器，一种是联盟，有关信息将在下一节进行详细讨论。

第3章将提供几个IBGP配置案例，并在回顾这两种配置选项的缺点的同时，给出相应的解决方案。

2.5　管理大规模BGP对等应用

前一节已经指出，当AS规模变得较为巨大时，试图建立全连接的IBGP将变得难以承受，这就是BGP应用于大规模网络时呈现的问题之一。BGP提供了如下4种配置工具，以简化大量BGP对等体的管理问题。

•　对等体组（peer group）。

•　团体（community）。

•　路由反射器（route reflector）。

•　联盟（confederation）。

前2种工具用于简化多个对等体（内部对等体或外部对等体）之间的路由策略管理，后2种工具则用于简化大量对等体间的IBGP管理。

2.5.1　对等体组

对大规模的BGP互联网络来说，通常需要对多个对等体实施路由策略。比方说，可能需要在传送给多个对等体的Update消息中设置相同的属性，或者对来自多个对等体的路由使用相同的过滤器。此时，将这些共享相同策略的对等体加入对等体组（peer group）就可以大大简化相应的配置和管理工作。

通过一个组名和一套路由策略就可以在Cisco路由器上定义对等体组，之后就可以将对等体加入到对等体组中。此后，如果发生任何路由策略变化，都无需再逐一对每个对等体进行操作，而只需对对等体组进行操作。此外，对等体组对提高路由器的性能也非常有效，因为此时的路由器不再需要为每条发送给每个对等体的更新信息重复咨询策略数据库，路由器只要咨询一次策略数据库，创建单条Update消息，即可将多个拷贝分发给对等体组中的所有对等体。

有时，可能需要对某个对等体组中的一个或多个成员施加额外的路由策略，此时，除了要为对等体组配置通用路由策略之外，还要在相应的邻居上配置额外的路由策略。

2.5.2　团体

与对等体组是对一组路由器实施路由策略不同，团体是对一组路由实施路由策略。路由器将其COMMUNITY属性设置为某个标识自己为某团体成员的值之后，就可以将路由加入预先配置的团体中，之后，邻居路由器就可以基于COMMUNITY属性值将其策略（如过滤或重分发策略）应用于特定路由。COMMUNITY属性既可以被设置为周知值，也可以被设置为网管员预定义的值，有关COMMUNITY属性的详细信息请参见2.3.3小节的“COMMUNITY属性”。

可以为一条路由设置多个COMMUNITY属性。路由器在接收到一条拥有多个 COMMUNITY属性的路由后，既可以基于全部属性来设置路由策略，也可以基于部分属性来设置路由策略。当包含COMMUNITY属性的路由被聚合之后，聚合路由将继承所有被聚合路由的COMMUNITY属性。

2.5.3　路由反射器

当AS内包含了大量IBGP对等体时，路由反射器将非常有用。除非EBGP路由被重分发进自治系统的IGP，否则所有的IBGP对等体之间都必须建立全连接关系。对n台路由器来说，将意味着要在AS内建立n（n-1）/2条IBGP连接。例如，图2-35中显示了6台全连接的IBGP路由器，还算不上大量路由器，但即便如此，也需要建立15条IBGP连接。

图2-35　全连接IBGP对等体

路由反射器为全连接IBGP对等体提供了一种可选替代方案：将某台路由器配置为RR（Route Reflector，路由反射器），其他IBGP路由器则被称为客户（client），客户不再需要与每台IBGP路由器都建立对等关系，只要与RR建立对等体关系即可（如图2-36所示）。路由反射器及其客户被共同称为簇（cluster）。

路由反射器是通过放宽“IBGP对等体不允许对外宣告学习自其他IBGP对等体的路由”的规则来进行工作的，例如，图2-36所示的互联网络中，路由反射器学习了其全部客户的路由，与其他IBGP路由器不同，RR可以将这些路由反射给其他客户以及其他非客户对等体。换句话说，来自某IBGP对等体的路由可以被RR反射给其他客户。为了防止可能出现的路由环路或其他路由差错，要求路由反射器不得更改其从客户接收到的路由的属性。

路由反射簇中的客户路由器可以与外部邻居建立对等关系，但是在路由反射簇里只能与内部邻居或簇里的其他客户建立对等关系。不过，RR却可以与簇外的内部邻居和外部邻居建立对等关系，并且可以将它们的路由反射给客户路由器（详见图2-37）。

图2-36　路由反射簇中的IBGP客户只需与路由反射器建立对等关系即可，大大减少了所需的IBGP连接数

图2-37　路由反射簇的对等关系

如果RR接收到去往同一目的地的多条路由，将会启动BGP决策进程来选择最佳路径。RFC1966中定义了3条RR用来决定要宣告哪条路由的规则，具体使用时取决于路由是如何学习到的。

•　如果路由学习自非客户IBGP对等体，则仅反射给客户路由器；

•　如果路由学习自某客户，则反射给所有非客户和客户路由器（发起该路由的客户除外）；

•　如果路由学习自EBGP对等体，则反射给所有非客户和客户路由器。

只要路由反射器支持路由反射器的功能即可，从客户的角度来看，它们只要与内部邻居建立对等体关系即可。这一点正是路由反射器吸引人的地方，因为路由器只要实现了基本的BGP功能就可以在路由反射簇中充当客户路由器。

路由反射器与本章前面所说的路由服务器的概念相似，这两类设备的主要目的都是通过为多个邻居提供单一对等点来减少对等会话数，之后邻居就依靠该类设备来学习它们的路由。路由反射器与路由服务器之间的区别在于，路由反射器本身也是路由器，而路由服务器则不是。

单RR与单路由服务器一样，会给整个系统带来单点故障问题。如果RR失效，所有的客户都将失去它们惟一的NLRI源，因而，从冗余性角度来考虑，一个簇中可以拥有多台路由反射器（如图2-38所示）。客户与每台路由反射器都有物理连接，而且每台路由反射器也都建立了对等关系，在其中一台RR出现故障的情况下，客户仍有一条去往另一台RR的连接，因而不会丢失可达性信息。

注意：　尽管一个客户在只有一条去往某一RR的物理链路的情况下，仍能与多个RR建立对等关系，但这种配置方式失去了冗余性的目的，因为此时仍然存在单RR（客户只与该RR有物理连接）的故障隐患。

图2-38　为实现冗余性，一个路由反射簇可以拥有多台路由反射器

一个AS也可以有多个路由反射簇，图2-39显示了一个拥有两个簇的AS，每个簇都配置了冗余的路由反射器，而且这些簇之间也实现了冗余互连。

由于客户并不知道它们是客户，因而路由反射器本身也可以是其他路由反射器的客户，这样就可以构建“嵌套式”的路由反射簇（参见图2-40）。

尽管客户无法与本簇之外的路由器建立对等关系，但是它们之间却可以建立对等关系，因而路由反射簇可以实现全连接（参见图2-41）。当客户之间建立全连接之后，即便配置了路由反射器，路由反射器也不会将一个客户的路由反射给其他客户。此时，路由反射器仅将客户的路由反射给非客户对等体，并将非客户对等体的路由反射给客户。

图2-39　一个自治系统中可以创建多个路由反射簇

图2-40　任一路由反射器都可以是其他路由反射器的客户

图2-41　可以建立全连接的路由反射簇

2.4节中提到，由于AS_PATH属性在同一个AS中不会发生变化，因而为了防止出现路由环路，要求BGP不能将学习自内部对等体的路由转发给其他内部对等体。但需要注意的是，路由反射器是一种被放宽了该规则的BGP路由器，因而为了防止出现路由环路，路由反射器必须使用两种BGP路径属性：ORIGINATOR_ID和CLUSTER_LIST。

ORIGINATOR_ID是一种由路由反射器创建的可选非传递性属性，是本地AS中路由发起者的路由器ID。路由反射器不会将某路由宣告回该路由的发起者，即便如此，如果发起者接收到的Update消息中包含了其自己的RID，则忽略该Update消息。

AS内的每个路由反射簇都以一个惟一的4个8位组来标识簇ID，如果簇中包含了多个路由反射器，则必须以手工方式为每个RR配置簇ID。

CLUSTER_LIST是一种可选非传递性属性，用于记录簇ID，就像AS_PATH记录AS号一样。当RR将来自客户的路由反射给非客户时，同时将其簇ID附加到CLUSTER_LIST中，如果CLUSTER_LIST为空，则RR将创建一个CLUSTER_LIST。RR接收到Update消息后就会检查CLUSTER_LIST，如果发现其簇ID位于簇列表中，则知道已经出现了路由环路，从而忽略该Update消息。

2.5.4　联盟

联盟是另一种控制大量IBGP对等体的方法，它就是一个被细分为一组子自治系统（被称为成员自治系统（member autonomous systems））的AS，如图2-42所示。联盟中的BGP发言者与同一成员AS中的对等体建立IBGP关系，而与其他成员AS中的对等体建立EBGP关系。BGP会为联盟分配一个联盟ID（confederation ID），该联盟ID被联盟之外的对等体视为整个联盟的AS号。外部对等体无法看见联盟的内部结构，它们将联盟视为一个AS。如图2-42所示，AS 9184就是一个联盟ID。

图2-42　一个典型的联盟示例

非常明显，实体细分概念可以提高可管理性，IP子网就是IP网细分后的产物，而VLSM可以进一步细分子网。与此类似，自治系统是大型互联网络（如Internet）的细分产物，而联盟则是自治系统的细分产物。

2.3.5小节中描述了两种类型的AS_PATH属性：AS_SEQUENCE和AS_SET。而联盟又增加了两种类型的AS_PATH，如下所示。

•　AS_CONFED_SEQUENCE：一个去往特定目的地所经路径上的有序AS号列表，其用法与AS_SEQUENCE完全一样，区别在于该列表中的AS号属于本地联盟中的自治系统。

•　AS_CONFED_SET：一个去往特定目的地所经路径上的无序AS号列表，其用法与AS_SET完全一样，区别在于该列表中的AS号属于本地联盟中的自治系统。

由于AS_PATH属性被用于成员自治系统之间，因而保留了环路预防功能。从成员AS中的BGP路由器的角度来看，其他成员AS中的对等体都属于外部邻居。

将Update消息发送给联盟之外的对等体时，将从AS_PATH属性中剥离AS_CONFED_SEQUENCE和AS_CONFED_SET信息，而将联盟ID附加到AS_PATH中。因此，外部对等体将整个联盟视为单个AS，而不是多个自治系统的集合。如图2-42所示，通用做法是从预留的AS号（64 512〜65 535）中为联盟中的成员自治系统进行编号。

在选择路由时，BGP的决策进程在保持一致的基础上增加了一条规则：联盟外部的EBGP路由优于成员AS的外部EBGP路由，而成员AS的外部EBGP路由优于IBGP路由。联盟与标准AS之间的另一个区别在于某些属性的处理方式不同，NEXT_HOP和MED等属性可以不加修改地宣告给联盟内其他成员AS的EBGP对等体。此外，还可以传送LOCAL_PREF属性。

与路由反射器环境下仅需要路由反射器支持路由反射不同，联盟中的所有路由器都必须支持联盟功能，这是因为联盟内的所有路由器都必须能识别AS_PATH属性中的AS_CONFED_SEQUENCE和AS_CONFED_SET。不过，由于在将路由宣告出联盟时会移除这些AS_PATH类型，因而其他自治系统中的路由器无需支持联盟功能。

在超大型自治系统中，可以同时使用联盟和路由反射器，可以在一个或多个成员AS中配置一个或多个RR簇，以便更好地控制IBGP对等体。

2.6　BGP消息格式

BGP消息是在TCP报文段中使用TCP端口179进行承载的，其最大长度是4 096个8位组，最小长度是19个8位组，所有BGP消息都有一个相同的头部（如图2-43所示）。对不同类型的BGP消息来说，数据部分可能位于该头部之后，也可能不位于该头部之后。

图2-43　BGP消息头部

•　标志（marker）字段长16个8位组，用于检测BGP对等体之间的同步丢失情况，并且在支持验证功能的情况下进行消息验证。如果消息类型为Open或Open消息中未包含验证信息，标志字段将被设置为全1；否则，标志字段值通过某些计算得到（作为验证进程的一部分）。

•　长度（length）字段长2个8位组，指示消息的全部长度（包括头部），以8位组为单位。

•　类型（type）字段长1个8位组，指示消息的类型。表2-6列出了各种可能类型的代码。

表2-6　BGP类型代码

2.6.1　Open（打开）消息

Open消息的格式如图2-44所示，该消息是TCP连接建立后发出的第一条消息。如果接收到的Open消息是可接受的，则发送一条Keepalive消息，以确认该Open消息。确认了Open消息之后，BGP连接就处于Established（建立）状态，并能发送Update、Keepalive及Notification消息。

图2-44　BGP打开（Open）消息的格式

BGP的Open消息包含了以下字段。

•　版本（Version）：该字段长为1个8位组，用于指定发起者所运行的BGP版本。

•　我的自治系统（My Autonomous System）：该字段长为2个8位组，用于指定发起者的AS号。

•　保持时间（Hold Time）：该字段长为2个8位组，用于表示发送端建议的保持时间的秒数。接收端将该字段的值与其配置的保持时间进行对比，要么接受较小的保持时间值，要么拒绝该连接。保持时间必须为0或至少3秒钟。

•　BGP标识符（BGP Identifier）：发起者的路由器IP。Cisco路由器将路由器ID设置为最大的环回接口IP地址，如果没有配置环回接口，则设置为最大的物理接口IP地址。

•　可选参数长度（Optional Parameters Length）：该字段长为1个8位组，用于表示后面可选参数（Optional Parameters）字段的长度（以8位组为单位）。如果该字段的值为0，那么就表示该消息中无可选参数字段。

•　可选参数（Optional Parameters）：该可变长度字段包含了一个可选参数列表，每个参数都由一个长为1个8位组的类型字段、一个长为1个8位组的长度字段以及一个可变长度的包含参数值的字段组成。

2.6.2　Update（更新）消息

Update消息的格式如图2-45所示，该消息用来向对等体宣告一条可行路由、撤销多条不可行路由或两者。

BGP的Update消息包括以下字段。

•　不可行路由的长度（Unfeasible Routes Length）：该字段长为2个8位组，用于指示随后被撤销路由（Withdraw Routes）字段的长度（以8位组为单位）。该字段值为0时表示没有路由要被撤销，且Update消息中无被撤销路由（Withdraw Routes）字段。

•　被撤销路由（Withdraw Routes）：该可变长度字段包含了一个要退出服务的路由列表，列表中的每条路由都以（长度，前缀）二元组形式加以表示。其中，长度表示的是前缀的长度，前缀表示的则是被撤销路由的IP地址前缀，如果该二元组中的长度部分为0，则前缀部分将匹配所有路由。

•　整个路径属性的长度（Total Path Attribute Length）：该字段长为2个8位组，用于指示随后的路径属性（Path Attributes）字段的长度（以8位组为单位）。该字段值为0时表示Update消息中未包含路径属性和NLRI。

•　路径属性（Path Attributes）：该可变长度字段列出了与随后字段NLRI相关的属性信息。每个路径属性都以可变长度的三元组（属性类型，属性长度，属性值）加以表示，该三元组中的属性类型部分是一个长为2个8位组的字段，由4个标记bit、 4个未使用bit以及1个属性类型代码组成（参见图2-46）。

图2-45　BGP Update消息的格式

图2-46　路径属性字段中的属性类型部分的格式

•　网络层可达性信息（Network Layer Reachability Information）：该可变长度字段包含了一个（长度，前缀）二元组。其中，长度部分以bit为单位表示后面的前缀长度，前缀部分则是NLRI的IP地址前缀。如果长度部分的值为0，则表示前缀将匹配所有IP地址。

表2-7列出了最常用的属性类型代码以及每种属性类型可能的属性值。

表2-7　属性类型及相应的属性值*

*除表中所列之外还有其他属性类型，但都属于其他厂商（非Cisco）的专用属性类型，因而超出了本书的讨论范围。

2.6.3　Keepalive（保持激活）消息

Keepalive消息以保持时间的1/3（但不得小于1秒钟）为周期进行交换，如果协商后的保持时间为0，则表示不发送Keepalive消息。

Keepalive消息仅包含长为19个8位组的BGP消息头部，不包含其他数据。

2.6.4　Notification（通告）消息

Notification消息的格式如图2-47所示，在检测到差错条件之后就发送该消息。该消息发出后，将立即关闭BGP连接。

图2-47　BGP Notification消息的格式

BGP的Notification消息包括以下字段。

•　差错代码（Error Code）：该字段长为1个8位组，用于指示差错类型。

•　差错子代码（Error Subcode）：该字段长为1个8位组，提供了更精确的差错信息。表2-8列出了各种可能的差错代码及相应的差错子代码。

•　数据（Data）：该可变长度字段用于诊断差错原因，该字段的内容与差错代码及差错子代码相关。

表2-8　BGP Notification消息的差错代码和差错子代码

2.7　附　注

1K. Lougheed和Y. Rekhter, “RFC 1105：边界网关协议（BGP）”（仍在发展中）。

2K. Lougheed和Y. Rekhter, “RFC 1163：边界网关协议（BGP）”（仍在发展中）。

3K. Lougheed和Y. Rekhter, “RFC 1267：边界网关协议3（BGP-3）”（仍在发展中）。

4Y. Rekhter和T. Li, “RFC 1771：边界网关协议4（BGP-4）”（仍在发展中）。

5Internet Engineering Steering Group, R. Hinden, Editor, “RFC 1517：CIDR（无类别域间路由）实现的适用性声明”（仍在发展中）。

6V. Fuller等，“RFC 1519：CIDR（无类别域间路由）：一种地址分配和聚合策略”（仍在发展中）。

7Y. Rekhter和C. Topolcic, “RFC 1520：在CIDR环境中通过提供商的边界交换路由信息”（仍在发展中）。

8R. Chandra和P. Traina, “RFC 1997：BGP团体属性”（仍在发展中）。

2.8　展　望

在讲解了BGP的基本知识及相关概念之后，第3章将讨论如何在Cisco路由器上配置BGP以及如何检测和排除BGP故障。除了学习如何配置BGP之外，还要学习如何设置路由策略以及如何重分发BGP和IGP。

2.9　推荐读物

Halabi和B.&D. McPherson所著的《因特网的路由器选择技术（第2版）》，由电子工业出版社于2001年6月出版。该书被众多读者视为BGP-4的权威著作。

Stewart J.W.III. 所著的BGP4：Inter-Donain Routing in the Internet,由马萨诸塞州里丁镇的艾迪生—维斯理—朗文出版社于1999年出版，该书虽不是专门针对Cisco的，但却是一本非常好的有关BGP的案头简明手册。

2.10　复　习　题

附录D中提供了以下复习题的答案。

（1）BGP-4与早期版本的主要不同之处是什么？

（2）CIDR解决了哪两个问题？

（3）有类别与无类别IP路由器之间的区别是什么？

（4）有类别与无类别IP路由协议之间的区别是什么？

（5）给定地址172.17.208.0/23、172.17.210.0/23、172.17.212.0/23和172.17.214.0/23，请使用最长可能的地址掩码，以单个聚合地址来汇总这些地址。

（6）什么是地址前缀？

（7）例2-16中的路由表取自某无类别路由器，路由器向以下目的地址转发数据包时的下一跳地址是什么？

172.20.3.5

172.20.1.67

172.21.255.254

172.16.50.50

172.16.0.224

172.16.51.50

172.17.40.1

172.17.41.1

172.30.1.1

例2-16：配置练习题（7）的路由表。

（8）请解释汇总是如何隐藏网络的不稳定性的。

（9）请解释汇总是如何产生不对称流量模型的。

（10）不对称流量是不被期望的吗？

（11）什么是NAP？

（12）什么是路由服务器？

（13）什么是与提供商相独立的地址空间？拥有此地址的好处是什么？

（14）拥有一个与提供商相独立的/21地址为何会有问题？

（15）什么是路由策略？

（16）BGP用以可靠连接其邻居的底层协议是什么？

（17）BGP的4种消息类型分别是哪些？每种消息类型又是如何使用的？

（18）在什么状态（或哪些状态）下，BGP对等体之间可以交换Update消息？

（19）什么是NLRI？

（20）什么是路径属性？

（21）BGP的4种路径属性分别是什么？

（22）AS_PATH属性的作用是什么？

（23）AS_PATH包括哪些不同类型的属性？

（24）NEXT_HOP属性的作用是什么？

（25）LOCAL_PREF属性的作用是什么？

（26）MULTI_EXIT_DISC属性的作用是什么？

（27）BGP发言者发起一条聚合路由时哪种或哪些属性会有用？

（28）什么是BGP管理性权值？

（29）假设去往同一目的地有两条路由，一条是EBGP路由，另一条是IBGP路由，请问 BGP路由器会优选哪条路由？

（30）假设某路由器有两条去往同一目的地的路由，路径A的LOCAL_PREF为300，且 AS_PATH中有3个AS号，路径B的LOCAL_PREF为200，且AS_PATH中有2个AS号。假定其他情况完全一致，请问路由器会优选哪条路径？

（31）什么是路由阻尼？

（32）请给出路由阻尼中的惩罚值、抑制门限、重用门限以及半衰期的定义。

（33）什么是IGP同步？为什么同步很重要？

（34）在什么情况下可以安全地关闭IGP同步机制？

（35）什么是BGP对等体组？

（36）什么是BGP团体？

（37）什么是路由反射器？什么是路由反射客户？什么是路由反射簇？

（38）路径属性ORIGINATOR_ID和CLUSTER_LIST的作用是什么？

（39）什么是BGP联盟？

（40）路由反射器能否用于联盟内？

（41）next-hop-self功能的作用什么？是否有其他实现该功能的替代方案？

本章主要讨论以下主题。

•　基本的BGP配置：本节将提供一系列BGP配置案例，包括在BGP路由器之间建立对等关系、将IBGP路由注入BGP、将BGP路由注入IGP、无IGP时的IBGP、IBGP作用于IGP之上、EBGP多跳以及聚合路由等。

•　管理BGP连接：本节将分别从管理和维护的角度讨论可以让BGP连接变得更易管理的各种命令和工具。

•　路由策略：本节将讨论重置BGP连接，并提供通过NLRI或AS_PATH来过滤路由、路由映射、管理性权值、管理距离及路由黑洞、使用LOCAL_PREF和 MULTI_EXIT_DISC属性、预附加（prepending）AS_PATH、路由标记以及路由阻尼等的大量案例。

•　大型BGP:本节将提供多个大型BGP设计案例，包括BGP对等体组、BGP团体、私有AS号、BGP联盟以及路由反射器等。

第3章
BGP-4的配置及故障检测与排除

许多刚接触BGP的读者都有些缺乏信心，这是因为BGP实现要远远复杂于IGP实现。对除ISP之外的大多数网络管理员来说，对BGP的处理远不及IGP，即便使用了BGP，小型ISP和非ISP用户所进行的配置操作也是非常基本的。由于大多数网络专业人士对BGP协议都缺乏深层次的了解，因而常常将BGP视为一种神秘或令人畏惧的路由协议。

通过第2章的学习可以知道，BGP协议本身相对比较简单，比EIGRP或集成式IS-IS都要简单得多。BGP的复杂性并不在于其协议本身，而在于其应用场景以及与其相关的功能强大的工具。如果AS不存在多归属情况或仅有最基本的路由策略，则通常不需要部署BGP。

本章将首先介绍基本的BGP配置，然后给出几个利用BGP设置路由策略（发送和接收路由宣告的规则）的配置案例，最后讨论大型AS中的BGP方法。

由于BGP的配置选项非常多，以至于无法通过几个案例研究来充分说明BGP的故障检测及排除，因而本章在讨论BGP的故障检测及排除问题时，给出了多种配置选项及案例。

3.1基本的BGP配置

本节将介绍BGP进程以及最常用的BGP控制技术的基本配置步骤若想了解详细的BGP实现细节信息，就请全面学习本节提供的全部内容。

3.1.1 案例研究：在BGP路由器之间建立对等关系

路由器之间的BGP会话需要通过以下两个步骤进行配置。

•第1步：利用命令router bgp建立BGP进程并指定本地AS号。

•第2步：利用命令neighbour remote-as指定邻居及邻居的AS号。

图3-1显示了两台位于不同自治系统中的路由器，这些路由器的BGP配置内容与EGP不同。第1章中提到，利用命令route egp来指定远程AS，利用命令autonomous-system来指定本地AS。而此处正好相反，命令router bgp指定的是本地AS，而每个邻居的AS号是通过命令neighbour remote-as来指定的。这个区别非常重要，只有核心EGP路由器能与多个远程AS建立对等关系（利用命令router egp 0），而任何BGP进程都能与任意数量的远程AS建立对等关系。此外，还取消了EGP中要求通过核心AS来连接末梢自治系统的限制，自治系统在BGP下可以建立全连接关系。

例3-1给出了图3-1中的路由器Taos和Vail的EBGP配置情况。

图3-1在路由器Taos和Vail之间建立BGP会话

例3-1：图3-1中路由器的EBGP配置。

例3-2显示了路由器Vail所记录的Taos的信息，其中显示的大部分信息对故障检测及排除工作都非常有用。附录A中提供了命令show ip bgp neighbors显示的全部字段信息。

例3-2：命令show ip bgp neighbors的输出结果中包含了与邻居建立对等连接的细节信息。

（待续）

例3-2输出结果中的第1行显示了路由器Taos的IP地址（192.168.1.255）、AS号（200）以及该路由器的BGP连接类型（外部链路），第3行显示了Vail和Taos之间使用的BGP的版本号以及Taos的路由器ID。第4行首先显示BGP有限状态机的状态，BGP表发生变化后，路由表版本号就会递增，由于例3-2中去往路由器Taos的对等连接在建立后就没有发生变化，因而路由表的版本号始终为1。如例3-2所示，Vail与Taos已连续对等了19小时32分2秒钟。

此外，还需注意底层的TCP连接。例3-2以高亮方式显示了这些输出行，表明该TCP连接的状态为Established（已建立）, Vail通过TCP端口11025向外发送BGP消息，Taos侧的目的端口为179。当希望在一条承载了多条BGP会话的链路上抓取数据包时，源端口号就非常重要。

如图3-2所示，在AS 100中增加了另一台路由器Aspen，由于Vail和Aspen位于同一AS中，因而它们属于内部邻居。

图3-2 Vail和Aspen之间以IBGP进行通信

例3-3显示了路由器Vail的配置情况。

例3-3：图3-2中路由器Vail的配置。

例3-4显示了Aspen的配置过程，利用BGP调试技术可以观察对等体会话的建立过程。其中的数字显示了从创建BGP配置（18:24:13）到BGP对等体开始协商（18:24:33）之间的时间为20秒，TCP连接就是在这段时间内建立的。之后BGP就从Idle（空闲）状态跃迁到Active（活跃）状态，整个协商过程持续了大约10秒钟时间。

例3-4：命令debug ip bgp events显示了Aspen与Vail间建立对等关系的BGP有限状态机的状态。

（待续）

例3-5:Aspen的邻居信息显示了Vail的路由器ID来自于某个物理接口。

请注意，Vail的路由器ID是192.168.1.226，是与Taos连接的接口地址。BGP路由器ID的选择规则与OSPF路由器ID的选择规则完全一样，如下所示。

•路由器首先选择其环回接口上数值最大的IP地址；

•如果没有配置环回接口的IP地址，那么路由器将选择其物理接口上数值最大的IP地址。被选为路由器ID的接口上无需运行BGP。

由于Vail未配置环回接口，因而路由器选择物理接口上数值最大的IP地址作为路由器ID。使用与环回接口相关的IP地址有以下两个好处。

•环回接口比物理接口更稳定，环回接口在路由器启动后就一直处于活跃状态，而且仅当整台路由器失效后该接口才失效；

•网络管理员可以有更多的余地将可预测或可识别的IP地址分配为路由器ID。

Cisco的BGP实现会始终使用学习自物理接口的路由器ID，即便该接口后来失效或被删除。因而，环回接口的稳定性只是一个微不足道的优点，其主要优点在于对路由器ID的控制能力，使得其易于与其他IP地址相区别。

例3-6演示了如何为Vail配置一个惟一的路由器ID。

但是，为一台正在运行的BGP路由器配置环回地址之后并不会改变路由器ID，必须对路由器Vail应用命令clear ip bgp（将在3.3节做更为详细的讨论），以清除其全部BGP会话。此时再去看一下例3-7中的路由器Aspen的邻居信息，就可以发现Vail的当前路由器ID已经是环回接口0的IP地址了。

例3-6：为路由器Vail配置一个惟一的路由器ID。

与例3-5相比，例3-7中关注的是路由表的版本。重置了路由器Vail的会话之后，路由表的版本就被递增到2，该变化还会同时反应在Connections established和dropped字段中。需要注意的是，这些字段的内容不应发生经常性的变化，否则表明邻居不稳定。

例3-7：为路由器Vail配置了环回地址并重置其BGP会话之后，Vail的路由器ID将变为其环回地址。

此外，还可以手工设置BGP发言者的路由器ID，以绕过物理接口地址和环回接口地址，完成次操作的命令是bgp router-id。例如，例3-8就将Vail的BGP路由器ID设置为1.1.3.2。

例3-8：手工设置BGP路由器ID。

在环回接口需要用作它用（如用作OSPF路由器ID或SNMP功能）时，命令bgp router-id将非常有用，但是，接口上的IP地址与所期望的BGP路由器ID则有所不同。

3.1.2案例研究：将IBGP路由注入BGP

第2章曾强调过，在AS边界处，出站路由宣告会影响入站流量，而入站路由宣告则会影响出站流量。因而，应分别考虑出站和入站路由宣告。本小节将通过几个将路由注入BGP的基本方法来讨论BGP的路由宣告问题。

图3-3中的AS 200使用EIGRP作为IGP, Taos需要将3个IP地址宣告给EBGP对等体：学习自EIGRP的192.168.200.0/24、直连到Taos的192.168.100.0/24以及连接Taos和AngelFire的192.168.1.216/30。前两个地址是完整的C类地址，而最后一个地址为子网地址，192.168.1.0的其他子网位于AS 200之外，因而需要将该子网（而不是主网地址）宣告出去。

图3-3 AS 200的IGP为EIGRP

例3-9给出了路由器Taos的“first-pass”配置情况。

例3-9：Taos的基本EIGRP和BGP配置。

例3-10显示了Vail的BGP表，所有的EIGRP网络都通过EBGP链路向外宣告。需要注意的是，该例配置中未使用命令redistribute来指定度量值，因而每条路由的度量值都是默认的EIGRP度量值，如例3-11中所示的Taos路由表。直连网络的度量值为0，192.168.200.0/24的度量值为409600。可以利用命令default-metric来更改默认的度量值选择方法。

注意： BGP的度量值是MULTI_EXIT_DISC，该属性的使用和操作将在3.3.8小节中进行详细论述。

例3-10:Taos正确宣告了192.168.100.0/24和192.168.200.0/24，但子网192.168.1.216/30被汇总为主网。

例3-11:Taos路由表显示其EIGRP度量值与Vail的BGP表中的度量值一样。

（待续）

虽然AS 200中的两个主网得到了正确宣告，但例3-9中的子网192.168.1.216/30却被汇总成了主网，原因是BGP-4在默认情况下在网络边界处进行路由汇总（虽然BGP-4是无类别的路由协议）。在图3-3所示的互联网络中，这种路由汇总不会带来任何问题，路由器Vail与192.168.1.0的两个子网有直连关系，因而知道这两条精确路由。但随着网络规模的扩大以及在其他路由器上使用192.168.1.0的其他子网，这种路由汇总将会给路由选择带来差错。要想关闭BGP的自动汇总功能，需要按照例3-12的方法配置路由器Vail。

例3-12：配置路由器Vail以关闭BGP的自动汇总功能。

例3-13显示了路由器Vail的BGP表。可以看出，Vail在宣告192.168.1.0的子网的同时，还宣告了主网192.168.1.0。通过例3-11中Taos的路由表即可看出原因，EIGRP也会执行自动路由汇总功能，并在路由表中为Null0增加一条汇总路由。除了子网路由之外，BGP还会获知该汇总路由，并将其宣告给路由器Vail。

例3-13：关闭了路由器Taos的BGP自动汇总功能之后的路由器Vail的BGP表。

要想关闭路由器Vail的EIGPR自动汇总功能，可以使用命令no auto-summary（如例3-14所示）。

利用重分发机制将路由注入BGP的好处是在几乎不更改BGP配置的情况下，能够将域内路由的变化宣告给BGP。如果AS 200的EIGRP域内增加或删除了一个网络，该变化会自动宣告给路由器Vail。此外，IGP-to-BGP重分发机制的另一个主要好处是可以宣告每一条IGP 路由。例如，AS 100和AS 200的网络管理员可能/也可能不希望将子网192.168.1.224/30从Taos宣告给Vail，如例3-15所示，如果不希望宣告该子网，就需要使用路由过滤。3.3节中将通过几个案例来解释各种不同的路由过滤配置选项。

例3-14：配置路由器Vail以关闭EIGPR的自动汇总功能。

例3-15显示了此时路由器Vail的BGP表情况。

例3-15：关闭了路由器Taos的EIGRP自动汇总功能之后的路由器Vail的BGP表。

将IGP重分发到BGP中时，基本上都需要进行路由过滤。在默认情况下，每条由IGP学习到的路由都要被重分发到BGP中，但AS的网络管理员可能希望仅宣告IGP路由中的某个子网，这样就需要过滤掉其他子网。或者，某个多归属AS不希望为其任何邻居AS提供转接服务，此时就需要使用路由过滤，来阻止将学习自某AS的外部路由宣告给其他AS。不过此时将存在路由回馈问题，即接收自EBGP的外部路由被宣告到IGP中之后又从IGP中被重分发到EBGP中。最佳实践要求在使用路由过滤时，应该用来确保仅重分发正确路由。在实际应用中，由于缺乏精确控制手段，很少会将IGP前缀重分发到BGP中。

一种可选的将IGP路由重分发到BGP中的方式是使用命令network，如第1章所述，该命令在IGP中的功能与在EGP和BGP中的功能是不一样的。当应用于IGP中时，命令network用于指定某接口或一组接口（这些接口上将要启用路由协议）的IP地址，而应用于EGP和BGP时，命令network则用来指定将要宣告的IP前缀。对每个由该命令指定的前缀来说，BGP都会检查其路由表，如果表中的某个表项与network前缀完全匹配，那么该前缀就会进入BGP表并被向外宣告。

例3-16显示了对路由器Taos应用命令network而不是重分发机制的配置情况。

例3-16：用命令network配置Taos。

（待续）

如例3-16所示，命令network分别指定了主网192.168.100.0和192.168.200.0，此外，还指定了子网192.168.1.216的子网掩码。需要注意的是，只有在BGP-4下才可以指定子网及子网掩码，对EGP或BGP的早期版本来说，虽然都是无类别协议，但只能指定主网。

请注意，在这种配置场合下，命令no auto-summary不能应用于EIGRP或BGP。这是因为，在未配置路由重分发的情况下，无需关闭自动汇总功能。例3-17显示了该配置结果。

例3-17：使用命令network重新配置Taos之后的Vail的BGP表。

与例3-15不同，子网192.168.1.224/30没有被宣告，这是因为没有使用命令network来指定该子网。网络管理员有比重分发更多的控制手段，也不需要路由过滤。对比例3-15和例3-17可以看出，ORIGIN代码有所不同：例3-15中被重分发的路由被标记了一个？，表示ORIGIN为“不完全的（incomplete)”；而例3-17中的路由则被标记了一个i，表示ORIGIN为IGP。由于第2章中讨论过的BGP决策进程的关系，这种标记在不同场合下可以是不同的，ORIGIN代码1(IGP）的优先级要高于代码3（不完全的）。

利用命令network最多可以指定200个地址，如果需要通过BGP连接宣告更多的地址，就需要使用重分发机制。

3.1.3案例研究：将BGP路由注入IGP

学习自EBGP邻居的前缀可以被自动增加到路由表中。如图3-4所示，AS 300正在宣告两条路由：192.168.250.0/24和192.168.1.212/30。对本例来说，AS 300的IGP以及路由器Tahoe的配置都不重要，重要的是Tahoe向其外部BGP对等体所宣告的前缀在Taos路由表中都显示为可达路由，并且向AS 300中的目的地发起的ping操作都正常（参见例3-18）。由于Taos的串口192.168.1.224/30没有对外宣告，因而需要使用扩展的ping。所有学习自BGP的路由在路由表中都被标记为B。

例3-18：向图3-4的AS 300中的某个地址发起ping操作，显示正常。

（待续）

图3-4在图3-3的拓扑结构中加入AS 300

尽管通过路由器Taos可以通达AS 300的网络，但是在AS 200中的内部路由器能够通达这些网络之前，必须将BGP路由宣告到EIGRP中。一种方式就是在路由器Taos上配置重分发机制，如例3-19所示。

例3-19：将BGP路由宣告到EIGRP中。

（待续）

如例3-20所示，AS 300的前缀已被宣告给了AngelFire，并且这些目的地均可达。但是对入站路由和出站路由来说，重分发的许多问题仍然存在。重分发会将每条BGP路由都宣告给IGP，但网络管理员可能希望仅重分发BGP路由中的某个子网，此时，仍然需要利用路由过滤来抑制非期望路由。

警告：不将BGP路由重分发到IGP中还有一个非常重要的原因。目前Internet全路由表大约包含80 000条前缀，如果IGP需要处理如此大量的路由会导致IGP进程出现“拥塞”，因而将所有或大部分Internert路由都重分发到IGP中，将会产生严重的网络崩溃。本章所讨论的各种重分发对前缀数量有限的企业网来说非常有用，但绝对不应该将BGP-to-IGP重分发机制应用于面向Internet的路由器当中。

例3-20:Taos将其学习自BGP的路由宣告给了EIGRP。

如果希望更加严格地控制将哪些路由宣告到AS 200中，可以使用静态路由，如例3-21所示。

例3-21：通过静态路由来控制要宣告到AS 200的路由。

（待续）

例3-21所示配置中只向AS 200宣告了192.168.250.0/24。如例3-22所示，AngelFire并不知晓子网192.168.1.212/30。利用本配置中的静态路由还可以保持AS 200的稳定性，如果AS 300中的网络192.168.250.0出现翻动现象，那么这些路由变化在被传递到Taos之后，不会被进一步传递到AS 200中。

例3-22：子网192.168.1.212/30没有被宣告给AngelFire。

当然，对单归属AS（如图3-4中的AS 200）来说，几乎没有任何理由需要将外部路由注入AS中。除非需要将精确路由注入到AS中，否则默认路由已完全足够，详见例3-23。

例3-23：在单归属AS中配置一条默认路由。

如例3-23所示，Taos生成了一条默认路由，并将该路由宣告给了所有EIGRP发言者；也可以通过配置，让BGP生产一条默认路由。如果Vial希望将默认路由宣告给其BGP邻居，则可以按照例3-24的方式进行配置。

例3-24：将默认路由宣告给BGP邻居。

如例3-24所示，以静态方式创建了一条去往接口Null0的默认路由，并利用命令network将该路由进行了宣告。例3-24所示配置的一个假设是路由器Vail知道全部路由信息，所有数据包都被转发给了Vail，任何无法匹配到精确路由的目的地址都将匹配该默认路由，且被丢弃。

对某些设计案例来说，可能只允许将默认路由发送给部分邻居，而不是所有邻居。此时，如果只希望将默认路由从Vail发给Taos（而不是Vail的其他邻居），可以按照例3-25的方式进行配置。

例3-25：将默认路由发送给特定BGP邻居。

BGP命令neighbor default-originate与OSPF命令defaultinformation-originate always类似，无论路由器是否有默认路由都会宣告默认路由。请注意，日U一个配置中出现的静态路由在本配置中已不再出现，但是去往0.0.0.0/0的路由仍然被宣告给了Taos，如例3-26所示。此外，例3-26还显示了Tahoe的路由表，与Taos不同，Tahoe的路由表中没有0.0.0.0/0表项。

例3-26：默认路由被宣告给了Taos，但没有宣告给Tahoe。

（待续）

将默认路由器宣告给BGP邻居并不会抑制精确路由，如例3-26所示，来自AS 300的路由仍然在Taos的路由表中。有时这一点非常重要，例如，某ISP可能希望向其某个客户发送去往其他客户的路由（部分Internet路由表）以及去往Internet其余地方的默认路由，这种应用场景在多归属到同一ISP时非常有用，此时客户网络可以优选最佳路由去往该ISP的其他客户，并使用默认路由到达其他外部目的地。

如果希望仅发送默认路由，那么就需要利用路由过滤来抑制精确路由。如例3-27所示，使用了命令neighbor distribute-list，这只是过滤BGP路由的一种方法，其他方法将在3.3节进行详细论述。

例3-27：利用命令neighbor distribute-list过滤BGP路由。

3.1.4案例研究：无IGP时的IBGP

如图3-5所示，在AS 100中增加了其他路由器，该路由器通过EBGP连接到其他AS。此时，AS 100为转接AS，将承载既不是源自AS 100也不是终结于AS 100的流量。

图3-5运行了IBGP的AS 100将承载AS 400与其他两个自治系统间的转接流量

为了承载转接流量，AS 100中的内部路由器将建立全连接的IBGP，配置如例3-28所示。

例3-28：配置AS 100中的内部路由器以建立全连接的IBGP。

例3-29显示了Alta的路由表，通过多个ping操作验证了AS 200和AS 300中的目的地是可达的。

例3-29：通过AS 100中的IBGP连接将AS 200和AS 300中的路由传递给了AS 400。

（待续）

在配置图3-5所示的IBGP时，应记住以下重要内容：

•必须关闭同步机制；

•每台IBGP路由器都必须与其他IBGP路由器建立对等关系；

•必须知晓连接IBGP路由器的所有网络和子网。

如例3-28所示，已经使用命令no synchronization关闭了同步机制。回顾第2章讨论过的同步规则可知，路由器不得将IBGP路由宣告给EBGP对等体，除非已通过IGP知晓了该路由。换句话说，BGP必须与IGP实现同步。无论是重分发，还是netowork语句，都不会将路由表中不存在的路由宣告出去。

如果IBGP学习到的路由已进入路由表，那么就可以绕开同步规则。此时，重分发或netowork语句都能与路由表中的IBGP路由进行匹配并宣告该路由，即使IGP并不知道该路由。因而，当启用了同步机制之后，IBGP路由将不得进入路由表中。

例3-30显示了在启用了同步机制之后Aspen的情况。通过BGP表可以看出，虽然该路由器已经学习了所有由其IBGP对等体所宣告的全部路由，但IGP路由表却显示没有任何路由进入路由表。尽管Aspen无EBGP对等体，但转发仍会受到影响。例如，当Telluride向192.168.250.1转发数据包时，由于Aspen的路由表中没有关于该目的地的表项，因而会丢弃该数据包。

例3-30：启用了同步机制之后，通过IBGP学习到的路由不会进入路由表。

（待续）

在例3-31中，Aspen关闭了同步机制，此时IBGP路由就进入了路由表。

注意：如果要关闭正在运行的BGP进程中的同步机制，在更改生效之前必须利用命令clear ip bgp*重置BGP进程。有关该命令的用法将在3.3.1小节做详细解释。

例3-31：关闭了同步机制之后，Aspen的IBGP路由就进入了路由表。

观察图3-5以及AS 100中的路由器配置情况可以看出，3台路由器中每一台都与其他两台路由器建立了对等关系，原因是路由器不能将学习自某个IBGP对等体的路由宣告给其他IBGP对等体。例如，路由器Vail从其与Tulluride的IBGP会话中学习到了AS 400的相关地址，如果不存在该IBGP会话，Vail将无法从Aspen学习路由。Aspen也通过相应的IBGP连接从其对等体Vail和Telluride学习路由。如果Aspen没有学到这些路由，将无法在Vail和Telluride之间转发数据包。

将EBGP学习到的路由宣告给IBGP对等体时，该路由的下一跳地址将不会发生变化。观察例3-30中Aspen的BGP表就会发现，去往其他自治系统的全部路由的下一跳地址都是发起这些EBGP路由的路由器的接口地址。例如，去往192.168.200.0/24的路由的下一跳地址是192.168.1.225，即Taos的接口地址。这些下一跳地址都进入了路由表，因而所有的IBGP路由器都必须知道如何到达这些下一跳地址。在图3-5的配置中，Vail和Telluride都对去往各自EBGP对等体的链路的子网地址应用了语句network,正是有了这些语句，才使得IBGP对等体知道如何到达这些链路上的下一跳地址。

Aspen也对其两条数据链路应用了语句network，所以Telluride知道如何到达位于路由器Vail的下一跳地址192.168.1.221,Vail也知道如何到达位于Telluride的下一跳地址192.168.1.197，这些地址对构建Vail与Telluride之间的IBGP对等会话也非常重要。如图3-5所示，虽然逻辑连接建立于Vail与Telluride之间，但IBGP会话所使用的TCP连接却穿越了Aspen，如果Vail与Telluride都不知道如何发现对方，那么将无法建立TCP连接。

使用network语句的位置也非常重要，例如，如果在路由器Vail（而不是路由器Aspen）上应用语句network 192.168.1.220 mask 255.255.255.252，那么该子网将无法通过Aspen向外宣告，Telluride也就无法知道如何到达下一跳地址192.168.1.221。

向IBGP对等体宣告路由时，EBGP路由的下一跳地址不会发生变化这一规则将不适用于相反方向。如果路由器将学习自IBGP的路由宣告给EBGP对等体，那么下一跳地址就是该宣告路由器的接口地址，即使该路由最初是从EBGP学习到的也依然如此。对比Aspen的BGP表中路由的下一跳地址（见例3-31）与Alta的BGP表中路由的下一跳地址（见例3-32），请注意，路由器Aspen显示了192.168.250.0/24的下一跳地址为位于路由器Tahoe的192.168.1.210，但路由器Alta针对同一路由的下一跳地址却是位于Telluride的192.168.1.206。事实上，路由器Alta学习自EBGP的每条路由的下一跳地址都完全一样。

例3-32：学习自EBGP的路由的下一跳地址总是宣告该路由的EBGP对等体的地址。

在向IBGP对等体宣告路由时，利用命令neighbor next-hop可以越过“EBGP路由的下一跳地址不发生变化”这一规则。例3-33解释了如何在AS 100中的路由器Vail和Telluride上使用命令neighbor next-hop。

例3-33：向IBGP对等体宣告路由时，将强制更改EBGP路由的下一跳地址。

（待续）

如例3-33所示，删除了先前在路由器Vail和Telluride上配置的network语句，由于此时这两台路由器在宣告学习自EBGP的路由时都将自己的地址作为下一跳地址，因而就不再需要network语句。例3-34显示了重配置之后路由器Aspen的BGP表。

例3-34:Vail和Telluride在向Aspen宣告学习自EBGP的路由时将自己宣告为下一跳地址。

本小节的主要目的是解释与IBGP行为相关的一些基本概念，但具体的解释方法却不完全一样。虽然在路由新闻组中可以找到许多有关“无IGP时使用IBGP”的相关讨论信息，但在实际中很少会有人这么做。如果确实这么做了，将会发现这样的部署方式。例如，本小节所示案例中就在配置中应用了network语句，这样内部路由器就能知道如何到达外部的下一跳地址。现实生活中的IBGP部署方式，要么使用next-hop-self功能，要么在外部接口上运行被动模式的IGP，偶尔使用的第三种选项就是将所连接的接口重分发到AS边界路由器的IGP中，但这种配置方式是一种非常笨拙的方法，一般不推荐使用。

更重要的是，IGP还能增强TCP会话（IBGP运行于TCP会话之上）的健壮性，当然也就能增强IBGP本身的健壮性。下面各小节将给出各种更为现实的BGP配置案例。

3.1.5案例研究：IBGP作用于IGP之上

如图3-6所示，重新配置了AS 100中的路由器。在图中所示的拓扑结构中，OSPF作为自治系统的IGP， IBGP仅运行于路由器Vail和Telluride之间。

例3-35显示了AS 100中的3台路由器的配置情况。

例3-35:AS 100中的路由器Vail、Aspen和Telluride的配置情况。

（待续）

图3-6在AS 100的路由器中增加了OSPF

在BGP配置中，启用了同步机制，EBGP路由被重分发到OSPF中（由于同步机制是默认启动功能，因而配置中无任何相关命令），这两个配置步骤是保证IBGP链路正确运行所必不可少的。此处的重分发所起的作用与前面案例研究中IBGP链接到路由器Aspen的作用相同，如果Aspen接收到一个源自AS 400、目的地是AS 200的数据包，那么就不知道该路由，将丢弃该数据包。

同步机制可以保证重分发工作的正确性。例如，假设去往192.168.100.0/24的路由没有被重分发到路由器Vail的OSFP中，那么将不会显示在路由器Telluride的路由表中。虽然Telluride从IBGP连接中知晓了该路由，但由于该路由没有位于其路由表中，因而无法将该路由宣告给Alta，致使没有任何去往该目的地的流量能从AS 400被转发到AS 100。当然，如果从AS 400到AS 100还有其他可选路径（图3-6中没有画出），那么就可以使用该路进。

例3-36显示了Telluride的BGP表和路由表，例3-37显示了Alta的路由表。注意观察 Telluride的配置信息就可以看出，没有从OSPF向BGP重分发任何路由，也没有应用BGP network语句。所有必需的路由都已存在于Telluride的BGP表中，而且这些路由也是要宣告给Alta的路由，Telluride路由表中的路由仅仅是为了满足同步的需要。

例3-36：图3-6中路由器Telluride的BGP表和路由表。

例3-37：图3-6中的路由器Alta的路由表。

图3-6所示的拓扑结构中存在一个非常严重的脆弱性，如果Aspen或其任一链路出现故障，AS 400将与其他互联网络失去网络连接。如图3-7所示，为了提高冗余性，在Vail和 Telluride之间增加了一条链路，并通过该链路建立了第二条IBGP会话。

图3-7在Vail和Telluride之间增加了一条新链路和第二条IBGP会话，以实现冗余性

例3-38显示了路由器Vail和Telluride的配置情况。

例3-38:AS 100中的路由器Vail和Telluride的配置情况。

例3-39显示了Telluride的BGP表情况，所有学习自Vail的路由都指示了两个下一跳地址，表示两个IBGP连接。A>表示当前使用的路径，如果该链路出现故障，则可以使用另一条链路。

例3-39：通过Telluride的路由表可以看出，为来自Vail的路由都提供了备选路径。

尽管图3-7所示的网络配置提供了冗余性机制，但故障倒换却很慢。默认情况下，BGP保持激活间隔为60秒，保持时间为180秒（如例3-40所示），在BGP检测到IBGP连接出现故障并切换到其他链路之前，很有可能已经超出了180秒。利用命令timers bgp可以重置BGP保持激活间隔和保持时间，从而改善故障倒换时间。例如，timers bgp 3 9可以将保持激活间隔设置为3秒，将保持时间设置为9秒。

例3-40：默认的BGP保持激活时间为60秒，默认的保持时间为180秒。

图3-8显示了一种更好的提供冗余机制的方法，此时不再通过备选路径创建两个IBGP会话，而是在路由器的环回接口之间创建单个IBGP会话。OSPF的作用是为IBGP会话找出最佳路径，并且在链路出现故障时可以更快地重路由IBGP会话。

图3-8在路由器Vail和Telluride的环回接口之间创建单个IBGP会话

例3-41显示了图3-8下的路由器Vail和Telluride的配置情况。

例3-41：在路由器Vail和Telluride的环回接口之间配置单个IBGP会话。

除了创建环回地址这个非常明显的不同之外，这些配置之间的重要区别就是语句neighbor update-source，该命令让BGP消息被溯源至环回接口的IP地址，而不是消息被发出的物理接口的IP地址。如果没有该语句，那么TCP会话的TCP源将成为出站接口的地址，TCP会话的端点将无法匹配，而且也无法到达。另一个重要区别就是OSPF下的network语句，该语句的作用是宣告环回地址；如果没有该语句，该地址将不可达，而且也无法创建IBGP会话。例3-42显示了重新配置后的Telluride的BGP表。

例3-42：来自Vail的路由的下一跳地址是Vail的环回地址。

注意：虽然本小节的案例中，利用BGP-to-IGP重分发机制可以更好地解释基本的IBGP行为，但值得一提的是，此时将会从外部BGP对等体接收到大量路由，将BGP路由重分发到IGP中将是一件很危险的事情。在与图3-8相似的网络拓扑中，最安全的方法就是配置全网状的IBGP连接——即在AS 100中的全部3台路由器的环回接口之间建立IBGP会话。之后，Aspen就可以学习到直接从BGP转发来的数据包的必要信息，并且无需部署重分发机制。

3.1.6案例研究：EBGP多跳

如前所述，正如可以在路由器的环回接口之间建立IBGP会话一样，也可以在环回接口之间建立EBGP会话，图3-9就显示了这样的EBGP会话。此时，Telluride和Alta之间的EBGP会话端点是环回接口。

图3-9在Telluride和Alta的环回接口之间建立EBGP会话

例3-43显示了图3-9中路由器Telluride和Alta的初始配置。

例3-43：在路由器Telluride和Alta的环回接口之间建立EBGP会话的配置情况。

请注意，每台路由器都配置了静态路由，这些静态路由的目的是让每台路由器都知道如何发现其邻居的环回接口的地址，以便建立TCP会话。前一个案例研究中，在OSPF中配置network语句的作用与此一样。在本应用场景下，由于路由器之间没有运行IGP，因而需要使用静态路由。在检测和排除IBGP故障时，请务必记住，在建立IBGP会话、交换BGP路由之前，IBGP路由器必须知道如何发现它们的对等体，如果两个IBGP邻居未建立对等关系，那么首先需要做的就是检查这两台路由器是否知道如何到达对方。

不幸的是，邻居们并不能总是按照配置所示的那样建立对等关系。例3-44提供了该问题的线索，高亮显示的配置行表明邻居之间没有直连。环回接口的地址确实没有直连，这也是需要静态路由的原因，但BGP所指出的这个事实却非常重要。

例3-44:show ip bgp neighbors输出结果显示Telluride到Alta的EBGP连接未建立。

重要之处就在于，虽然可以通过多跳路由器创建IBGP连接，但在默认情况下，EBGP邻居必须是直连的。如图3-9所示，源自Alta环回接口的数据包必须被路由到串行接口，而对Telluride来说，数据包必须要从串行接口路由环回接口。换句话说，TCP包必须穿越环回接口之间的两跳路由。

启用命令neighbor ebgp-multihop之后，通过更改EBGP包的TTL默认值1，可以克服EBGP的一跳限制。例3-45解释了命令neighbor ebgp-multihop的使用情况，并将EBGP包的TTL更改为2。

例3-45：利用命令neighbor ebgp-multihop来克服Alta和Telluride之间的一跳EBGP限制。

例3-46给出了配置变更后的输出结果。可以看出，已经建立了EBGP会话，而且给出了新的跳数限制。

例3-46：命令show ip bgp neighbors显示已经与Alta建立了EBGP连接。

与IBGP通常在环回接口之间配置不同，大多数EBGP会话都是在直连接口上进行配置的，因而并不会经常使用ebgp-multihop。当两个外部邻居之间有多条冗余直连链路（如多条ATM或帧中继虚电路）时，在环回接口之间配置EBGP就非常有用。因为此时仅希望有一个EBGP会话，在EBGP所使用的链路出现故障后，EBGP会话还可以重路由到备用链路。

3.1.7案例研究：聚合路由

如图3-10所示，AS 100包含了8个C类地址，所有这些地址都可以被聚合为192.168.192.0/21。Stowe通过EIGRP学习内部网络路由，并通过EBGP向Sugarbush宣告聚合路由。

BGP下有两种聚合地址创建方式：第一种方式是在路由表中为聚合地址创建静态表项，之后再利用network命令宣告该聚合地址；第二种方式是使用命令aggregate-address。

1．利用静态路由进行聚合

例3-47示范了如何使用静态路由项为Stowe创建聚合地址，并使用命令network宣告该聚合地址。

图3-10 AS 100的所有内部网络都能被聚合为单一地址192.168.192.0/21

例3-47：在BGP下使用静态路由项及命令network创建聚合地址。

由于聚合地址本身并不是合法的终端目的地址，因而静态路由指向Null接口，该路由在Stowe路由表中仅代表一条精确路由。如果数据包的目的地址属于AS 100的C类地址，那么AS 100的外部路由器将匹配该聚合地址并转发给Stowe，到了路由器Stowe之后，数据包将被匹配到更精确的地址，并被转发到正确的内部下一跳路由器。如果因某种导致更精确的C类地址不在Stowe路由表中的话，将把该数据包转发到Null接口并予以丢弃。

例3-48显示了Stowe和Sugarbush的BGP表，Stowe的BGP表中只有这么一条聚合地址，路由器的BGP配置使得任何其他地址都没有进入BGP表。

例3-48:Stowe和Sugarbush都仅包含了一条聚合路由。

2．抑制精确路由

对图3-10所示的简单拓扑结构来说，前面所说的聚合地址创建方式已经足够了。但是，随着拓扑结构和路由策略复杂程度的提高，命令aggregate-address提供的配置选项会更有用，本案例研究的后半部分将主要介绍命令aggregate-address及其配置选项。

要想宣告由aggregate-address指定的聚合地址，必须通过重分发或network命令要求聚合地址中至少有一个更精确的地址进入BGP表。例3-49示范了如何利用aggregate-address和重分发机制配置Stowe。

例3-49：在BGP下利用命令aggregate-address创建聚合地址。

例3-50显示了Stowe和Sugarbush的BGP表情况，本例中Stowe的BGP表与例3-48中的有很大不同。此时，表中包含了全部精确路由，但Sugarbush的BGP表却仍然保持不变，仅被宣告了聚合地址。

例3-50:Stowe的BGP表中包含了全部精确路由，而Sugarbush仅被宣告了聚合地址。

Stowe BGP表中精确路由左侧的状态代码表示这些路由都被抑制了，原因在于应用命令aggregate-address时使用了summary-only选项。如果没有该选项，则将同时宣告聚合路由和这些精确路由。

3．宣告聚合路由和精确路由

对于像图3-10所示的简单拓扑结构来说，同时宣告聚合路由和精确路由没有任何意义，但这种情况对图3-11所示的应用场景却非常有用。此时，AS 100多归属到AS 200,AS 200需要从AS 100接收全部路由以设置路由策略，但AS 200仅能向AS 300发送聚合路由。

图3-11 AS 100多归属到AS 200

虽然宣告了AS 100的精确路由，但是在发送给AS 200时携带了值为NO_EXPORT的COMMUNITY属性。如第2章所述，携带该属性的路由不能发送给EBGP对等体，因而虽然AS 200知道这些路由，但不会宣告给AS 300，宣告给AS 300的只有那些未携带COMMUNITY NO_EXPORT属性的聚合路由。例3-51显示了Stowe的配置情况，Mammoth的配置与此类似（将在本小节后面内容中描述）。

例3-51：配置Stowe以同时宣告聚合路由和精确路由。

如上例所示，命令aggregate-address中删除了关键字summary-only，因而可以向AS 200同时宣告聚合路由和精确路由；命令neighbor 192.168.1.253 send-community指定将COMMUNITY属性发送给Sugarbush；命令neighbor 192.168.1.253 route-map COMMUNITYout通过名为COMMUNITY的路由映射过滤BGP出站路由。如果路由映射与访问列表101的更新相匹配，则不会设置COMMUNITY属性；如果路由与访问列表101不匹配，则该路由的COMMUNITY属性将被设置为NO_EXPORT。

读者可能会对access-list 101的用法感到陌生。通常情况下，扩展IP访问列表中指定的第一个IP地址是源地址，第二个地址是目的地址，而本案例中的第一个地址是路由前缀，第二个地址是前缀的掩码，使用这种访问列表的原因是必须精确指定前缀。如果使用了access-list 1 permit 192.168.192.0 0.0.7.255，那么将同时匹配聚合地址192.168.192.0/21和精确路由192.168.192.0/24。

例3-52给出了Sugarbush的BGP表，可以看出，表中包含了聚合路由和精确路由。此外，还使用了命令show ip bgp community no-export，以显示携带NO_EXPORT COMMUNITY属性的路由情况，列出了Stowe除聚合路由外的其他全部路由。

例3-52:Sugarbush的BGP表中包含了聚合路由和精确路由，除聚合路由外，Stowe的其他全部路由都携带了NO_EXPORT COMMUNITY属性。

（待续）

例3-53：显示了Burke的BGP表，除聚合路由之外没有宣告任何路由。

例3-53:Burke的BGP表中仅包含聚合路由。

Mammoth做出了与Stowe相同的路由宣告。出于示范目的，例3-54中采用了不同的配置方式来实现相同的目的，即对Mammoth使用了IP前缀列表（而不是访问列表）。

例3-54：图3-11中的Mammoth配置。

（待续）

与路由映射相似，前缀列表也是以名字而不是数字进行标识的。如例3-54所示，前缀列表的名字为AGGREGATE，列表中的每行都用一个序列号（seq）来标识该行在多行列表中的位置，以方便编辑。如果在录入前缀列表时没有输入序列号，Cisco IOS Software会自动按照顺序为当前录入的行加入一个序列号。在关键字permit|deny之后，需要指定一个前缀及前缀长度。

如例3-54所示，Mammoth配置中的前缀列表与192.168.192.0/21完全匹配。当然，也可以增加配置选项以匹配一段前缀，如命令ip prefix-list AGGREGATE seq 5 permit 192.168.192.0/21 ge 24将匹配所有前21bit与192.168.192.0相匹配，且长度大于等于24bit的前缀，该行将匹配AS 100中的所有精确路由。另一方面，关键字le用于匹配长度小于等于指定bit数的前缀。

Diamond的BGP表与Sugarbush非常相似，聚合路由和精确路由都在表中。除了来自Sugarbush的聚合路由之外，例3-53中Burke的BGP表显示了该聚合路由也被Diamond宣告了。例3-55详细列出了Diamond的聚合路由和其中的一条精确路由，可以看出，聚合路由未携带任何COMMUNITY属性（尽管聚合路由有ATOMIC_AGGREGATE和AGGREGATOR属性集），而精确路由则携带了COMMUNITY属性。

例3-55：详细分析Diamond BGP表中的两条路由的属性情况。

（待续）

4。宣告聚合路由和选定的精确路由

在前面的应用场景中，向AS 200发送了AS 100的精确路由，从而让AS 200能实施其路由策略。也就是说，AS 200可以利用这些路由对发往AS 100的流量设置路由优先级，AS 100通过控制其出站宣告也可以影响其入站流量。例如，通过Stowe/Sugarbush链路而不是Mammonth/Diamond链路进行路由宣告可以让入站流量使用Stowe/Sugarbush链路，在AS具有多样化的地理分布特征时，管理员可能就希望实施这样的路由策略。例如，Stowe可能位于佛蒙特，而Mammoth则位于加利福利亚，此时，管理员可能希望入站流量使用最靠近目的地的入口点，从而最大程度地减少内部路由选择操作。

为了完成上述目的，下面列出了需要在图3-11中的AS 100上应用的路由策略。

•通过Stowe/Sugarbush链路宣告192.168.192.0/24、192.168.193.0/24和192.168.194.0/24。

•通过Mammonth/Diamond链路宣告192.168.196.0/24、92.168.197.0/24和192.168.198.0/24。

•不宣告192.168.195.0/24和192.168.199.0/24。

•通过上述两条链路宣告聚合路由以做备用，在任一条链路出现故障的情况下，所有的入站流量都可以被路由到另一条链路。

为了抑制聚合路由的子网，需要在aggregate-address命令中使用选项suppress-map,例3-56给出了上述路由策略在Stowe和Mammoth上的配置情况。由于COMMUNITY路由映射及EIGRP的配置与前面一小节完全一致，因而本例不再重复列出。

例3-56：在aggregate-address命令中使用选项suppress-map抑制选定的前缀。

（待续）

Stowe的配置中使用了一个名为VERMONT的路由映射，用于确定要抑制的路由，而路由映射又反过来使用了access-list 1来标识适当的路由。该访问列表允许前缀192.168.195.0/24及所有前22bit与192.168.196.0/22相匹配的前缀，其他所有前缀则与访问列表最后隐含的”拒绝所有”相匹配，因而没有被抑制。

注意：理解路由映射的逻辑有时很痛苦，在上面的这个案例中，被访问列表所拒绝的路由是“拒绝以免被抑制”，也就是说，允许宣告该路由。相反，那些被访问列表所允许的路由则是“允许以便被抑制”，也就是说，不允许宣告这些路由。

Mammoth的配置中使用了一个名为CALIFORNIA的路由映射，用于确定要抑制的路由。Mammoth使用前缀列表（而不是访问列表）来标识适当的路由。前缀列表中的序列5允许所有前22bit与192.168.192.0/22相匹配，且长度小于等于24的前缀，序列10则允许前缀192.168.199.0/24。带有这些前缀的路由宣告都将被抑制，而其他被前缀列表隐式拒绝的路由则不受抑制。

例3-57显示了Sugarbush和Diamond的BGP表情况。例如，Sugarbush将去往192.168.193.0/24的数据包转发给了Stowe(192.168.1.254），而将去往192.168.196.0/24的数据包转发给了Diamond(192.168.1.237）；Diamond反过来又将去往192.168.196.0/24的数据包路由给了Mammoth(192.168.1.245)。Stowe和Mammoth都在宣告聚合路由，当某条链路出现故障时，正常情况下通过该链路转发的数据包将通过另一条链路来匹配聚合路由。

例3-57:BGP表显示Stowe和Mammoth都宣告了AS 100中精确路由的不同子网，但同时宣告了聚合路由。

（待续）

5．更改聚合路由的属性

命令aggregate-address的另一个可用选项是attribute-map,该选项可以更改聚合路由的属性。如例3-57所示，由于精确路由都是从EIGRP重分发到BGP中的，因而这些精确路由都携带值为Incomplete（不完全的）的ORIGIN属性。但是，由于聚合路由都源自Stowe和Mammoth的BGP进程，因而这些聚合路由的源都是IGP。假设管理员希望AS 200通过Mammoth/Diamond链路沿着聚合路由来传递全部流量，而将Stowe/Sugarbush链路作为备用链路。如第2章所述，对去往同一目的地的两条路由来说，BGP决策进程将优选ORIGIN为IGP的路由，次选ORIGIN为Incomplete（不完全的）的路由。如果Stowe将其聚合路由的ORIGIN更改为Incomplete（不完全的），那么AS 200中的路由器将优选Mammoth/Diamond链路。例3-58给出了此时的Stowe配置情况。

例3-58:Stowe将其聚合路由的ORIGIN更改为Incomplete（不完全的）。

例3-59显示了Sugarbush的BGP表情况。在重新配置之前，Sugarbush优选学习自EBGP的聚合路由，次选学习自IBGP的聚合路由（参见例3-57）。但是由于在BGP决策进程中，ORIGIN属性的优先级要高于IBGP/EBGP，因而选择了来自Diamond、ORIGIN为IGP的IBGP路由。

有趣的是，重新配置Sugarbush后还会影响AS 300中的路由选择。如例3-60所示，Sugarbush的优选路由是IBGP路由，由于启用了同步机制，因而不会将该IBGP路由宣告给EBGP对等体Burke，这样一来，Burke仅能学习到来自Diamond的聚合路由。

例3-59：由Stowe(192.168.1.254）宣告的聚合路由的ORIGIN为Incomplete（不完全的），由Diamond宣告且源自Mammoth的聚合路由是优选路由。

例3-60：只有Diamond将聚合路由宣告给Burke。

6。为聚合路由使用AS_SET

图3-12中的互联网络是对图3-11进行修改后的版本，同时还修改了聚合地址的源。AS 100和AS 200都将AS 100的全部路由宣告给了AS 300和AS 400，没有做任何聚合。

图3-12 Burke创建了一个聚合路由并宣告给了Sun

AS 300中的路由器Burke抑制了AS 100的精确路由并将聚合路由发送给AS 400中的Sun。例3-61中的Burke配置与本案例研究中已经看到过的配置非常相似。

例3-61:Burke被配置成抑制AS 100的精确路由并向AS 400中的Sun发送聚合路由。

例3-61中Burke的配置与先前看到的配置之间的一个不同之处就是命令neighbor distribute list的使用。该命令实现了一个路由过滤器，且操作方式与《TCP/IP路由技术（第一卷）》中讨论的命令distribute-list一致。本例中的路由过滤器是为了防止将聚合路由重新宣告回Sugarbush。

例3-62显示了Sun的BGP表情况。正如所预料的那样，Sun的BGP表中包含了来自Sugarbush的精确路由以及来自Burke的聚合路由。对本案例研究来说，需要关注的是与聚合路由相关的AS_PATH属性。聚合路由的AS_PATH属性的AS_SEQUENCE以发起该聚合路由的AS为起始，由于该聚合路由是由Burke发起的，因而AS_SEQUENCE中仅包含AS 300，但该聚合路由实际指向的却是AS 100。与所有路由汇总一样，路由聚合会丢失大量的路由选择信息。

例3-62：来自Burke的聚合路由的AS_PATH中仅包含AS 300（即发起该聚合路由的AS)。

如例3-63所示，Burke在聚合路由中设置了ATOMIC_AGGREGATE和AGGREGATOR属性，以指示出现了信息丢失。

例3-63：Burke在聚合路由中设置了ATOMIC_AGGREGATE和AGGREGATOR（由AS300 192.168.1.250聚合）属性，以指示出现了信息丢失。

在图3-12所示的拓扑结构中，路径信息的丢失会出现一个问题。与Burke不同，Sun并没有路由过滤器来防止将聚合路由宣告给Sugarbush, Sugarbush在接收到来自Sun的聚合路由后，由于发现自己的AS号没在AS_PATH中，因而将该聚合路由加入自己的BGP表中（如例3-64所示）。

例3-64：由于Sugarbush未发现自己的AS号位于AS_PATH中，因而接受来自Sun的聚合路由。

如果来自AS 100的某条精确路由失效，则Sugarbush将会丢弃所有去往那个网络的数据包。但是如果有聚合路由，那么这些数据包将会被匹配到该聚合路由上。例如，假设去往AS 100中192.168.197.0/24网络的接口出现故障，那么Stowe将宣告该情况，导致所有BGP表都将删除去往该目的地的路由；接着，Sugarbush收到一个目的地址为192.168.197.5的数据包，由于没有找到精确路由，因而将该目的地匹配到聚合路由并将数据包转发给Sun；同样，Sun也没有找到精确路由，因而又将该目的地匹配到聚合路由并将数据包转发给Burke；由于Burke是该聚合路由的发起者，也没有精确地址，因而丢弃该数据包。这样一来，发往无效目的地的数据包在被正确丢弃前仍然要无谓地经过两跳额外的路由器进行转发。如果Sugarbush将聚合路由宣告给了Burke，那么问题将更加严重，此时不再是数据包被延迟丢弃，而是将出现路由环回，直至TTL到期。

为了解决这个问题，Burke除了可以将AS_SEQUENCE作为AS_PATH属性的一部分，还可以在aggregate-address语句中增加关键字as-set来宣告AS_SET。如第2章所述，AS_SET是一个去往精确地址（组成聚合路由）路径上的无序的AS号列表，与AS_SEQUENCE不同，AS_SET不用于确定最短路径，其作用仅仅是恢复聚合路由中丢失的环路检测功能。

例3-65给出了Burke宣告AS_SET的配置情况。

例3-65：配置Burke以宣告AS_SET。

例3-66给出了Sun的BGP表情况，去往精确地址路径上的所有AS号都包含在聚合地址中的AS_PATH中。这样一来，当聚合路由被宣告给Sugarbush时，Sugarbush就可以发现其AS号200位于AS_PATH中，因而会拒绝接受该路由。

例3-66：路由器Burke在AS_PATH属性中包含AS_SET后，去往精确地址路径上的所有AS号都将包含在聚合地址中。

在宣告AS_SET时非常重要的一点是，聚合路由将继承所有被聚合路由的属性。如图3-12所示，所有精确路由的AS_PATH是（300,200,100），因而AS_SET是以一个有序列表的方式出现在Sun的BGP表中，与AS_SEQUENCE没有任何区别。

图3-13给出了一个不同的拓扑结构，图中增加了一个新的AS，网络192.168.197.0/24从AS 100迁移到了AS 500。虽然Burke仍然能接受到同样的路由，但现在并不能匹配所有的AS_PATH属性，因而此时的AS_SET将被宣告为一个无序列表（如例3-67所示）。

图3-13网络192.168.197.0/24从AS 100迁移到了AS 500，此时Burke无法再将AS_SET表示为一个有序列表

例3-67：与AS_SEQUENC的有序形式不同，此时的AS_SET以一个无序列表的形式出现在Sun的BGP表中。

（待续）

7．基于选定的精确路由构建聚合路由

在宣告带有AS_SET的聚合路由时，有时可能希望聚合路由不要继承所有被聚合路由的属性。如图3-14所示，Sugarbush收到了所有来自AS 100和AS 500的路由，并向Burke宣告了一条聚合路由。

图3-14 Sugarbush在宣告携带AS_SET属性的聚合路由时，要求聚合路由不继承192.168.197.0/24的NO_EXPORT COMMUNITY属性

在配置图3-14时出现的一个问题是，AS 500在宣告192.168.197.0/24时携带了NO_EXPORT COMMUNITY属性，Sugarbush使用了AS_SET选项后，聚合路由将继承NO_EXPORT属性（如例3-68所示）。请注意，此处的NO_EXPORT属性仅仅在本地传递给了聚合路由，并没有被加入到聚合路由的宣告中。因而Sugarbush将接受该属性，不向外宣告该属性。

例3-68：命令show ip bgp community no-export显示了所有携带NO_EXPORT COMMUNITY属性的路由，此时聚合路由继承了被聚合地址中192.168.197.0/24的属性。

命令aggregate-address的最后一个选项是advertise-map,用于选择聚合路由所基于的精确路由。如图3-14所示，如果Sugarbush在构建聚合路由时不考虑192.168.197.0/24，那么聚合路由将不继承该路由的相关属性，例3-69显示了Sugarbush在命令aggregate-address中使用advertise-map选项的配置情况。

例3-69：配置Sugarbush以选择聚合路由所基于的精确路由。

例3-69中的选项advertise-map指向了一个名为ALLOW_ROUTE的路由映射（标识了聚合路由所基于的精确路由），而该路由映射又反过来指向access-list 1（拒绝192.168.197.0/24且允许其他所有路由）。由于Sugarbush在构建聚合路由时忽略了192.168.197.0/24，因而形成的聚合路由不会继承192.168.197.0/24的NO_EXPORT属性（如例3-70所示）。

例3-70：利用advertise-map选项重新配置Sugarbush之后，聚合路由不再包含NO_EXPORT属性。

在限制聚合路由所基于的精确地址前缀时可能会存在一些问题。在图3-14所示的互联网络及其相关配置中，假设Stowe与Sugarbush间的链路出现故障，如果聚合路由仅基于来自AS 100的前缀，那么就无法再对外进行宣告，因而从AS 300及以外将无法到达AS 500中的目的地。

3.2管理BGP连接

Cisco IOS提供了一系列功能特性，以帮助管理BGP对等体连接。第一个功能特性就是neighbor description语句，与description语句可以在接口配置模式下进入类似，neighbor description语句也不会对路由器造成功能上的影响，而且还为配置文件增加了一个描述性的文本字符串。前面已经遇到了很多应用于BGP邻居的配置选项，在本章后面的内容中还将遇到很多其他选项。当BGP的配置变得越来越复杂时，neighbor description语句可以帮助提示每个对等体是谁、在何处。例3-71演示了neighbor description语句的使用方法。

描述性语句可以包含任何希望加入的有用信息，最多80个字符。该例中包含了链路类型、邻居路由器的名字以及用于何处和电路ID。

例3-71:neighbor description语句可以减轻复杂的BGP配置所带来的混淆程度。

利用neighbor password语句，两个BGP对等体之间还可以使用密码进行相互验证，在例3-72所示配置中，为邻居192.168.1.253输入了密码noT4U2n0。

例3-72：BGP的邻居验证。

请注意，在路由器的全局配置中加入了service password-encryption选项，这样在显示配置文件时会对密码进行加密，从而提高了私密性。

不同BGP邻居连接之间的密码既可以不一样，也可以完全一样。通过指定一个对等体组名（而不是一个IP地址），可以为一个对等体组设置一个通用密码，而不用为每个邻居单独设置密码。但是对每条BGP连接来说，两个邻居的密码必须一致。

在配置BGP邻居密码时，IOS使用了MD5验证机制。MD5是一种由RSA Data Security公司开发的单向报文摘要（message digest）或安全哈希（secure hash）函数，由于其工作方式有些类似于算术校验和，因而有时也被称为密码校验和（cryptographic checksum)。MD5对任意长度的明文报文（此处就是BGP消息）和密码计算出一个128位的哈希值，该“指纹”信息会与报文一同被传送，知道密码的接收方也会计算其自己的哈希值；如果报文未发生变化，接收方的哈希值应该与发送方随同报文传送的哈希值完全一致。如果不知道密码将无法解密（除非拥有非常强大的计算能力），因而未经验证的路由器（可能是恶意的也可能是无意的）无法与运行了邻居验证机制的路由器建立对等关系。

可用于邻居连接的其他选项是命令neighbor advertisement-interval和neighbor version。其中，第一个命令用于将默认的BGP更新间隔更改到指定间隔（0～600秒之间），如果需要通过某条链路交换大量路由，利用该命令可以增大宣告间隔，从而降低对该链路可用带宽的影响。除非能真正了解了这样做的后果，否则不应更改宣告间隔，以免降低重收敛时间。

在BGP邻居不支持默认的BGP-4时，命令neighbor version非常有用。比起通过协商让版本4的路由器向下兼容邻居所支持的版本，更好的做法是配置路由器与特定邻居运行特定版本。如果邻居双方都支持版本4，那么该命令将毫无用处，也无需使用该命令。

在多个去往同一目的地的路由中进行选择时，Cisco IOS实现的BGP决策进程已经考虑了AS_PATH属性的长度。但RFC 1771并不包含本步骤，因而Cisco的BGP发言者偶尔也会与不考虑AS_PATH长度的其他厂商路由器建立对等关系，这样就存在潜在的路由决策不兼容性。此时，可以用命令bgp bestpath as-path ignore让Cisco路由器在其决策进程中忽略AS_PATH的长度。

在某些路由策略场合中，可能希望限制某路由器能够从其邻居所接受的前缀数量。例如，从某特定AS只能向外宣告一定量的前缀，当前缀数量超过该数量时都可能会被该自治系统的管理员指示为错误。也可以签订某服务协议，仅同意接收一定数量的前缀，为了宣告更多的前缀，邻居AS的管理员必须首先得到许可。为了增强这样的路由策略，需要使用命令neighbor maximum-prefix。下面来看一下例3-73。

例3-73：限制路由器能从邻居处接收的前缀数量。

例3-73中的路由器被配置为最大能从192.168.1.253接受300个前缀，如果超出了这个数量，路由器就会关闭与该邻居的BGP连接，在应用命令clear ip bgp 192.168.1.253之前，都不会再次建立BGP会话。

在前缀数量超限时断开对等会话的做法可能会产生比较严重的后果，但同时又希望在事情发生时能得到通告。例3-74就没有关闭会话，而是让路由器生成一个日志消息。

例3-74：当邻居发送的前缀数量超限时让路由器生成一条日志消息。

当邻居宣告的前缀数超过最大值的75%（本例中为225个前缀）时，就会生产一条日志消息。当然也可以更改默认比例，例3-75就示范了如何让路由器在超过最大值的90%时生成日志消息。

例3-75：当邻居发送的前缀数量超过最大允许值的90%时，路由器将生成一条日志消息。

有时可能需要临时断开与某个对等体的连接，但又不想删除其邻居配置。如例3-76所示，此时就可以利用命令neighbor shutdown来断开与邻居192.168.1.237的连接。

例3-76：临时中断邻居连接。

与命令shutdown关闭单个接口类似，例3-76中的命令neighbor shutdown可以关闭到指定邻居的TCP端口179的连接。利用命令show ip bgp neighbor可以看出，该邻居被指示为出于管理目的而被关闭。

最后，可以利用命令timers bgp来更改默认的BGP Keepalive（保持激活）时间间隔（默认60秒）和保持时间间隔（默认180秒），一种可能争论的是通过减小这些时间间隔来加速邻居不可达性的检测速度，但实际上，对这个问题的解决方案是消除邻居不可达性的原因。利用命令timers bgp来更改默认的时间间隔时，是应用于每个邻居，而不是单个邻居。即便某邻居的默认Keepalive（保持激活）时间间隔和保持时间间隔有所不同，所要使用的时间间隔也要作为对等进程的一部分进行动态协商。因而在正常情况下，几乎没有任何理由来使用本命令。

3.3路由策略

Webster（韦伯斯特）大字典将策略（policy）一词定义为“涵盖了总体目标和可接受措施的高级的、全面的规划”。路由策略（routing policy）就是一种定义了路由器如何接受、如何宣告路由的规划。路由策略所涵盖的目标就是正确地转发或抑制IP包。可接受的措施意味着要以对路由器的CPU和内存资源影响最小、对所连接链路的带宽资源影响最小以及对邻居路由器的策略影响最小的方式来实施路由策略。

注意：请不要将本节及本章所用的术语路由策略（routing policy）与Cisco提供的策略路由（Policy Routes）功能相混淆。有关这些特殊静态路由（通过命令ip policy route-map来实现）的讨论请参见第14章。

路由策略非常重要，尤其在BGP环境中更是如此。从本质上来看，BGP用于互联自治系统，邻居自治系统可能并不受你的管理控制，这就需要非常细致地规划BGP路由策略，必须完全了解应该将哪些数据包转发给邻居、应该从邻居接受哪些数据包以及在什么情况下转发和接收这些数据包。制定了完整的路由规划之后，就需要设计完成这些路由策略的配置脚本，此时就需要彻底理解BGP的各种可用配置选项。实践证明，实验室在这个阶段非常有用，可以在将实施方案应用于生产性网络之前进行设计方案的测试并验证各种假设条件。只有在完全设计、理解和验证了配置方案之后，才能将其付诸于实施。

上述步骤中的任一个差错都会对互联网络产生非常严重的后果，引来用户、客户、服务提供商及管理层的不满。由于可能会破坏流量在Internet某些重要部分的转发，因而许多服务提供商都会停止与经常出现策略配置错误的客户建立BGP对等关系。被拒绝建立BGP对等关系所带来的经济影响将会非常严重（当客户本身也是一个服务提供商时尤其如此）。没有任何一种IP路由策略能提供与BGP相媲美的策略能力，但同时，也没有任何一种协议会带来像BGP一样严重的潜在后果。

本节将讨论各种可用的BGP路由策略配置选项，读者已经了解了一些用于配置路由策略的基础工具。如果学习过《TCP/IP路由技术（第一卷）》中此处的内容，那么就已经知道了如何配置IP路由协议以宣告选定的路由以及如何将路由从一个协议重分发到另一个协议，知道如何使用路由过滤器和路由映射，如何处理不同IP路由协议的管理性距离和度量值，知道了有多条路径进出一个区域、一个路由域或一个AS时的潜在危险，以及如何避免这些潜在危险的一些基本策略。本节将会给出一些BGP特有工具的应用案例，如处理ORIGIN和 COMMUNITY属性以及过滤来自单个邻居的NLRI。

最后，出站路由宣告会影响入站流量，入站路由宣告会影响出站流量。因而在设计路由策略时，非常重要的一点是必须分别考虑要宣告的路由和要接收的路由，分别设计入站路由策略和出站路由策略。

3.3.1重置BGP连接

当BGP发言者的配置发生变更后，通常都需要重置受影响的BGP连接，以便让配置变更生效。Cisco IOS Software Command Summary（软件命令汇总）列出了以下必须重置BGP连接的几种情况。

•增加或更改BGP相关的访问列表；

•更改BGP相关的权值；

•更改BGP相关的分发列表；

• BGP相关的定时器规约发生变化；

•更改BGP的管理性距离；

•更改BGP相关的路由映射。

上面列出的所有内容都会在一定程度上影响路由器的BGP路由策略，这也是需要重置BGP连接的缘由。无论是谁都不会希望自己所做的路由策略变更操作成为“空中楼阁”，不起作用。与其如此，还不如完全配置一个新的路由策略并实施该策略。但需要注意的是，如果允许每输入一条路由策略语句就即刻起作用的话，将会产生路由环路、黑洞路由或其他不期望的结果。

在Cisco IOS的Exec模式下，通过命令clear ip bgp可以重置BGP连接，可以将重置操作应用于指定邻居、对等体组或所有路由器邻居。如果要重置到某个指定邻居的BGP连接，必须要指定该邻居的IP地址。例如，如果要重置邻居192.168.1.253的BGP连接，那么就需要使用命令clear ip bgp 192.168.1.253；如果要重置名为subscribers的对等体组的全部成员的连接，那么就需要使用命令clear ip bgp subscribers；如果要重置某路由器的全部BGP连接，则可以使用命令clear ip bgp*。

在实际应用中，应该仅重置那些确实因配置变更而受影响的BGP连接。在重置连接时，会向其邻居发送一条Cease（终止）消息，以关闭BGP会话和TCP连接，使全部缓存均失效，之后再开始建立一个新的BGP连接。该进程启动后将会中断去往或来自该BGP连接的所有服务。在新配置仅影响一条或两条BGP的情况下，如果重置全部连接，将会给生成性网络带来非常严重的后果。

Cisco提供了一种软重配置（soft reconfiguration）机制，用于替代全部重置机制，软重配置机制不再拆除并重新建立TCP和BGP连接，而是仅触发更新操作以便让新的路由策略生效。软重置操作可以仅应用于出站策略或仅应用于入站策略，也可以同时应用于出站和入站策略；在变更后的策略仅影响出站流量时就可以使用出站软重配置，在变更后的策略仅影响入站流量时就可以使用入站软重配置。与“硬”重置相似，在软重置中也可以指定单个邻居、对等体组或全部BGP连接。

例如，假设在某台BGP路由器上更改了影响去往邻居192.168.1.253的流量的策略，为了触发应用于该邻居的新策略，应使用命令clear ip bgp 192.168.1.253 soft out。

当变更后的策略仅影响入站流量时可以使用入站软重配置。从Cisco IOS Software Release 12.1开始，全面支持入站路由的动态软重配置。但是在这之前的版本，在使用入站软重配置之前，必须首先在BGP配置中加入neighbor soft-reconfiguration inbound语句，之后再为每

个受到新入站策略影响的邻居应用clear ip bgp soft in命令。假设在图3-14的路由器Stowe上更改了入站路由策略，且该策略影响接收自邻居192.168.1.253的流量，那么就需要按照例3-77进行Stowe的BGP配置。

例3-77：配置某邻居进行软重配置。

加入neighbor soft-reconfiguration inbound语句之后，路由器开始存储来自指定邻居的更新消息，这些更新不会受到现有入站策略的任何修改，以便让路由器能在触发软重配置之后正确应用这些新的入站路由策略。在按照例3-77为Stowe配置了新的入站路由策略之后，就可以在Exec模式下输入clear ip bgp 192.168.1.253 soft in命令，之后路由器就可以使用已存储的、未被修改的更新消息来实施新的入站路由策略。

也可以同时为入站策略和出站策略触发软重配置。例如，不带关键字in或out的命令clear ip bgp 192.168.1.253 soft将向邻居192.168.1.253发送更新消息，并将入站策略应用于已存储的、来自于邻居的更新消息。

使用入站软重配置的一个明显缺点就是需要一定的内存来存储更新消息。如果邻居宣告了大量路由，或者要存储大量邻居发送来的更新消息，那么对本地路由器的内存消耗将非常大。因而需要采取一定的措施来避免这种内存负荷，当路由器的入站BGP路由策略发生变化后，其邻居将发送出站软重配置，正在从其邻居接收更新的本地路由器将应用新的入站路由策略。只有在无法从受影响的邻居发送出站软重配置或安排好已经发送了出站软重配置时，才应该使用入站软重配置。当路由策略发生变化后会影响很多邻居的流量，当必须将策略变更同时应用于所有邻居时，就需要使用入站软重配置。无论是哪种情况，都必须仔细权衡路由策略对本地路由器内存造成的影响。

3.3.2案例研究：通过NLRI过滤路由

路由过滤几乎是所有路由策略的核心，对入站和出站路由策略来说，最可能的就是要定义路由器应接受哪些路由和应宣告哪些路由。

BGP可用的第一个也是最简单的路由过滤器就是由distribute-list命令定义的路由过滤器。该路由过滤器是针对每个邻居或对等体组所定义的，并指向一个定义了前缀（路由过滤器将要作用的前缀）或NLRI的访问列表。

图3-15所示互联网络就是用来说明这个问题的，并给出了两个案例研究。

AS 50的IGP是RIP, AS 30的IGP是集成式IS-IS, AS 100和AS 200是转接AS，例3-78给出了图3-15中5台路由器的初始配置。

图3-15 AS 30多归属到不同的转接自治系统

例3-78：通过NLRI过滤路由——初始路由器配置。

请注意，图3-15中显示的所有数据链路都没有IP地址。由于所有的BGP会话都是在路由器ID（由路由器的环回接口定义）之间定义的，因而数据链路地址与本例无关。这些配置中的一个重点就是静态路由，将通过这些静态路由告诉路由器如何发现其邻居的路由器ID，如果没有静态路由，将无法建立BGP会话。

注意：为了更清楚地示范路由策略的应用情况，本案例研究以及后续的几个案例研究都使用了IGP和BGP间的互重分发。此外需要注意的是，互重分发通常是一种不好的操作方式，尤其是当包含了很多前缀时，将BGP重分发到IGP中永远是不好的。

图3-15中的AS 30出于冗余性目的进行了多归属，但不应该成为转接AS，也就是说，AS 100和AS 200间的流量不应该通过AS 30进行传递。例3-79中Innsbruck的BGP表显示该路由策略并没有生效，Innsbruck显示去往AS 50中的目的地的某个下一跳路由器是Zermatt(172.30.255.254）。原因是Meribel将这些地址同时宣告给了Cervinia和Innsbruck, Cervinia将这些地址宣告给了Moritz，由Moritz将这些重分发到IS-IS中，之后Zermatt就从其AS 30中的IS-IS邻居学习到这些地址，并将这些地址重分发到BGP中，最后又宣告给Innsbruck。

例3-79:Innsbruck显示Zermatt是去往AS 50中目的地的一个可行下一跳。

如果Innsbruck失去了与NAP的连接，那么将会把去往AS 50的数据包转发给Zermatt，使得AS 30成为转接AS。为了防止这种情形的发生，需要在Zermatt和Moritz上实施出站路由策略，仅允许宣告AS 30的内部地址。例3-80显示了Zermatt的BGP配置情况。

例3-80：在Zermatt上实施出站路由策略，仅允许宣告AS 30的内部地址。

上面仅显示了与本例相关的部分Zermatt配置数据。

除了所引用的邻居不同之外，Moritz的distribute-list配置与此完全一致。对这两台路由器来说，access-list 1都是允许所有内部路由，拒绝所有其他路由。

例3-79中的另一个问题是，Innsbruck列出的去往AS 50中目的地的下一跳不但有Meribel(10.50.250.1），也有Cervinia(10.200.60.1），这样一来Cervinia的BGP表中就存在了两个同样的表项，显示Meribel和Innsbruck是AS 50中地址的下一跳路由器。出现这个问题的原因是Innsbruck和Cervinia不但与Meribel建立了对等关系，而且它们之间也建立了对等关系。

这个问题并不会导致任何路由紊乱——因为Meribel撤销了一条路由之后，该撤销路由也将会在Innsbruck和Cervinia之间进行宣告。这个问题更多的是一个完美性与清晰性问题，无效路由根本就不应该存在于BGP表中。

为了解决这个问题，例3-81给出了Innsbruck的BGP配置情况。

例3-81：消除Innsbruck BGP配置中的冗余下一跳路由器。

Cervinia有一个与Innsbruck完全相同的路由过滤器，该过滤器阻塞了AS 50的地址在Innsbruck和Cervinia之间的BGP连接上进行宣告。本配置中的一个关注点就是访问列表的第3行，图3-15 显示子网172.29.2.0/24位于AS 50中，但访问列表却要过滤172.29.0.0。这是因为RIP（有类别协议）没有在Meribel上将该子网重分发到BGP中，而是将其汇总为一个主网地址。子网172.29.1.0/24位于AS 30中，而IS-IS是无类别协议，因而在Zermatt和Moritz上将该子网重分发到BGP中。由于访问列表中的第3行必须精确匹配到主网地址，因而Innsbruck的访问列表并没有起作用。

最后，例3-79显示AS 30中的某些地址（如192.168.100.0）正从Meribel被宣告给Innsbruck。这个问题与前一个问题类似，Cervinia将路由宣告给Meribel, Meribel又将这些路由宣告给了Innsbruck。例3-82显示的Innsbruck配置阻塞了来自Meribel的全部入站路由（AS 50的内部路由除外）。

例3-82：配置Innsbruck以阻塞来自Meribel的全部入站路由（AS 50的内部路由除外）。

例3-83显示了Innsbruck的BGP表情况。与例3-79中的BGP表相比较，可以欣喜地发现，BGP表已经变小了，也变得更有意义。

例3-83：增加了路由过滤器之后的Innsbruck的BGP表。

（待续）

3.3.3案例研究：通过AS_PATH过滤路由

在面对大量被宣告地址时，通过NLRI过滤将会显得非常笨拙或完全不适用。图3-15仅宣告了很少的地址，但前面的访问列表就已经显得有些冗长了。

前一小节的各个例子都有一个共同特点，那就是使用访问列表来标识单个AS中的全部地址。在这种情况下，与在访问列表中穷举每个内部地址相比，采取按AS号进行过滤的方式将更加简单。命令ip as-path access-list可以定义多种标识AS号的访问列表。命令neighbor distribute-list调用的是标识NLRI的访问列表，而命令neighbor filter-list调用的是AS_PATH访问列表。

AS_PATH访问列表使用了一种功能强大的被称为正则表达式（regular expressions或简写为regex）的文本解析工具。正则表达式通常用于Perl、Expect、awk、Tcl等编程语言以及搜索引擎和UNIX应用程序（如egrep）中，使用字符串（既可以是元字符，也可以是直接量）在文本中寻找匹配项。当应用于AS_PATH访问列表中时，正则表达式用于在BGP更新消息中的AS_PATH属性中寻找匹配项。

直接量（litera1）是用来描述匹配什么内容的正则字符，而元字符（metacharacter）则用于描述如何进行匹配。例如，regex^[4-7]表示匹配任何以数字4～7开头的文本串，在这个表达式中，4和7是直接量，元字符是^、[]和-。其中，插入记号（^）是一行的起始标志—— “字符串将以以下字符开始”；方括号（[]）表示一组被称为字符类别（character class）的字符——“任何位于方括号中的字符”；连字符（-）表示区间——“位于第一个直接量和最后一个直接量之间的任何连续值”。表3-1汇总了最常见的元字符。附录B中给出了一个简短的正则表达式使用方法教程，如果对正则表达式不熟悉，建议在继续学习本章内容之前先阅读附录B的相关内容。

其他元字符（以及表3-1所列的部分元字符）匹配的内容要多于它所指示的内容。为了简化起见，表3-1仅列出了与AS_PATH访问列表相关的元字符及其匹配内容。

表3-1与AS_PATH访问列表相关的正则表达式中的元字符

在前一小节中，路由器Zermatt和Moritz被配置为仅宣告去往AS 30内部地址的路由，其他路由均被过滤，以防止AS 100或AS 200试图将AS 30用作转接AS。为了实现该过滤器，需要在访问列表中分别列出AS 30中的全部地址。例3-84•给出的Zermatt配置中，利用了AS_PATH访问列表来实现前一小节案例研究中的相同目的。

例3-84：利用AS_PATH访问列表配置Zermatt，让其仅宣告去往AS 30内部地址的路由。

Moritz的配置文件中有一个完全相同的AS_PATH访问列表，此处的正则表达式使用了两个元字符——第一个元字符匹配行起始，第二个元字符匹配行结束。表达式中没有包含直接量。该正则表达式用于匹配不包含AS号的AS_PATH。如例3-85所示，Zermatt的BGP表中AS_PATH为空的路由就是目的地在AS 30内的路由，这些路由与AS_PATH列表语句相匹配，因而被允许。与其他访问列表相似，AS_PATH访问列表在最后也有隐含的”拒绝全部”之意，例3-85中的其他路由都与该隐式拒绝条件相匹配，因而不向外宣告。

例3-85：Zermatt的BGP表中AS_PATH为空的路由就是目的地在AS 30内的路由。

在前面的案例研究中，路由器Innsbruck和Cervinia在接收来自Meribel的路由时，仅接收被宣告地址位于AS 50内部的路由，此外，这两台路由器不应该相互宣告学习自Meribel的路由。例3-86给出了利用AS_PATH访问列表来实现同样目的的Innsbruck的配置情况。

例3-86：利用AS_PATH访问列表将Innsbruck配置成仅从Meribel接收被宣告地址位于AS 50内部的路由。

（待续）

access-list 1被应用于发送给Cervinia的出站更新消息。该访问列表的第一个语句拒绝AS_PATH中带有AS号50的所有更新消息，50前后的元字符确保仅匹配50，如果遗漏了元字符，那么该语句将不但匹配50，还会匹配500、5000、350等数字。正则表达式的第二个语句说明“匹配所有字符，匹配0或多个字符实例”，也就是说，匹配所有内容。这个正则表达式是“允许全部”版本的AS_PATH访问列表，这两行的意思是要求Innsbruck不向Cervinia宣告任何学习自Meribel的路由，但向其宣告其他路由。

access-list 2被应用于来自于Meribel的入站更新消息，该访问列表的第一个语句表示”匹配行起始，然后是50，最后是行结束”，换句话说，匹配那些只有AS号50的AS_PATH，这些路由都是被允许的。对Meribel所宣告的学习自其他AS的路由来说，它们的AS_PATH中不仅仅包含50，因而这些路由被该访问列表最后的隐式“拒绝”所拒绝。

对图3-15所示的拓扑结构来说，Cervinia的AS_PATH访问列表与Innsbruck相同。但是图3-16的拓扑结构做了一些修改，增加了AS 125，并充当AS 200和AS 50间的转接AS，如果Meribel与NAP间的连接出现故障，那么进／出AS 50的流量都要通过AS 125和AS 200进行转接。看一下前面例子中的AS_PATH访问列表，access-list 1拒绝AS_PATH中包含50的全部路由，这就包括了学习自Oberstdorf的去往AS 50的路由，该路由的AS_PATH为（125,50），因而Innsbruck无法从Cervinia学习这些路由，也就无法利用这些替代路由进入AS 50。

图3-16 AS 125提供了一个去往AS 50的可选路径

为了解决这个问题，例3-87给出了Cervinia的配置情况。

例3-87：配置Cervinia以便将AS 125作为去往AS 50的转接AS

如例3-87所示，access-list 1拒绝了仅包含AS号50的AS_PATH，而不是像前一个例子中那样拒绝所有包含AS号50的AS_PATH。这样一来，Cervinia直接学习自Meribel的路由都被拒绝了，而学习自Oberstdof的路由则都被允许了。

3.3.4案例研究：通过路由映射过滤路由

还可以利用路由映射来实现路由过滤器。路由映射既可以使用访问列表（通过NLRI进行过滤），也可以使用AS_PATH访问列表（通过AS_PATH属性进行过滤）。例3-88给出了图3-15中Zermatt的一种可能配置。

例3-88：利用路由映射来配置Zermatt进行路由过滤。

本例中的access-list 1与“通过NLRI过滤路由”案例研究中使用的访问列表一样，但那时的访问列表是通过命令neighbor distribute-list进行调用的，而本例中命令neighbor route-map将出站路由纳入名为Innsbruck的路由映射，再由该路由映射利用命令match ip address调用访问列表。该路由映射允许所有被访问列表所允许的路由，拒绝其他路由。

路由映射也可以调用AS_PATH访问列表，如例3-89所示的Zermatt的配置。

例3-89:Zermatt利用路由映射来调用AS_PATH访问列表。

例3-89中的Zermatt配置与其在例3-88中的配置基本差不多，惟一的区别就是使用了命令match as-path，而不再是match ip address。这里所说的AS_PATH访问列表与”通过AS_PATH过滤路由”案例研究中的AS_PATH访问列表完全一样，本例中允许AS_PATH属性为空的路由——即源自AS 30的路由，其他路由都被拒绝。

路由映射既可以过滤入站BGP更新，也可以过滤出站BGP更新。在前一个案例研究中，路由器Innsbruck过滤了来自Meribel的入站路由，仅接受AS_PATH属性为50且不包含其他AS号的路由。此外，Innsbruck还过滤了去往Cervinia的路由，仅允许AS_PATH中无AS 30的路由。例3-90显示了利用路由映射实现相同目的的Innsbruck的配置情况。

例3-90：Innsbruck利用路由映射进行路由过滤。

当需要在单台路由器上配置多个路由过滤器时，使用路由映射要比分发列表（distribute list）或过滤器列表（filter list）要有效得多。这是因为路由映射可以使用名字而不是数字，直观的名字会使配置工作变得简单，也更容易理解。在例3-88和例3-89中，名为Innsbruck的路由映射可以非常清楚地表示出该路由映射关心的是哪些邻居，而例3-90中的路由映射名字则表示出了通达这些邻居的路径。

但使用路由映射的主要原因不仅是其标识特殊路由的能力（利用match语句），还有其更改路由属性的能力（利用set语句）。后面的5个案例研究将示范如何使用路由映射来实现更为复杂的路由策略，这些案例研究将分别示范如何影响以下路由优先级的方法。

•单台路由器内（去往同一目的地的多条BGP路由）

•单台路由器内（去往同一目的地的多条来自不同路由协议的路由）

•本地自治系统内

•邻居自治系统内

•邻居自治系统之外的自治系统内

3.3.5案例研究：管理性权值

通常情况下，BGP路由器都会存在去往同一目的地的多条路由，虽然BGP有默认方法来选择这些路由，但实际情况中可能需要忽略这些默认方法并实施一定的路由策略。尽管RFC并没有提供如何影响单台路由的路由优先级的方法，但Cisco的IOS提供了这方面的方法。

Cisco提供的第一个专用工具就是管理性权值（administrative weight），每台路由器都被分配了一个权值，值在0~65 535之间。当存在去往同一目的地的多条路由时，路由器会优选权值最大的路由。在默认情况下，源自本路由器BGP路由的权值为32 768，而学习自其他邻居的BGP路由的权值为0。

当去往同一目的地存在多条路由时，管理性权值会忽略BGP决策进程中的其他因素；但管理性权值仅在本地有意义，也就是说，不会被宣告给邻居BGP发言者。因而，在某台路由器上为某条路由分配的权值不会影响该路由在其他路由器上的优先级。

如图3-17所示，改善了AS 30的连接关系，Zermatt和Moritz都双归至AS 100和AS 200，以提高冗余性，每台路由器都从Innsbruck和Cervinia收到了去往AS 50中目的地址的路由。第2章有关BGP决策进程的讨论中谈到，当在多条去往统一目的地的多条路径中选择优选路径时，如果所有属性都相等，那么BGP将选择来自路由器ID最小的邻居的路由。这也意味着图3-17中的Zermatt和Moritz将使用Innsbruck来到达AS 50中的目的地，这是因为Innsbruck的路由器ID小于Cervinia，如例3-91输出结果所示。Zermatt和Moritz的BGP表显示可以通过Innsbruck(10.100.83.1）或Cervinia(10.200.60.1）到达AS 50中的目的地，由于Innsbruck的路由器ID小于Cervinia，因而Zermatt和Moritz都将来自Innsbruck的路由标记为最佳路由。

图3-17 Zermatt和Moritz都部署了多归属连接，以提高冗余性

例3-91：图3-17中的Zermatt和Moritz的BGP表。

为了使流量更加均衡，Zermatt应该使用与Innsbruk间的链路去往AS 50，将与Cervinia间的链路作为备份；而Moritz则应该使用与Cervinia间的链路去往AS 50，将与Innsbruk间的链路作为备份。这两台路由器都通过控制路由的权值来实施该路由策略，如例3-92所示。

例3-92：通过控制路由权值来让Zermatt和Moritz遵循既定的路由策略。

例3-92中的配置使用了命令neighbor weight，该命令根据宣告路由的邻居为路由分配不同的权值。Zermatt为学习自Innsbruck(10.100.83.1）的路由分配了权值50 000，为学习自Cervinia(10.200.60.1）的路由分配了权值20 000，而Moritz则正好相反。这样一来，这两台路由器将优选权值较大的路由，在优选路由失效后将使用备选路径，如例3-93输出结果所示。

例3-93:Zermatt和Moritz将权值最大的路由指派为“最佳”路由，而本地发起的路由的权值仍为默认的32 768。

（待续）

如果学习自某个邻居的所有路由的权值均一样，那么命令neighbor weight将非常有用。但有时必须为来自同一邻居的不同路由设置不同的权值，实现该路由策略的一种方式是利用命令neighbor filter-list weight，与命令neighbor filter-list用于路由过滤相似，该命令将调用一个AS_PATH访问列表，以根据AS_PATH属性来标识路由。虽然一个邻居最多可以有一个neighbor filter-list in和一个neighbor filter-list out命令，但命令neighbor filter-list weight的多个实例可能会被分配给单个邻居。可以为命令neighbor filter-list和neighbor filter-list weight配置相同的邻居，虽然这两个命令看起来十分相似，但它们的作用和效果却相差甚远。

图3-18给出的拓扑结构与例3-17相似，但增加了其他AS连接到NAP上。Innsbruck和Cervinia都将来自AS 50和AS 75的路由宣告给了Zermatt和Moritz.，此时建立了一个新的路由策略，要求Moritz使用Cervinia去往AS 75中的目的地，而使用Innsbruck去往AS 50中的目的地。

图3-18将AS 75连接到NAP

例3-94显示了利用命令neighbor filter-list weight配置Moritz的情况。

例3-94：通过命令neighbor filter-list weight配置Moritz优选Cervinia作为去往AS 75的下一跳路由器。

access-list-2中的正则表达式_75$标识的是以75结尾的AS_PATH的路由，将匹配路径（100，75）和（200,75）。与此类似，access-list-3将匹配以50结尾的AS_PATH的路径。在Innsbruck(10.100.83.1）的邻居配置中，将去往AS 75的路由的权值设置为40 000，而将去往AS 50的路由的权值设置为60 000。在Cervinia(10.200.60.1）的邻居配置中，将去往AS 75的路由的权值设置为60 000，而将去往AS 50的路由的权值设置为40 000。例3-95显示了Moritz的BGP表情况。

例3-95:Cervinia是去往AS 75的优选下一跳路由器，Innsbruck是去往AS 50的优选下一跳路由器。

（待续）

如果在同一个邻居配置中同时使用了命令neighbor weight和neighbor filter-list weight，命令neighbor filter-list weight将具有优先权。如果没有用命令neighbor filterlist weight为来自对等体的路由设置权值，则将用命令neighbor weight来设置权值。

此外，还可以通过命令neighbor route-map来控制路由权值。例3-96显示了利用路由映射配置Moritz的情况，可以达到与例3-94相同的效果。

例3-96：通过路由映射配置Moritz，将Cervinia作为去往AS 75的优选下一跳路由器。

当利用路由映射设置权值时，只能匹配AS_PATH；无法利用命令match ip address来匹配单个IP地址。与命令neighbor filter-list weight和neighbor weight一样，还可以在同一个邻居配置中使用weight-setting路由映射，但weight-setting路由映射的优先级要高于这两个命令。

3.3.6案例研究：管理性距离和后门路由

Cisco提供的另一个控制单台路由器上路由优先级的专用工具就是管理性距离（administrative distance）。管理性权值是对学习自不同BGP对等体的去往同一目的地的所有路由进行路由优先级的控制，而管理性距离则是对学习自不同路由协议的去往同一目的地的所有路由进行路由优先级的控制。也就是说，管理性权值的控制效果体现在BGP表中，而管理性距离的控制效果体现在IP路由表中。

通常情况下，根据路由所来自的协议或源来为路由分配管理性距离，距离越短，表示该路由越优。表3-2显示了不同协议的管理性距离。可以看出，在一个AS内，如果路由器从RIP和OSPF学习到了去往同一目的地的不同路由，那么将优选OSPF路由，这是因为OSPF的管理性距离（110）小于RIP路由的管理性距离（120)。

注意：当静态路由引用的是接口而不是下一跳地址时，则认为该目的地是一个直连网络。

EBGP的管理性距离为20，小于所有的IGP距离。这看起来似乎对图3-18所示的互联网络产生一定的问题，当Zermatt将AS 30的某个内部地址宣告给Innsbruck时，该地址被传递给Cervinia，之后又会被Cervinia传递回Moritz。由于Moritz是通过EBGP学习到该路由的，因而优选的将是来自EBGP的路由，而不是来自IS-IS的路由（因为IS-IS路由的距离为115）。不过事实上，由于有BGP环路避免机制，因而不会发生这个问题。Moritz在来自Cervinia的路由的AS_PATH中发现了AS号30，因而将丢弃该路由。

另一方面，IBGP不会将AS号加入到AS_PATH中，因而当某条路由学习自IGP之后又通过IBGP对等体在AS内进行传递时，将会产生路由环路或黑洞路由。因而将IBGP路由的距离设置为200，高于所有的IGP路由，对去往同一目的地的路由来说，学习自IGP的路由的优先级总是高于IBGP路由。

本地（local)BGP路由是指那些因使用了BGPnetwork命令而源自本地路由器的路由。与IBGP路由一样，这些路由的管理性距离也为200，因而优先级也低于所有的IGP路由。

《TCP/IP路由技术（第一卷）》第13章中给出了一个案例研究，说明了如何控制IGP路由的默认距离，如果希望更改BGP路由的默认距离，需要使用命令distance bgp，该命令可以分别设置EBGP、IBGP和本地BGP路由的距离。例3-97中的配置将IBGP路由的距离更改为95，使得IBGP路由的优先级高于所有去往同一目的地的IGP路由（EIGRP路由除外）。

例3-97：将IBGP路由的距离更改为95，使得IBGP路由的优先级高于所有去往同一目的地的IGP路由（EIGRP路由除外）。

与IGP不同，一般很少会有好的理由来更改所有BGP路由的默认距离，但是在某些情况下，需要更改某些BGP路由的默认距离。如图3-19所示，在路由器Meribel和Lillehammer间增加了一条专用链路，路由器在该链路上运行RIP，该链路被称为后门（back door）。也就是说，AS 50和AS 75之间的某些流量需要通过该专用后门路由（而不是公用NAP）进行传递，原因可能是AS 50和AS 75之间拥有商业合作关系，希望他们之间的通信通过专用链路进行疏导，而不是通过公用Internet进行疏导。

图3-19在AS 50和AS 75之间增加了一条专用后门链路，允许这两个自治系统的IGP进程进行直接通信，而不是通过EBGP会话进行通信

在这个例子中，AS 50中的172.17.0.0与AS 75中的172.18.0.0之间的流量应使用该后门链路，只有当后门路由失效时才使用NAP路由。问题的关键是管理性距离，例如，Lillehammer从Meribel学习到的去往172.17.0.0的路由，一种是通过RIP在后门链路上学习到该路由，另一种是通过BGP在NAP链路上学习到该路由。EBGP路由的距离是20，而RIP路由的距离是120，因而优选EBGP路由，如例3-98输出结果所示。

例3-98:Lillehammer通过RIP和EBGP学习到去往172.17.0.0的路由，由于EBGP路由的管理性权值为20，因而优选该路由。

（待续）

一个解决办法就是使用BGPnetowrk命令，如例3-99所示。

例3-99：使用netowrk命令将学习自EBGP的路由当作本地BGP路由。

在例3-99所示配置中，命令network将学习自EBGP的路由视为了本地BGP路由。例如，网络172.17.0.0通过EBGP被宣告给了Lillehammer，并进入了路由表。虽然172.17.0.0并不是一条真正的本地路由，但仍将命令network 172.17.0.0加入到了Lillehammer的BGP配置之中，由于该地址位于路由表中，因而命令netowrk与其相匹配，并将该路由设置为本地路由。

这个逻辑看起来似乎有些奇怪，但却十分有效。172.17.0.0最初是一条EBGP路由，后来被netowrk命令更改成了一条本地BGP路由。由于去往172.17.0.0的EBGP路由已经被Lillehammer视为一条本地BGP路由，并被分配了管理性距离200，而此时去往172.17.0.0的RIP路由的管理性距离将小于本地BGP路由，因而将成为优选路由，如例3-100输出结果所示。

例3-100：通过让Lillehammer将去往172.17.0.0的EBGP路由视为一条管理性距离为200的本地BGP路由，使得往该网络的RIP路由成为优选路由。

虽然正确控制了管理性距离，但本配置仍有问题。通过network命令将EBGP路由转换为本地路由，那么本地BGP路由器将在其EBGP更新中宣告该路由。例如，Lillehammer将在其EBGP更新中通过NAP向其对等体宣告172.17.0.0。由于Meribel的BGP进程是从重分发中学习到去往172.17.0.0的路由，因而宣告该路由时携带ORIGIN为Incomplete（不完全的）属性。但是，由于配置了network语句，因而Lillehammer宣告该路由时携带的ORIGIN属性为IGP，这样一来，Cervinia和Innsbruck选择Lillehammer为去往172.17.0.0的下一跳路由器，如例3-101所示。去往172.17.0.0的外部流量就被转发到Lillehammer，而Lillehammer又通过后门链路转发这些流量。但是，实际上仅希望172.17.0.0和172.18.0.0之间的流量通过后门链路进行转发，其他流量还是使用NAP进行转发。

例3-101:Cervinia的BGP表显示Lillehammer(10.75.100.1）为去往网络172.17.0.0的最佳下一跳，导致Lillehammer与Meribel间的后门链路成为所有去往172.17.0.0的外部流量的转接网络。

例3-102显示了利用命令network backdoor解决该问题的方法，该命令是Cisco提供的另一个专用工具。

例3-102：限制外部流量流经Lillehammer与Meribel间的后门链路。

命令network backdoor与命令network的效果相同：EBGP路由被视为本地BGP路由，而且管理性距离被更改为200。两者的区别是命令network backdoor所指定的地址没有被宣告给EBGP对等体。对网络172.17.0.0来说，新配置在Lillehammer中生成了相同的路由表（如例3-100所示），但Cervinia的BGP中却不再包含学习自Lillehammer的去往该网络的路由。

3.3.7案例研究：使用LOCAL_PREF属性

LOCAL_PREF属性被用于在去往同一目的地的多条路由中设置路由优先级，与管理性权值不同，LOCAL_PREF并不是限制单台路由器，而是在IBGP对等体之间进行传递。LOCAL_PREF属性不会应用于EBGP对等体之间——因为其名字就是本地优先级。

路由器的LOCAL_PREF属性取值范围在0～4 294 967 295之间，值越大，表面该路由越优。在默认情况下，所有被宣告给IBGP对等体的LOCAL_PREF属性值都是100。利用命令ip default local-preference可以更改LOCAL_PREF属性的默认值，利用路由映射和命令set local-preference可以更改单条路由的LOCAL_PREF属性值。

在图3-20中，AS 30被多归属到单一AS上，为了实现冗余性，在Zermatt与Moritz之间以及Innsbruck与Saalbach之间增加了链路，并且在这些链路上均运行了IBGP。

图3-20 AS 30被多归属到单一AS上

AS 30的路由策略要求所有去往AS 75的出站流量都必须使用Moritz-Saalbach间链路，所有去往AS 50的出站流量都必须使用Zermatt-Innsbruck间链路，只有在优选链路不可用时，才可以使用另一条链路。例3-103显示了Zermatt和Moritz的配置情况。

例3-103：利用LOCAL_PREF属性影响路由优先级。

（待续）

每台路由器都将来自EBGP对等体的入站路由链接到名为PREF的路由映射上，该路由映射中的序列10标识入站路由的AS_PATH。Zermatt的AS_PATH以50结尾，因而入站路由的LOCAL_PREF为200；Moritz的AS_PATH以75结尾，因而入站路由的LOCAL_PREF为300；而所有不与序列10相匹配的路由都被序列20所允许，从而得到默认值100。

注意：在实际中，两台路由器可能会分配相同的LOCAL_PREF值。本例中使用不同的LOCAL_PREF值，是为了更清楚地观察每个路由映射的影响。

例3-104显示了这两台路由器的BGP表情况。

例3-104:Zermatt为去往AS 50中目的地的路由LOCAL_PREF分配数值100, Moritz为去往AS 75中目的地的路由LOCAL_PREF分配数值300。

（待续）

请注意，例3-103中的配置与早先案例中的IS-IS配置之间存在很重要的区别。本例中的BGP路由并没有被分发到IS-IS域，相反，每台路由器都宣告了一条默认地址。当向某个外部目的地发送流量时，内部路由器将把数据包转发到最近的默认地址——Zermatt或Innsbruck，之后再由这些路由器依据外部路由的LOCAL_PREF属性，将数据包转发给各自的EBGP对等体或者通过冗余链路转发给各自的IBGP对等体。

不将BGP重分发到IS-IS中并不是一时兴起，对本例的拓扑结构和路由策略来说是必需的。例如，如果Moritz将去往172.17.0.0的EBGP路由重分发到IS-IS，那么该路由将通过IS-IS域重分发给Zermatt, Zermatt接受该路由后又再次重分发回BGP，并进入其BGP表中。由于Zermatt将该路由加入到其BGP表中，因而该路由被认为是本地发起的路由，相应的权值为32 768。管理性权值要优先于LOCAL_PREF，因而Zermatt将通过IS-IS域去往172.17.0.0的路由视为最佳路由，而不是通过直连链路去往Moritz。

3.3.8案例研究：使用MULTI_EXIT_DISC属性

MULTI_EXIT_DISC（即MED）属性用于影响邻居自治系统中的路由决策，MED被称为外部度量值（external metric），并且在BGP表中被标记为“度量值”。与LOCAL_PREF相似，MED是一个4个（8位组）数值，因而取值范围为0〜4 294 967 925。

当BGP发言者从对等体学习到路由后，可以将该路由的MED传递给任意IBGP对等体，但不会传递给EBGP对等体，因而MED仅在邻居自治系统之间具有相关性。如果图3-20中的路由器Zermatt向Innsbruck宣告携带了某MED值的路由172.16.0.0,Innsbruck可以将该MED值再宣告给Saalbach；但是当Innsbruck和Saalbach将该路由宣告给AS 50和AS 75中的EBGP对等体时，则无法在路由中携带MED。

MED是一个相对比较弱的属性，在BGP决策进程中，在去往同一目的地的多条路由中进行决策时，权值、LOCAL_PREF和AS_PATH长度以及ORIGIN都优先于MED，但是当这些变量均相同时，将选择MED值最小的路由。

提示：读者可能会感到有些糊涂了，不过一定要记住，优选LOCAL_PREF值最大的路由，而优选MED值最小的路由。MED的另一个术语是度量值（metric），而度量值的另一个术语是距离（distance），因而只要记住“最高的优先级、最短的距离”即可。

可以在路由映射下使用命令set metric来控制MED属性。如图3-20所示，AS 30希望AS 100通过Saalbach-Moritz链路向网络172.16.0.0发送入站流量，通过Innsbruck-Zermatt链路向网络172.31.0.0发送流量，而AS 100则可以通过任一条链路发送其他流量。例3-105显示了Zermatt和Moritz的配置情况。

例3-105：配置Zermatt和Moritz以控制MED属性。

（待续）

每台路由器都将去往EBGP对等体的出站路由链接到名为MED的路由映射上，该路由映射中的序列10调用access-list 1并分配了一个MED值，以匹配相应的路由。Zermatt为去往172.31.0.0的路由分配的MED值为100,Moritz为去往172.16.0.0的路由分配的MED值为100，任何不与序列10中的访问列表相匹配的路由都被序列20所允许，并且分配的MED值为200。例3-106显示了Innsbruck的BGP表情况。

通常情况下，只有当去往同一目的地的多条路由均源自同一AS时，才比较这些路由的MED值。这是因为MED的作用就是在去往邻居AS存在多条链路时，允许AS为入站流量传达其优先级。通常来说，比较两个不同自治系统的优先级毫无意义，但是在某些特定场合下却另当别论。

例3-106：基于不同路径的度量值，Innsbruck将去往172.16.0.0的数据包转发给Saalbach(10.100.65.1)，将去往172.31.0.0的数据包转发给Zermatt(172.30.255.254)。

图3-21给出的AS 50和AS 75之间存在一条后门链路。与“管理性距离和后门路由”案例研究类似，网络172.17.0.0和172.18.0.0都被RIP经后门链路对外进行宣告，并用于这两个自治系统间的专用通信。

图3-21应该将AS 50和AS 75间的后门路由也作为备用路由

由于使用了命令network backdoor，因而AS 75不再宣告172.17.0.0, AS 50也不再宣告172.18.0.0，但是在这个例子中，AS 50和AS 75希望AS 100中的路由器使用后门链路作为备用路由。例如，当Meribel去往NAP的接口失效时，Innsbruck和Saalbach应该将去往172.17.0.0的数据包转发给Lillehammer，再经后门链路转发给AS 50。这就需要Meribel和Lillehammer向外宣告不存在于其AS中的路由，并明确将这些路由标识为备用路由。在这种情况下，由于去往同一目的地的路由都是源自不同自治系统中的路由器，因而比较这些不同自治系统的MED值就显得很有意义了。

有两个命令与图3-21的应用场景相关。第一个命令是set metric-type internal，该命令被用作路由映射的一部分，用于将BGP路由的MED设置为与去往同一目的地的IGP路由的度量值一致。例如，Meribel去往172.17.0.0的RIP路由是一跳，Lillehammer去往同一目的地的RIP路由（学习自后门链路）是两跳。命令set metric-type internal可以让这些路由器的BGP路由在宣告网络时继承这些度量值，因而AS 100中的路由器将优选Meribel的路由（因为其MED为1），而不是Lillehammer去往同一目的地的路由（因为其MED为2)。

第二个相关命令用于接收端（即图3-21中AS 100中的路由器），命令bgp always-compare-med的作用是让路由器比较去往同一目的地的多条路由（即便这些路由源自不同的自治系统）的MED值。例3-107示范了如何使用这两个命令来配置Meribel、Lillehammer和Saalbach。

例3-107：配置图3-21中的Meribel、Lillehammer和Saalbach，以便让Saalbach比较来自不同自治系统的MED值。

（待续）

请注意，在Meribel的配置文件中，虽然网络172.17.0.0被重分发到了BGP中，但仍然对该网络使用了network语句。由于network语句被用于Lillehammer上的路由，因而需要利用该语句将ORIGN属性确定为IGP，如果没有该语句，则来自Meribel的该路由的ORIGIN属性将为Incomplete（不完全的）。在BGP决策进程中，ORIGIN的优先级要高于MED，这就意味着虽然Lillehammer路由的MED值较大，但仍然会成为AS 100的优选路由。

Meribel配置中另一个重要细节是过滤来自路由器Lillehammer的入站NLRI的分发列表，该过滤器允许去往192.168.75.0和172.18.0.0的路由，并拒绝所有其他路由。尤为重要的一个事实是，由Lillehammer宣告的去往172.17.0.0的路由被该过滤器拒绝了，否则，管理性权值为20的该EBGP路由将优先于Meribel的RIP路由，从而产生路由环路。

例3-108给出了Saalbach的BGP情况，Meribel去往172.17.0.0的路由（MED为1）优于Lillehammer的路由（MED为2）。由于172.18.0.0直连在Lillehammer之上，因而相应的本地度量值和MED均为0。之后通过RIP将该路由宣告给了Meribel，在路由器Meribel上的本地度量值为1，这同时也反应在Meribel的路由的MED中。当任一条优选路由失效后，将选择备用路由，去往该目的地的流量也将使用后门链路。

例3-108：去往172.17.0.0和172.18.0.0的路由的MED与AS 50和AS 75的内部RIP度量值相匹配。

（待续）

3.3.9案例研究：预附加AS_PATH

MULTI_EXIT_DISC属性会影响来自邻居自治系统的入站流量，但无法影响更远端的自治系统的路由决策。

图3-22再次给出了在前面案例研究中已经遇到过的拓扑结构。研究一下例3-109中的Meribel的BGP表，可以发现路由器Meribel拥有两条去往AS 30中同一目的地的重复等价路径。由于这两条路径的所有其他属性值均完全一样，且Innsbruck的路由器ID比较低，因而Meribel的BGP决策进程选择Innsbruck作为去往AS 30的全部流量的下一跳路由器。如此一来，AS 50去往AS 30的流量根本就不会使用Cervinia-Moritz间的链路，从而导致该可用带宽的利用率极低。

图3-22 AS 50与AS 30之间存在两条等价路径

例3-109：Meribel的BGP显示去往AS 30中的目的地存在两条路径。由于Innsbruck的路由器ID(10.100.83.1）小于Cervinia的路由器ID(10.200.60.1)，因而被选择为所有流量的最佳路径。

由于AS 30与AS 50不是直接相连的邻居自治系统，因而AS 30无法利用MED来影响AS 50的路由决策，但是通过命令set as-path prepend修改所宣告路由的AS_PATH属性之后，AS 30就可以影响AS 50的路由决策了。假设AS 30希望AS 50将所有去往172.16.0.0和172.31.0.0的流量都转发到Cervinia，并将所有去往10.30.0.0、172.29.1.0/24和192.168.100.0的流量都转发到Innsbruck。例3-110给出了Zermatt和Moritz的配置情况。

例3-110：配置Zermatt和Moritz以预附加AS_PATH。

（待续）

每台路由器都通过名为PATH的路由映射来过滤出站数据包。路由映射中的语句10使用access-list 3来标识特定路由（通过NLRI），以匹配那些在AS_PATH中增加了AS号30的路由。请注意，此处所说的AS号30是在正常加入AS_PATH的AS 30之外额外加入的。路由映射的语句20允许所有与access-list 3不匹配的路由。

例3-111显示了Meribel上的BGP表情况，可以看出预附加后的路由要比来自优选路径的路由长，而路由器将选择AS_PATH较短的路由。

例3-111：Meribel的BGP显示了来自Zermatt和Moritz的预附加AS_PATH，路由器将选择AS_PATH较短的路由。

（待续）

在使用AS_PATH预附加策略时需要特别谨慎，如果不能完全了解所做配置的影响，则将可能会出现无法预料或蹩脚的路由选择结果。例如，假设在Moeritz的配置中应用了命令set as-path prepend 30 30，该命令在AS_PATH中增加了两个AS号为30的实例（而不是一个实例）。检查一下该命令对去往10.30.0.0的路由所产生的影响，图3-22中的Cervinia从Moritz接收到一条携带了AS_PATH为（30，30,30）的路由，从Meribel接收到一条去往同一目的地但携带了AS_PATH为（50，100,30）的路由，由于这两条路由的AS_PATH长度完全一样，所以Cervinia将选择下一跳地址较小的路由，即来自Meribel的路由。原来的目的是希望仅影响AS 50的路由选择，但这种配置却导致AS 200也选择了较长路径去往目的地。

另一个需要注意的是，在预附加AS_PATH时应该总是使用被预附加路由器的AS号。如果使用了其他AS号，而该AS号又被某AS所使用，那么该路由被宣告给这个AS时，这个AS将不接收该路由。

3.3.10案例研究：路由标记

可以将路由标记字段理解为路由选择更新消息中用于跨越路由域来传送信息的“口袋”。标记所表示的信息与路由协议本身无关，路由协议也不会对标记做任何操作。当路由从协议A被重分发到协议B，然后又从其他点被重分发回协议A时，标记将十分有用。转接路由协议更新消息中的标记字段允许协议A在转接路由域的另一侧向其对等体发送信息，通常该信息对转接路由协议来说是前后矛盾或没有任何意义的。

RIP-2、EIGRP、集成式IS-IS、OSPF和BGP都支持路由标记，RIP-1和IGRP不支持路由标记。《TCP/IP路由技术（第一卷）》的第14章介绍了路由标记，并给出了一些应用示例，而本案例研究将集中阐述BGP环境中的路由标记应用策略。

图3-23给出了一个路由标记非常有用的应用场景。AS 1300为多个自治系统间的流量提供转接功能，3个外层自治系统的每条路由都通过EBGP被宣告给了AS 1300中的3台边界路由器中的某一台，之后这些路由被重分发到OSPF中，接着又在其他两台边界路由器上被重分发回了BGP，然后又被宣告给了它们的EBGP对等体。

图3-23 AS1300是其他3个自治系统的转接AS

注意：本应用场景所描述的配置情况（将BGP重分发到IGP中）可能会应用于某些大型企业网，但是正如本章反复声明的那样，不应该在服务提供商的AS中或拥有大量BGP前缀的AS中将BGP重分发到IGP中。

图3-23所示拓扑结构的问题是，3个外层自治系统的BGP进程必须通过OSPF来共享路由信息，而OSPF却不了解BGP的路径属性，因而将丢失所有的路径信息。例3-112显示了路由器Turoa的BGP情况，可以看出，所有的路由看起来都似乎源自AS 1300。如果AS 1400有一条可选路径去往AS 1100或AS 1200，但是由于该信息已被丢失，因而将无法做出准确的路由决策。

例3-112：来自AS 1100和AS 1200的路由AS_PATH信息在穿越AS 1300中的OSPF域时都丢失了，因而所有学习自AS 1300的路由似乎都源自AS 1300。

BGP可以利用OSPF包中的路由标记在穿越OSPF域时携带AS_PATH信息。实际上，Cisco的BGP实现自动完成了该功能。例3-113给出了去往192.168.1.0（位于AS 1200中）的Zao的路由细节（穿越OSPF域），请注意查看被标记为1200的标记字段。

例3-113：当路由器Naeba将其去往192.168.1.0的EBGP路由重分发到OSPF时，将路由的AS_PATH信息写进OSPF AS-External LSA的外部路由标记字段，可以看到该标记存在于OSPF域另一侧的路由器Zao的路由表项中。

请参考《TCP/IP路由技术（第一卷）》第9章，以了解OSPF AS-External LSA的详细格式及使用方式。

但是，当IGP路由被重分发到BGP中时，BGP进程并不能自动假定IGP的路由标记字段中包含了AS_PATH信息，因而必须配置BGP进程来恢复AS_PATH信息。一种从重分发路由中恢复AS_PATH信息的方法是使用命令set as-path tag，例3-114示范了如何使用命令set as-path tag来配置路由器Zao。

BGP配置中的语句redistribute ospf调用了名为GET_TAG的路由映射，该路由映射将重分发后的路由的AS_PATH属性设置为OSPF标记字段中的值。例3-115显示了该配置结果，现在Turoa的BGP表中已经包含了去往AS 1100和AS 1200中路由的准确的AS_PATH信息。

例3-114：配置Zao从重分发路由中恢复AS_PATH信息。

例3-115：Turoa的BGP表中包含了准确的AS_PATH信息。

Zao利用命令set as-path tag从OSPF标记字段中拾取AS_PATH信息时，无需配置Happo或Naeba，但是自动进入标记字段的惟一信息只有AS_PATH。请注意，在例3-115中，来自AS 1100和AS 1200的路由的ORIGIN属性都被标记为Incomplete（不完全的）。路由器Thredbo和Yangii使用BGPnetwork命令来宣告ORIGIN属性为IGP的内部路由，但是由于Happo和Neaba并没有将该信息加入到OSPF标记字段中，因而Turoa看见的ORIGIN代码将是Incomplete（不完全的），从而路由器Zao将会把该路由从OSPF重分发到BGP中。

这是否是一个问题，与Turoa是否有备用路径去往AS 1100和AS 1200有关，并且与路由的ORIGIN属性是否影响BGP决策进程有关。Cisco还提供了一种可选的配置方式，被称为自动标记（automatic tag)，该功能不但加入AS_PATH信息，还加入ORIGIN代码。自动标记是由命令set automatic-tag完成的，由命令table-map从BGP进程中调用包含该命令的路由映射。与命令set as-path tag（该命令应用于将路由从IGP重分发到BGP中的路由器）不同，命令set automatic-tag应用于将路由从BGP重分发到IGP中的路由器。

图3-23中的3台AS 1300路由器将被配置成一致，以设置自动标记。例3-116显示了路由器Naeba的配置情况。

例3-116：配置Naeba以加入AS_PATH信息和ORIGIN代码。

（待续）

例3-117显示了Turoa的BGP表情况，可以看出该BGP表几乎与例3-115中的表完全相同，只不过现在来自AS 1100和AS 1200的路由已经能正确地反应IGP的ORIGIN属性了。

路由标记的另一种用途是标识一定的路由组，可能是用于路由过滤。在图3-23中，路由器Naeba和Happo可能被配置成在将EBGP路由重分发到OSPF之前，标记这些EBGP路由的某些子网，之后Zao（从OSPF域中检索这些路由）就可以通过它们的公共标记（而无需再通过NLRI进行路由过滤）来识别这些路由。第2章曾经说过，BGP COMMUNITY属性也被设计用来标识公共路由组中的路由，但是，在图3-23所示拓扑结构中，无法穿越OSPF域传达COMMUNITY属性。有关使用路由标记完成此功能的案例请参见《TCP/IP路由技术（第一卷）》第14章中的“案例研究：路由标记”。

最后，可以仅在将IGP重分发到BGP中时使用路由标记。使用了network命令之后，BGP路由被认为是源自本地路由器，因而不会继承IGP路由的任何属性（包括标记在内）。

例3-117:Turoa的BGP表中不但包含了正确的AS_PATH信息，也包含了正确的ORIGIN代码。

3.3.11案例研究：路由阻尼

如第2章所述，路由阻尼是一种为翻动路由分配惩罚值的进程。当某路由的惩罚值在一定时期内累积到一定程度后，将抑制该路由，也就是说，不再宣告该路由。在默认情况下，路由每发生一次翻动，就要被分配惩罚值1 000，当路由的惩罚值累积超过2 000后，就会被抑制，直至惩罚值降低到750以下。惩罚值的上限和下限阈值分别被称为抑制门限（suppress limit）和重用门限（reuse limit)。累积的惩罚值每5s减少一次，并以某种速率（如15分钟）降低到一半，该速率是一种指数函数，通常被称为半衰期（half-life)。如果惩罚值是3 000，那么经过15分钟后将减小到1 500；如果惩罚值是300，那么15分钟后将减小到150。此外，路由在经过一个被称为最大抑制门限（maximum suppress limit）的最长时间之后也能被抑制，通常该时间是半衰期的4倍，即60分钟。

在BGP进程配置中，可以使用命令bgp dampening来启用路由阻尼机制，如果希望更改默认值，可以使用bgp dampening halflife reuse suppress max-suppress。

在图3-24所示的拓扑结构中，路由器Colorado被归属到5个其他自治系统，如果远程自治系统宣告的路由出现翻动现象，那么Colorado必须将该变化情况宣告给所有EBGP对等体。虽然这对本例所示的拓扑结构不会造成很严重的负担，但是假想一下，如果Colorado有150个EBGP对等体（而不是图中所示的5个）时，将会产生什么样的后果？任何一次普通的路由翻动都会给中心路由器造成非常严重的处理负担。

图3-24任一个“Spoke（星型）”自治系统中的路由出现翻动现象，“Hub（中心）”路由器Colorado都要向其所有的EBGP对等体宣告该路由变化情况

例3-118给出了Colorado的BGP配置情况。

例3-118：让Colorado在出现路由翻动时向其EBGP对等体发送更新消息。

例3-119给出了Colorado的BGP表情况。请注意，10.1.4.0/24被标记了d，表示该路由已经被阻尼或抑制，10.1.7.0/24被标记了h，表示曾经出现过路由翻动。也就是说，虽然该路由的惩罚值没有大到被抑制的程度，但是仍然有惩罚值。

例3-119：路由10.1.4.0/24和10.1.7.0/24都有惩罚值，第一条路由的惩罚值超过了2 000，从而被阻尼。

由于例3-119中BGP表的路由项不是很多，因而可以很容易地看出不稳定路由。但是，当BGP路由项达到成千上万条时会是什么样子呢？通过查看标记d或h来寻找不稳定路由的方法是行不通的，需要利用命令show ip bgp flap-statistics和show ip bgp dampened-paths来寻找不稳定路由。顾名思义，第一条命令显示所有出现翻动现象的路由以及翻动的次数，第二条命令仅显示那些已经被抑制的路由。例3-120显示了这些命令在路由器Colorado上的应用情况，对被抑制路由来说，两条命令的输出结果都表示了何时会再次宣告这些路由，该时间是暂时不再为路由继续分配惩罚值的时间。请注意，只有配置了BGP阻尼之后，才能记录路由的翻动统计情况。也就是说，无法利用命令show ip bgp flap-statistics检查未运行阻尼进程的路由器的不稳定路由。

例3-120：仅显示BGP表中出现翻动的路由或仅显示已经被抑制的路由。

仔细查看例3-120中的路由情况，可以看到不但显示了统计情况，还显示了累积的惩罚值。在例3-121中，去往10.1.4.0/24的路由的惩罚值为1 815，虽然半衰期衰退进程已经将惩罚值降低到了抑制门限2 000以下，但仍然未达到重用门限750。从输出结果可以看出，需要 19分10秒就可以达到重用门限。

例3-121：如果使用命令show ip bgp指定某条不稳定路由，将会显示该路由的惩罚值。

在某些情况下，可能希望被抑制路由在到达重用门限之前就重新使用该路由。例如，AS 30的管理员可能会保证已经鉴别了子网10.1.4.0/24的翻动原因并已经解决了该问题，从而希望恢复流量。此时就可以使用以下两条命令：clear ip bgp flap-statistics和clear ip bgp dampening。这两条命令在清除某条路由或全部路由（依赖于是否在命令中指定路由）的惩罚值方面的效果完全一致，只是第二条命令仅清除被抑制路由的惩罚值。命令clear ip bgp flap-statistics还可以通过路由的AS路径来标识一组路由（或者指定过滤器列表，或者使用正则表达式），例如，命令clear ip bgp flap-statistics regexp_30_将清除AS_PATH属性中有AS号30的所有路由的翻动统计信息。在AS 30是转接AS，且某条故障链路导致通过该AS 30可到达所有目的地的路由都累积惩罚值时，该命令将非常有用。

3.4大型BGP

大型BGP(Large-scale BGP）是一个主观用词，需要由自己来判断本网的BGP拓扑结构是否已经大到需要使用本节所讨论的各种工具。不过，作为一条规则，应该在中等及以上规模的互联网络中使用对等体组和团体。虽然有时也会在中等及以上互联网络中见到路由反射器，但是只有在超大的BGP拓扑结构（如大型ISP）中才会使用BGP联盟。本节的案例研究将逐一解释上述工具的使用情况。

3.4.1案例研究：BGP对等体组

在前一个案例研究中，图3-24给出的BGP拓扑结构是一个自治系统多归属到多个其他自治系统。但是，假如路由器Colorado拥有150个EBGP对等体（而不再是5个EBGP对等体），那么除了标准的配置之外，还需要为每条邻居连接配置出站和入站路由过滤器，因而对每个邻居来说，需要配置以下5条BGP语句。

• 1条neighbor remote-as语句；

• 1条neighbor ebgp-multihop语句，因为BGP连接位于环回地址之间；

• 1条neighbor update-source语句，原因同上；

• 1条neighbor filter-list out语句；

• 1条neighbor filter-list in语句。

这样一来，对150个EBGP对等体来说，将需要配置750条BGP语句。

当需要为多个BGP对等体实施相同的路由策略时，通过将这些对等体指定为某对等体组的成员，可以极大地简化路由器的BGP配置工作。此时，大多数配置选项和路由策略都无需再为每个邻居进行单独配置，只需要为对等体组配置一次即可。对等体组仅与其所定义的路由器有关，不与该路由器的对等体进行通信。按照下面的步骤就可以定义对等体组。

• 第1步：指定对等体组名称。

• 第2步：指定适用于对等体组全部成员的路由策略和配置选项。

• 第3步：指定属于本对等体组的邻居。

例3-122中的配置文件在路由器Colorado上创建了一个名为CLIENTS的对等体组。

例3-122：在路由器Colorado上创建一个名为CLIENTS的对等体组。

语句neighbor CLIENTS peer-group用于创建对等体组，接下来的4条语句定义了适用于对等体组全体成员的配置选项和路由策略，之后使用neighbor remote-as来指定EBGP邻居，然后增加了一条语句将该邻居指定到对等体组CLIENTS中。

通过合并共享的配置选项和路由策略，对等体组可以极大地缩短BGP的配置文件，回到Colorado拥有150个EBGP的应用场景。如果所有对等体都是对等体组CLIENTS的成员，那么配置文件将从750条语句缩减到305条语句，配置将变得更简单，也更容易理解。可以在一处地方定义所有的配置选项，惟一需要知道的就是哪些邻居属于哪个对等体组。

如果对等体组的所有成员都属于同一个AS，那么在对等体组配置中指定公共AS还可以进一步缩减配置文件。虽然所有的成员都可能是同一个远程AS的EBGP对等体，但大多数情况下，同一个AS中的大量对等体都是IBGP对等体。如图3-25所示，路由器NewMexico和Idaho被增加为Colorado的对等体。

例3-123显示了Colorado的配置情况。

例3-123：利用对等体组配置Colorado的内部对等体。

（待续）

图3-25为AS 100增加了2个IBGP对等体

NewMexico和Idaho被加入到对等体组LOCAL中，在对等体组配置中为它们指定了公共AS号，就像公共的出站路由策略一样。

注意： AS_PATH access-list 3允许所有来自AS 200、400或600的路由，而来自AS 300和AS 500的路由都被隐式拒绝，与源自Colorado的本地路由一样。

为单个对等体组成员定义的入站路由策略优先于为整个对等体组定义的入站路由策略。例如，假如要求Colorado不但接收来自EBGP对等体California的子网10.1.5.0/24，而且要遵循其他对等体组路由策略和选项，那么就需要按照例3-124重新配置Colorado。

本例在邻居配置中为California(10.1.255.4）增加了一个distribute-list 10，虽然Colorado的配置将California定义为CLIENTS对等体组的一个成员，但分发列表却优先于为California定义的入站filter-list 2。

例3-124：为对等体组中的单个邻居应用路由策略。

利用命令show ip bgp peer-groups可以显示路由器上所定义的对等体组的详细情况。如例3-125所示，通过在该命令的末尾指定对等体组的名称，还可以观察特定对等体组的细节情况。

例3-125：命令show ip bgp peer-groups可以显示路由器上所定义的对等体组的详细情况。

3.4.2案例研究：BGP团体

对等体组可以将公共路由策略应用于一组邻居，而团体（community）则可以将路由策略应用于一组路由。团体是一种BGP路由属性，因而在BGP发言者之间进行传递。按照以下步骤即可配置团体属性。

•第1步：利用路由映射标识将要设置属性的路由。

•第2步：利用命令set community设置属性。

•第3步：利用命令neighbor send-community指定属性所要发送的邻居。

在图3-26中，AS 100通过NAP连接到AS 2000上，AS 2000中的路由策略要求，子网10.2.2.0/24只能宣告给AS 100，但不能宣告给Colorado所连接的其他EBGP对等体。为了实施本路由策略，需要使用NO_EXPORT属性，该属性允许路由通过某邻居AS进行宣告，但不允许该AS将该路由宣告给其他自治系统。

图3-26用于BGP团体案例研究的拓扑结构

例3-126显示了路由器Austria的配置情况。

例3-126：限制AS 2000中的子网被宣告到AS 100之外。

例3-127显示了例3-126配置的输出结果。Colorado的BGP表包括了去往10.2.2.0/24的路由，表明Idaho已经将该路由宣告给了IBGP对等体，但Nevada的BGP表并不包含该路由，因而可以看出，Colorado已经遵守了NO_EXPORT属性，并且已经抑制该路由发送给其EBGP对等体。

例3-127：去往10.2.2.0/24的路由被设置了NO_EXPORT属性，因而Colorado不将该路由宣告给其EBGP对等体（如Nevada)。

当然，任何自治系统都不可能是真正自治的，因为其他AS还会告诉它应该怎么做。假定希望AS 100忽略由Austria设置的NO_EXPORT属性，并将10.2.2.0/24宣告给了Colorado的EBGP对等体，那么就需要按照例3-128来配置Idaho，以实现该路由策略。

例3-128：配置Idaho以删除AS 2000所宣告的团体属性。

Idaho配置中的语句set community none没有设置团体属性，而是删除了已有的团体属性，这就是为什么不需要在本配置中使用语句neighbor send-community的原因。例3-129给出了Colorado和Nevada的配置输出结果。

例3-129：此时的Colorado已看不见为去往10.2.2.0/24的路由所设置的NO_EXPORT属性，因而将该路由宣告给其EBGP对等体。

（待续）

NO_ADVERTISE团体属性发送的消息与NO_EXPORT一致——让路由器不将路由宣告给任何对等体。两者的不同之处在于，NO_ADVERTISE是发送给IBGP对等体（而不是EBGP对等体）的。假如图3-26中的Idaho希望将子网10.2.1.0/24和10.2.3.0/24宣告给Colorado，但不希望该对等体（Colorado）将这些路由再宣告给自己的IBGP或EBGP对等体，那么就需要按照例3-130来配置Idaho。

例3-130：在Idaho上为选定的前缀配置NO_ADVERTISE团体属性。

回顾一下Austria的配置，宣告10.2.2.0/24时携带了NO_EXPORT团体属性，而AS 2000的其他两个子网未携带团体属性。现在的Idaho已经完全颠覆了该路由策略，子网10.2.2.0/24已无团体属性，而子网10.2.1.0/24和10.2.3.0/24则携带了NO_ADVERTISE属性，以防止这两条路由被宣告到AS 100之外。例3-131显示了该配置的输出结果。

例3-131:Colorado知道来自AS 2000的3条路由，但仅将10.2.2.0/24宣告给其对等体。

（待续）

注意：例3-131给出了命令show ip bgp的另一种使用方式，此处使用了一个正则表达式来显示AS_PATH中带有AS号2000的全部路由。

被称为LOCAL_AS的团体属性在一定程度上是NO_EXPORT和NO_ADVERTISE的混合属性，该属性与BGP联盟（在一个AS中配置自自治系统）同时使用，携带LOCAL_AS属性的路由可以被宣告给联盟中的其他子自治系统，但无法被宣告到构成联盟的AS之外。

到现在为止，已经解释了被BGP发言者自动执行的周知团体属性，也可以自定义配置这此团体属性。可以采取以下两种方式来指定这些团体属性：

•十进制格式，在1～4 294 967 200之间。

•AA:NN格式，其中AA是一个16bit AS号，取值范围在1～65535之间，NN是一个任意的16bit数，取之范围在1～65440之间。

在图3-26中，AS 100的每个“客户”自治系统都有两个子网。假设AS 100需要对每个客户AS的某个子网实施一定的路由策略，而对另一个子网实施不同的路由策略，此时就可以在Colorado上使用一个冗长的访问列表通过其NLRI来标识每条路由（回顾前面所说的拥有150个客户自治系统（而不是5个客户自治系统）的应用场景）。另一种方法是让每个客户AS都为每个子网分配两个预定义团体属性中的一种属性。例如，每个客户AS都为某个子网分配团体值5，而为另一个子网分配团体值10。例3-132给出了Utah的配置情况。

例3-132：在Utah上为子网分配团体属性。

Colorado的其他EBGP对等体的配置都相似，如例3-133所示。除了让Colorado为每种路由策略标识路由更为简单之外，该方法还为客户自治系统的管理员提供了一定的回旋余地，即用于决定哪些路由被用于哪些路由策略。

例3-133:Colorado的EBGP对等体所宣告的每条路由都是community 5或community 10的成员。

团体列表（community list）被用于标识路由（通过它们的团体属性），该列表是访问列表的一种特殊应用形式：列表中可能会有多行语句，每行都有一个“permit（允许）”或“deny（拒绝）”动作；该列表由1〜99的数字所标识，并且在最后都有一个隐式的“拒绝全部”之意。在例3-134中，Colorado使用团体列表来为路由分配LOCAL_PREF属性（根据它们的团体值）。

注意：在客户自治系统被多归属到AS 100时可能会使用该路由策略。为简化起见，本例未展示这样的拓扑结构。

例3-134：利用团体列表为路由分配LOCAL_PREF属性（根据它们的团体值）。

待续

来自对等体组CLIENTS成员的入站路由被发送到名为COMM_PREF的路由映射中。路由映射的序列10使用community-list 1来标识团体值为5的路由，并为这些路由的LOCAL_PREF分配值150。序列20使用community-list 2来标识团体值为10的路由，并为这些路由的LOCAL_PREF分配值200。例3-135显示了Colorado的BGP表结果。

例3-135：属于团体5的路由（如例3-131所示）的LOCAL_PREF被分配为150，而属于团体10的路由的LOCAL_PREF被分配为200。

RFC 1997和RFC 1998（描述了BGP的团体属性）说明了AA:NN的使用方法。在默认情况下，Cisco IOS使用较老式的十进制格式。如果希望使用新格式，就需要在全局路由器配置模式下使用命令ip bgp-community new-format，以该格式输入团体时，可以直接以AA:NN格式来输入团体（十六进制或十进制）。例如，下面3种形式都可以用来指定团体400:50(AS 400，数值50)。

• set community 400:50

• set community 0x1900032

• set community 26214450

上面的3条命令都指定了一个32bit数，其中，前16bit是十进制数400，后16bit是十进制数50。无论使用上述3种命令中的哪一种，在路由器配置文件和BGP表中显示的团体都是400:50。

例3-136给出了利用该格式表示的Utah配置。

例3-136：让Utah以AA:NN格式显示团体。

就像有标准访问列表和扩展访问列表一样，团体列表也有标准团体列表和扩展团体列表之分。与IP访问列表相似，标准团体列表被编号为1～99，而扩展团体列表则被编号为100～199，这两种类型团体列表的区别在于，扩展团体列表可以使用正则表达式来指定团体（在使用AA：NN格式时非常有用）。如果希望利用AA:NN格式在Colorado上实现前面所说的LOCAL_PREF策略，则需要按照例3-137所示方式重新配置Colorado。

例3-137：使用扩展团体列表。

（待续）

例3-137中Colorado的配置除了使用了扩展团体列表之外，其余配置与例3-134中的配置完全相同。如果使用的是标准团体列表，就需要为每个AS增加一个独立的语句行，如例3-138所示。

例3-138：使用标准团体列表。

使用了扩展团体列表之后，只要一行就可以完成匹配条件。正则表达式。*匹配任意AS号，5则表示匹配团体号的公共部分。

例3-139显示了路由器Colorado上匹配community-list 101和community-list 102的路由情况。对大规模BGP实现（可能会有几万条BGP路由项）来说，联合使用团体列表和命令show ip bgp community-list将非常有用。因为通过团体列表，可以很容易地在如此众多的路由中找到特定团体属性的路由，之后再显示与团体列表相匹配的路由。

例3-139：命令show ip bgp community-list显示了与特定团体列表相匹配的BGP路由。

（待续）

一条路由可以拥有多个团体属性，假设图3-26中的路由器Austria将其所有的子网（携带2000:100团体属性）都宣告给Idaho，这些来自Ausreia的路由在Idaho上也都成为团体100:2000的成员。例3-140显示了Idaho的配置情况。

例3-140：让Idaho为来自Ausreia的路由增加一个团体值。

上面的配置中有两点值得关注。首先，由路由映射IDAHO中的语句10将团体值设置为6555600。IOS 12.0及以后版本都支持命令ip bgp-community new-format，路由器Idaho运行的是IOS 11.0，因而不支持AA:NN格式，不过通过快速计算可以看出，十进制数6555600正好等于32bit数100:2000（或0x6407d0），由于Colorado运行的是IOS 12.0，因而能正确解析以AA：NN格式出现的32bit数。值得说明的一点是，虽然团体属性可以用AA：NN、十进制或十六进制等格式来表示，但无论如何，团体值都是一个32bit数。

其次，是与命令set community一起使用的关键字additive。如果命令set community 6555600未使用关键字additive，那么Idaho将会替换所有被匹配的携带团体100:2000的路由的已有团体属性，而这个案例的目的是增加一个团体值，不是要替换由Austria发送的团体值。例3-141显示了Colorado的配置结果。

例3-141：团体属性2000:100由Austria加入，而团体属性100:2000则由Idaho加入。

当某条路由拥有多个团体属性时，团体列表和匹配语句的使用将有些许不同。语句ip community-list 1 permit 2000:100匹配团体属性中有2000:100的所有路由，而语句ip community-list 1 permit 2000:100 100:2000则匹配团体属性中有2000:100或100:2000或两者的所有路由。如果仅希望匹配团体值为2000:100和100:2000（不多也不少）的路由，那么就需要在匹配语句中加入关键字exact-match，如例3-142所示。使用了该关键字之后，团体属性中只有2000:100或100:2000或者除两者之外还有其他团体属性的路由都没有被匹配上。

例3-142：使用关键字exact-match之后，仅匹配那些与指定团体列表完全匹配的路由。

如果可以为一条路由分配多个团体属性，那么就应该有方法在不删除全部团体属性（如语句set community none的功能）的情况下删除某些团体属性，该功能由命令set comm-list delete来完成。

在前面的配置中，去往图3-26所示AS 2000中的子网的路由携带了团体属性2000:100和100:2000，在AS 400中，应保留的团体属性是100:2000，而不是2000:100。例3-143显示了California的配置情况。

例3-143：让California选择性地删除特定团体值。

路由映射DROP_COMM引用了community-list 1，并删除了该团体列表指定的团体，例3-144显示了该配置的输出结果。可以看出，在团体列表的单行中可以指定多个团体属性，但是，当团体列表被用于命令set comm-list delete时，团体列表的每一行只能指定一个团体。因此，如果希望从路由中删除2000:100、NO_EXPORT和300:5等团体属性，就必须在团体列表中配置3行语句。

例3-144：没有在California的BGP中匹配到同时拥有团体属性2000:100和100:2000的路由，但来自AS 2000的路由都携带了单一团体属性100:2000。

3.4.3案例研究：私有AS号

读者对私有IP地址（定义于RFC 1918中）已经很熟悉了，私有IP地址的范围是10.0.0.0〜10.255.255.255、172.16.0.0〜172.31.255.255和192.168.0.0〜192.168.255.255。这些地址的出现是为了应对IP地址不断被耗尽的威胁，当某互联网络需要IP地址，但不需要将这些地址对外公开（也就是说，不需要通过Internet直接可达）时，就可以使用私有IP地址，而无需使用公有IP地址。但是由于任何人都可以使用私有IP地址，因而这些地址不是全球惟一的，不能将这些地址宣告给公众Internet。

与私有IP地址类似，也存在私有AS号，这些私有AS号也是为了应对AS号不断被耗尽的威胁。私有AS号的取值范围是64 512～65 535，被保留用作私有用途。如果采用BGP的用户是单归属到一个ISP，那么该用户就可以使用也鼓励该用户使用私有AS号。

例如，对于前面图3-26的案例研究来说，连接在路由器Colorado上的自治系统都被称为AS 100的“客户”自治系统，通过NAP连接到AS 100的AS 2000表示公众Internet。AS 100可能是一个ISP，连接在其上的自治系统可能是其用户；AS 100也可能是某大型企业互联网络中公开连接的一部分，其他连接在其上的自治系统则是其私有分部。无论是哪种情况，图3-26中的5个“客户”自治系统都只能通过NAP和AS 100才可达，它们拥有独立AS号的惟一原因就是可以使用BGP将它们连接到AS 100上，AS 100可以将它们的路由宣告到Internet（不包含AS号）。图3-27给出的拓扑结构与图3-26类似，区别在于此处的“客户”自治系统使用的AS号不在私有AS号池之内。

图3-27连接在Colorado上的自治系统使用私有AS号

与私有IP地址类似，不能将私有AS号宣告到Internet，因为这些AS号不是全球惟一的。如例3-145所示，无需进一步配置，AS 100的客户AS号都通过NAP被宣告给了路由器Austria。

例3-145:Austria的BGP表显示了来自AS 100的某些路由的AS_PATH中存在私有AS号，如果Austria是公众Internet的一部分（通过NAP连接到AS 100上），则不能在AS_PATH中携带这些私有AS号。

在例3-146中，Idaho被配置为禁止通过NAP向外宣告私有AS号。

例3-146：过滤私有AS号。

命令neighbor remove-private-AS的作用从其名字中就可以看出来，其作用是在路由被宣告给指定邻居之前从AS_PATH中删中删除私有AS号。通过例3-147可以看出，此时所有从Idaho宣告到Austria的路由的AS_PATH属性中仅包含AS 100,AS 100中的路由器仍然有客户自治系统的全部路径信息，能够将数据包正确转发到目的AS。从这方面来说，AS 100在宣告客户子网时就像这些子网是AS 100的一部分一样，是一种自治系统级别的路由汇总。

例3-147：在Idaho的配置中增加命令neighbor remove-private-AS之后，AS 100客户自治系统的私有AS号对Austria来说都不可见了。

3.4.4案例研究：BGP联盟

BGP联盟可以将AS分割为多个子自治系统，从而让大型转接自治系统变得更具管理性。被分割的AS本身将成为联盟，而分割后的子自治系统则成为成员自治系统。联盟之外的自治系统将整个联盟视为一个AS，看不见成员自治系统。由于成员自治系统对外界来说是隐而不见的，因而可以使用公有或私有AS号（虽然最佳实践建议使用私有AS号）。

联盟的好处是可以极大地降低IBGP对等会话的数量。IBGP通常用于每个成员AS之内，而被称为联盟EBGP(confederation EBGP）的特殊EBGP版本运行于成员自治系统之间，无需在联盟内部的一个AS的BGP发言者与另一个AS的BGP发言者之间配置IBGP会话。

图3-28给出了一个BGP联盟示例，AS 1200被分割为3个联盟自治系统：AS 65533、 AS 65534和AS 65535。从外部自治系统（如AS 1000和AS 1500）的角度来看，整个联盟就是一个AS，即AS 1200，这些外部自治系统并不知道联盟的成员自治系统。

图3-28 AS 1200是一个BGP联盟，虽然包含了多个子自治系统，但邻居自治系统仍将联盟视为一个AS 1200

联盟EBGP运行于Panorama和Sunshine、Sunshine和Talisman、Talisman和Whitetooth之间。例3-148给出了Talisman的配置情况。

例3-148：将Talisman配置为一台联盟路由器。

Talisman被配置为联盟路由器之后，其本地AS为65 534。与其他EBGP连接一样，其与Whitetooth及Sunshine的对等连接也已建立，并且与Lakeridge之间的连接为IBGP连接。命令bgp confederation identifier的作用是告诉路由器：其是BGP联盟的成员及其联盟ID。而命令bgp confederation peers则列出Talisman所连接的成员自治系统，该命令告诉BGP进程，该EBGP连接是联盟EBGP，而不是普通的EBGP。

联盟可以仅运行BGP，可以在整个联盟中运行一个公共IGP，也可以在每个成员AS中运行不同的IGP。如图3-28所示，AS 1200中的所有路由器都运行OSPF, OSPF允许联盟内的所有本地通信，并且告诉BGP进程如何发现它们的邻居。在例3-148所示配置中，没有在任何路由器上进行OSPF和BGP的路由重分发，随后的配置示例中将不再显示OSPF的配置情况。

例3-149显示了Lakeridge和Sugarloaf的配置情况。

例3-149：在联盟路由器Lakeridge和外部路由器Sugarloaf之间配置EBGP。

在Lakeridge的配置中未使用命令bgp confederation peers，这是因为Lakeridge未运行联盟EBGP，而是与Sugarloaf之间运行了普通的EBGP连接。请注意，从Sugarloaf的角度来看，Lakeridge位于AS 1200之中，而不是位于AS 65534之中，这是因为Sugarloaf作为联盟之外的路由器，根本不知道成员自治系统的情况。

从某种程度上来说，联盟EBGP是普通BGP和IBGP的混合物。在联盟内部应遵守以下规则。

•联盟外部路由的NEXT_HOP属性在整个联盟中都被保留。

•被宣告到联盟之内的路由的MULTI_EXIT_DISC属性在整个联盟中都被保留。

•路由的LOCAL_PREF属性在整个联盟中都被保留，而不仅仅是在为它们赋值的成员AS之内。

•在联盟内部需要将成员AS的AS号加入到AS_PATH中，但这些AS号不能被宣告到联盟之外。在默认情况下，成员AS号被列在AS_PATH中作为AS_PATH属性类型4，即AS_CONFED_SEQUENCE。如果在联盟中使用了命令aggregate-address，关键字as-set会使位于聚合点之后的成员AS号被列在AS_PATH中作为AS_PATH属性类型3，即AS_CONFED_SET。

• AS_PATH中的联盟AS号用于实现环路避免功能，但是在联盟中选择最短AS_PATH时则不考虑这些联盟AS号。

上述特性的的本质原因是整个联盟都被外界视为一个自治系统。下面将给出不同的例子来说明上述特性。

如图3-28所示，AS 1000中的路由从Bridger宣告到Nakiska，并携带NEXT_HOP属性172.17.255.1，这些路由经IBGP从Nakiska宣告到Sunshine时将保留该属性。如果Sunshine采用普通的EBGP连接连接到Talisman，那么Sunshine在将这些路由宣告到Talisman之前会将这些路由的NEXT_HOP属性更改为10.33.255.1。但是，由于该连接是联盟EBGP连接，因而将保留该原始NEXT_HOP属性，Lakeridge将拥有下一跳地址为172.17.255.1的去往172.17.0.0和172.18.0.0的路由。由于Lakeridge到Sugarloaf的连接是普遍的EBGP连接，因而这些路由被宣告给Sugarloaf时的NEXT_HOP属性为10.34.255.2。

在图3-28所示的整个联盟中都使用了命令neighbor next-hop-self，因而通过IGP都能知道下一跳地址。读者可以观察Talisman和Lakeridge配置中的这些命令。

Bridger被配置为宣告MED为50的路由，Nakiska被配置为将相同路由的LOCAL_PREF设置为200，详见例3-150所示的配置结果。虽然在普通EBGP会话中，Sunshine不会宣告源自AS 1000的MED，也不会宣告仅与AS 65533相关的LOCAL_PREF，但是由于联盟被外部视为单一AS，因而这些值在整个联盟内部都必须保持一致。

例3-150：路由器Lakeridge上的来自AS 1000的路由的MED值为50, LOCAL_PREF值为200，这些值在整个联盟EBGP连接中保持一致。

（待续）

从例3-150可以看出，在去往AS 1000网络的路由的AS_PATH中包含了AS 65533。例中所示的AS_CONFED_SEQUENCE之所以出现在圆括号中，原因有二：一是该属性没有被宣告到联盟之外（如例3-151所示），二是该属性仅用于在联盟内部实现环路避免功能（而不是路径选择功能）。

例3-151:Sugarloaf将图3-28中的联盟视为单一自治系统，无法看见联盟内的成员自治系统；例3-150中出现在圆括号内的AS_CONFED_SEQUENCE被联盟ID 1200所替代。

如例3-152所示，从Whitetooth和Panorama的BGP表可以看出，成员AS号并没有对路径选择进程产生任何影响，这两台路由器都有两条路径去往AS 1000和AS 1500中的目的地——一条是通过其IBGP邻居，另一条是通过其联盟EBGP邻居。例如，Whitetooth有两条路径去往网络172.17.0.0，这两条路径的AS_PATH分别是（65534, 65533, 1000）和（65533, 1000），很明显后一个AS_PATH较短；但实际上，成员AS号是要被忽略的，因而这两条路径被视为等价路径：(1000）。对BGP决策进程来说，在其他条件均相同的情况下，普通EBGP路由优于联盟EBGP路由，联盟EBGP路由优于IBGP路由。在例3-152中，需要在联盟EBGP路由和IBGP路由之间做出决策，通过这两台路由器的BGP表可以看出，每个实例均选中了联盟EBGP路径。

例3-152：在AS联盟中选择最短AS_PATH路由时，不考虑以圆括号形式出现在Whitetooth和Panorama BGP表中的AS_CONFED_SEQUENCE。

（待续）

对图3-28所示的拓扑结构来说，忽视成员AS号不会产生任何问题。但是接下来分析一下图3-29所示的拓扑结构，与图3-28相比，只有AS 65534和AS 65535中的BGP路由器ID不同（被互换了），其余完全一致。虽然该变化看起来有些微不足道，但分析一下该变化对Sunshine的BGP决策进程的影响就会看出问题了：Talisman和Panorama同时宣告了去往AS 1500网络的路由，由于成员AS号被忽略了，且这两个邻居是联盟EBGP对等体，因而这两条路由的AS_PATH长度一致；同时，由于Talisman和Panorama都使用了命令neighbor next-hop-self，因而这两条路由去往下一跳的IGP路径也都相同；为此，只能选择邻居路由器ID最小的路径了，从而最终选中Panorama。如此一来，Sunshine将选择通过AS 65535经Panorama的路径，而不是更直接的、经Talisman的路径（如例3-153所示）。

图3-29交换了AS 65534和AS 65535中的路由器的路由器ID

例3-153：由于Panorama的路由器ID较小，致使Sunshine选择了次优路径去往AS 1500中的网络。

几乎没有任何办法能够解决图3-29所示拓扑结构带来的问题，试着过滤路由或控制管理性权值将会使配置变得非常复杂，而创建联盟的一个主要原因就是简化配置。试着利用LOCAL_PREF或MED属性来控制路由选择则充满了差错危险，因为这些属性是在整个联盟内进行宣告的。如果拓扑结构中存在环回，那么这些属性将会把路由选择到非期望地点。

因而必须通过联盟的设计来避免图3-29所示拓扑结构所引起的问题。从OSPF的设计中可以获得一个通用设计技术，即OSPF要求所有区域（area）都必须通过单一骨干区域来进行互联，从而消除了区域间的环路可能性。

图3-30中的路由器与前面的案例完全一样，但重新设计了成员自治系统：AS 65000是骨干自治系统，其他自治系统都要通过AS 65000进行互联。这样做的一个直接结果就是，任何非骨干区域AS之间的路径都有相同的距离值。从图中还可以看出，AS 65000和AS 65535之间的连接仍然可以具备冗余连接，但非骨干自治系统之间则没有冗余连接，利用BGP的环路避免机制，就可以阻止AS间的次优路径。

图3-30 AS 65000是联盟中的骨干AS，其他区域都通过AS 65000进行互联，使得所有非骨干自治系统间的AS_PATH都有相同的长度

像图3-30所示的无环路拓扑结构的另一个好处是可以在成员自治系统之间使用MED属性。为什么MED在这样的拓扑结构中就安全呢？首先来看一下图3-31所示的拓扑结构。该拓扑结构与图3-28中的联盟类似，只是AS 65534到AS 65535有冗余连接，假如这里使用了MED，那么AS 65535将优选Whitetooth/Lakeridge链路（而不是Panorama/Talisman链路）去往AS 1500。虽然可以在这两个自治系统之间获得正确的路由选择，但问题是MED也被路由器从AS 65534转发到了AS 65533，因而依赖于AS 65533如何处理MED以及Talisman传送的是哪个MED,AS 65533仍有可能会选择一条次优路由。

对图3-30来说，AS 65500可以安全地将MED发送给AS 65535，这是因为AS 65535去往其他非骨干自治系统的惟一路径就是通过骨干AS。Sunshine或Talisman都不会接受AS_PATH中包含65500的路由，因而MED被这些路由器发送到AS 65535的时候，其他成员自治系统是看不见的。

在默认情况下，对图3-30中的Panorama和Whitetooth来说，联盟EBGP路由将优于IBGP路由，因而Panorama将会把所有去往AS 1000和AS 1500网络的流量都发送给Sunshine, Whitetooth则将去往相同目的地的流量发送给Talisman。由于可以使用MED，因而AS 65535可以将所有去往AS 1000网络的流量都通过Panorama/Sunshine链路进行发送，而将所有去往AS 1500网络的流量都通过Whitetooth/Talisman链路进行发送。例3-154显示了Sunshine和Talisman的配置情况。

图3-31 MED属性在整个联盟内都被转发。如果AS 65534希望利用MED来影响AS 65535的优先级，则AS 65533也将收到这些MED

例3-154：让Sunshine和Talisman将MED发送给AS 65535。

（待续）

Sunshine将AS_PATH中包含1000的所有路由的MED值均设为100，而将AS_PATH中包含1500的所有路由的MED值均设为200,Talisman则与此相反。例3-155给出了配置前后Panorama的BGP表情况。在第一个BGP表中，路由器优选联盟EBGP路径去往所有目的地；而在第二个BGP表中，由于更改了MED值，因而Panorama选择了与Whitetooth间的IBGP链路来发送去往AS 1500网络的流量，而Whitetooth则优选联盟EBGP链路来转发流量。

例3-155:AS 65000中的路由器被配置成发送EMD属性前后的Panorama的BGP表对比情况。

如图3-32所示，在联盟中增加了两个本地子网：AS 65533中的10.33.5.0/24和AS 65535中的10.35.5.0/24,Sunshine和Talisman被重新配置成对这两个子网应用与外部网络相同的路由策略。也就是说，设置MED，让AS 65535将所有去往10.33.5.0/24的流量都通过Panorama/Sunshine链路进行发送，而将所有去往10.35.5.0/24的流量都通过Whitetooth/Talisman链路进行发送。

图3-32在AS 65533和AS 65535中增加了本地子网

从例3-156中的Panorama的BGP表可以看出，路由策略并没有发挥出所期望的效果。虽然正确配置了MED，但是路由器仍然优选其联盟EBGP路径去往这两个子网，而没有为去往10.35.5.0/24的流量优选MED较小的IBGP路径，原因在于：在默认情况下，BGP决策进程是不考虑联盟内部路由（即AS_PATH属性中无外部AS号的路由）的MED属性的。

例3-156:Panorama根据最小MED值来选择路径去往联盟外部的目的地，但是在选择联盟内部路径时却不考虑MED属性。

命令bgp deterministic-med的作用是让BGP进程在选择去往联盟内部目的地的路径时比较MED值。例3-157示范了让Panorama使用命令bgp deterministic-med时的配置情况。

例3-158显示了Panorama使用了命令bgp deterministic-med之后的输出结果，此时的Panorama就使用了MED最小的路径，而不再区分该路径是成员AS内部或外部路径了。通过使用前面案例研究中提及的命令bgp always-compare-med也能达到相似的效果，与命令bgp deterministic-med不同，命令bgp always-compare-med始终比较去往同一目的地的路径 MED属性，而不管MED是否宣告自相同的AS。对一个基于骨干的联盟来说（如图3-32所示），这不会有什么问题，因为任一个AS都只有一条路径去往邻居AS。

例3-157:Panorama在选择去往联盟内部目的地的路径时比较MED值。

例3-158:Panorama在选择联盟内部和联盟外部路由时均考虑MED属性。

还可以使用命令bgp bestpath med confed来完成上述目标。该命令与bgp deterministic-med的效果相同，区别在于：如果某条路由的AS_PATH中有一个外部AS号，而其他去往同一目的地的路由的AS_PATH中只有联盟AS号，那么路由器将选择MED最小的联盟内部路径，而忽视带有外部AS号的路径。不过这种情形极少出现，去往同一目的地如果存在两条路由，且其中一条路由指示该目的地位于联盟内部，而另一条路由指示该目的地位于联盟外部，则可以很明显地看出，要么配置有误，要么设计很差。

3.4.5案例研究：路由反射器

路由反射器是大规模自治系统中减少IBGP对等连接数量的另一种有效方法。与BGP联盟相比，路由反射器有如下两个好处。

•联盟中的所有路由器都必须理解和支持联盟机制，而路由反射只需要路由反射器了解路由反射机制即可，客户路由器将与RR间的连接都视为普通的IBGP连接；

•无论是从所需的配置命令还是从拓扑结构的设计上，路由反射的实现都相对简单些。

另一方面，如果希望利用各种EBGP控制机制来管理大规模AS，联盟将是一种较好的选择。本案例研究将示范使用两种方法的可能性。

图3-33对图3-32中的AS 65533做了一些改动，Frotress是一台路由器反射器，Nakiska和Marmot都是客户路由器。

图3-33带有路由反射器的拓扑结构：Frotress是路由器反射器，Nakiska和Marmot是客户

例3-159给出了上述3台路由器的配置情况。

例3-159：将Frotress配置成路由器反射器，将Nakiska和Marmot配置成客户路由器。

除了仅与RR之间建立IBGP对等关系之外，Nakiska和Marmot都是标准的IBGP配置。此外，Nakiska还与路由反射簇之外的Bridger建立了对等连接。为Fortress增加的惟一命令就是为每个客户路由器都增加一条语句neighbor route-reflector-client，使得Fortress成为路由反射器。该语句的作用是实现路由反射器所需的松散的IBGP规则（在第2章讨论过）——顾名思义，就是将学习自某个客户的IBGP路由宣告给其他客户以及路由反射簇之外的IBGP对等体，将学习自路由反射簇之外的IBGP对等体的IBGP路由宣告给客户。

例3-160显示了Marmot BGP表中的路由项10.33.5.0/24，最后一行显示了由RR加入的ORIGINATOR_ID和CLUSTER_LIST属性，由RR加入的ORIGINATOR_ID属性表示了宣告该路由的客户，去往10.33.5.0/24的路由的发起者是Nakiska(10.33.255.2），该属性可以确保路由不会在簇内形成环路。如果Fortress在Update（更新）消息中接收到该NLRI，那么就会识别出Nakiska的路由器ID，从而忽略该路由。由于该属性是可选非传递性属性，因而路由器无需支持和理解该属性就能加入路由反射簇中，只是会丧失环路预防等功能。

与ORIGINATOR_ID类似，CLUSTER_LIST也是一种环路预防机制。长为4个8位组的簇ID用于标识路由反射簇，由RR将簇ID加入到CLUSTER_LIST中，如果RR接收到的更新消息的CLUSTER_LIST中包含其自己的簇ID，则知道已经出现了路由环路，从而忽略该路由。该功能在路径穿越多个路由反射簇时非常有用。图3-33中路由的CLUSTER_LIST是10.33.255.4，即Fortess的路由器ID。在默认情况下，RR会在CLUSTER_LIST中录入自己的BGP RID，为了在CLUSTER_LIST中指定RR的RID之外的簇ID，需要使用命令bgp cluster-id，簇ID的取值范围为1〜4294 967 295，也可以用点分十进制的格式来指定簇ID。

例3-160：从Marmot关于子网10.33.5.0/24的BGP表项中可以看出，ORIGINATOR_ID和CLUSTER_LIST属性都是由路由反射器加入的。

如果希望在一个簇中配置多台路由反射器，就需要使用命令bgp cluster-id，以确保所有RR都将自己标识为同一簇中的成员。如图3-34所示，在拓扑结构中增加了路由器Norquay，并被配置成第二台RR，以增强路由反射簇的冗余能力。

图3-34在路由反射簇中增加Norquay以增强冗余能力

例3-161显示了Fortress和Norquay的配置情况。

例3-161：将Fortress和Norquay配置为路由反射器。

这两台RR的簇ID均被配置为33，它们之间通过标准的IBGP建立对等关系，并利用语句neighbor route-reflector-client与路由反射客户建立对等关系。从而，这两台RR可以将路由反射给客户，但IBGP规则却阻止它们宣告IBGP路由。

路由反射客户配置发生的惟一变化就是为Norquay增加IBGP配置，如例3-162所示。

例3-162：路由反射客户Nakiska和Marmot分别与Fortress和Norquay建立对等关系。

（待续）

例3-163给出了Marmot BGP表中子网10.33.5.0/24的情况。例3-160中只有单条路径去往目的地，但现在已经有了两条路径，而且这两条路径完全等价；由于路由器没有被命令maximum-paths配置为同时使用这两条路径，因而路由器将选择来自10.33.255.4的路由（即下一跳地址最小的路由）。

例3-163:Marmot正在接收来自RR(Fortress和Norquay）的路由。

虽然路由反射客户可以拥有EBGP连接（如图3-34所示的Nakiska），但通常情况下，客户应该仅与RR建立IBGP连接，而不应拥有其他IBGP邻居。这也就意味着，路由反射簇之间的连接必须通过路由反射器来建立，而不能由客户直接建立，原因就在于客户路由器不会检查所接收路由的CLUSTER_LIST属性，客户无法检测簇间环路。RR之间通过标准的IBGP建立对等关系，并遵守所有的IBGP规则，RR之间传递的额外信息是用于环路预防的CLUSTER_LIST属性。AS内的路由反射器之间必须建立全连接关系，并且还要与本AS内不属于路由反射簇的路由器之间建立全连接关系，如图3-35所示。

对于客户只能与其RR建立对等关系的规则来说，存在两种例外情况。第一种是客户本身又是另一个簇的路由反射器，这种情况就形成了路由反射器“嵌套”，也就是创建了层次化的路由反射簇（如第2章的图2-40所示）。

第二种例外情况是客户之间建立了IBGP全连接（如第2章的图2-41所示）。客户之间建立全连接关系有助于提高网络的健壮性，采用这种设计方式时，需要利用命令no bgp client-to-client reflection来配置路由反射器。这样一来，全连接的客户之间就可以按照普通的IBGP规则进行路由交换了，而且RR也不在客户之间反射路由了，但仍然需要将来自客户的路由反射给簇外的对等体，并将来自簇外对等体的路由反射给客户。

图3-35互联路由反射簇的链路必须位于路由反射器之间，而不能位于客户路由器之间

3.5推荐读物

Halabi等所著的《因特网的路由器选择技术（第2版）》，由电子工业出版社于2001年6月出版，该书是Cisco IOS Software的权威使用手册。

3.6展望

到本章为止，已经介绍完了本书所有外部网关协议的相关内容。随后的章节将介绍一些高级的IP路由问题，包括网络地址转换、多播路由和服务质量。此外，后续章节中包含外部网关协议的案例研究都将使用BGP。

3.7命令汇总

表3-3汇总了本章用到的所有命令。

表3-3命令汇总

3.8配置练习题

表3-4给出了本章配置练习题（1）～(13）所要用到的路由器及地址情况。附录E中提供了以下配置练习题的答案。

表3-4配置练习题（1)〜(13）所要用到的路由器及地址情况。

表3-4列出了配置练习题（1)～(13）所要用到的自治系统、路由器、接口及相应的IP地址，并列出了所有路由器的接口情况。对每道配置练习题来说，如果表中指示该路由器拥有一个环回接口，那么该接口就应该是所有IBGP连接的源。除非练习题中有特别规定，否则EBGP连接应该总是位于物理接口地址之间。

提示：在做每道配置练习题之前，应该根据表中所列子网画出互联网络的拓扑结构。

(1）表3-4中的AS 1是一个转接AS，其IGP是OSPF,aera 0跨越整个AS。要求不将AS内部的网络宣告到AS之外，而且运行了EBGP的子网都不允许被宣告到AS 1之内。请写出AS 1中的路由器配置，将所有内部邻居都归入对等体LOCAL。对R3来说，仅允许在环回接口间建立EBGP对等关系。最后，要使用密码ExeRcisel来验证所有的IBGP连接。

(2）表3-4中的AS 2是一个末梢（非转接）AS，其IGP是EIGRP。请配置AS 2中的路由器，让它们与外部对等体建立EBGP对等关系，并将EIGRP路由重分发到BGP中。此外，要求将学习自BGP的路由重分发到EIGRP中。最后，请部署必需的路由过滤器，以防止不正确路由被重分发。

(3）网络192.168.1.0、192.168.2.0、192.168.3.0、192.168.4.0和192.168.5.0均位于AS 2之中，AS 2的管理员希望邻居AS在发送去往192.168.1.0和192.168.3.0的流量时优选R5，并希望邻居AS在发送去往192.168.2.0和192.168.4.0的流量时优选R6，此时次优链路均作为更优链路的备份链路。192.168.5.0是一个私有网络，不允许将其宣告给EBGP对等体。请修改配置练习题（2）的配置文件，以实现上述路由策略。

(4）配置R5和R6的EBGP邻居，以便将默认路由宣告给AS 2。注意，不允许宣告其他路由。

(5)AS 2的邻居AS的管理员不同意配置练习题（2）中的某些路由策略，希望其AS中的所有路由器在发送去往192.168.3.0的流量时优选R6，将R5作为备份，在发送去往192.168.4.0的流量时优选R5，将R6作为备份。配置练习题（2）中的其他策略均接受。请给出实现上述路由策略的配置文件。

(6）表3-4中的AS 3是一个末梢（stub)AS,AS 4是一个转接AS，这两个自治系统的IGP均为OSPF,R7和R8的内部接口均位于aera 0。请给出R7和R8的BGP及OSPF配置文件，将表3-4所列出的内部地址均宣告给所有的EBGP对等体，并确保OSPF域中的路由器能够到达外部目的地。不要在BGP和OSPF之间进行路由的重分发，而且要确保R7的BGP路由器ID为192.168.3.254。

(7）请修改配置练习题（6）的配置文件，让R7和R8在直连两者的链路上运行OSPF，并将BGP从该链路上删除。子网172.16.3.0/24与172.16.4.0/24之间的流量应优选该直连链路，而将其他EBGP链路均作为备用链路。AS 3内的其他地址与AS 4间的流量应优选EBGP链路，而将直连链路作为备用链路。此外，来自其他自治系统的流量可以将直连链路作为备用路由。例如，在去往AS 4的EBGP链路出现故障时，邻居AS可以将去往AS 4的流量发给AS 3，再通过该直连链路转发给AS 4。

(8）表3-4中的AS 5是一个转接AS，其IGP是IS-IS,level 2区域47.0001跨越整个AS,192.168.9.0、192.168.10.0、192.168.11.0和192.168.12.0均是AS 5的内部网络。请给出R9、R10和R11的IS-IS及BGP配置文件，要求确保IS-IS域中的路由器都知道所有的外部路由，并将所有的内部网络都宣告给全部EBGP对等体。不要将IS-IS路由重分发到BGP中。

(9）请修改配置练习题（8）的配置文件，仅让AS 4知道网络192.168.12.0，其他自治系统都不知道。

(10）请修改配置练习题（9）的配置文件，让AS 3和AS 4优选经AS 1的路径去往网络192.168.11.0。

(11）表3-4中的AS 6拥有192.168.16.0、192.168.17.0、192.168.18.0和192.168.19.0等几个内部网络。请给出R12的BGP配置，要求向其邻居AS宣告这些网络以及这些网络的汇总路由，而邻居AS仅向其他自治系统宣告汇总路由。

(12）请修改R12的EBGP邻居的最后配置，让邻居不接受不属于R12宣告的聚合路由的所有前缀，不接受长于24bit的前缀，而且要求所接受的前缀数量不得超过5条。

(13）例3-164给出了表3-4中R7的BGP配置情况，表3-4中所列出的前缀均通过OSPF进行宣告。

例3-164：路由器R7的配置。

（待续）

请解释路由映射EX 13的作用。

(14）图3-36中的路由器R1是路由器R2、R3和R4的路由反射器，并通过帧中继PVC与这些邻居进行互连。请给出R1的配置文件，要求为连接在这4台路由器上的网络提供完全的网络连接性，簇ID为6500。

图3-36配置练习题（14）的路由反射簇

3.9故障检测及排除练习题

附录F中提供了以下故障检测及排除练习题的答案。

图3-37给出了故障检测及排除练习题（1）〜(6）的互联网络拓扑结构。

(1）例3-165给出了图3-37中路由器R2的BGP配置情况。

例3-166给出了R2的BGP表和路由表情况，虽然表中有去往图3-37中各自治系统目的地的路由，但ping这些目的地均失败，为什么？

图3-37故障检测及排除练习题（1）～(6）的互联网络

例3-165：路由器R2的配置。

例3-166：图3-37中R2的BGP表和路由表。

（待续）

(2）例3-167给出了图3-37中路由器R1和R5的debug输出结果，通过这些信息可以看出哪些问题？

例3-167：图3-37中路由器R1和R5的debug输出结果。

(3）例3-168给出了图3-37中路由器R1和R3的BGP表情况，第一个表显示通过R6(172.16.255:25)或R3（172.16.254.9)均可到达172.17.0.0/24，那么R1将选择哪条路径？为什么？

例3-168：图3-37中路由器R1和R3的BGP表。

（待续）

(4）例3-169给出了图3-37中路由器R1、R3、R6和R7的BGP及IGP配置情况。

例3-168显示了R1和R3的BGP表。对下面的每个目的地来说，R6将使用哪个下一跳地址？请解释使用这些地址的原因。

目的地：

172.20.7.102

172.18.58.35

10.53.12.6

(5）例3-170给出了图3-37中路由器R1和R3的BGP配置情况。

例3-170：路由器R1和R3的BGP配置。

要求抑制所有精确路由，仅宣告聚合路由。但R8的BGP表（如例3-171所示）却仍然显示存在精确路由，问题出在什么地方？

例3-171：图3-37中路由器R8的BGP表。

(6）来自AS 60、去往图3-37中其他自治系统的数据包应通过R6和R1之间的链路进行转发，而将R7和R3之间的链路作为备用链路（虽然去往Internet的流量仍然使用该链路）。为了实施该路由策略，R3应仅宣告默认路由和聚合路由172.16.0.0/13,R1应宣告精确路由。例3-172显示了R1、R3、R6和R7的配置情况。

例3-172:R1、R3、R6和R7的配置。

（待续）

例3-173显示了R7的路由表，从表中可以看出是否实现了上述目标？如果没有，为什么？

例3-173：故障检测及排除练习题（6）中R7的路由表。

(7）再次回顾例3-19和例3-98,Meribel将其本地路由172.17.0.0宣告给EBGP对等体（ORIGIN属性为Incomplete），而Lillehammer又将该路由又宣告回Meribel(ORIGIN属性为IGP)。请问这是否会让Meribel优选来自Lillehammer的路由，从而形成路由环路？

(8）例3-174给出了图3-24中路由器Colorado的配置情况。

例3-174：图3-24中路由器Colorado的配置。

图3-24中显示的所有路由器ID都配置在环回接口上，除BGP之外，这些路由器上未运行任何路由协议。假设图中所示的全部链路都正常，请问其他5台路由器是否都是Colorado的EBGP对等体？如果不是，为什么？

(9）参考故障检测及排除练习题（8）中路由器Colorado（如图3-24所示）的配置文件，请问从配置中删除语句no auto-summary的后果是什么？

(10）参考故障检测及排除练习题（8）中的配置文件，请问入站路由过滤器允许哪些路由？

(11）参考故障检测及排除练习题（8）中路由器Colorado（如图3-24所示）的配置文件，请问子网10.1.3.0/24中的主机可以ping哪些子网（除了自身AS内部的子网或AS间链路之外）?

第2部分
高级 IP 路由问题

第4章　网络地址转换

第5章　IP多播路由简介

第6章　IP多播路由的配置及故障检测与排除

第7章　大规模多播路由

第8章　IPv6

第9章　路由器管理

本章将主要讨论以下主题。

• NAT操作：本节将讨论网络地址转换的基础知识,包括基本概念、术语以及典型的NAT应用。

• NAT存在的问题：本节将探讨NAT应用中可能出现的潜在问题，并解释这些问题的解决方案——通过Cisco IOS Software提供的功能或网络设计技术。

• NAT配置：本节将给出各种案例研究，以示范如何配置Cisco IOS Software来执行典型的NAT功能。

• NAT故障检测与排除：本节将介绍各种检测及排除Cisco NAT故障的方法和工具。

第4章
网络地址转换

NAT.（Network Address Translation, 网络地址转换）是一种将数据包中的IP地址替换为其他IP地址的功能，该功能通常由路由器或防火墙来实现。本章主要讨论路由器中的NAT功能。

注意：　缩略语NAT可以用来表示网络地址转换（network address translation）及网络地址转换器（network address translator）（即运行 NAT功能的软件）。

4.1　NAT 操作

NAT的详细描述请参见RFC 1631。与CIDR（Classless Iinterdomain Routing,无类别域间路由）类似,NAT的本意也是通过利用较少的公有IP地址来表示大量私有IP地址的方式来降低IP地址空间的耗用速度,但此后用户发现NAT在网络迁移和融合、服务器负载共享以及创建“虚拟服务器”等方面也非常有用。本节将逐一介绍这些应用场景。在这之前,首先介绍NAT的功能及相关术语。

4.1.1　NAT 基本概念

图4-1描述了一个简单的NAT功能。设备A拥有一个属于私有地址空间（由RFC 1918所指定）的IP地址,而设备B拥有一个公有IP地址,当设备A向设备B发送数据包时,数据包需要穿越一个运行了NAT功能的路由器,由NAT路由器将数据包源地址字段中设备A的私有IP地址（192.168.2.23）替换成可以在Internet进行路由的公有IP地址（203.10.5.23）,并转发数据包。当设备B向设备A发送应答数据包时，数据包的目的地址将是203.10.5.23，因而该数据包仍要经过NAT路由器，由SSNAT路由器将目的地址替换成设备A的私有IP地址。

图4-1　NAT路由器将设备A的私有IP地址（192.168.2.23）替换成公有可路由的IP地址（203.10.5.23）

对NAT操作中所涉及的端系统来说，NAT操作是完全透明的。如图4-1所示，设备A仅知道其IP地址是192.168.2.23，而不知道地址203.10.5.23。另一方面，设备B认为设备A的地址就是203.10.5.23，根本不知道地址192.168.2.23，该私有地址对设备B来说。是隐而不见的。

NAT可以进行双向地址隐藏。如图4-2所示，在设备A和设备B上同时执行了NAT，设备A认为设备B的地址是172.16.80.91，而实际上设备B的真实地址是92.31.7.130。可以看出，为支持该地址方案，NAT路由器需要在双向转换源地址和目的地址。

图4-2　NAT路由器在双向转换源地址和目的地址

Cisco NAT设备将NAT世界划分为内部（inside）和外部（outside）两部分，内部网络通常是私有企业或ISP，外部网络是公共Internet或面向Internet的服务提供商。此外，Cisco NAT设备将地址也划分为本地（local）地址和全局（global）地址，本地地址是内部网络中设备看见的地址，全局地址则是外部网络中设备所看见的地址。根据上述4个术语，可以将地址归入以下4类。

•IL（Inside Local,内部本地地址）：分配给内部设备的地址，这些地址不会被宣告到外部网络。

•IG（Inside Global,内部全局地址）：内部设备被外部网络所知晓的地址。

•OG（Outside Global,外部全局地址）：分配给外部设备的地址,这些地址不会被宣告到内部网络。

•OL（Outside Local,外部本地地址）：是外部设备被内部网络所知晓的地址。

如图4-2所示,设备A和设备B分别位于内部网络和外部网络，192.168.2.23是内部本地地址，203.10.5.23是内部全局地址，172.16.80.91是外部本地地址，192.31.7.130是外部全局地址。

IG地址被映射到IL地址，OL地址被映射到OG地址，NAT设备在地址转换表（address translation table）中跟踪地址映射情况。例4-1显示了图4-2中NAT路由器的地址转换表，该表包含了3个表项，从下往上看，第一个表项将OL地址172.16.80.91转换为OG地址192.31.7.130，第二个表项将IG地址203.10.5.23转换为IL地址192.168.2.23，这两个表项都是静态表项，是在配置路由器转换指定地址时创建的。最后（顶部）一个表项将内部地址转换为外部地址，该表项是动态表项，是在设备A首次将数据包发送给设备B时创建的。

例4-1：图4-2中NAT路由器的地址转换表。

如前所述，NAT表项可以是静态表项或动态表项。静态表项是本地地址与全局地址之间的一对一映射，也就是说，将一个惟一的本地地址映射到一个惟一的外部地址。动态表项可以是多对一或一对多映射，多对一映射是指可以将多个地址映射到单个地址，而一对多映射则是指可以将单个地址映射到多个可用地址中的某一个地址。

下面将描述NAT的各种常见应用场景，并进一步说明静态NAT以及多种动态NAT的实现方式。

4.1.2　NAT 与 IP 地址保护

NAT的最初使命就是要减缓IP地址的耗用速度，这也是RFC 1631的重点。NAT概念的主要假设就是每个企业在任何时刻仅有少量主机连接到Internet上，而且某些设备（如打印服务器和DHCP服务器）根本就不需要连接到企业外部,因而企业可以从RFC 1918定义的私有地址空间中为网络设备分配IP地址,而将数量少得多的所分配的公有IP地址放置到企业边缘的NAT地址池中（如图4-3所示）。非惟一的私有地址是IL地址,而公有地址则是IG地址。

当内部设备向Internet发送数据包时,NAT设备会从内部全局地址池中动态地选择一个公有IP地址，并将其映射到该设备的内部本地地址，该映射操作将被记录在NAT表中。如例4-2所示，图4-3中来自企业的3个内部地址（10.1.1.1.20、10.1.197.64和10.1.63.148）通过NAT向外发送数据包，并且，来自IG池的3个地址（205.110.96.2、205.110.96.3和205.110.96.1）被分别映射到IL地址。

图4-3　在本NAT设计方案中，公有IP地址池为8倍数量的私有地址空间提供服务

例4-2:图4-3中3个来自内部本地地址空间的地址被动态映射到3个来自内部全局地址池的地址

来自外部设备（响应内部设备）的所有数据包的目的地址都是IG地址，为了确保指定连接的所有数据包都能被正确转换，要求必须在NAT表中为最初的映射关系保持一段时间。同时，当同一台设备周期性地向同一个或多个外部目的地发送数据包时，在NAT表中为表项保持一段时间也有助于减少随后的查找操作。

当表项第一次进入NAT表时，同时启动了一个定时器，该定时器的周期被称为转换超时时间（translation timeout）。每当该表项被用于转换数据包的源地址或目的地址后，该定时器就被重置。如果定时器到期，则将从NAT表中删除该表项，而动态分配的地址也将回到地址池中。Cisco的默认转换超时时间为86 400秒（即24小时），可以利用命令ip nat translation timeout来更改该默认时间。

注意：　默认转换超时时间与协议类型有关，后面的表4-3中列出了不同协议的转换超时时间值。

由于多个IL地址都可以映射到地址池中的每个IG地址，因而这种NAT应用属于多对一应用，对图4-3所示应用场景来说，就是8对1的转换关系。这个概念读者应该很熟悉，电话公司就是利用这种概念来设计交换机和中继电路的，设计容量只要同时满足全部用户中的一部分即可，航空公司利用这种概念对外超额预定航班。我们可以将这种应用理解为将IL地址统计复用到IG地址上，但是这种应用的风险（与电话公司和航空公司一样）就是一定要清楚峰值利用周期以及容量被全部耗尽时的风险。

对多对一应用来说，没有严格的本地地址空间与地址池大小的比例限制。对图4-3来说，为了满足特定需求，可以进一步扩大和/或缩小IL/IG的地址范围。例如，即便是包含了16 000 000个地址的IL地址范围10.0.0.0/8，也可以被映射到仅包含4个地址（甚至更少）的地址池——205.110.96.1〜205.110.96.4。真正的限制不是特定IL地址范围内的地址数量，而是使用该地址的实际设备数量，如果只有4台设备使用10.0.0.0/8范围内的地址，那么地址池中最多只需要4个地址，但如果内部网络的设备达到500 000台，那么就需要更大的地址池了。

当动态地址池中的地址出现在NAT表中时，就不能再用于映射其他地址了。如果地址池中的地址都被耗尽了，那么随后要穿越NAT路由器的内部数据包都将无法进行地址转换,从而被丢弃。因而一定要确保NAT池足够大且转换超时时间足够小，从而保证动态地址池永远不会被耗尽。

几乎所有企业都拥有邮件、Web及FTP服务器等需要从外部可访问的系统，而且这些系统的地址必须保持不变，否则外部主机将无法知道每次该如何到达这些系统，因而这些系统无法使用动态NAT，必须将它们的IL地址静态映射到IG地址上，而这些用于静态映射的IG地址则不能进入动态地址池。虽然这些IG地址被永久记录在NAT表中，但仍然可以从动态地址池中选择这些地址，从而会产生地址歧义。

本小节描述的NAT技术对一个不断增长的企业来说非常重要，与其不断从地址管理机构或ISP处申请更多的IP地址空间，还不如将现有的公有IP地址放置到NAT池中，并采用私有地址空间为内部网络设备重新编址。根据企业规模的大小和现有地址的分配结构，可以一次性完成重新编址工作,也可以逐步分期分布完成。

4.1.3　NAT 与 ISP 迁移

如第2章中描述的那样，CIDR的一个缺陷就是会增大用户更换ISP时的难度。如果用户已经从ISP1处分配到了地址块，但又希望将Internet服务提供商更换为ISP2，则只能将ISP1的IP地址归还给ISP1，并从ISP2处重新获取IP地址，这种地址退还工作对企业来说十分困难，而且花费不菲。

提示：　不应该过分强调地址迁移工作的难度和花费，如果在最初的时候就做好地址规划，将能极大地减轻这种地址迁移工作。

假设ISP1（拥有CIDR地址块205.113.48.0/20）为其用户A分配了一个地址空间205.113.50.0/23，如果用户A决定将其Internet服务迁移到ISP2（拥有CIDR地址块207.36.64.0/19）,ISP2又为用户A分配了一个新的地址空间207.36.76.0/23，此时，用户A无需为其内部系统重新分配IP地址，只要使用NAT即可（如图4-4所示）。虽然将地址空间205.113.50.0/23退还给了ISP1，但用户A仍然可以使用该地址空间作为IL地址，虽然该地址空间来自公有地址空间，但用户A可以不再使用该地址空间将其互连网络联接到公众Internet上。同时，将来自ISP2的地址空间207.36.76.0/23作为IG地址，并将IL地址映射（静态或动态）到这些IG地址上即可。

该NAT应用方案的一个风险就是内部本地地址有可能会被泄露到公众Internet上，如果发生了这种情况，那么被泄露地址将与合法拥有该地址的ISP1相冲突。如果ISP2使用了严格的路由过滤机制，那么这样的错误将不会泄露到Internet上。但是应该像第2章所强调的那样，任何时候都不应假设AS外部对等体能正确进行路由过滤。因而在使用这种NAT应用方案时要特别谨慎，在允许数据包进入ISP2之前必须转换所有的IL地址。

图4-4　该企业用户虽然拥有一个属于ISP1的内部本地地址空间，但属于ISP2的用户，因而使用NAT将其IL地址转换到分配自ISP2的CIDR地址块的IG地址

本NAT应用方案衍生出来的另一个问题是ISP1很可能会将地址空间205.113.50.0/23重新分配给其他用户B，那么用户A将无法到达用户B。例如，假设用户A网络中的某台主机希望将数据包发送到newbie@ISPl.com，DNS将会把目的地址解析为205.113.50.100,发送数据包的主机也将使用该地址。但不幸的是，该地址被主机误认为是用户A本地网络中的地址,从而数据包会被错误路由或被丢弃。

通过上面的案例，希望用户明白本小节所讨论的地址迁移方案虽然暂时非常有用，可以降低当前迁移的复杂度，但用户最终应该将内部网络重新编址为私有地址。

4.1.4　NAT 与多归属自治系统

CIDR的另一个不足之处在于很难实现多归属到不同的服务提供商。图4-5重新分析了第2章曾经讨论过的问题,用户多归属到ISP1和ISP2,并拥有一个CIDR地址块（属于ISP1地址块中的子网）,为了与Internet建立正确的通信关系,ISP1和ISP2都需要宣告该用户的地址空间205.113.50.0/23。如果ISP2不宣告该地址,那么该用户的所有入站流量都将经过ISP1；如果ISP2宣告了205.113.50.0/23,而ISP1仅宣告自己的CIDR地址块,那么该用户的入站流量将匹配精确路由,从而全部选择ISP2,这样就会产生以下问题。

图4-5　由于多归属用户的CIDR地址块是ISP1的CIDR地址块的一个子网,因而ISP1和ISP2都得宣告精确聚合路由

•ISP1必须在其CIDR地址块中“打孔”。这就意味着可能需要在很多路由器上修改相应的过滤器和路由策略。

•　ISP2必须宣告其竞争对手的部分地址空间,而这样做很可能会引起这两个ISP的反感。

•宣告用户的精确地址空间,那就意味着会弱化CIDR在控制Internet路由表规模方面的效率。

•某些全国性的服务提供商不接受长于/19的前缀,也就意味着Internet上的某些地方将无法知道该用户经过ISP2的路由。

图4-6显示了通过NAT来解决CIDR在多归属环境中的问题的方法:在连接ISP2的路由器上配置网络地址转换,将IG地址池设置为ISP2分配的CIDR地址块。这样,ISP2就不用再宣告ISP1的地址空间,ISP1也无需再宣告该用户的精确路由,该用户企业网中的主机既可以通过选择最靠近的边缘路由器来访问Internet,也可以通过设置一定的路由策略来访问Internet。对主机发送出来的数据包来说，无论经过哪台路由器，其IL地址都一样；但是，如果数据包是要发送给ISP2，那么就需要进行地址转换。因而从Internet的角度来看,根据转发数据包的ISP不同,来自用户的数据包中的源地址也将不同。

图4-6　利用NAT来解决图4-5中CIDR所遇到的问题

图4-7　给出了更有效的设计方案:在两台边缘路由器上都实施NAT,来自每个ISP的CIDR地址块都设置为各自NAT中的IG地址池,IL地址来自私有地址空间10.0.0.0。这样该企业用户就可以更加容易地更改ISP,所要做的只是在变更ISP时重新配置其IG地址池。

图4-7　该企业用户的IL地址与任何ISP都没有关系,ISP分配的CIDR地址块都成为NAT内部全局地址池

4.1.5　端口地址转换

前面所讨论的NAT多对一应用是一种将大量地址统计复用到一个较小的地址池的应用技术,但也有一对一的地址映射应用。例如,当来自内部全局地址池的地址被映射到内部本地地址时,在第一次映射被清除之前,这些IG地址将不能被映射到其他地址。不过,NAT有一种特定功能,可以将多个地址同时映射到单个地址,Cisco将这种功能称为PAT（port address translation,端口地址转换）,某些场合也将这种功能称为NAPT（network address and port translation,网络地址和端口转换）或IP伪装（IP masquerading）,有时也被称为地址超载（address overloading）。

TCP/IP会话并不是两个IP地址之间的包交换,而是两个IP套接字之间的包交换。所谓的套接字就是（地址,端口）二元组,如Telnet会话可以由（192.168.5.2,23）和（172.16.100.6,1026）之间的包交换组成。PAT会同时转换IP地址和端口号,来自不同地址的数据包可以被转换为同一个地址,但相应的端口号不相同,这样就可以共享同一个地址了。图4-8解释了PAT的工作原理。

图4-8　PAT同时转换IP地址和相关的端口号，因而允许多台主机同时使用同一个全局地址

如图4-8所示，4个携带内部本地地址的数据包到达NAT路由器,其中数据包1和数据包4的地址相同但源端口号不同，数据包2和数据包3的地址不同但源端口号相同。NAT路由器将这4个数据包的源地址都转换为同一个内部全局地址,由于这些数据包拥有不同的源端口号,因而仍保持着惟一性。通过转换端口号,大约可以将32 000个不同的内部本地套接字转换到同一个内部全局地址,因而对SOHO（Small Office/Home Office,小型办公室/家庭办公室）应用环境来说,PAT是一种非常有用的应用工具。此时,在去往ISP的单连接上,多台网络设备只需要一个IP地址。

4.1.6　NAT 与 TCP 负载分发

利用NAT可以将多台相同的服务器表示为单个地址。如图4-9所示，外部网络设备到达的服务器地址都是206.35.91.10,但实际上内部网络中存在4台镜像服务器,NAT路由器采取轮询（round-robin）方式在这4台服务器之间分发会话,即数据包1~4（每个数据包都来自不同的源地址）的目的地址被转换为服务器1~4,而数据包5（来自另一个源地址的会话）则将被转换到服务器1。

图4-9　发送给服务器集群（由单个地址206.35.91.10来表示）的TCP数据包以轮询方式被分别转换到4台相同服务器的真实地址

很明显,图4-9中的4台服务器必须提供相同的可访问内容。这是因为,访问服务器集群的主机可能这次选中的是服务器2，而下一次选中的则可能是服务器4，只有这样才能保证让主机在任何时刻都觉得访问的是同一台服务器。

该应用方案与基于DNS的负载共享方案类似。DNS的负载共享方案是采取轮询方式将同一个名字解析为多个不同的IP地址，该方案的不足之处在于主机接收到名字/地址解析结果后会缓存该解析结果,以后的会话将被发往同样的地址,从而降低了负载共享的效率。而基于NAT的负载共享方案仅在打开一个新的来自外部网络的TCP会话时才进行地址转换,因而可以更均衡地实现负载分发操作。对NAT TCP负载均衡来说,NAT路由器不会转换任何非TCP包的地址。

需要注意的是，与基于DNS的负载均衡类似，基于NAT的负载均衡也不稳定，因为NAT路由器并不感知服务器的故障，仍然会将数据包转换到该故障服务器的地址。这样一来，一台故障或离线服务器就会造成去往该服务器集群的流量出现路由黑洞。

4.1.7　NAT 与虚拟服务器

NAT技术不仅可以让外部通过同一个地址访问所有服务，还可以将多种服务分发到不同的地址（如图4-10所示）。

图4-10　让NAT基于目的端口号将入站数据包转换到不同的地址

如图4-10所示,企业拥有一台邮件服务器（本地地址为192.168.50.1）和一台HTTP服务器（本地地址为192.168.50.2.）,这两台服务器的全局地址均为206.35.91.10。当外部主机向内部网络发送数据包时,NAT路由器除了要检查目的地址之外,还要检查目的端口号。如图4-10所示,主机向206.35.91.10发送了一个目的端口号为25（表示邮件）的数据包，由NAT路由器将该数据包的目的地址转换为邮件服务器的地址192.168.50.1；同一台主机发出的目的端口号为80（表示HTTP）的数据包,则被NAT路由器将该数据包的目的地址转换为Web服务器的地址192.168.50.2。

4.2　NAT 存在的问题

虽然前面所讨论的NAT应用都非常简单明了，但NAT的底层功能却并不如此简单，主要有如下两个原因。

•　需要全面处理IP和TCP头部;

•　某些特定协议和应用程序的特性。

更改IP地址或TCP端口号的内容可以更改某些其他字段的含义，尤其是校验和。许多协议和应用程序都是根据数据字段中的IP地址来携带IP地址或信息，因而修改头部中的IP地址可能会更改被封装数据的含义,从而可能会破坏该应用。本节将讨论与NAT操作有关的常见问题。

4.2.1　头部检验

由于IP包的校验和是对整个头部进行计算的，因而当源IP地址或目的IP地址（或两者）发生了变化后，需要重新计算校验和。TCP头部的校验和也一样如此，需要根据TCP头部和数据来计算校验和。同时,还要对包含了源IP地址和目的IP地址的伪头部计算校验和，因而当IP地址或端口号发生变化时,TCP的校验和也必然发生变化。Cisco的NAT机制可以完成这些校验和的重新计算功能。

4.2.2　分段

回顾4.1.7小节的内容,可以让NAT根据目的端口号目的地址转换为不同的本地地址。例如，可以将目的端口号为25的数据包转换为特定IL地址，而将携带其他目的端口号的数据包转换为其他IL地址。但是,如果目的端口号为25的数据包在到达NAT路由器之前就在网络中某处被分段了,又将如何呢？包含源和目的端口号的TCP或UDP头部仅位于第一个报文片段,如果仅仅转换和转发该片段，那么NAT路由器将无法知道是否需要转换后续片段。

由于IP不能保证数据包按有序方式到达目的地，因而极有可能在第一个片段还未到达NAT路由器之前，后续片段就已经到达NAT路由器了。为此，必须设计NAT来处理这样的可能事件。

Cisco的NAT机制可以保持片段的状态信息，如果转换了第一个片段，则将保持该信息，从而可以以相同的方式转换后续到达的片段。如果后续片段先于第一个片段到达NAT路由器，则NAT路由器仅存储该片段,直至第一个片段到达后才进行检测。

4.2.3　加密

Cisco的NAT机制可以更改许多应用程序在数据字段中携带的IP地址信息。但是，如果数据字段被加密了，NAT将无法读取这些数据。因而，为了保证NAT操作的正常进行，既不能加密IP地址，也不能加密某些衍自特定内容（如TCP校验和）的相关信息。

另一种需要关注的应用是使用IPSec的VPN。对特定模式的IPSec来说，如果更改了IPSec包中的IP地址，IPSec将变得亳无意义，从而破坏了VPN应用。如论釆用了何种形式的加密操作，都需要将NAT路由器放置在安全侧，而不能将其放置在被加密路径上。

4.2.4　安全

由于NAT可以隐藏内部网络的某些细节信息,因而被某些人视为一种安全解决方案。经地址转换后的主机每次出现在Internet上的地址都可能不一样，但这至多只能被视为一种非常弱的安全手段。虽然NAT可能会延缓攻击者对特定主机的攻击速度，强迫其尝试多种IP地址欺骗程序（shell game），但无论如何也不能阻止有毅力有知识的攻击者。更糟糕的是,NAT根本就不能阻止拒绝服务或会话劫持等常见攻击。

4.2.5　协议相关问题

对发送数据包穿越NAT的终端系统来说，NAT应该是透明的，但很多应用程序（包括各种商业应用程序以及使用了部分TCP/IP协议簇的应用程序）都使用IP地址。数据字段中的信息可能会基于IP地址,或者IP地址就被携带在数据字段中，如果NAT路由器在转换IP头部中的IP地址时，根本就不知晓对数据所造成的影响，就可能会破坏这些应用程序。

表4-1列出了Cisco NAT实现所支持的应用程序。对于被表中列为在应用程序数据字段中携带IP地址信息的应用程序来说，NAT能够感知这些应用程序，并能正确地校正这些数据。请注意，表中仅列出了本书写作之时Cisco NAT所支持的应用程序，用户在部署NAT之前，应通过Cisco Web网站或TAC来查看最新的应用程序支持情况。

表4-1　直接取材自www.cisco.com网站上的Cisco白皮书:“Cisco IOS网络地址转换（NAT）包更新”。

1. ICMP

某些ICMP消息中包含了产生该消息的数据包的IP头部，表4-2列出了这些消息类型,Cisco的NAT可以检测出这些消息类型。如果消息中的IP信息与头部中被转换后的IP地址相匹配,那么NAT也将转换该IP信息。此外,ICMP头部的校验和也将像TCP和UDP那样被正确校正。

2. DNS

TCP/IP互联网络的一个核心功能（特别是对Internet来说）就是DNS（Domain Name System,域名系统），如果系统无法通过NAT获得DNS请求和响应,DNS将无法正常工作。图4-11给出了在不能转换DNS包的NAT路由器周围部署DNS服务器的方式。

图4-11中的NAT服务器进行双向地址转换:对内部网络来说，外部主机看起来就像是在网络10.0.0.0中，对外部网络来说,内部主机看起来就像是在网络204.13.55.0中。在内部和外部网络中均部署了DNS服务器,每台DNS服务器中都包含了适用于本NAT侧、将域名映射为IP地址的资源记录。

图4-11　如果NAT不支持DNS，那么必须在NAT两侧都部署DNS服务器，分别为NAT两侧的网络提供域名与IP地址的映射关系

该应用方式的一个问题就是很难维护两台DNS服务器上不一致的资源记录。一个更严重的问题是NAT映射只能采取静态方式,以匹配DNS资源记录中的映射条目,此时,地址池方式的NAT将无法工作（因为其映射关系处于动态变化中）。一种更好的应用方式（也是Cisco所支持的NAT实现方式）是让NAT支持DNS查询的地址转换。

虽然详细解释DNS的操作已经超出了本书范围，但简要描述DNS的一些重要概念将有助于读者理解DNS与NAT何时可以共存、何时不能共存。读者对域名结构可能比较熟悉,如域名cisco.com描述的就是顶级域名（com）下的二级域名（cisco）。所有IP名字空间都是以树状方式组织起来的,主机名连接在递进的更高级域名上,直至所有域名都在根部汇合。

注意：　Paul Al bitz和Cricket Liu编著的DNS and BIND（O’Reilly and Associates，1992）是一本有关DNS的优秀读物。

名字服务器存储了部分域（domain）的名字空间信息，特定名字服务器中的信息可能涵盖整个域，或域的一部分，甚至是多个域,每台名字服务器上所包含的部分名字空间信息就是名字服务器的区域（zone）。

DNS服务器既可以是主用服务器，也可以是备用服务器，主用DNS服务器从文件（以本地方式存储在DNS服务器所运行的主机上）中获取其区域信息,并作为其区域的权威（authoritative）服务器。备用DNS服务器从主用DNS服务器处获取其区域信息,其方式通过区域传输（zone transfer）的进程从主用DNS服务器上下载区域文件。

由于区域传输属于文件传输，因而NAT无法从文件中解析出地址信息。即便NAT能够解析出地址信息，但是由于区域文件一般都很大,因而会给NAT设备造成严重的性能负担。如此一来,由于区域文件中的信息在区域传输过程中不会进行地址转换,因而同一区域的主用和备用DNS服务器不能位于NAT设备的两侧。

区域文件中的信息由RR（Resource Records，资源记录）条目组成，资源记录的类型主要有:为域指定权威服务器的SOA（Start-of-Authority）记录、记录别名的CNAME（Canonical Name,规范名）记录、为域指定邮件服务器的MX（Mail Exchange,邮件交换）记录以及用于Windows NT名字服务器中的WINS（Windows Internet Name Server, Windows互联网名字服务器）记录等。对NAT来说,RR的两个重要作用是提供A（Address,地址）记录（将主机名映射为IP地址）和PTR（Pointer,指针）记录（将IP地址映射为名字）。当主机需要为特定名字找出IP地址时,其DNS解析器将查询DNS服务器的A记录；如果主机希望找出特定IP地址所代表的名字（反向查找）时,就需要查询DNS服务器的PTR记录。

图4-12给出了DNS消息的详细格式,该消息用于承载来自主机的查询消息和来自服务器的响应消息。与大多数数据包头部类似,DNS消息的头部也是一组携带了消息管理和处理信息的字段,对NAT有意义的头部信息包括一个标识消息类型（查询消息或响应消息）的比特,以及用于指示包含在DNS消息其余4部分内容中的RR数量的字段。

顾名思义，Question（问题）段是一组向服务器提问的字段，问题中可以包含一个名字（服务器必须从其A记录中为该名字匹配一个地址）或一个地址（服务器必须从其PTR记录中为该地址匹配一个名字）。请注意,每条DNS消息中都包含一个且仅包含一个问题。

当然，Answer（答案）段就是对问题的回答,答案可能会列出一条或多条RR，也可能根本就不列任何RR。Authority（权威）段和Additional（附加）段所包含的信息是对答案的补充,也有可能为空。

图4-12　DNS消息格式

当DNS包穿越Cisco NAT设备时，NAT设备将逐一检查包中的Question（问题）、Answer（答案）、Authority（权威）段和Additional（附加）段。如果该消息是一条将名字匹配到IP地址的查询消息,那么将不会包含IP地址,Answer（答案）和Additional（附加）段将为空,因而也不会进行地址转换。但是,对该查询消息的响应消息来说,其Answer（答案）段中将包含一条或多条A RR, Additional（附加）段也可能会包含相应的信息,因而NAT设备需要检索其地址转换表,以在其记录中找到相匹配的IP地址。找到匹配项后将转换响应消息中的IP地址,如果没有找到匹配项,则将丢弃该消息。

如果DNS消息是一条将已知IP地址匹配为名字的查询消息（反向查找）,NAT设备将检索其地址转换表,以匹配Question（问题）段中的地址。如果找到该地址的匹配项,NAT设备将转换该消息中的IP地址；如果没有找到匹配项,将丢弃该消息。对该查询消息的响应消息来说,其Answer（答案）段中将包含一条或多条PTR RR, Additional（附加）段也可能会包含相应的信息。与此类似,既可能会转换这些记录中的IP地址,也有可能会丢弃该响应消息。

总而言之,在应用DNS和NAT时应记住以下两点。

•　DNS A和PTR查询可以穿越Cisco NAT设备,因而NAT一侧中的主机可以向NAT另一侧的DNS服务器提出查询请求；

•　DNS区域传输进程无法穿越Cisco NAT设备,因而同一区域的主用和备用DNS服务器不能放置在NAT两侧。

3. FTP

FTP（File Transfer Protocol,文件传输协议）是一种与众不同的应用协议，它使用了两条连接（如图4-13所示）。其中,控制连接由主机发起,被主机用来与服务器交换FTP命令；数据连接则由服务器发起,用于进行真正的文件传输。

图4-13　一条FTP会话包含两条独立的TCP连接，分别是由主机发起的控制连接和由服务器发起的数据连接

建立FTP会话、传输文件的事件顺序如下。

（1）FTP服务器在TCP端口号21（即控制端口）上执行被动打开操作（也就是说,开始侦听连接请求）。

（2）主机选择临时端口用于建立控制连接和数据连接,图4-13中显示的端口号分别为1026和1027。

（3）主机在数据端口上执行被动打开操作。

（4）主机为控制连接执行主动打开操作,以便在其控制端口（如图4-13中的1026）与服务器的端口21之间建立一条TCP连接。

（5）为了进行文件传输,主机需要通过控制连接发送一个PORT命令，让服务器在主机的数据端口（如图4-13中的1027）上打开一条数据连接。

（6）服务器为数据连接执行主动打开操作,在其端口20与主机的数据端口之间创建一条TCP连接。

（7）此时就可以通过数据连接来传输所请求的文件了。

对某些安全网络来说，上述事件顺序可能会出现一些问题,对于部署防火墙或访问列表等常规安全实践来说更为如此。这些安全实践一般都通过检查TCP头部中的ACK或RST bit（标识一条连接请求）,以此来拒绝由外部网络向任意端口发起的连接请求。可以发现,当FTP服务器试图与主机的临时端口建立一条穿越防火墙的连接时,该连接会被防火墙所拒绝。

注意：　通过关键字established，可以让Cisco访问列表查找TCP头部中的ACK或RST bit。

为了克服这个问题，主机可以使用命令PASV（而不再是PORT）来打开数据连接,该命令让服务器被动地打开一个数据端口并向主机告知该端口号。之后,主机就主动打开去往该服务器端口的数据连接,由于该连接请求是通过防火墙向外建立的（而不是向内建立的）,因而不会被防火墙所阻断。

该解决方案对NAT的意义在于，命令PORT和PASV不但携带了端口号，还携带了IP地址，因此，如果FTP消息要穿越NAT设备,就必须转换这些IP地址。更糟的是,IP地址以点分十进制格式的ASCII字符进行编码,也就是说,FTP消息中的IP地址不是定长的（即正常情况下的32bit二进制表示形式）。例如,地址10.1.5.4是8个ASCII字符（包括点号）,而204.192.14.237是14个ASCII字符。因而进行地址转换后会更改消息的长度。

如果进行地址转换后的FTP消息的大小保持不变,那么Cisco的NAT设备仅重新计算校验和（除了对IP头部所做的各种操作之外）；如果地址转换操作让消息变短了,NAT设备将以ASCII字符0来填充该消息,以保证与原始消息的大小一致。

如果地址转换后的消息长度比原始消息长了，那么事情将变得非常复杂。这是因为，TCP的SEQ号和ACK号都直接基于TCP报文段的长度,Cisco的NAT设备中保存了一张用于跟踪SEQ号和ACK号变化情况的表,当FTP消息被转换后,就会在该表中加入一条包含源和目的IP地址及端口号、初始序列号及序列号的增量、时间戳等信息的表项,通过该信息,就可以正确地调整FTP消息中的SEQ和ACK号,在FTP连接关闭后可以删除该信息。

4. SMTP

SMTP（Simple Mail Transfer Protoc，简单邮件传输协议）消息中通常都包括域名，但不包括IP地址，但是在请求邮件传输时可以使用IP地址（而不是域名）,因而Cisco的NAT设备会检查SMTP消息中的相应字段,并在发现IP地址时进行地址转换。

与SMTP用于上传邮件并在服务器之间传输邮件不同，POP（Post Office Protocol，邮局协议）和IMAP（Internet Message Access Protocol,Internet消息访问协议）仅用于将邮件从邮件服务器下载到客户端。这两个协议的消息体中仅使用主机名,从来不使用IP地址,因而这些协议的消息在穿越NAT设备时无需进行特殊的检查。

5. SNMP

SNMP（Simple Network Management Protocol，简单网络管理协议）利用各种丰富多样的MIB（Management Information Bases,管理信息库）来管理各种各样的连网设备。除了大量基于Internet的MIB组之外,很多厂商还开发了许多针对自己设备的私有MIB。

从上述基本描述可以推断,MIB中可以包含一个或多个IP地址。由于SNMP拥有大量的消息、格式及变量,NAT设备无法检查SNMP消息内容中的IP地址,因而,NAT不支持对SNMP消息中的IP地址进行转换操作。

6.路由协议

IP路由协议与SNMP一样存在类似的问题。IP路由协议的种类非常多，每种协议都有自己的包格式和操作特性，因而NAT路由器无法转换IP路由协议包中的IP地址。NAT路由器在内部接口上运行路由协议的同时,还可以在外部接口上运行路由协议,但无论是通过单一路由协议,还是利用重分发机制,路由协议包都无法穿越宣告地址变化的NAT边界。由于NAT路由器位于路由域的边界,可以使用默认地址或少量汇总地址,因而这种限制也不会带来太多的问题。

7. Traceroute

各种路由跟踪工具多多少少总有些差别，像Cisco的trace命令使用的是ICMP包，而Microsoft Windows 95下的tracert则使用的是UDP包。不过这些路由跟踪工具的基本功能都相同:首先将携带增量TTL的数据包发送到目的地,再将发送ICMP超时差错消息的中间系统的地址记录下来。如前所述,Cisco NAT设备会转换ICMP的超时消息,因而可以跟踪穿越NAT设备的路由情况。

图4-14中的NAT路由器实施双向转换操作：路由器jerry.insidenet.com的IP地址为10.1.16.50，被转换为IG地址204.13.55.6；路由器berferd.outsidenet.com的IP地址为147.18.34.9,被转换为OL地址10.2.1.3,因而jerry通过OL地址来知晓berferd。

图4-14　NAT路由器实施双向转换

当jerry向berferd执行路由跟踪操作时,目的地是10.2.1.3。例4-3显示的第一跳是NAT路由器,之后由NAT路由器将目的地址转换为147.18.34.9,将源地址转换为204.13.55.6,并将该数据包转发到外部接口。当berferd接收到该跟踪包（该包被发送到伪造端口）之后,响应一个ICMP端口不可达差错包,该包的目的地址是204.13.55.6、源地址是147.18.34.9,由NAT路由器将这些地址转换为目的地址是10.1.16.50、源地址是10.2.1.3,这也是jerry最终接收到的数据包。因而,整个路由跟踪过程一切正常,但内部设备只能看见外部本地地址。

例4-3:图4-14中从jerry.insidenet.com到berferd.outsidenet.com的路由跟踪过程显示一切操作均正常,但对内部设备来说,NAT路由器“隐藏”了外部全局地址。

4.3　NAT 配置

配置NAT的第一步就是指定内部和外部接口,除此之外,具体配置与配置静态NAT或动态NAT有关。对静态NAT来说,在NAT表中创建一个合适的映射表项即可；对动态NAT来说,需要创建一个供地址转换时使用的地址池,并创建访问列表以标识需转换的地址,最后再利用一个命令将地址池和访问列表关联起来。

本节将示范NAT常见应用环境中的各种常规配置技术。

4.3.1　案例研究:静态NAT

如图4-15所示,内部网络采用10.0.0.0地址空间进行编址,主机A和主机C必须能够与外部网络进行通信,这两台设备的IP地址被转换成公有IP地址204.15.87.1/24和204.15.87.2/24。

图4-15设备A和C的内部本地地址都被路由器Mazatlan中的NAT进程静态转换为内部全局地址

例4-4显示了在Mazatlan上实现NAT的配置情况。

例4-4:在 Mazatlan上实现静态NAT。

路由器的E0接口被命令ip nat inside指定为内部接口，帧中继子接口 S1.705被命令ip nat outside指定为外部接口。

接下来，内部本地地址被命令ip nat inside source static映射到内部全局地址。上例中使用了两次该命令，分别用于主机C和主机A。例4-5显示了NAT表的情况。

例4-5：主机C和A的IL地址被静态转换为IG地址。

当主机A或C向外部网络发送数据包时，Mazatlan可以在其NAT表中查找到源地址，并进行正确的地址转换。路由器Acapulco有一条去往网络204.15.87.0的路由（对本例来说是一条静态路由），但并不知道网络10.0.0.0,因而Acapulco和主机D可以响应来自主机A和C的数据包。如果主机B或路由器Veracruz向主机D发送数据包，将正常转发该数据包，不进行地址转换；但是当主机D响应未转换的IL地址时，由于Acapulco无相关路由，因而将丢弃该响应数据包，如例4-6所示。

例4-6：当图4-15中的主机D响应主机B未被转换的IL地址时，Acapulco无网络10.0.0.0路由，因而将丢弃该响应数据包。

外部全局地址也可以被静态转换为外部本地地址。例如，假设图4-15中内部网络的管理员希望主机D “看起来”是内部网络的一部分，也就是说，使用地址10.1.3.1。例4-7显示了路由器Mazatlan的NAT配置情况。

例4-7：让Mazatlan将外部全局地址静态转换为外部本地地址。

除了加入命令ip nat outside source static之外，路由器Mazatlan的NAT配置没有发生其他变化。命令ip nat outside source static在本例中的作用是将OG地址201.114.37.5映射为OL地址10.1.3.1。例4-8给出了NAT表的结果。

例4-8：通过在Mazatlan上增加一条命令，将OG-to-OL映射加入到了NAT表中。

虽然本案例研究仅包含了静态映射，但如例4-9所示，当流量在主机A和主机D、主机C和主机D之间传递时，也同时发生了动态映射。在每种情况下，内部映射都被自动映射为外部映射。

例4-9：主机A和C的内部地址被自动映射到主机D的外部地址。

需要注意的是，本配置并不会阻止内部网络的主机向主机D的OG地址（而不是OL地址）发送数据包。如图4-16所示，主机A能够成功地ping主机D的OL（10.1.3.1）地址或OG地址（201.114.37.5）。

图4-16　主机A可以向主机D的OL地址或OG地址发送数据包

事实上，调试例4-10中主机 C的输出结果能够更详细地揭示出网络的行为，主机 C向主机 D的 OG地址发起 ping操作，但应答包显示的源地址却是主机 D的 OL地址。去往目的地201.114.37.5的ICMP Echo Request（回显请求）包在穿越NAT设备时未被更改，但源地址为201.114.37.5的 ICMP Echo Reply（回显应答）包在穿越NAT设备时却被更改为OL地址。

例4-10：虽然主机C是向201.114.37.5发起ping，但NAT设备却将应答包的源地址更改为10.1.3.1。

提示：　如果准备在实验室中重新演练本案例，那么例4-10将揭示一个非常有用的技巧。主机C实际上是一台禁用了IP路由选择（no ip routing）的Cisco路由器，并利用命令ip default-gateway指向Veracruz的本地附属接口。如例4-10所示，这样就可以使用IOS的扩展调试工具，从而能够从主机的视角来观察网络的行为。

如果内部网络的管理员希望阻止流量被发送到OG地址，那么就需要实现路由过滤器（如例4-11所示）。

例4-11：通过路由过滤器来阻止内部网络流量被发送到OG地址。

请注意，在接口E0上应用了入站过滤器。必须在转换地址之前应用路由过滤，在接口S1.705上应用的出站过滤器无法区分被转换后的目的地址。图4-17给出了过滤结果，主机A仍然能够到达主机D的OL地址，但所有发往OG地址的数据包都被阻塞了。

图4-17　在Mazatlan上实施了路由过滤之后，内部主机只能通过主机D的OL地址到达主机D

通过例4-10的debug输出结果以及例4-6，可以看出NAT本身并不能保证不将私有地址或非法IP地址泄露到公众Internet。明智的管理员会在连接ISP的接口上过滤私有的A、B、C类地址，明智的ISP也会在连接其用户的接口上做同样的事情。

对本案例研究中的不同配置来说，一个主要难点就在于几乎没有任何“现实中的”设备会使用IP地址去访问其他设备，它们几乎无一例外地都使用域名，因而DNS服务器中必须拥有正确的、与其所在的NAT侧相关联的IP地址。在图4-18中，内部网络和外部网络中都放置了DNS服务器，DNS1可能会有以下域名到地址的映射项：

图4-18　DNS1是内部网络的权威服务器，DNS2是外部网络的权威服务器

此处的所有主机都有本地地址（内部网络的本地地址）。DNS2可能会有以下域名到地址的映射项：

HostD.outsidenet.com IN A 201.114.37.5

这些表项都被映射到全局地址。DNS1是inside.net的权威服务器，DNS2是outside.net的权威服务器。例4-12给出了Mazatlan的配置情况。

例4-12：Mazatlan的NAT配置，支持图4-18中的DNS1和DNS2。

除了3台内部主机和1台外部主机之外，例4-12的配置中还有2台DNS服务器。如果主机A希望向主机D发送数据包，那么就需要先向DNS1发送一条DNS查询消息，以获取HostD.outsidenet.com的IP地址。然后DNS1向DNS2查询，由DNS2返回主机D的IP地址201.114.37.5,当该DNS消息穿越NAT设备时，地址被转化为10.1.3.1，DNS1将该地址传递给主机A，主机A就将数据包发送到该地址，之后再由NAT设备转换该数据包的源地址和目的地址。

如果主机D希望与内部网络中的主机通信，那么操作过程正好与上面相反：主机D可能会向DNS2查询HostC.insidenet.com的IP地址，然后DNS2向DNS1查询，由DNS1返回主机C的IP地址10.1.2.2，该地址又被NAT设备转换成204.15.87.2，并被DNS2传递给主机D。之后，当主机D与主机C之间交换数据包时，就由NAT设备来转换数据包的源地址和目的地址。

4.3.2　案例研究：动态NAT

前面所讨论的静态NAT配置案例研究中存在的一个主要问题就是可扩展性问题，如果图4-18中的内部设备不是4台，而是60台或6000台将会如何呢？与维护静态路由表项一样，随着网络规模的不断扩大，维护静态NAT映射关系将成为一个极大的管理负担。

图4-19中的内部网络使用10.1.1.0~10.1.2.255作为其IL地址空间，ISP为其分配的公有地址空间是204.15.86.0/23，该公有地址空间被用作地址池，实现IG地址到IL地址的动态映射。为了实现更好的可管理性和可预测性，地址空间10.1.1.0/24被映射到204.15.86.0/24，10.1.2.0/24被映射到204.15.87.0/24。

图4-19　内部网络拥有大量的IL地址和IG地址

命令ip nat pool将创建一个地址池并为该地址池命名，之后该地址池被指定为IG地址池，并被命令ip nat inside source list链接到IL地址段。例4-13显示了Mazatlan的配置情况。

例4-13：Mazatlan被配置为从地址池中动态分配IG地址。

从配置中可以看出，创建的地址池分别名为PoolOne和PoolTwo,分配给PoolOne的地址段是204.15.86.1~204.15.86.254，分配给PoolTwo的地址段是204.15.87.1~204.15.87.253。请注意，上述地址段中不包含网络地址和广播地址，命令中的关键字netmask负责进行合规性检查，以确保不会映射到204.15.87.255这样的地址。netmask的一个可替换关键字是prefix-length,例如，ip nat pool PoolTwo 204.15.87.1 204.15.87.253 prefix-length 24与带有关键字netmask 255.255.255.0的命令的效果完全相同。有了这些命令，就可以在分配204.15.86.0~204.15.86.255这样的地址段时，不会映射到“0”和“255”这样的主机地址上。但是一个好的配置实践应仅为地址池配置有效地址，以避免产生不必要的混淆。

另外需要注意的是，PoolTwo中不包含地址204.15.87.254,因为该地址已被静态分配给了DNS1。为了保证在任何时候，外部设备都能向内部设备发起会话（如DNS1）,必须采取静态地址分配方式。如果这些设备的IG地址是动态分配的，那么外部设备将无法知道该向哪个地址发送数据包。

其次，配置中使用了访问列表，以标识被转换的IP地址。在Mazatlan的配置文件中，access-list 1被用来标识IL地址段10.1.1.0~10.1.1.255, access-list 2则被用来标识IL地址段10.1.2.0~10.1.2.255。

最后，IL地址被链接到正确的地址池。例如，语句ip nat inside source list 1 pool PoolOne表示源自内部网络的IP地址（也就是IL地址）以及与access-list 1指定的地址段相匹配的地址都被转换为取自PoolOne的IG地址。

例4-4给出了配置动态NAT后的Mazatlan的NAT表，可以看出，惟一的映射表项就是DNS1的静态映射项。

例4-14：首次配置Mazatlan的动态NAT时，除了一条静态映射项之外，NAT表中没有其他任何表项。

例4-15给出了内部网络设备向外部网络发送流量后的NAT表，每个地址池都按照数值顺序（由低向高）分配IG地址。

例4-15：当内部设备向外部网络发送数据包时，动态IL-to-IG映射表项开始进入NAT表。

网络管理员可能希望IG地址的主机部分与被映射IL地址的主机部分相匹配，这时就需要在定义地址池的语句最后增加关键字type match-host（如例4-16所示）。

例4-16：通过配置让IG地址的主机部分与被映射IL地址的主机部分相匹配。

例4-17给出了相应的NAT表情况，与例4-15相比可以看出，两个例子中都转换了相同的IL地址。不过本例不再是从各个地址池中顺序选择IG地址，而是选择了主机部分相匹配的IG地址。

例4-17：IG地址的主机部分与被映射IL地址的主机部分相匹配。

在默认情况下，NAT表中动态映射表项的保持时间为86 400秒（24小时），也可以利用命令ip nat translation timeout将该时间设置为0~2 147 483 647秒（约68年）之间的任意时间。在第一次进行地址转换时开启超时周期，在每次数据包被映射表项所转换后又被重置。当地址池中的某个地址被映射到NAT表中的地址后，该地址将不能再被映射到其他地址。如果超时周期到期时没有新的映射“选中”该映射表项，那么就从NAT表中删除该表项，地址池中的该地址又重新回到地址池中，成为可用地址。如果在命令ip nat translation timeout中使用0秒或关键字never，该映射表项将永远不会从NAT表中被删除。

利用命令show ip nat translations verbose可以看到所有出现转换超时的映射表项（如例4-18所示）。命令ip nat translations verbose显示了映射表项进入NAT表中的时间、该表项最后一次被用来转换地址的时间以及超时周期到期前的剩余时间。可以使用Flags（标志）字段来标识动态转换之外的转换类型，例如，例4-18中最后一个表项就被显示为静态转换。

例4-18：使用命令ip nat translations verbose可以显示每条映射表项的详细超时周期情况。

当IL的地址段大于地址池中的IG地址数时，转换超时周期就显得非常重要。看一下例4-19中的配置情况。

例4-19：1 022个IL地址共享拥有254个IG地址的地址池。

例4-19中1 022个IL地址（10.1.0.0~10.1.3.254）被映射为254个可用IG地址，这就意味着，当NAT表中包含254个映射表项时，将不存在更多的可用IG地址，所有IL地址未被转换的数据包都将被丢弃。采取这种地址映射方案的设计者认为网络中只有一小部分用户会访问外部网络，但是由于NAT表中的映射表项将被保留24小时，从而会加大IG地址的耗尽几率。因此设计者应适当降低超时周期，以降低IG地址被耗尽的几率。

4.3.3　案例研究：网络融合

NAT在防止互联网络之间可能存在的地址冲突方面非常有用。前面的两个案例研究描述的是使用私有地址空间的网络与使用公有地址空间的网络之间的连接情况，其中，采取公有地址编址方式的互联网络可能是其他网络或Internet，最基本的要求就是必须转换RFC 1918私有地址，因为这些地址不是全球惟一的。有了NAT技术，许多企业可以在自己的互联网络中使用着相同的IP地址，当穿越Inetrnet时由NAT设备将这些私有地址“隐藏”起来。

也可以采用前面案例研究中使用公有地址空间（这些公有地址不是由地址分配机构分配的）为内部网络进行编址的配置方式。例如，内部网络的地址空间可能是171.68.0.0/16,当连接到Internet上时，由于这些地址可能已经被正式分配给了其他公司，将这些未经转换的数据包发送到Internet上将造成路由冲突，因而必须进行NAT转换。

另一种地址冲突的可能情形就是两个先前独立的网络进行融合。如图4-20所示，Surf公司和Sand公司经融合后形成了一家Surf n’Sand公司，作为两家公司融合的一部分工作就是连接现有的两个互联网络。但不幸的是，这两个互联网络的设计师在建设网络的时候都采用了相同的地址看见10.0.0.0,致使Surf公司互联网络中很多设备的地址都与Sand公司中的设备地址相同。

图4-20　必须将两个拥有很多重复地址的互联网络连接在一起

最佳解决方案是对新网络进行重新编址，但很多时候地址方案设计得都很差，使得重新编址工作变得非常复杂。例如，Surf n’Sand公司互联网络中的所有设备都采取手工方式配置IP地址，而没有通过DHCP进行地址分配。在完成网络的重新编址之前，可以使用NAT作为连接两个网络的临时解决方案。

注意：　本应用中的NAT只是一种临时解决方案，让互联网络中的地址长期存在冲突状况是一种非常不好的网络配置实践。

Surf n’Sand公司的网络管理员首先向其ISP或地址分配机构申请一段公有地址空间，并被分配了CIDR地址块206.100.160.0/19。然后，将该地址块一分为二，将地址块206.100.160.0/20分配给以前的Sand互联网络，将地址块206.100.176.0/20分配给以前的Surf互联网络。这里的一个假定是：虽然10.0.0.0网络能够支持1 600多万个主机地址，但本例两个网络中的实际主机数都不超过/20地址空间。

图4-21中的路由器Cozumel和Guaymas负责连接这两个互联网络，配置情况如例4-20所示。

图4-21　在两个互联网络的边界处使用NAT路由器以解决地址冲突问题

例4-20：图4-21中路由器Cozumel和Guaymas的NAT配置。

DNS服务器对本案例来说非常关键，在NAT配置中，每台DNS服务器都有一个静态的IL-to-IG地址映射表。假设Sand互联网络中的某台设备Beachball.sand.com希望向Surf互联网络中的Snorkel.surf.com发送数据包，并进一步假设这两台设备的IP地址均为10.1.2.2，那么将顺序发生以下事件。

（1）主机Beachball向DNS2查询Snorkel.surf.com的IP地址。

（2）DNS2向DNS1（是surf.com域的权威服务器）发出查询请求，该请求的源地址是10.16.95.200、目的地址是206.100.176.1，该查询又被转发到路由器Guaymas（Guaymas将路由206.100.176.0/20宣告到EIGRP中）。

（3）Guaymas根据静态NAT映射表项将源地址从10.16.95.200转换到206.100.160.1，并将数据包转发到Cozumel。

（4）Cozumel根据静态NAT映射表项将目的地址从206.100.176.1转换到10.100.50.1，并将该请求转发到DNS1。

（5）DNS1响应该查询请求，告知Snorkel.surf.com的IP地址是10.1.2.2，该响应消息的源地址是10.100.50.1、目的地址是206.100.160.1，响应消息被转发到Cozumel（Cozumel将路由206.100.160.0/20宣告到OSPF中）。

（6）Cozumel将DNS响应消息的源地址转换为206.100.176.1, NAT路由器也在响应消息的Answer（答案）字段中发现了地址10.1.2.2，该地址与access-list 1相匹配，从而被转换为名为Surf的地址池中的地址，对本例来说就是地址206.100.176.3。接着，该映射表项就被录入到NAT表中，响应消息也被转发到Guaymas。

（7）Guaymas将该DNS响应消息的目的地址转换为10.16.95.200，并将该响应消息转发给DNSl。

（8）DNS1通知Beachba11：Snorkel.surf.com的IP地址是206.100.176.3。

（9）接着，Beachba11开始用源地址10.1.2.2、目的地址206.100.176.3向Snorkel发送数据包。

（10）在路由器Guaymas处，源地址与access-list 1相匹配，因而从名为Sand的地址池中选择一个地址，对本例来说就是地址206.100.160.2。将源地址进行地址转换后，该映射表项就被录入到NAT表中，数据包也被转发到Cozumel。

（11）Cozumel发现目的地址206.100.176.3被映射到其NAT表中的10.1.2.2，从而将该目的地址映射为该IL地址，并将数据包转发给Snorkel。

（12）Snorkel发送一个源地址为10.1.2.2、目的地址为206.100.160.2的响应数据包，该数据包被转发到Cozumel。

（13）Cozumel将该数据包的源地址转换为206.100.176.3，并将该数据包转发给Guaymas。

（14）Guaymas将该数据包的目的地址转换为10.1.2.2，并将该数据包转发给Beachball。

通过上例可以看出，虽然这两台设备的IP地址完全一样，但它们都不知道对方的真实IP地址。上述方案的关键是路由器Cozumel和Guaymas的路由配置，要求任一台路由器都不能将10.0.0.0网络的信息泄露给对方，两台路由器的配置都不允许将携带10.0.0.0网络中目的地址的数据包转发给对方路由器（将数据包发送给直连的子网10.255.13.248/29除外）。访问列表access-list 1的作用是让这两台路由器都不对源自路由器E1接口的数据包进行地址转换。

注意：　故障检测与排除练习题（3）将要求读者进一步考虑该访问列表的配置。

例4-20中另一个值得关注的细节是，路由器Guaymas上有多个内部接口，多个内部接口是完全可行的。

上述配置中没有很明显表达出来的一个重要主题就是NAT转换超时周期与DNS缓存TTL（Time-To-Live，生存时间）周期之间的协调问题。当DNS服务器从其他DNS服务器接收到一条资源记录后，将缓存该资源记录，以便使用该记录直接响应随后到来的查询请求。对本例研究来说，DNS2会缓存将Snorkel.surf.com映射为206.100.176.3的ARR，之后DNS2就可以直接响应对Snorkel的地址查询请求，而无需再次查询DNS1。该缓存RR有一个相对应的TTL，当TTL到期时就会清除该RR。需要注意的是，DNS的TTL周期必须小于NAT的转换超时周期。

例如，假设NAT转换超时周期在10.1.2.2~206.100.176.3映射表项上到期，IG地址将重新回到地址池中，206.100.176.3之后将被映射到Surf互联网络中的一个不同的IL地址。但DNS2仍然保持着将Snorkel.surf.com映射为206.100.176.3的RR映射表项，此时如果Sand互联网络中的设备向DNS2查询Snorkel的地址，那么DNS2将响应以过期信息，从而导致数据包被发送到错误的主机。

本案例研究的最后一个关注点是Internet接入。通过在Cozumel和Guaymas之间的子网增加一台接入路由器就可以很容易地实现Internet接入（如图4-22所示），来自Surf和Sand互联网络的数据包的源地址都被进行了地址转换，惟一需要做的就是为Cozumel和Guaymas增加默认路由，以指向Internet接入路由器。

图4-22　Internet接入路由器不支持NAT功能，Internet流量的所有地址转换操作均由Cozumel和Guaymas完成

4.3.4　案例研究：通过 NAT多归属到 ISP

4.1.4小节中解释了如何通过NAT来克服多归属到不同ISP时引起的不同CIDR地址块问题。图4-7中的用户多归属到不同ISP，每个ISP看见的数据包的源地址都属于自己的地址空间，任一个ISP都不会从用户处接收源地址属于其他ISP地址块的数据包。

根据前面已经学习过的NAT案例研究，可以很容易地写出图4-7中两台NAT路由器的配置文件。但是，当其中的某台路由器多归属到这两个ISP（如图4-23所示）时将会如何呢？Montego从两个ISP接收了全部BGP路由，因而可以为所有目的地选择最佳提供商。当某个数据包被转发到ISP1时，该数据包的源地址必然源自ISP1分配的地址块205.113.50.0/23；当某个数据包被转发到ISP2时，该数据包的源地址必然源自ISP2分配的地址块207.36.76.0/23。

图4-23　ISP1和ISP2均为JamaicaNet分配了一个CIDR地址块，当数据包被转发给某个ISO时，其源地址必然源自该ISP分配的地址块

例4-21给出了让Montego在不同的接口上使用不同地址池的配置情况。

ISP分配的地址块分别被指定在地址池ISP1和ISP2中，本NAT配置的一个重要特征就是语句ip nat inside source调用的是路由映射，而不是访问列表。通过路由映射，不但可以指定IL地址，还可以指定数据包所要转发的接口或下一跳地址。ISP1_MAP指定源地址属于10.0.0.0网络（与access-list 1所标识的一样）的数据包以及将这些数据包通过接口S1.708转发到ISP1，指定源地址属于10.0.0.0网络的数据包以及将这些数据包通过下一跳地址207.36.65.254转发到ISP2。

注意：　通常情况下，为保持一致性，仅使用命令match interface或match ip next-hop,本例同时使用这两个命令的目的是起示范作用。

例4-21:图4-23中Montego的配置。

例如，地址为10.1.2.2的内部设备发送了一个目的地址为137.19.1.1的数据包。由于路由器Montego通过OSPF将默认路由宣告进了JamaicaNet，因而该数据包被转发给了Montego。Montego执行路由查找并确定去往目的地的最佳路由是经ISP2，出接口为S1.709、下一跳地址为207.36.65.254。第一条ip nat inside source语句的作用是根据ISP1_MAP来检查该信息，虽然源地址匹配，但出接口却不匹配。第二条ip nat inside source语句的作用是根据ISP2_MAP来检查该信息，此时源地址与下一跳地址均匹配，这样就将源地址转换为ISP2地址池中的地址。

例4-22给出了流量穿越ISP之后的Montego的NAT表情况。由于一个IL地址可以被映射为多个地址池中的某个地址，因而地址映射属于扩展延伸，可以显示协议类型和端口号。有关扩展映射的相关内容将在案例研究“端口地址映射”中做详细讨论。

例4-22：Montego的NAT表显示地址映射所选择的IG地址与数据包所要转发的ISP有关。

例4-22 NAT表中值得关注的内容是有关IL地址的3条表项。UDP流量及其中的一个TCP会话通过ISP2去往目的地，IL地址所映射的IG地址是207.36.76.2，其他TCP会话则通过ISP1，地址相应地就被映射为205.113.50.3。通过这些表项可以看出，虽然源地址均相同，但IG地址所选择的地址池在发生变化，而这一切都取决于数据包被转发到何处。

图4-24显示了3个自治系统的DNS服务器，ISP1和ISP2中的服务器必须接入Ochee。其中Ochee是JamaicaNet的权威DNS服务器，这样Ochee就必须拥有两个CIDR地址块中地址的静态NAT表项。通常不允许将一个IL地址同时静态映射为多个IG地址（因为这样做会产生映射歧义），但是对本案例来说，由于同一个NAT设备同时实现双向映射，因而不存在歧义问题，当Montego路由Ochee的DNS查询消息以及对DNS1和DNS2的响应消息时,能够进行正确的地址转换操作。

图4-24　DNS服务器Ochee必须拥有静态IL-to-IG映射表项，以便能响应DNS1和DNS2的查询请求

为了能够将一个IL地址映射为多个IG地址，需要在映射语句的最后增加关键字extendable，例4-23显示了Montego的NAT配置情况。

从DNS1的角度来看，Ochee的地址是205.113.50.1，请注意，NAT地址池ISP1被修改为不包含该地址。从DNS2的角度来看，Ochee的地址是207.36.76.100，该地址取自207.36.76.0/23地址块的中间，而不是两端，从而使得地址池ISP2变得不连续。上例配置中的地址池经修改后指定了两段地址：Ochee地址之前的地址和Ochee地址之后的地址。

例4-23：让Montego能够将一个IL地址静态映射为多个IG地址。

在配置不连续的地址段时，首先要为该地址池命名，并指定前缀长度或网络掩码，之后出现的配置提示符要求输入地址段列表。例4-24显示了地址池ISP2的配置步骤（包括提示符）。

例4-24：为不连续的地址段配置NAT地址池。

4.3.5　端口地址转换

前面案例研究中多归属NAT路由器的反方向是将多台设备连接到Internet的SOHO路由器，这里不是为每台设备均配置独立的公有IP地址，而是采用了PAT（Port Address Translation，端口地址转换）机制，以便让所有的SOHO设备都能共享单个IG地址。

PAT可以实现地址超载（overloading），即将多个IL地址映射到同一个IG地址。为此，路由表中的NAT表项都必须是扩展（extended）表项，不但跟踪相关的IP地址信息，还要记录协议类型和端口号信息。通过同时转换数据包的IP地址和端口号，理论上最多可以将65535个IL地址转换到单个IG地址（基于16bit的端口号计算得到）。

注意：　每条NAT表项大约占用160字节的内存，65 535条表项则将消耗10MB左右的内存和大量的CPU资源，因而在实际的PAT配置中，几乎没有映射过这么多的地址。

Cisco的NAT设备试图保持BSD的语义，在可能的情况下都会将IL端口号映射到相同的IG端口号，只有当与IL地址相关联的端口号已经能够被其他映射占用的情况下，才会映射为不同的IG端口号。

图4-25显示了连接到ISP上的3台设备情况。

接入路由器的串行接口上有一个分配自ISP的公有IP地址，如例4-25中的配置所示。

图4-25　Barbado利用PAT技术将3个内部主机地址映射为单个串行接口地址

例4-25：在图4-25的路由器Barbado上启用PAT。

利用关键字overload就可以启用PAT机制，虽然命令ip nat inside source可以引用一个地址池，但本例仅引用了配置了IG地址的接口。与以前一样，访问列表用于标识IL地址。

例4-26给出了数据包穿越接入路由器之后的接入路由器的NAT表情况。大多数IG端口都与IL端口相匹配，但需要注意表中的两个实例，其IL套接字有一个端口号已经被使用（192.168.1.2:11000和192.168.1.2:11001），因而NAT为这些套接字选择了一个未被使用的端口号，该端口号与IL端口不匹配。

例4-26：不同IL地址被映射到同一IG地址的不同端口号。

4.3.6　案例研究：TCP 负载均衡

图4-26给出的拓扑结构与PAT案例研究中的类似，只是这里的3台内部设备不再是主机，而是3台拥有镜像内容的相同服务器，目的是创建一台地址为199.198.5.1的“虚拟服务器”，即被外部视为拥有IG地址的单台服务器。在实际应用中，路由器Barbados会将地址循环（round-robin）转换为这3个IL地址。

图4-26　3台内部设备是拥有镜像内容的相同服务器，从外部看来就是单台服务器

例4-27给出了路由器Barbados的配置情况。

例4-27：路由器Barbados的NAT配置将TCP负载平均分配到3台相同的服务器上，外部设备只能看见单个内部全局地址。

需要注意的是，前面大多数案例研究中都是转换IL地址，而本案例是转换IG地址。地址池V-Server包含了一个可用IL地址列表，关键字type rotary的作用是以轮询方式分配地址池中的地址。与往常一样，访问列表的作用是标识需要转换的地址，对本例来说就是单个目的地址199.198.5.1。

例4-28显示了4台外部设备都向虚拟服务器发送了TCP流量之后的NAT表情况。可以看出，从地址池中为前3条连接（从下往上看）由低到高地按序分配了IL地址，由于地址池中仅有3个可用IP地址，因而第4条连接又被映射到最小的IL地址。

例4-28：到虚拟服务器地址199.198.5.1的TCP连接在3个真实服务器地址之间进行了负载均衡。

4.3.7　案例研究：服务分发

可以利用NAT来创建虚拟服务器，通过TCP或UDP服务（而不是TCP连接）来分发连接。图4-27中的互联网络与图4-26中的互联网络非常相似，只是此时的服务器不再相同了，不同的服务器提供不同的服务。从外部来看，这3台服务器就是一个地址为199.198.5.1的单台服务器。

图4-27　提供不同服务的3台内部设备被外部网络视为单台服务器

例4-29给出了路由器Barbados的NAT配置情况。

例4-29：Barbados的NAT被配置成根据与IP地址相关的TCP或UDP端口号来转换虚拟IG地址。

本配置中没有地址池或访问列表，而是列出了一系列简单的IL-to-IG映射关系。这些语句与以前静态语句之间的不同之处是指定了TCP或UDP以及源端口和目的端口。由于多个语句中都出现了相同的IP地址（本次是IG地址），因而必须使用关键字extendable；由于Cisco IOS Software能够自动加入本关键字，因而无需手工输入。上述语句按顺序分别映射的是SMTP（TCP端口25）、syslog（UDP端口514）、TFTP（UDP端口69）、FTP（TCP端口20和21）和HTTP（TCP端口80）。

例4-30给出了刚配置完的Barbados的NAT表情况，表中只有静态映射表项。

例4-30：在出现动态转换之前，Barbados的NAT表中只包含IL套接字到IG套接字的静态映射表项。

例4-31给出了流量穿越Barbados之后的NAT表情况。请注意，所有动态映射表项中仅出现了两个OG地址，然而会话却被映射到不同的IL地址（依据与IG地址相关联的端口号）。

例4-31：UDP和TCP包依据相关联的端口号被映射到不同的IL地址。

4.4　NAT 的故障检测与排除

Cisco NAT机制可以完成很多功能，配置也非常简单。如果出现了故障，可以重点关注以下问题。

•　动态地址池是否包含了正确的地址段？

•　动态地址池之间是否与地址重叠？

•　静态映射所用的地址与动态地址池中的地址是否重叠？

•　访问列表是否正确指定了需要进行转换的地址？是否遗漏了部分地址？是否包含了部分不应包含在内的地址？

•　是否正确指定了内部和外部接口？

对一个新的NAT配置来说，最常见的问题不是NAT本身，而是路由问题。请记住，NAT需要改变数据包中的源地址或目的地址。在进行地址转换之后，路由器是否知道如何路由新的地址？

另一个问题就是超时。如果NAT表中的动态映射表项超时后，被转换地址仍然被缓存在某些系统中，那么数据包将会被发送给错误的地址，或者目的地被误认为已经消失。除了前面已经讨论过的命令ip nat translation timeout之外，还可以更改其他默认超时周期。表4-3列出了命令ip nat translation可用的全部关键字及相应的默认超时周期值，可以将默认值更改为0~2 147 483 647秒之间的任何值。

NAT表所能容纳的映射表项理论上没有数量上的限制，但在实际应用中，映射表项的数量受到NAT设备的内存和CPU的限制，或者受到可用地址或可用端口的数量限制，每条NAT映射表项大约要占用160字节的内存容量。如果今后遇到因性能或策略等因素而不得不限制Nat映射表项时，可以使用命令ip nat translation max-entries。

另一条非常有用的故障检测与排除命令是show ip nat statistics（如例4-32所示）。该命令将显示NAT配置的汇总信息，包括有效转换类型的数量、命中现有映射表项的次数、未命中现有映射表项的次数（导致试图创建一个新的映射表项）以及地址转换到期的数量，对动态地址池来说，还包括地址池类型、全部可用地址数、已分配地址数、未成功分配的次数以及使用地址池进行转换（refcount）的次数。

例4-32:命令show ip nat statistics可以显示很多有助于分析和检测及排除NAT配置故障的信息。

最后，可以手工清除NAT表中的动态NAT映射表项。这一招在希望尽快清除非期望映射表项（而不是等到超时周期过期）或需要清除整个NAT以重新配置地址池时非常有用。请注意，当地址池中的地址被映射到NAT表中时，Cisco IOS Software不允许更改或删除地址池。命令clear ip nat translations的作用是清除映射表项，可以通过全局和本地地址或者通过TCP和UDP转换（包括端口转换）来指定清除某条映射表项，也可以使用通配符（*;）来清除整个NAT表。当然，该命令只能清除动态映射表项，无法删除静态映射表项。

4.5　参考文献

[1]Egevang和K.B.& P.Francis. RFC 1631: IP网络地址转换（NAT）（仍在发展中）。

4.6　展 望

通过本章的讨论，读者已经清楚了NAT在有效使用可用网络地址方面的作用。下一章“IP多播路由简介”将探讨一组设备必须共享相同信息时，如何利用多播路由协议来更有效地利用现有网络资源。

4.7　命令汇总

表4-4汇总了本章用到的所有命令。

4.8　配置练习题

请根据图4-28来完成配置练习题（1）~（5）。

图4-28　配置练习题（1）~（5）所要使用的互联网络

（1）图4-28中的ISP1为AS 3分配了地址块201.50.13.0/24，ISP2为AS 3分配了地址块200.100.30.0/24，RTR1和RTR2从ISP路由器处接收全部BGP路由，但不向ISP传送任何路由，它们之间运行IBGP，并在所有以太网接口上运行OSPF,BGP与OSPF之间不进行路由重分发。路由器接口的地址如下。

RTR1, E0: 172.16.3.1/24

RTR1, E1: 172.16.2.1/24

RTR1, S0: 201.50.26.13/30

RTR2, E0: 172.16.3.2/24

RTR2, E1: 172.16.1.1/24

RTR2, S0: 200.100.29.241/30

SVR1是AS 3的权威DNS服务器，其地址为172.16.3.3，DNS1以地址201.50.13.1到达SVR1，而DNS2以地址200.100.30.254到达SVR1。请据此写出RTR1和RTR2的路由及NAT配置文件，正确使用ISP分配的地址块转换内部地址，任一台内部设备都能到达两个ISP，但在任何情况下，源地址为私有地址的数据包都不能离开AS 3。

（2）图4-28中SVR2的地址是172.16.2.2,SVR3的地址是172.16.2.3，请修改配置练习题（1）中的配置文件，使得ISP1所在AS中的设备能够以轮询方式连接到DNS服务器（地址为201.50.13.3）上。

（3）从ISP2发往200.100.30.50的HTTP数据包被发送到图4-28中的SVR2，从ISP2发往200.100.30.50的SMTP数据包被发送到图4-28中的SVR3，请修改前面的配置文件，以实现本练习题的地址转换要求。

（4）要使图4-28中的5台外部设备（201.50.12.67~201.50.12.71）被AS 3中的设备分别视为192.168.1.1~192.168.1.5，请在前面的配置文件中增加相应的NAT配置语句。

（5）当AS 3中地址位于子网172.16.100.0/24中的设备向ISP2发送数据包时，要求IG地址均为200.100.30.75，请按此要求修改前面配置练习题中的配置文件。

（6）如图4-29所示，在拓扑结构中增加了冗余链路，使得RTR1和RTR2都有去往两个ISP的连接，并且两台路由器均从两个ISP处接收全部BGP路由，RTR1的S1接口地址为200.100.29.137/30，RTR2的S1接口地址为201.50.26.93/30。请写出这两台路由器的配置文件，要求保证前面练习题中的各种功能特性仍能正常工作。

图4-29　配置练习题（6）所要使用的互联网络

4.9　故障检测与排除练习题

（1）请指出例4-33配置中的错误。

例4-33:故障检测与排除练习题（1）的配置文件。

（2）图4-30中的RTR1连接了两个地址空间重叠的互联网络。

在图中的路由器上部署了NAT机制（具体配置详见例4-34），但是网络设备无法通过该路由器进行通信，请问错在何处？

图4-30　故障检测与排除练习题（2）所要使用的互联网络

例4-34：故障检测与排除练习题（2）的配置文件。

（3）参考图4-21中Cozumel和Guaymas的配置，如果删除这两个配置中的access-list 1的第一行，将会产生什么结果？Cozumel和Guaymas是否仍能ping通对方？

本章将主要讨论以下主题。

•IP多播的要求：本节将解释IP多播的基本概念，并讨论实现有效多播的功能需求（如编址和信令）。

•多播路由存在的问题：本节将探讨所有IP多播路由协议存在的共性问题。

•DVMRP（Distance Vector Multicast Routing Protocol,距离矢量多播路由协议）操作：本节将描述DVMRP的操作。

•MOSPF（Multicast OSPF,多播OSPF）操作：本节将描述MOSPF的操作。

•CBT（Core-Based Trees，核心树）操作：本节将描述CBT的操作。

•PIM（Protocol Independent Multicast，协议无关多播）简介：本节将介绍PIM-DM和PIM-SM所共享的基本PIM功能。

•PIM-DM（Protocol Independent Multicast, Dense Mode,协议无关多播—密集模式）操作：本节将描述PIM-DM的操作。

•PIM-SM（Protocol Independent Multicast, Sparse Mode,协议无关多播—稀疏模式）操作：本节将描述PIM-SM的操作。

第5章
IP多播路由简介

多播实质上就是向一组接收者发送数据的进程。将单播和广播视为多播的子集可能还存在着一定的争议，这是因为单播环境下的组成员只有一个，而对广播来说，所有可能的接收者都是组成员。本章将解释为何这样的论断仅局限于概念理解层面，因为在实际网络环境中（至少如此），多播、单播和广播之间的区别还是非常明显的。

虽然通常将无线电广播和电视节目的分发称为“广播”，但它们实质上是多播。发射器以一定的频率发送数据，通过调谐到相应的频率，部分接收组就可以接收数据，在某种意义上，这里所说的频率就是多播地址。在一定发射频率范围内的所有接收者都能接收到信号，但只有那些侦听正确频率的接收者才能真正地收到这些信号。

通过信号范围可以引出一个非常重要的概念，无线电广播和电视信号发射都有一个发射范围（scope）——它们受限于发射器的功率，不在发射范围之内的接收者都接收不到信号。通过本章内容的学习，读者将知道多播也有类似的范围。

《TCP/IP路由技术（第一卷）》中已经介绍了一些基本的IP多播知识，RIP-2、EIGRP和OSPF在交换路由信息时，都使用了多播机制以提高效率。应用程序使用多播机制的原因也是如此，即提高网络效率，节约网络资源。图5-1中有多台IP主机，其中的一台主机是数据源（S），需要将数据传送给一组（G）接收者，接收者不止一个，但该接收组也不包含全部接收者。

一种方法是源主机采取重复的单播机制来分发数据。也就是说，源主机为组中的每台目的主机均创建一个包含相同数据的独立数据包，之后以单播方式将每个数据包都发送给指定主机（如图5-2所示）。

图5-1　源主机必须将相同的数据传送给多个接收者

图5-2　利用单播将相同的数据发送给多个接收者会给源主机带来非常大的负担

如果只有少量目的地，那么该方案能工作得很好。实际上，目前很多“多播”应用采取的都是重复单播方式。但是，当接收者增加到成百上千或成千上万个时，将极大地加重主机为相同数据创建和发送多份拷贝时的负担。更重要的是，主机的接口、直连的介质、直连的路由器以及低速WAN链路都将成为潜在的瓶颈。当数据属于时延敏感型且单个数据包无法容纳全部数据时还会出现新的问题，如果所有2号数据包拷贝都必须在完成1号数据包的排队及发送工作之后才能处理，那么排队时延将会给数据流引入无法接受的间隙。

另一种可能的方法是采取广播方式来发送数据（如图5-3所示），这样可以解决源主机和本地设备的负担，此时只需为每个数据包发送一份拷贝即可。但广播方式将处理负担外延到了网络中的其他主机，这些主机都必须接收一份广播包并加以处理，非目的主机只有通过高层协议（该功能也可能由应用程序自身完成）才知道应该丢弃这些数据包。即使接收组中的主机数量仅占整个网络中主机数量的一小部分，相应的处理负担也是无法接受的。

注意：　当组成员仅占整个多播域中主机数量的一小部分时，就将该域称为稀疏式多播域（sparsely populated），在本章的后面还会遇到此概念。

广播的另一个难题在于IP路由器不会将数据包转发到广播目的地，如果图5-3中的网络云是一个路由式互联网络（而不是单一广播介质），那么这些广播包将无法到达远程主机。虽然可以使用定向广播，但这可能是最差的解决方案，不但所有的主机都要接收数据包，而且源主机还得发送重复的数据包。

图5-3　以广播方式发送数据会给网络的其余部分带来负担

多播机制可以让源主机只向单个主播目的地址发送一份数据包，从而解决了发送重复数据包的处理负担；侦听多播地址的接收者都能接收数据包，从而解决了非目的主机处理非期望数据包的负担。与广播包不同，多播路由器能够转发多播包。

IP多播机制的许多方面本章都不涉及，本书的关注点是IP路由，因而本章的重点是IP多播路由。此外，本章还会简单涉及部分与路由相关的主题。如果希望全面了解IP多播，请参考5.11节中的参考文献。

5.1　IP 多播的需求

IP多播并不是一个新概念。Steve Deering曾于1986年撰写了第一个有关多播主机需求的RFC，但直到最近，随着企业一对多和多对多应用的日益增多，大家才开始逐渐关注多播。

常见的一对多应用包括远程教育或企业新闻的视频和音频传送、基于网络的娱乐节目、新闻和股票更新、数据库或网站复制等。经典的多对多应用是会议，包括视频、音频和共享白板，多用户游戏也是一种常见的多对多应用（虽然很多企业不愿意在网络上提供该服务）。随着基于组的应用日益增多，与广播方式或重复的单播方式传送数据相比，多播所具有的效率和性能也变得更有吸引力。

在实施IP多播时，必须在大量的协议面前做出抉择，正因为如此，多播机制目前主要部署于企业网之内，因为单一管理机构比较容易做出协议选择。但随着多播应用的不断增多，客户越来越要求ISP支持穿越Internet的多播。随着越来越多重复的单播流量都要穿越Internet，消耗越来越多的带宽资源，ISP内的多播部署也越来越受关注。虽然近期企业已经开始关注多播，但最终将IP多播引向成熟的“杀手级应用”却可能是Internet娱乐。

有关多播的应用研究已经在Internet的一个子网上进行了很长一段时间，该子网被称为多播骨干网（Multicast Backbone）或MBone, ISP也开始向其用户提供多播服务，如UUNET的UUcast。但在整个Internet上都提供多播服务还有待进一步研究，并需要开发相应的AS间协议，如MBGP（Multiprotocol BGP，多协议BGP）和BGMP（Border Gateway Multicast Protocol，边界网关多播协议）。在路由策略支持能力方面，当前没有任何一种IP多播路由协议能与BGP相比拟，除非能够制定足够的策略增强工具，否则多播难以得到整个Internet的接受。

如果要在路由式互联网络上支持多播机制，必须满足以下3个基本需求。

•　必须有标识多播组的地址集；

•　必须有主机加入和离开多播组的相应机制；

•　必须有一种路由协议，让路由器在不过分占用网络资源的情况下有效地将多播流量发送给组成员。

本节将逐一分析上述基本需求，后面的章节将详细讨论满足上述基本需求的各种协议。

5.1.1　多播IP地址

IANA将D类IP地址保留用作多播地址，根据《TCP/IP路由技术（第一卷）》第2章中介绍的第一个8位组（octet）原则，D类地址的前4个bit始终是1110（如图5-4所示）。在次约束条件下计算32bit数的最小和最大值，可以知道D类地址范围为224.0.0.0~239.255.255.255。

图5-4　D类地址范围为224.0.0.0~239.255.255.255

与A、B、C类地址范围不同，D类地址范围是一种“平面”结构，不使用子网（如图5-5所示），因而D类地址有28个可变bit，可以为2^28（超过 268 000 000）个多播组进行编址。

图5-5　与A、B、C类IP地址不同，D类地址不分网络部分和主机部分

多播组是通过多播IP地址来定义的，多播组可以是永久性（permanent）的，也可以是临时性（transient）的。这里所说的永久组是指该多播组拥有永久分配的多播地址，而不是指其成员被永久分配到该多播组中，事实上，主机可以自由地加入或离开任何多播组。与此类似，临时组指的是非永久存在的多播组（如视频会议组），为该多播组分配一个非保留地址，并在该组终止时释放该地址。

表5-1列出了由IANA分配给永久组的周知地址，之前在学习路由协议时读者就已经遇到了其中的大多数地址。例如，在多路接入网络中，OSPF DRother路由器向地址为224.0.0.6的 OSPF DR和BDR发送更新消息，而DR则向地址为224.0.05的DRother路由器发送数据包。

表5-1 部分周知保留多播地址

IANA将地址段224.0.0.0〜224.255.255.255保留给路由协议和其他网络维护功能，多播路由器不转发目的地址为该地址段的数据包。此外，该地址段之外还有部分地址被保留给了开放组和商业组，如224.0.1.1被保留给NTP（Network Time Protocol，网络时间协议），224.0.1.8被保留给 SUN NIS+,224.0.6.0〜224.0.6.127被保留给Cornell ISIS Project。另一个被保留的地址段为239.0.0.0〜239.255.255.255，有关该地址组的使用将在5.2.6小节进行详细讨论。附录C或RFC 1700中列出了完整的D类保留地址列表。

组成员的NIC（Network Interface Card,网络接口卡）也必须支持多播，当主机加入一个多播组之后，NIC会计算出一个可预见的MAC地址，为此，所有支持多播的以太网、令牌环、FDDI NIC都使用保留的IEEE 802地址0100.5E00.0000来确定一个多播MAC地址。值得注意的是，该地址的第8个bit是1，对IEEE 802地址来说，该bit是I/G（Individual/Group,个体/组）bit，当该bit被置位时，表示该地址为多播地址。

1.以太网和FDDI上的多播

以太网和FDDI接口将组IP地址的低23位映射到被保留MAC地址的低23位，从而构建一个多播MAC地址（如图5-6所示），图5-6中利用D类IP地址235.147.18.23创建了MAC地址0100.5E13.1217。

图5-6　以太网和FDDI网络上的多播地址是将IP地址的最后23位与MAC地址0100.5E00.0000的前25位组合而成

回顾《TCP/IP路由技术（第一卷）》第9章中的内容，当时曾简要说明了全部OSPF路由器（All OSPF Routers）地址224.0.0.5使用的MAC地址是0100.5E00.0005，而OSPF指派路由器（All OSPF Designated Routers）地址224.0.0.6使用的MAC地址是0100.5E00.0006，现在就可以明白为何如此了。

由于仅将IP地址的低23位映射到MAC地址，因而多播MAC地址不是全球惟一的，如IP地址225.19.18.23与235.147.18.23生成的MAC地址都是0100.5E13.1217。事实上，通过计算D类地址的全部数量（2^28）与保留前缀后的NAC地址数量（2^23）之比，可以看到32个D类IP地址会映射为同一个MAC地址。

IETF的观点是，同一个LAN中两个或多个组地址生成完全相同的MAC地址的几率非常低，是完全可以接受的。只有在很少的场合下才可能会出现这样的地址冲突现象，此时同一个LAN中两个组的成员将能接收到对方的流量。在多数情况下，每个组的数据包都会去往不同的端口号或有不同的应用层验证机制，因而每个组的成员都会在传送层或更高层丢弃其他组发来的数据包。

这种可预测MAC地址方案有以下两个好处。

•　本地网中的多播源或路由器只需要向多播MAC地址发送一份数据帧，即可保证LAN中的组成员都能接收到；

•　由于知道了组地址之后即可知道MAC地址，因而无需ARP进程。

2.令牌环上的多播

令牌环网络上的多播处理方式有所不同。为访问运行了普通TR功能（如活动监视器、环参数服务器和环差错监视器）的站点，令牌环需要指定功能性（functional）MAC地址或功能相关（function-dependent）MAC地址。TRMAC地址的第一个8位组的第一个bit是I/G地址，该bit指示地址是单播地址（I/G=0）或广播/多播地址（I/G=1），第二个bit是U/L（Universal/Local，全球/本地）bit，该bit指示地址是设备制造商内嵌地址（U/L=0）或本地管理地址（U/L=1）。此外，第三个8位组的第一个bit是FAI（Functional Address Indicator，功能地址指示符）bit，其作用是区别功能性地址（I/G=1，U/L=1, FAI=0）与本地管理性组地址（I/G=1，U/L=1，FAI=1）。通过对FAI bit之后的31个bit中的某个bit（也只能是一个bit）进行置位，可以创建特殊的功能性地址，如活动监视器的功能地址是C000.0000.0001，网桥是C000.0000.0100。由于仅置位31个bit中的一个bit，因而一共存在32种功能性地址，该规则对IP多播来说非常重要。

令牌环MAC地址采用little-endian格式（即从右向左读取每个8位组），而以太网采用的则是big-endian格式（即从左向右读取每个8位组），因而以太网多播MAC地址 0100.5E13.1217将会被令牌环读取为8000.7AC8.48E6。该TR地址中的FAI bit是0，但FAI之后的31个bit中有多个bit被置位为1，因而令牌环认为该地址是非法功能性地址。

注意：　FDDI也使用little-endian格式的MAC地址，但不使用令牌环这样的功能性地址，因而支持与以太网相似的映射方案。

由于无法像以太网地址那样将IP地址映射到令牌环地址中，因而需要其他方法来解决这个问题。目前有以下两种方法来解决TR帧携带IP多播包的问题：

•　为所有携带多播包的帧使用广播地址FFFF.FFFF.FFFF;

•　使用一个保留的功能性地址C000.0004.0000。

Cisco路由器默认使用第一种方法，通过在TR接口上配置命令ip multicast use-funct-ional，也可以支持第二种方法。

但上述两种方法都有一定的缺陷。第一种方法的效率比较低，需要将多播包传送给环中的所有站点，并依靠上层协议来接受或拒绝这些多播包。第二种方法要求环中所有站点的TR NIC都能识别该功能性地址，但并不是所有的NIC都能做到这一点。第二种方法的另一个问题是识别该功能性地址的TRNIC需要向该站点的CPU发送一个中断，这样一来，即便环中的IP多播流量中等，如果去往不同多播组的多播流量都被映射到同一个功能性地址，那么主机的性能也将受到严重影响。正因为有这么多的限制因素，所以使得令牌环难以有效地支持IP多播。

5.1.2　组成员概念

在加入一个组之前，主机（或其用户）必须知道可以加入哪些组以及如何加入这些组。宣告多播组的方法有很多种，就像在线“TV指南”或Web目录一样（如图5-7所示）。

图5-7　定位多播组的一种方法是查看Web通知

也有一些工具使用SDP（Session Description Protocol，会话描述协议）和SAP（Session Advertisement Protocol，会话宣告协议）等协议来描述多播事件并宣告这些描述。图5-8给出了一个使用这些协议的应用程序示例，用户也可以通过邀请（如通过电子邮件）了解多播会话。

图5-8　使用SDP和SAP的应用程序Multikit Listen，显示了由这些协议所宣告的多播会话

有关上述机制的详细讨论已经超出了本书范围，本节假定主机已经知道多播组，在此基础上讨论如何加入和离开多播组。在讨论完这些问题之后，读者将会明白IGMP（Internet Group Management Protocol，互联网组管理协议），是如何处理这些问题的，IGMP是在单个子网中管理IP多播组的事实协议。

1.加入和离开多播组

有趣的是，多播会话源无需是其发送流量的多播组的成员，事实上，多播源通常都不知道该多播组的成员是哪些主机。接收者可以在任何时间自由加入和离开多播组，这与早期的模拟无线电广播信号或电视信号类似，听众可以在任何时间收听/收看或关闭节目，信号发射站无法直接获知谁正在收听/收看节目。

如果多播源和所有的组成员都在同一个LAN中，则无需部署其他协议，若此时源想多播IP（和MAC）地址发送数据包，组成员“收听”该地址即可。但是，如果通过路由式互联网络发送多播流量，情况将变得十分复杂。每台路由器仅仅将所有的多播包都转发到每个LAN上（以免这些LAN中存在组成员），但这种方式在一定程度上削弱了多播节约网络资源的目的。如果某些LAN中没有组成员，那么浪费的带宽和处理资源不仅仅局限于该子网，还包括通向该子网的全部数据链路和路由器。

因而，路由器必须有一定的机制来了解其所连接的网络是否有组成员，如果有，那么须了解其属于哪个多播组。当路由器能够感知多播会话时，就可以向其所连接的子网查询希望加入接收组的主机，该查询可能会被发送给“本子网内的全部系统”地址224.0.0.1，或者被发送给某个被查询多播组的特定地址。如果有一个或多个主机返回了响应消息，那么路由器就可以只将多播包发送给这些子网（如图5-9所示）。

路由器可以周期性地向子网发送查询消息。如果子网中仍然有组成员，那么这些组成员将会响应路由器的全部查询消息，以便让路由器知道它们仍是组中的有效成员；如果没有主机响应，那么路由器就会认为子网中的全部主机都已离开了多播组，从而不再向该子网转发多播组的数据包。

图5-9　多播组成员发现

2.加入等待时间

到目前为止，前述多播方案存在的一个问题是，如果主机知道所希望加入的多播组，那么该主机并不总是能够等到路由器查询该多播组。为了减小等待时间，该主机可以向路由器发送一个请求加入多播组的消息，而无需等待路由器发出查询消息。路由器接收到加入请求之后，就会立即将多播流量转发到该主机所在的子网。

该进程的好处并不局限于本地子网，在5.2.2小节中将会看到，主机发起加入请求还能让多播路由协议更加有效。如果某路由器所连接的子网中没有任何组成员，而且这些子网也不为去往其他路由器的多播流量提供转接功能，那么该路由器就可以请求上游路由器不要向其转发多播流量，这样就可以让多播流量不进入无组成员的网络中。如果之后该路由器收到来自其所连接子网的加入请求，那么该路由器将会向上游路由器发出请求消息，并开始接收相关的数据流。

该方案的折衷方式是，如果某主机向其本地路由器发出加入请求，那么就需要等待本地路由器向其上游邻居请求正确的多播流量，从而加大了加入等待时间（join latency）。加入等待时间是从主机发送加入请求到主机能真正接收到组流量之间的时间周期。当然，如果该主机决定加入多播组的时候，其所在子网中已有该多播组的其他组成员，那么加入等待时间将几乎为零，此时该主机无需向路由器发出加入请求，而只需侦听已经被转发给子网中其他组成员的多播包。

3.离开等待时间

当主机离开多播组时，允许主机显式地通知本地路由器将会提高相应的处理效率，这样本地路由器在认为子网中已经没有组成员的时候，就无需发出查询消息并等待无主机响应，而是可以更加主动地确定子网中是否还有剩余组成员。一旦接收到主机发来的离开通告，路由器就会立即向子网发出一条查询消息，以询问是否还有剩余组成员，如果接收不到任何响应，那么路由器就会断定网络中已经没有组成员，从而不再向该子网转发该多播组的数据包。这样就可以缩短离开等待时间（leave latency），离开等待时间是从子网中的最后一个组成员离开多播组到路由器停止向该子网转发多播流量之间的时间间隔。

由主机发起的组离开机制也能提高路由协议的效率，如果路由器知道其所连接的子网上已经没有任何组成员，那么就可以将自己从多播树中“剪除”，路由器确定子网中已无组成员的速度越快，就能越早地“剪除”自己。

缩短加入和离开多播组的时间也能改善多播网络的整体质量。主机可能会知道大批的多播组，如果加入和离开等待时间较短，那么意味着终端用户可以轻易地通过可用多播组进行 “频道冲浪”，就跟用户可以随意地浏览无线电广播和电视频道一样。

4.组维护

主机希望加入某个组时会给路由器发送一条消息，该消息被称为报告（report）。主机在发送报告时可以使用多个可能的目的地址。

•　可以用单播方式将报告发送给发出查询消息的路由器。此时的问题是，该子网上可能会有多台路由器在跟踪该多播组，因而所有相关的路由器都必须接收该报告。

•　可以将报告发送给地址为224.0.0.2的“本子网内的全部路由器”。但是用户很快就会发现，这对子网上其他组成员能接收到该报告也有作用。

•　为了保证其他组成员能接收到报告，可以将报告发送到地址为224.0.0.1的“本子网内的全部系统”。但这样会降低多播的效率，强制子网内所有具备多播功能的主机（而不仅仅是组成员）都在二层以上处理该报告。

•　还可以将报告发送到组地址，这样就可以确保子网内的全部组成员以及侦听该多播组成员的路由器都能接收到该报告。对于非组成员的主机来说，其NIC可以根据二层地址来拒收这些报告。

如果子网内的所有组成员都需要响应路由器发出的查询消息，将会对带宽产生不必要的浪费，毕竟路由器只要知道子网内是否还有该多播组的组成员，而无需确切地知道到底有多少个组成员或者都是哪些主机。所有组成员都响应查询消息所带来的另一个问题是，所有组成员同时响应可能会产生一定的冲突，退避并重传会消耗更多的网络及主机资源。如果所有的组成员都在该子网内，那么在主机发送报告之前产生多次冲突的可能性会随之增大。

将报告发送到组地址可以解决统一子网中出现多个报告的问题。当接收到查询消息之后，每个组成员都根据一个随机数启动一个定时器，直到该定时器超时，组成员才发送报告。由于定时器是随机的，因而最大的可能就是只有一个定时器最先超时，由该成员发送报告；由于报告被发送到组地址，因而其他组成员也都能收到该报告，这些组成员接收到报告之后，就取消各自的定时器，也就不再发送各自的报告了，因而通常只会在子网中发送一个报告。每个子网一个报告是所有路由器的统一要求。

5.网络中存在多台路由器

同一个子网中可能存在多台路由器，每台路由器都希望知道子网中是否有组成员。图5-10给出了一个示例，子网中存在两台路由器，这两台路由器通过不同的路由从同一个多播源处接收了相同的多播流，如果其中的一台路由器或路由失效，组成员依然可以通过另一台路由器继续接收多播会话。但是在正常情况下，两台路由器同时将相同数据流转发到子网中的效率比较低。

图5-10　两台路由器接收到相同的多播会话，但只有一台路由器将其转发到子网中

路由器之间能够相互感知的原因是路由协议，因而为了保证只有一台路由器将多播会话转发到子网中，需要增加一台指派路由器或查询路由器（querier），以完成多播路由协议的功能。查询路由器的作用就是转发多播流，其他路由器仅负责侦听，并在查询路由器出现故障时才开始转发多播流。

允许路由协议选举一台查询路由器的问题是存在多种可用路由协议。如果图5-10中的两台路由器运行了两种不兼容的路由协议，那么将无法检测到对方路由器上的查询路由器选举进程，从而每台路由器都将自己确定为查询路由器，两者都转发数据流。

不过，本地组管理协议与路由协议无关，每台路由器都必须运行该通用协议来查询组成员。因而将查询路由器功能交给组管理协议非常有意义，这就保证了同一子网中的路由器在确定由谁负责转发多播会话时可以运行相同的协议。

5.1.3　IGMP

无论多播互联网络中运行了多少种路由协议，都要求在主机和路由器之间运行IGMP（Internet Group Management Protocol，互联网组管理协议），所有希望加入多播组的主机和所有接口连接的子网上存在多播主机的路由器都必须运行IGMP。该协议是类似于ICMP的控制协议，某些功能也相似。与ICMP类似，IGMP负责管理高层数据交换，IGMP消息也被封装在IP头部（协议号为2），与ICMP不同的是，该消息仅局限于本地数据链路，这由IGMP的实现规则（即要求路由器永远也不转发IGMP消息）以及将TP头部中的TTL设置为1来共同完成。

目前存在两种版本的IGMP:定义在RFC 1112中的IGMPv1和RFC 2236中的IGMPv2。Cisco IOS Software Release 11.1及以后版本默认支持IGMPv2，不过许多主机的TCP/IP实现仍然仅支持IGMPv1（如安装了服务包SP4之前的Windows NT 4.0），因而可以通过命令ip igmp version来更改默认支持的IGMP版本。

下面将主要讨论IGMPv2，并简要说明与IGMPv1的不同之处。虽然IOS目前还不支持IGMPv3，但本书也会简要提及，因为将来的Cisco IOS Software可能会支持IGMPv3。

1.IGMPv2主机功能

运行IGMPv2的主机使用下列3种类型的消息。

•　Membership Report（成员关系报告）消息

•　Version 1 Membership Report（版本1成员关系报告）消息

•　Leave Group（离开组）消息

成员关系报告消息用于指示某主机希望加入某多播组，当主机第一次加入组时就发送该消息，其有时也作为本地路由器发出的Membership Query（成员关系查询）消息的响应消息。

当主机了解到多播组并希望加入时，不会等待本地路由器发出的查询消息，就像读者今后在各章节中学习到的多播协议那样，路由器可能不知道（事实上大多数时候都不知道）主机所希望加入的特定多播组，因而不会因组成员目的而发出查询消息。如果主机必须等待查询消息，那么可能根本就没有机会加入组。相反，当主机第一次加入某多播组之后，会主动向该多播组发送一条成员关系报告消息。

在路由器中，是通过（源，组）地址对来标识多播会话的。其中，源地址是会话发起者的地址，组地址是D类组地址。如果本地多播路由器并不知道主机所希望加入的多播会话，那么将会向上游多播源发送一个请求消息，接收到数据流之后，路由器就开始向请求了组成员关系的主机所在子网转发数据流。

成员关系报告消息的IP头部中的目的地址是组地址，该消息本身也包含了组地址。为了确保本地路由器能接收到主动发出的成员关系报告消息，主机需要在很短的间隔内发出一条或两条重复的报告消息，RFC 2236的建议间隔为10秒钟。

IGMPv2主机后向兼容，支持IGMPv1的成员关系报告消息。有关IGMPv2检测和支持同一子网内IGMPv1主机及路由器的相关机制将在后面进行详细讨论。

本地路由器利用查询消息周期性地轮询子网，每条查询消息中都包含一个Max Response Time（最大响应时间），通常为10秒（以1/10秒的倍数为单位）。主机接收到查询消息之后就设置一个延时定时器（值为0〜最大响应时间之间的任意值），在定时器到期时，主机会向其所属的每个多播组都发送一条成员关系报告消息，作为查询消息的响应消息。

注意:　所有启用了多播功能的设备都是组地址为224.0.0.1的“本子网内所有系统”组的成员。由于这属于默认特性，因而主机无需向该组发送成员关系报告消息。

由于成员关系报告消息的目的地址是组地址，因而除了路由器之外，位于本子网内的其他组成员也能接收到该消息。如果主机接收到某多播组的成员关系报告消息时，其延时定时器未到期，那么不会向该组发送成员关系报告消息。这样一来，路由器就可以知道本子网内至少有一个组成员，而无需让子网内的所有组成员都发送报告消息。

当主机离开组时，会以Leave Group（离开组）消息通告本地路由器，该消息包含了将要离开的多播组的地址。但是与成员关系报告消息不同，离开组消息被发送给地址为224.0.0.2的“本子网内全部路由器”，这是因为只有本子网内的多播路由器才需要知道主机是否要离开组，其他组成员根本无需知道。

RFC 2236建议，只有在将要离开的主机是发送了成员关系报告消息（以响应查询消息）的最后一台主机时，才发送离开组消息。下面将会解释，本地路由器响应Leave Group（离开组）消息的方式总是向其余组成员进行查询，如果不是“最后一个响应者”的其他组成员静静地离开多播组，那么路由器会继续转发多播会话，而不会发出查询消息，从而会在一定程度上节省网络带宽。不过，这种行为并不是必须的，如果多播应用的设计者不希望使用一个状态变量去记住哪台主机是最后一个响应查询消息的主机，那么也可以在任一台主机离开多播组时就发送离开组消息。

2.IGMPv2路由器功能

由路由器发送的IGMP消息只有查询消息。IGMPv2中有两种子类型的查询消息。

•　General Query（常规查询）

•　Group-Specific Query（特定组查询）

路由器利用General Query（常规查询）消息来轮询其所连接的每个子网，以确定是否有组成员以及检测子网中何时无任何组成员。在默认情况下，每60秒发送一条查询消息，也可以使用命令ip igmp query-interval将默认值更改为0〜65 535间的任意值。

如前所述，查询消息中也包含了最大响应时间，该值指定了主机必须以成员关系报告消息响应查询的最长时间，在默认情况下，最大响应时间为10秒。也可以使用命令ip igmp query-max-response-time来更改该默认值，最大响应时间由消息中的8bit字段来表示，以1/10秒的倍数为单位（虽然命令ip igmp query-max-response-time中的单位为秒）。例如，默认值10秒在消息中被表示成100倍的1/10秒，因而取值范围为0〜255倍的1/10秒，即0〜25.5秒。

常规查询消息被发送给地址为224.0.0.1的“本子网内全部系统”，不引用任何特定组，因而该单条消息会轮询子网中所有处于有效状态的组，以便从组成员获得报告消息。路由器会跟踪已知多播组以及连接了子网（含有有效组成员）的接口，如例5-1输出结果所示。

例5-1:命令show ip igmp groups显示了路由器所关心的IP多播组

如果Cisco多播路由器在3倍查询间隔（默认为3分钟）内无法收到特定子网上某多播组的成员关系报告消息，那么路由器将断定该子网上已经无该多播组的有效成员，从而涵盖了单个组成员被断开或在离开多播组时没有遵循IGMPv2规则等可能情况。

注意：　这与RFC 2236有所不同，RFC 2236中规定的是2倍查询间隔加上1个最大响应时间间隔。

正常情况下，主机在离开多播组时应该发送离开组消息，路由器接收到该消息后，就要确定该子网上是否还有剩余的组成员。为此，路由器需要发出Group-Specific Query（特定组查询），与常规查询不同，特定组查询中包含了组地址，并且用该组地址作为查询消息的目的地址。

如果特定组查询出现丢失或损坏，那么子网上的剩余组成员可能不会发送报告消息，这样一来，路由器可能会错误地认为该子网上已经无有效组成员，从而停止向该子网转发该多播组的会话包。为了避免这种情况的发生，路由器会以1秒为间隔发送两条特定组查询消息。

当具备多播功能的路由器初次在子网上被激活时，会将自己假定为查询路由器（负责向该子网发送所有的常规查询和特定组查询）并立即发出常规查询。

注意：　RFC 2236建议发送多条查询消息，但Cisco的IGMPv2仅发送一条。

该操作方式不仅可以快速发现子网上的有效组成员，而且可以向该子网上可能存在的其他多播路由器发出通告。当子网中存在多台多播路由器时，查询路由器的选举规则非常简单：IP地址最小的路由器即为查询路由器。因而，当子网中的已有路由器接收到新路由器发送出来的常规查询之后，就会检查查询消息的源地址。如果该地址小于自己的IP地址，那么就会将查询路由器的角色转让给新路由器；如果自己的IP地址较小，那么就继续发送查询，当新路由器接收到这些查询消息之后，发现子网中的现有路由器的IP地址较小，则放弃查询路由器的角色。

如果非查询路由器在Other Querier Present Interval（其他查询路由器呈现间隔）周期内没有收到来自查询路由器发出的查询消息，那么将会认为查询路由器已不存在，从而接替查询路由器的角色。Cisco IOS软件默认的其他查询路由器呈现间隔是查询间隔（Query Interval）的2倍（即120秒），也可以使用命令ip igmp query-timeout更改该默认值。

3.IGMPv1

IGMPv1与IGMPv2之间的主要区别如下。

•　IGMPv1无Leave Group（离开组）消息，这就意味着从最后一台主机离开多播组到路由器停止转发组流量的时间周期会更长。

•　IGMPv1无Group-Specific Query（特定组查询）消息，原因是IGMPv1无离开组消息。

•　IGMPv1无法在查询消息中包含最大响应时间，主机的最大响应时间始终为10秒钟。

•　IGMPv1无查询路由器选举进程，依赖多播路由协议在子网中选举一个指派路由器。由于不同的多播路由协议采用不同的选举机制，因而在IGMPv1下，同一个子网中可能会存在多台查询路由器。

后面的“IGMP消息格式”中将解释这些区别对IGMPv1和IGMPv2消息字段的影响。

在某些情况下，IGMPv1和IGMPv2可以共存于同一个子网中。

•　某些组成员运行IGMPv1，而其他组成员运行IGMPv2；

•　某些组成员运行IGMPv1，而路由器运行IGMPv2

•　路由器运行IGMPv2，而某些组成员运行IGMPv1；

•　某台路由器运行IGMPv1，而该子网中的其他路由器运行IGMPv2。

RFC 2236中描述了多种允许IGMPv2适配这些应用场景的实现机制。如果同一子网中同时存在IGMPv1成员和IGMPv2成员，那么IGMPv2成员在确定是否要抑制自己的Membership Report（成员关系报告）消息时，将版本1和版本2成员关系报告消息视为完全一样。也就是说，如果IGMPv2成员在其延时定时器到期之前，接收到来自路由器的查询消息，并且随后又接收到版本1成员关系报告消息，那么就不再发送成员关系报告消息。另一方面，IGMPv1主机会忽略IGMPv2消息，也就是说，如果首先向多播组发送的是版本2成员关系报告消息，那么IGMPv1成员仍然会在延时定时器到期时发送报告消息，这不但不会影响IGMPv2主机，而且能让IGMPv2路由器知道组成员中存在IGMPv1成员。

如果主机运行的是IGMPv2，而本地路由器运行的是IGMPv1，那么IGMPv1路由器会忽略IGMPv2消息。因而当IGMPv2主机接收到IGMPv1查询消息之后，会发出版本1成员关系报告消息作为响应消息。由于IGMPv1查询中不指定最大响应时间，因而IGMPv2主机使用IGMPv1的固定周期10秒钟。IGMPv2主机可以向也可以不向IGMPv1路由器发送离开组消息，IGMPv1无法识别离开组消息，因而会忽略这些消息。

如果IGMPv2路由器接收到的是版本1成员关系报告消息，那么就认为该组所有成员运行的都是IGMPv1。因而该IGMPv2路由器会忽略离开组消息，也不发送会被IGMPv1成员忽略的特定组查询消息，而是设置一个被称为Old Host Present Timer（老式主机呈现定时器）的定时器（如例5-2所示）。该定时器的定时周期与Group Membership Interval（组成员关系间隔）相同，无论何时接收到一条新的版本1成员关系报告消息，该定时器都会被重置；该定时器到期时，路由器会断定子网中已经无IGMPv1成员，从而恢复为IGMPv2消息及相关处理进程。

注意；　如前所述，Group Membership Interval（组成员关系间隔）是路由器在认定子网中无任何组成员之前等待成员关系报告消息的时间。Cisco的默认组成员关系间隔是 Query Interval（查询间隔）的3倍。

例5-2：多播路由器正在接收组239.1.2.3的IGMPv2成员关系报告消息以及组228.0.5.3的IGMPv1成员关系报告消息，IGMPv1成员关系报告消息会让路由器为该组设置一个老式主机呈现定时器。

请注意，例5-2中的路由器一直在发送IGMPv2常规查询，这些查询消息与IGMPv1查询消息的主要区别在于最大响应时间不是0。IGMPv1中没有使用携带该时间值的字段，IGMPv1主机也会忽略该字段，因而IGMPv1主机会将IGMPv2查询消息解析为IGMPv1查询消息。

例5-2中另一个值得关注的地方是，仅为组228.0.5.3设置了老式主机呈现定时器，路由器仅将该组视为IGMPv1组，而将位于同一接口上的组239.1.2.3视为IGMPv2组。

如果同一个子网中同时存在IGMPv1和IGMPv2，那么IGMPv1路由器将不参与查询路由器的选举进程，因而为了保持一致性，IGMPv2路由器将按照IGMPv1进行操作。由于没有自动转换为IGMPv1的相关机制，因而必须使用命令ip igmp version 1以手工方式将IGMPv2路由器配置为IGMPv1路由器。

4.IGMPv3

由于IGMPv3仍处于发展之中，Cisco暂时也不支持，因而本小节不会像对前两个版本那样进行详细阐述，而是给出IGMPv3将要增加以及可能会得到广泛使用的一些功能特征。

IGMPv3增加的一个主要内容就是定义了Group-and-Source-Specific Query（特定组和源查询），这样不仅可以通过组地址来标识组，还可以通过源地址来标识组。与此相对应，为了支持该标识方式，对成员关系报告及离开组消息都做了相应的修改。

当某个多播组拥有多个源（属于多对多组）时，IGMPv3路由器可以根据组成员的请求进行源过滤。例如，某特定组成员可能希望从某指定源接收组流量，或者希望从指定源之外的所有源接收组流量，那么该组成员就可以在成员关系报告消息中用Iclude或Exclude来进行源过滤。如果某特定子网上没有成员希望从某特定源接收流量，那么多播路由器就不会将该多播源的流量转发到该子网中。

5.IGMP消息格式

IGMPv2使用单一消息格式（如图5-11所示），封装消息的IP头部指示协议号为2，由于IGMP消息不能离开其所发起的本地子网，因而TTL被始终设置为1。此外，IGMPv2消息中还携带了IP Router Alert（路由器告警）选项，让路由器“更严格地检查该数据包”。

图5-11　IGMPv2消息格式

IGMPv2消息的字段定义情况如下。

•　类型（Type）字段：描述了以下4种消息类型。

—多播路由器利用Membership Query（成员关系查询）消息（0x11）来检查子网中是否还有组成员，General Membership Query（通用成员关系查询）消息将组地址字段设置为0.0.0.0，而特定组查询则将该字段设置为被查询组的组地址。

—由组成员发送的Version 2 Membership Report（版本2成员关系报告）消息（0x16），以告知路由器本子网中至少还有一个组成员。

—IGMPv 2主机用来与IGMPv 1保持后向兼容性的Version 1 Membership Report（版本1成员关系报告）消息（0x12）。

—由最后一个发送成员关系报告消息的成员所发送的离开组（Leave Group）消息（0x17），以告知路由器其将要离开多播组。

•　最大响应时间（Max Response Time）字段：仅在查询消息中进行设置，对其他类型消息来说，该字段总是为0x00。该字段指定了一个时间周期（单位为1/10秒），在该时间周期内，至少要有一个组成员必须响应以成员关系报告消息。

•　校验和（Checksum）字段：16bit IGMP消息反码和的反码，使用标准的TCP/IP校验和算法。

•　组地址（Group Address）字段：在常规查询消息中被设置为0.0.0.0，在特定组查询消息中被设置为组地址。成员关系报告消息在该字段中携带被报告的多播组的地址，而离开组消息则在该字段中携带将要离开的多播组的地址。

图5-12给出了IGMPv1的消息格式。

图5-12　IGMPv1消息格式

IGMPv1与IGMPv2消息格式的区别如下。

•　第一个8位组被分为4bit版本字段和4bit类型字段；

•　第二个8位组（IGMPv2中为最大响应时间字段）未使用，被始终设置为0x00。

还有一个区别在于，IGMPv1消息的IP头部中未设置路由器告警（Router Alert）选项。

IGMPv1仅定义了以下两种类型的消息。

•　主机成员关系查询（Host Membership Query，类型1）消息

•　主机成员关系报告（Host Membership Report，类型2）消息

IGMPv1的版本字段始终为1，因而主机成员关系查询消息的版本字段加上类型字段是 0x11，与IGMPv2成员关系查询消息中的8bit类型字段值一样；主机成员关系报告消息的版本字段加上类型字段是0x12，而IGMPv2成员关系报告消息中的类型字段值为0x16。

5.1.4　CGMP

IP多播的一个基本设计原则就是仅将流量分发到希望接收流量的目的地。通过前面的学习，读者已经明白D类编址以及相应的MAC编址方式是如何在数据链路层满足该设计需求的，也知道了IGMP如何让路由器确定是否要向特定子网分发多播会话。在后面的内容中，将会介绍IP多播路由协议是如何将这些规则扩展到互联网络上的，以及如何仅将多播会话分发到那些所连子网上有组成员的路由器上。

但是，对交换式网络（如图5-13所示）来说又会如何呢？大型办公楼和园区大量存在这样的网络，以太网交换机（实际上就是高处理能力、高端口密度的透明网桥）通过学习与端口相关的MAC地址来限制单播流量，并利用该信息来过滤和转发数据帧。但是，广播流量会被转发到每一台以太网交换机的每一个端口上，因而通常会将图5-13所示的大型网络分割为多个VLAN（Virtual LAN，虚拟LAN），以控制广播流量的范围。不过，现实中经常出现的却是一个个大型“平面式”交换网络——一个子网，即一个广播域。

图5-13　除非将该交换式园区网分割为多个VLAN，否则将成为单个广播域。也就是说，路由器端口定义了一个3层子网，所有广播帧都将被转发到全部384个交换端口上

携带IP多播包的数据帧也像多播帧一样，会被转发到同一个广播域中的每个端口，其中，广播域就是所有主机所归属的多播组。图5-14解释了该问题，图中3个多播成员连接在一个24端口交换机上，其中的一个组成员向路由器发送了一条IGMP成员关系报告消息，之后路由器开始将相应的多播会话转发到该子网。由于IGMP是3层协议，因而以太网交换机没有什么简易方法来确定组成员在哪些端口上，所以会将多播流量转发到其他23个交换端口上（源端口除外）。

图5-14　3个组成员之一向路由器发出IGMP成员关系报告消息，加入多播组A（a），当路由器开始转发多播会话时，以太网交换机将数据帧复制到除源端口之外的所有端口（b）

很明显，对交换机来说，最优处理方式是仅将多播会话转发到连接了组成员的端口上。如果能实现该处理方式，不但能提高交换效率，而且也是LAN承载多播会话的一种优选方式。例如，一路视频会议多播流大约占用1Mbit/s带宽，一路MPEG II视频流则大约占用 4Mbit/s带宽，如果能将多播会话局限于组成员所在的交换端口，则将能大大节省网络和主机的资源。

CGMP（Cisco Group Membership Protocol, Cisco组成员关系协议）就是支持该功能的一种协议，可以只将多播会话分发到那些连接了组成员的交换端口上。在分析CGMP的操作方式之前，将简要回顾一下其他控制交换式多播流量的解决方案。

1.交换式网络中可选的多播控制方法

除了CGMP之外，交换式网络中还有如下3种约束多播流量的方法，Cisco Catalyst软件同时支持这些方法。

•　手工配置交换式多播树

•　GMRP

•　IGMP Snooping（IGMP侦听）

由于这3种解决方案都没有直接承载在路由协议之上，因而本小节仅加以简要描述，有关细节信息及完整的配置指导请参见Cisco CCO上的Catalyst Switch Software Documentation（Catalyst交换机软件文档）。

手工配置交换式多播树的意思是在交换机的桥接表中加入静态表项，Cisco Catalyst交换机将该表称为CAM（Content Addressable Memory，可编址内容存储器）表。假设图5-13中的组成员连接在交换机的端口2/3、2/4和2/19上，路由器连接在端口1/1上，组IP地址是239.0.5.10，从而相应的多播MAC地址是0100.5E00.050a。以手工方式将该信息配置到Catalyst CAM表中的命令如下。

第一条命令将该表项增加到交换机的CAM表中并写入交换机的NVRAM中，该表项只能通过命令clear cam或clear config才能予以清除。作为一种可选项，可以用关键字static来替代permanent，此时该表项就不会被写入NVRAM，在交换机重置时即可被删除。

第二条命令是可选命令，其作用是告知交换机多播路由器所处的端口位置，进而将在交换机内限制多播流量的范围。

使用手工配置方式时存在一些限制条件，其中两个最明显的限制条件是非动态、不可扩展。只要有其他组成员加入到不同的交换机端口上，有组成员离开或在交换机上增加不同的多播组，都需要手工配置这些信息。除非多播组规模较小、较固定，否则这种手工配置方式都是不可行的。

另一个限制条件是手工配置方式无法穿越VLAN边界。例如，如果组239.0.5.10位于 VLAN1上，且VLAN2也位于该交换机上，那么239.0.5.10的组成员就无法位于第二个VLAN之中——所有的组成员都必须位于同一个VALN中。

另一种可选技术是GMRP（GARP Multicast Registration Protocol, GARP多播注册协议）。GMRP是IEEE 802.1p标准中定义的开放式协议，可以在交换机中动态注册/撤销注册MAC层多播组地址。利用命令set gmrp enable即可在交换机上启用GRMP，而无需在路由器上做其他配置。如IEEE 802.1p标准所建议的那样，GRMP是一种严格的二层协议。

第三种可选技术就是IGMP Snooping，利用命令set igmp enable即可在Catalyst交换机上启用IGMP Snooping，此后交换机软件将会检查ICMP消息，并知道多播路由器和组成员所处的位置。与Cisco专有的CGMP不同，IGMP Snooping得到多数交换机制造商的支持，因而适用于多厂商交换式网络。但是，检测IGMP消息就意味着必须检测每个IP包，如果以软件方式来实现，则会严重影响交换机的性能，因而建议只有在多播网络中的所有交换机都能以硬件方式实现IGMP Snooping时才开启该功能，因为使用专用的ASIC（ApplicationSpecific Integrated Circuits，专用集成电路）可以实现对IP包的线速检测。例如，Cisco Catalyst交换机就是以NFFC II（NetFlow Feature Card II, NetFlow特性卡II）来实现该功能的。

2.CGMP的操作

虽然Cisco路由器和交换机都会被配置为运行CGMP，但是只有路由器会产生CGMP包，交换机上的CGMP进程仅仅是读取CGMP包。CGMP包的类型有以下两种。

•　加入（join）包：由路由器发出，告知交换机将一个或多个成员加入到多播组中。

•　离开（leave）包：由路由器发出，告知交换机将一个或多个成员从多播组中删除，或者删除同时删除多播组。

这两种CGMP包的格式都一样，包的目的地址也始终为保留MAC地址0100.0cdd.dddd，启用了CGMP功能的交换机将始终侦听该地址。

这两种CGMP包中的基本信息就是一对或多对MAC地址，如下所示。

•　GDA（Group Destination Address，组目的地址）

•　USA（Unicast Source Address，单播源地址）

当CGMP路由器被激活时，会发送一条GDA被设置为0（0000.0000.0000）、USA被设置为自身MAC地址的CGMP Join（加入）包，以便让交换机知道自己。之后，启用CGMP功能的交换机就知道接收到加入包的端口上连接了一台多播路由器，路由器每隔60秒就发送一个这样的数据包，以保持激活状态。

当主机希望加入多播组时，会发送一条IGMP成员关系报告消息，如图5-15（a）所示。此时遵循IEEE 802.1规程的交换机会将该主机的MAC地址录入到自己的CAM表中。

图5-15　当Cisco路由器在CGMP接口上接收到IGMP成员关系报告消息之后（a），会发送CGMP加入包，以告知交换机将主机的MAC地址映射到组MAC地址（b）

注意：　Catalyst交换机的CAM表属于桥接表，记录所侦听到的MAC地址以及侦听到这些MAC地址的端口。

当路由器接收到IGMP成员关系报告消息之后，会发送一条GDA被设置为组MAC地址、USA被设置为主机MAC地址的加入包，如图5-15（b）所示。现在交换机已经感知了多播组，而且由于交换机知道主机所连接的端口，因而可以将该端口加入到多播组中，当路由器向组MAC地址发送数据帧时，交换机会将数据帧的拷贝发送给与该多播组相关的所有端口（路由器端口除外）。

只要交换式网络中仍然有组成员，路由器就会每隔60秒发送一次IGMP查询消息，并被交换机转发给组成员，之后由交换机将IGMP报告消息（为查询消息的响应消息）转发给路由器。

当主机发送IGMPv2离开消息时，该消息会被转发给路由器，如图5-16（a）所示。接着路由器会发送两条IGMP特定组查询消息，并被交换机转发到所有组端口，如果其他组成员响应了该特定组查询消息，那么路由器就会向交换机发送一个GDA被设置为组MAC地址、USA被设置为即将离开的组成员MAC地址的CGMP离开包，如图5-16（b）所示，以告知交换机从多播组中删除该即将离开的组成员端口。如果没有成员响应特定组查询消息，那么路由器将断定该子网中已无组成员，从而会向交换机发送一个GDA被设置为组MAC地址、USA被设置为0的CGMP离开包（如图5-16（c）所示），以告知交换机从其CAM表中删除该多播组。

表5-2汇总了CGMP包中GDA和USA的各种可能值以及相应的含义，只有最后两个离开包没有讨论过。其中一个离开包的GDA被设置为0、USA被设置为路由器的MAC地址，其作用是告知交换机从CAM表中删除所有多播组以及与路由器端口相关的端口，如果在交换机端口上关闭了路由器的CGMP功能，就会发送该消息。另一个离开包的GDA和USA均被设置为0，其作用是告知所有接收到该消息的交换机，从CAM表中删除所有多播组及相关的端口，如果在路由器上使用了命令clear ip cgmp，就会发送该消息。

图5-16　当路由器在CGMP接口上接收到IGMP离开消息后（a），会查询该子网中是否还有其他组成员（b）。如果有其他组成员发出了响应消息，路由器将会向交换机发送CGMP离开包，以告知交换机删除即将离开的组成员；如果没有收到成员响应消息，那么路由器将会向交换机发送CGMP离开包，以告知交换机删除整个多播组（c）

3. CGMP包格式

携带CGMP包的数据帧的源MAC地址是发信路由器的MAC地址，目的MAC地址是保留多播地址0100.0cdd.dddd。只有路由器能发起CGMP包，数据帧中的CGMP包被封装在SNAP头部中，SNAP头部的OUI字段是0x00000c，类型字段为0x2001

图5-17显示了CGMP的包格式。

图5-17　CGMP的包格式

CGMP包中的各字段定义如下。

•　版本（Version）；总是被设置为0x1，以表示版本1。

•　类型（Type）；指示数据包为Join（加入）包（0x0）或Leave（离开）包（0x1）。

•　保留（Reserved）；总是被设置为0（0x0000）。

•　计数（Count）:指示数据包携带了多少GDA/USA对。

•　GDA是组目的地址（Group Destination Address），该字段非0时指示多播组的MAC地址，该字段为0（0000.0000.0000）时指示所有可能的多播组。

•　USA是单播源地址（Unicast Source Address），该字段非0时可以指示发信路由器的MAC地址或组成员的MAC地址，该字段为0时指示所有组成员和发信路由器。

5.2　多播路由存在的问题

目前存在以下5种处于不同发展和部署阶段的多播路由协议。

•　DVMRP（Distance Vector Multicast Routing Protocol，距离矢量多播路由协议）

•　MOSPF（Multicast OSPF，多播OSPF）

•　CBT（Core-Based Trees，核心树）

•　PIM-DM（Protocol Independent Multicast, Dense Mode，协议无关多播—密集模式）

•　PIM-SM（Protocol Independent Multicast, Sparse Mode，协议无关多播—稀疏模式）

后续章节中将对有关每种多播路由协议的细节信息进行详细说明，并讨论每种协议的优缺点。虽然Cisco IOS Software不同时支持上述5种协议，但学习它们有助于更好地理解为何支持/不支持它们。在上述5种协议中，Cisco IOS Software支持PIM-DM和PIM-SM，也支持DVMRP，并允许将PIM网络连接到DVMRP网络上。上述5种协议都属于多播IGP，有关跨越AS边界的多播技术将在第7章中进行详细讨论。

虽然这5种多播路由协议之间的差别很大，但与单播路由协议相似，它们之间也有一些共同点，本节将讨论任意多播路由协议设计方面的一些通用问题。

5.2.1　多播转发

与其他路由器一样，多播路由器的两个基本功能也是路由发现和包转发。本小节将讨论多播转发方面的特殊需求，下一小节将讨论多播路由发现方面的需求。

单播包转发就是将某个数据包向确定的目的地进行转发。除非配置了某些特殊策略，否则单播路由器不会关心数据包的源。在接收到数据包之后，单播路由器会检查数据包的目的IP地址，并执行最长匹配路由查找操作，最后通过某个接口将数据包向目的地进行转发。

与单播路由器将数据包向目的地进行转发不一样，多播路由器是将数据包向远离源的方向进行转发。这个区别看起来有些微不足道，但这正是正确进行多播包转发的基础。多播包源自单个源，但却去往一组目的地。对特定路由器来说，数据包会到达某个入接口，但却可能将多份数据包拷贝从多个出接口进行向外转发。

如果存在路由环路，那么一个或多个被转发的数据包将会回到入接口，然后被复制并沿着相同的出接口被转发出去，其结果就是产生多播风暴（multicast storm），让数据包不断地被环回、复制，直至TTL到期。由于数据包会被不断地复制，因而多播风暴比简单的单播环路产生的后果更加严重。因此，所有的多播路由器都必须能感知数据包的源，而且必须只能向离开源的方向转发数据包。

一个有用的常见术语就是上行（upstream）和下行（downstream），多播包应该总是沿着自源至目的地的下行方向进行传递，而不能沿着自目的地至源的上行方向进行传递。为此，每台多播路由器都必须维护一个记录（源，组）或（S，G）的多播转发表，以保证来自特定源、去往特定组的数据包只能到达上行接口，并从一个或多个下行接口转发出去。从定义上来看，上行接口比下行接口更靠近多播源（如图5-18所示）。如果路由器在其他接口（而不是该多播包所属源的上行接口）上接收到一个多播包，那么就丢弃该多播包。

当然，路由器需要利用某种机制来确定给定（S，G）的上行和下行接口，而这就是多播路由协议的职责。

5.2.2　多播路由

单播路由协议的功能就是发现去往特定目的地的最短路径，这可以通过邻居路由器的宣告（距离矢量）或由拓扑结构数据库计算出来的最短路径树（链路状态）来确定。这两种方式的结构都是在路由表或转发表中创建一条表项，以指示从哪个接口将数据包转发出去，而且还可能包括下一跳路由器。从单播路由协议的角度来看，被引用的接口是去往目的地路径上的下行接口，也就是最靠近目的地的接口。

图5-18　通过标识与每个多播源相关的上行和下行接口，路由器可以避免多播路由环路

与此相反，多播路由协议的功能是确定上行接口，也就是最靠近源的接口。这是因为多播路由协议关心的是去往源最近的路径，而不是去往目的地最近的路径，多播包的转发进程也被称为反向路径转发（reverse path forwarding）。

多播路由协议在确定去往源的最短路径时，最简单的方法就是参考单播转发表。但是，正如上一小节所指出的那样，转发多播包的依据是独立的多播转发表中的信息，其原因是路由器不仅要为特定的（S，G）的源记录上行接口，还要记录与多播组相关的下行接口。

最简单的多播包转发方法就是将上行接口之外的所有接口都宣告为下行接口，但是这种被称为RPB（Reverse Path Broadcasting，反向路径广播）的方法有非常明显的缺点。顾名思义，RPB可以有效地将数据包广播到被路由互联网络中的所有子网上，但组成员可能仅位于众多子网中的某个子网——甚至可能是一个很小的子网。这样一来，将每个多播包的拷贝都泛洪到每个子网上，不仅会破坏多播仅将数据包分发给感兴趣接收者的目的，而且会破坏多播路由协议本身的目的。

稍加改进后的包转发进程就是TRPB（Truncated Reverse Path Broadcasting，剪枝反向路径广播），当路由器通过IGMP发现其所连接的某些子网中无组成员，且这些子网无下一跳路由器时，路由器就不会将多播流量转发到这些子网上。与树的术语一致，TRPB中将这样的非转接性子网称为叶子网络（leaf network）。虽然TRPB有助于节约叶子网络的资源，但是仅对PRB做了有限的改进，路由器之间的链路带宽是非常宝贵的，在TRPB下无论是否需要都必须承载多播流量。

因而多播路由协议的第二个功能就是确定与（S，G）接口对相关的实际下行接口。当所有的路由器都确定了特定源和特定多播组的上行接口和下行接口后，就建立了多播树（如图5-19所示），树根是与源直连的路由器，树枝则连接到组成员所驻留的所有子网。如果数据包仅从去往组成员的接口向外转发，则称为RPM（Reverse Path Multicast，反向路径多播）。

图5-19　从多播源到所有组成员所在子网的路径构成了一棵多播树

多播树仅在多播会话期间存在，由于组成员在整个会话生存期内都可以加入和离开组，因而多播树的结构是动态变化的。多播路由协议的第3种功能是管理多播树，当组成员加入多播组时负责嫁接，当组成员离开多播组时负责剪枝。接下来的3个小节将围绕第3种功能进行详细描述。

5.2.3　稀疏与密集拓扑结构

密集拓扑结构指的是某个互联网络中的多播组成员占全部主机的绝大多数，而稀疏拓扑结构指的则是互联网络的多播组成员仅占全部主机中一小部分，但并不是说稀疏拓扑结构下的组成员数量很少。例如，在拥有100 000台主机的网络中，稀疏拓扑结构下的组成员可能为2 000个。

对稀疏和密集拓扑结构来说，没有绝对的数量比例界限，但通常可以说，密集拓扑结构常见于交换式LAN和园区网络环境中，而稀疏拓扑结构则常见于WAN中。非常重要的一点是，多播路由协议在设计时就针对某种拓扑结构，并被指定为密集模式（dense mode）协议或稀疏模式（sparse mode）协议。表5-3列出了上述5种多播路由协议的类别情况。

5.2.4　隐式加入与显式加入

如前所述，成员可以在多播会话生存期内的任何时间加入和离开多播组，因而多播树是动态变化的。多播路由协议的作用就是管理这种多播树的变化情况，在组成员加入多播组时负责嫁接，在组成员离开多播组时负责剪枝。

多播路由协议可以通过隐式（implict）加入或显式（explict）加入策略来完成这项工作，其中，隐式加入由发送方发起，而显式加入则由接收方发起。

以隐式方式维护多播树的多播路由协议通常被称为广播/剪除（broadcast-and-prune）或泛洪/剪除（flood-and-prune）协议。当发送方第一次发起多播会话时，互联网络中的每台路由器都利用反向路径广播机制将数据包从所有接口（上行接口除外）转发出去，因而多播会话会到达互联网络中的所有路由器。当路由器接收到多播流量时，通过IGMP来确定其直连的子网中是否有组成员，如果没有组成员，而且没有下游路由器（需要将多播流量转发给下行路由器），那么该路由器将会向其上游邻居发送一条被称为剪除消息（prune message）的毒性反转（poison-reverse）消息。之后，上游邻居就不再向该被剪除路由器转发多播会话流量。如果该邻居的直连子网中也没有组成员，而且其所有下游路由器都已经被剪除出多播树，那么该邻居也会向其上游路由器发送剪除消息。这样一来，最终的多播树就会删除所有通向那些直连子网中无组成员的路由器的树枝。图 5-20解释了这种广播/剪除技术。

对转发表中的每个（S，G）来说，互联网络中的每台路由器都会维护其每个下行接口的状态，即转发（forward）或剪除（prune）。其中，剪除状态有一个与其相关的定时器，当定时器到期时，会重新将多播会话流量发送给该接口上的邻居。此时，每个邻居都会再次检查组成员，并将多播流量泛洪到自己的下游邻居，如果发现了新的组成员，那么将继续接受多播流量；否则，会向上游邻居发送新的剪除消息。

与稀疏拓扑结构相比，广播/剪除技术更适用于密集拓扑结构。该技术要求在初始时刻向所有路由器进行泛洪，然后进行周期性地重泛洪（当剪除状态定时器到期时），并维护剪除状态。如果许多或大部分树枝都要被剪除，此技术将会给网络资源带来很大的浪费。此外，该技术在维护剪除状态时还存在一个不合逻辑的强制性约束，即要求那些未加入多播树的路由器也得记住“它们不是多播树的一部分”。

对稀疏拓扑结构来说，一种更优的解决方案就是显式加入，此时由直接连接了组成员的路由器发起加入请求。当组成员通过IGMP告知路由器其希望加入多播组时，路由器会向上游源发送加入请求消息。与剪除消息不同，该消息被称为嫁接（graft）消息，路由器通过发送该消息将自己嫁接到多播树中。如果某路由器的所有组成员都离开了多播组，且该路由器没有处于活动状态的下游邻居，那么该路由器就会将自己从多播树中剪除出去。

由于显式加入协议从不会将多播会话流量转发到那些没有提出显式加入请求的路由器，因而可以节省网络资源。此外，由于未加入多播树的路由器无需保持剪除状态，因而可以节省路由器的总体内存资源。由此可见，显式加入协议更适用于稀疏拓扑结构。当然，可以认为无论是稀疏拓扑结构还是密集拓扑结构，显示加入协议的扩展性都更好。表5-4列出了5种多播路由协议采用显式加入和隐式加入协议的情况。

图5-20　广播/剪除协议首先利用RPB将多播会话发送给网络中的所有路由器（a），那些没有连接组成员的路由器会自行将自己从多播树中剪除出去（b），因而多播树中仅去往那些带有组成员的路由器（c）

表5-4 隐式加入和显式加入协议

5.2.5　有源树与共享树

某些多播路由协议会为每个多播源构建独立的多播树，由于这些多播树的根都是多播源，因而被称为有源树（source-based trees）。本章前面所说的多播树都是有源树。

如前所述，在多播会话的生存期内，随着组成员的加入和离开，多播树会发生动态变化，并且由多播路由协议负责管理多播树的变化情况。但某些多播树可能不会发生变化，图5-21给出了同一互联网络中的两个多播树，从图中可以看出，虽然这两个多播树有不同的源和不同的成员，但它们的路径至少经过同一台路由器。

图5-21　两个多播树的现状虽然不同，但都通过同一台RP路由器

共享树（shared trees）利用了多个多播树可以共享网络中的同一台路由器这一事实。共享树不再以每个源为根建立多播树，而是以一台共享的被称为RP（Rendezvous Point，聚合点）或核心（core）的路由器为根。RP是预先确定好的，在策略上位于互联网络之中。当多播源开始一个多播会话时，需要首先向RP注册，由与多播源直连的路由器来确定去往RP的最短路径，或者由RP负责确定去往每个多播源的最短路径。显式加入协议用来创建从连接了组成员的路由器到RP的多播树，与有源树记录（S，G）不同，共享树记录的是（*,G）状态，该状态表明RP是去往多播组的多播树的源，而且可能会存在多个多播源（位于RP上游）。更重要的是，有源树需要为每个源记录单独的（S，G），而共享树只需要为每个多播组记录一个（*，G）。

通过一些简单的计算即可说明（S，G）表项的影响。假设有一个有源树，属于泛洪/剪除多播域，它拥有200个多播组，每个组平均30个多播源，每台路由器必须为每个组记录30条（S，G）表项，则一共30×200=6 000条表项；如果200个多播组中各有150个多播源，那么（S，G）表项数将达到150×200=30 000条。

注意：　请记住，对于交互式多播应用来说，许多组成员（接收者）同时也是多播源（发送者）。

与此相反，共享树只要为每个多播组记录一条（*，G）表项即可，因此，如果一个共享树多播域中有200个多播组，那么RP只要记录200条（*，G）表项，最重要的是，该数量不会随着多播源数量的变化而变化。可以用另外一种方式来说明这个问题，有源树是（SG,GN）的幂函数，而共享树是（GN）的幂函数，其中GN是多播域中的组数，SG是每个多播组中的源数。除此以外，共享树还能降低对非RP路由器的影响，这是因为这些路由器无需保存不由它们转发数据包的组的状态信息，这些路由器仅为每个活动下游组记录一条（*，G）表项。

这种扩展性意味着共享树更适用于稀疏拓扑结构，但是也要考虑一些折衷情况。首先，对每个组的每个成员来说，从源经RP到目的地的路径可能不是最优路径。重新看一下图5-21，多播组2的成员连接在路由器R5上，从源S2到该组成员的最优路径应该是R2-R1-R5，但是多播源的流量必须先经过RP，因而最后选择的路径为R2-R3-RP-R4-R5。因此，必须仔细选取RP，以便尽可能地减少次优路径。共享树的另一个缺点是存在多个大带宽多播会话时，RP将成为瓶颈。正是由于存在次优路径和RP拥塞问题，因而设计得不好的共享树互联网络中将存在时延问题。此外，RP也是单点故障源。最后，共享树也很难进行故障调试。

表5-5列出了使用有源树和共享树的多播路由协议情况。与表5-4相比可以看出，虽然 MOSPF使用了显式加入协议，但也同时使用了有源树。不过相反情况总是错误的，也就是说，使用共享树的协议必须始终使用显式加入，因为没有其他方式可以维护无环路多播树。

表5-5 有源树和共享树协议

5.2.6　多播定界

通过前面对多播路由问题的讨论可以看出，虽然多播路由能够比其他路由选择策略（如重复的单播或简单的泛洪）节省网络资源，但是在某些情况下也会浪费网络资源，特别是在稀疏拓扑结构中使用广播/剪除机制时更是如此。在某些情况下，对整个互联网络的规模来说，多播源和所有组成员通常都聚集在较近的位置，因而利用某种机制将多播流量限制在互联网络中组成员所在区域，将能大大节省网络资源。有时，出于安全性或其他策略考虑，可能需要将多播流量限定在一定范围内。

当多播流量被限定在“孤岛”内时，就称这些多播流量被限定区域（scoped）了。换句话说，多播定界（multicast scoping）就是限定多播流量的边界。

1.TTL定界

一种建立多播边界以限定多播流量的方法就是在出接口上设定特殊的过滤器，以检查所有多播包的TTL值。数据包的TTL值经路由器正常递减后，仅转发TTL值超出预配置阈值的数据包，其他的数据包则被丢弃。

图5-22给出了一个示例。在图中所示的路由器上，到达接口E2的多播包的TTL值为13，该路由器将该多播包的TTL值递减为12，接口E0的多播TTL阈值为0（为默认值），这样就不会有任何多播包会因TTL值而被阻塞，因而会将一份数据包拷贝从接口E0转发出去。与此相似，也会从接口E1转发出去一份数据包拷贝（因为接口E1的TTL阈值被设置为5，小于该数据包的TTL值），但是，由于接口E3的TTL阈值被设置为30（意味着仅转发TTL值大于30的数据包），因而不会从接口E3向外转发该多播包。

图5-22　多播包从下行接口（接口的TTL阈值小于出站数据包的TTL）被转发出去

TTL定界曾经被用于MBone, MBone是一个通过IP-over-IP隧道经互联网相连的区域性多播网络。表5-6给出了MBone中限制多播流量的典型TTL值，如果希望将多播流量限定在某个站点之内（如大带宽实时视频），可以配置多播源应用程序，转发TTL值小于等于15的数据包。

表5-6 Mbone TTL阈值

TTL定界方法也有一些缺点。首先，接口的TTL阈值会被应用于所有的多播包，如果希望某些多播会话不受TTL阈值限定，而仅限定其他多播会话，那么就需要使用其他定位多播会话源的应用程序。这样又会出现第二个问题，那就是必须信任用户能在其多播应用程序中正确地设置TTL值。如果某多播会话的TTL被多播源设置得非常大，那么将会穿越事先设定的多播边界。

TTL定界的另一个问题是很难在所有网络中加以实施，只能用于简单的网络拓扑结构。随着多播网络规模和复杂度的日益增大，正确预测TTL阈值来容纳和传递正确的多播会话将变得非常困难。

最后，TTL定界在广播/剪除协议下的效率很低。图5-23解释了这个问题，图中的互联网络是一个多播站点，边界路由器的接口上被配置了TTL阈值8，多播源正在生成多播会话，所有多播包的TTL都被设置为8。为了与本地策略一致，需要将多播流量限定在多播站点之内，由于多播树左边的树枝上没有组成员，因而这些路由器应该将自己从多播树中剪除出去，直至与多播源直连的路由器，事实上，从图中可以看到有一台路由器已经向其上游邻居发送了剪除消息。

图5-23　在边界路由器上设置的多播过滤器阻止了路由器向上游邻居发送剪除消息

但问题在于边界路由器及其配置的TTL过滤器，当多播包到达该路由器时，由于多播包的TTL值小于路由器接口的TTL阈值，因而多播路由器的两个下行接口都会丢弃这些多播包。虽然这是大家所期望的处理行为，但丢弃多播包也就意味着不会出现IGMP查询消息。如果没有IGMP查询，边界路由器就不会向上游邻居发送剪除消息，这样一来，多播流量就会被毫无必要地持续通过所有路由器转发给边界路由器。

2.管理性定界

有关管理性定界方法的详细描述请见RFC 2365^7，这是另一种限定多播流量边界的方法，此方法不再是过滤TTL值，而是使用一段D类地址来进行多播定界。这样一来，只需要对组地址进行过滤就可以设置多播边界，这些被保留用作多播范围定界的D类多播地址是239.0.0.0〜239.255.255.255。

管理性定界多播地址空间还可以按照层次化方法进行细分。例如，RFC 2365建议将 239.255.0.0/16用作本地范围或本站点范围，239.192.0.0/14用于组织机构范围，不过企业可以根据自己的需要自由使用这些保留地址空间。在这一点上，这些保留的D类地址类似于被保留用作私有用途的RFC 1918地址，并且与RFC 1918地址相似。这些管理性定界多播地址不是全球惟一的，因而必须设置相应的过滤器，来过滤239.0.0.0〜239.255.255.255，以避免该地址空间内的地址被泄露到公众Internet上。

其实读者在本章和本书的其他地方已经接触了TTL定界和地址定界。回顾一下，IGMP和OSPF包的TTL始终被设置为1，就是要阻止任何路由器转发这些数据包，此时流量范围就是本地子网。与此相似，路由器不转发224.0.0.0〜224.0.0.255地址范围内的数据包，而该地址（包含了表5-1所列的全部地址）也是将流量范围限定在本地子网之内。

5.3　DVMRP 操作

DVMRP（Distance Vector Multicast Routing Protocol，距离矢量多播路由协议）利用广播/剪除技术为每个多播源构建一个独立的有源树，由于其使用RIP的一个变体来发现到多播源的最短路径，因而被命名为距离矢量多播路由协议。每个多播树的维护过程都是动态变化的，当组成员离开和加入多播组时，都要对多播树进行剪枝和嫁接。

DVMRP使用以下7种类型的数据包。

•　DVMRP Probe（探测）

•　DVMRP Report（报告）

•　DVMRP Prune（剪除）

•　DVMRP Graft（嫁接）

•　DVMRP Graft Acknowledgement（嫁接确认）

•　DVMRP Ask Neighbors 2（询问邻居2）

•　DVMRP Neighbors 2（邻居2）

这些数据包的目的地址都是224.0.0.4，该地址被保留用作All DVMRP Routers（全部 DVMRP路由器）地址（详见表5-1）。以下各小节将详细描述这几种数据包的使用情况，5.3.4小节还将详细描述这些数据包的包格式。

目前有多种DVMRP版本，RFC 1075^8描述的是版本1，版本3及最近的版本请参见 Internet草案。需要注意的是，DVMRP的早期版本在功能和包格式上都有所不同，本章将尽力说清楚DVMRPv3与早期版本之间的差异，但由于篇幅所限，要完整地说清楚所有差异则难以实现。除非特别指出，否则本章所说的DVMRP指的都是DVMRPv3。如果读者正在与早期版本打交道或者对其感兴趣，可以读一读RFC 1075或支持早期版本的路由器提供的软件文档。

注意：　MBone上的大多数路由器都运行了DVMRP，这其中，多数路由器运行的是mrouted或mgated版本。

虽然Cisco IOS Software不支持DVMRP的完整实现，但支持到DVMRP网络（如MBone）的连接。

5.3.1　邻居发现和维护

DVMRP路由器被激活后的第一件事就是利用Probe包发现其邻居。每个Probe包都包含以下信息。

•　一组描述发信路由器DVMRP能力的标记，这些标记被用来确定与早期协议版本的后向兼容性；

•　一个阶段（Generation）ID，用来检测邻居状态的变化；

•　一个邻居地址列表，发信路由器从这些地址接收到Probe包。

上述信息中最重要的信息就是邻居地址列表。当DVMRP路由器接收到Probe包后，会记录发信路由器的地址和接收到Probe包的接口。前面说过，接收路由器永远也不会转发目的地址位于224.0.0.0/24地址段的数据包，一方面，由于Probe包的目的地址是224.0.0.4，另一方面，路由器在发送Probe包时设置的TTL值为1，因而DVMRP接收路由器知道发送方是一个直连邻居。当路由器发送自己的Probe包时，会列出所有从子网（在该子网上发送Probe包）上学习到的邻居地址，一旦路由器发现自己的IP接口地址位于邻居的Probe包中，那么就知道已经与邻居建立了双向通信连接。

DVMRP路由器发现邻居之后，仍然使用Probe包来保持激活状态，每隔10秒发送一次Probe包，如果在35秒之内都没有收到Probe包，那么就宣告邻居已经断开。

早期的DVMRP版本不使用Probe包，而是在接收到来自邻居的路由宣告消息之后，就认为已发现邻居。

在邻居发现进程中，如果在拥有组成员的子网中发现了多台路由器，那么早期版本的 DVMRP会选择一台指派路由器——将该子网上IP地址最小的路由器设置为指派路由器。指派路由器是子网上惟一可以向子网发送多播会话包和IGMP查询消息的路由器。对DVMRPv3来说，是通过IGMPv2查询选举进程（而不是从接收到的路由宣告消息中读取源IP地址）来确定指派路由器的。

如前所述，广播/剪除多播路由协议必须存储剪除状态，但是当路由器重启后，将无法知道发送或接收了哪些剪除信息。如果该路由器必须等待下一周期到达的路由更新，那么就需要花费较长的时间来重新建立多播转发，此时就需要利用阶段ID来解决这个问题。阶段ID是一个非递减的32bit数，衍生于某些变化基准（如time-of-day时钟）。当DVMRP路由器重启时，其阶段ID会发生变化，当邻居路由器在该路由器的Probe包中发现变化后的阶段ID之后，就会清除先前从该路由器接收到的全部剪除信息，还会立即将自己的路由表拷贝发送给邻居。由于已经清除了剪除状态，因而重启后的路由器能够重新转发多播数据，并重新决定是留在多播树中还是将自己从多播树中剪除出去。

5.3.2　DVMRP路由表

DVMRP路由表的主要作用是确定每个多播源的上行接口。前面的章节中已经解释过，该进程对环路避免来说非常重要，如果在除上行接口（该接口最靠近源）外的其他接口上接收到一个来自源的数据包，那么就必须丢弃该数据包。

DVMRP使用了一个RIP变体来宣告完整的路由表以及所有直连的启用多播的子网，路由信息是通过DVMRP Report（报告）消息进行宣告的，利用All DVMRP Routers（全部DVMRP路由器）地址224.0.0.4发送给所有邻居。路由更新每60秒发送一次，该周期被称为路由报告间隔（Route Report Interval）。当通过探测进程发现一个新邻居时，就不会遵循该规则，而是立即以单播方式向新邻居发送路由表。这种立即发送更新消息的机制也能用于缩短路由的重新收敛时间。

与每台路由器相关的度量值是跳数，跳数限制被明确定义为32跳，但是一条路由的度量值取值范围可以是1〜63。其中，度量值1〜31被用来表示可达的源，而33〜63则被用来表示路由相关性（route dependencies）。

为了正确进行剪除工作，DVMRP路由器必须感知其下游邻居（依靠其从特定多播源转发数据包）。对每个源网络来说，下游路由器通过向上游路由器发送毒性反转路由（其度量值是被宣告路由的度量值加上无穷大），来向上游路由器通告路由的相关性。例如，假设路由器A将网络172.16.1.0/24宣告给路由器B（跳数为3），路由器B确定路由器A是去往该子网的上游路由器，则路由器B必须告知路由器A，需要依靠路由器A将多播流量从源转发到本子网。因而，路由器B将172.16.1.0/24宣告给路由器A时携带的度量值为35（3+32），路由器A将该路由宣告识别为路由相关性。

DVMRP路由表的另一个功能是选举指派转发路由器（designated forwarder）。当多台上游路由器连接到同一个多路接入（multiaccess）网络（如图5-24）中时，只有指派转发路由器负责将多播包转发给下游路由器，从而避免了将多份数据包拷贝转发到该多路接入网络中。当多路接入网络中的两台或多台路由器进行路由交换时，可以说明哪台路由器最靠近多播源。如图5-24所示，由于上游路由器B距多播源仅有一跳，而上游路由器A为两跳，因而上游路由器B是图中所示多播源的指派转发路由器。如果有多台路由器到多播源的距离都相等，那么该共享网络上IP地址较小的路由器就成为指派转发路由器。

图5-24　当多台上游路由器都通过相同的数据链路连接到多播源时，需要选举一台指派转发路由器

5.3.3　DVMRP包转发

当路由器第一次从某特定多播源接收到一个多播包之后，会使用路由表来执行RPF检查（RPF Check），以验证该数据包到达的是相对于数据包源的上行接口。如果数据包到达的是其他接口，那么就会被丢弃；如果数据包到达的是上行接口，那么就会在转发表中记录（S，G），并且将数据包拷贝转发给所有下游相关邻居。路由器也会利用IGMP来查询其每个叶子网络（即没有邻居的网络）中的组成员情况，并将多播包拷贝转发给所有包含了组成员的叶子网络。

如果没有下游相关邻居，没有包含组成员的叶子网络，那么路由器将会向上游路由器发送一条剪除消息。如果上游路由器也没有本地组成员，而且从其下游相关邻居接收到了一条剪除消息，那么该路由器将会向其上游邻居发送一条有关自己的剪除消息。这样一来，多播树就会被动态剪枝，而仅保留拥有活动组成员的树枝。

剪除消息中包含一个剪除生存期（prune lifetime），表示上游路由器重新从多播源向被剪除路由器转发多播包之前应该保持剪除状态的时间，默认的剪除生存期是2小时。如果接收剪除消息的路由器就是向上游邻居发送剪除消息的路由器，那么剪除生存期将被设置为2小时或已接收到的关于同一个（S，G）的所有下游剪除消息中剩余生存期这两者的最小值。

如前所述，主机可以在任何时刻通过向其本地路由器发送IGMP成员报告消息来表达自己加入多播组的意愿，如果该路由器先前将自己从该多播树（从该多播组传送多播包）中剪除出去了，那么就必须将自己重新嫁接到这个多播树上。这可以通过向上游邻居发送DVMRP Graft（嫁接）消息来实现，该嫁接消息会逐跳向上游传送，直至发现该多播树的一个有效树枝。

如果路由器发送了嫁接消息，且未开始从所请求的多播组接收流量，那么就必须有某种机制来了解多播源是否已停止发送多播流量或者嫁接消息是否已丢失。因而对每一跳来说，要求每个上游路由器在接收到嫁接消息之后都要向其下游邻居发送一条Graft Ack（嫁接确认）消息作为确认。此外，嫁接消息的发起路由器还会启动一个嫁接重传（Graft Retransmission）定时器，如果在定时器到期时仍未收到嫁接确认消息，那么就会重新发送一条嫁接消息并重置定时器。最初的嫁接重传定时器周期为5秒，之后的定时器周期则采用二进制指数回归算法来计算。

5.3.4　DVMRP消息格式

DVMRP包的IP头部指定的协议号是2，请注意，该协议号与IGMP相同（最初DVMRP是IGMP协议的一个子集）。本小节将描述DVMRPv3的消息格式，有关早期版本的消息格式请参见RFC 1075或其他相关文档。

1．DVMRP消息头

图5-25显示了DVMRP消息头的格式，是每条DVMRP消息的起始部分。

图5-25　DVMRP消息头

DVMRP消息头的字段信息如下。

•　类型（Type）:IGMP类型号，对DVMRP消息来说均是0x13。RFC 1075在该位置指定了一个4bit版本字段和一个4bit类型字段，其中，版本字段为0x1，类型字段为0x3。请注意，版本1消息头的8bit结果为0x13，与版本3相同，因而版本3具备后向兼容能力。实际的DVMRPv3版本是在主版本（Major Version）字段中指定的。

•　校验和（Checksum）：一个标准的IP式校验和，长16bit，是DVMRP消息的反码的反码。

•　次版本（Minor Version）和主版本（Major Version）：对所有DVMRPv3消息来说，它们被分别设置为0xFF和0x03。

•　代码（Code）：指定DVMRPv3的消息类型。表5-7列出了代码字段的各种可能值以及相应的消息类型。

表5-7 代码值指定的DVMRP消息类型/MRP消息类型

Ask Neighbors（代码3）和Neighbors（代码4）已分别被Ask Neighbors 2（代码5）和 Neighbors 2（代码6）所代替。到现在为止还没有讨论过上述消息，它们常被用于mrinfo和 mstat等故障诊断命令，将在第6章的故障检测与排除中进行详细说明。

2．DVMRP Probe（探测）消息格式

DVMRP Probe消息可以提供以下功能。

•　路由器之间可以通过侦听所有DVMRP发言路由器（由发信路由器在发信接口上检测）来进行相互定位；

•　让DVMRP路由器之间交换各自的能力信息；

•　在去往同一个下游组成员存在多条路径时，可以选举一台指派转发路由器；

•　通过每10秒发送一次来提供保持激活功能，如果35秒之内仍未接收到来自邻居的探测消息，那么就断定该邻居已断开。

图5-26显示了Probe消息的格式。

图5-26　DVMRP Probe消息格式

DVMRP Probe消息的字段信息如下。

•　能力（Capabilities）：将头部中的8个保留bit用作能力标记，Probe消息是惟一一个修改头部字段的DVMRP消息。表5-8列出了能力标记及其含义，如果标记被设置为1，那么发信路由器就支持相应的能力。

表5-8 DVMRP能力标记

•　阶段（Generation）ID：一个非递减的32bit数，在路由器重启后，利用该字段可以无需等待整个报告间隔即可检测邻居状态的变化情况。当检测到阶段ID发生变化后，所有来自发信路由器的剪除信息都被视为无效且被清除。如果剪除信息已经被发送给上游邻居，那么就会发送一条嫁接消息，这样一来，重启后的路由器就被认为是多播树上的一台新路由器，重新进行广播/剪除进程。

•　邻居地址（Neighbor Address）：列出了邻居情况，发信路由器在发信接口上从这些邻居接收到Probe消息。

3．DVMRP Route Report（路由报告）消息格式

如图5-27所示，Route Report消息每60秒发送一次，该消息包括一个或多个网络掩码列表以及一个或多个源网络地址及相关联的度量值（与网络掩码相对应）列表（对每个网络掩码来说）。虽然图5-27中的源网络长度为3个8位组，但实际长度可变（如本小节所述）。

图5-27　DVMRP Route Report消息格式

DVMRP Route Report消息的字段信息如下。

•　掩码（Mask）：网络掩码，总是假定网络掩码的第一个8位组为255，因而掩码字段中仅包含最后3个8位组。该假定意味着DVMRP路由不能被聚合到前缀长度小于8的地址中。

•　源网络（Source Net）：一个前缀长度与前面网络掩码相对应的源网络地址，源网络字段的长度随网络掩码的变化而变化。例如，如果网络掩码字段为255.0.0，该掩码字段描述的掩码是255.255.0.0（因为第一个8位组总是被假定为255），那么跟在该网络掩码之后的源网络字段是2个8位组（与所指定的前缀长度相对应）。

默认路由器的网络掩码为0.0.0，一个8位组源网络为0，DVMRP路由器总是将其解析为0.0.0.0/0，而不是0.0.0.0/8。

•　度量值（Metric）：发起报告消息的路由器与源网络之间接口度量值之和。度量值以跳数为单位，32表示无穷大，但度量值取值范围是1〜63。如5.3.2小节所述，路由器通过向上游路由器宣告一条毒性反转路由（其度量值是接收到的度量值加上无穷大（32）），来向上游路由器通告路由相关性，因而度量值33〜63表示下游相关性。

4．DVMRP Prune（剪除）消息格式

图5-28显示了Prune消息的格式。

图5-28　DVMRP Prune消息格式

DVMRP Prune消息的字段信息如下。

•　源主机地址（Source Hosting Address）：发信主机的IP地址。

•　组地址（Group Address）：被剪除多播组的地址。

•　剪除生存期（Prune Lifetime）：上游邻居保存剪除信息的时间（以秒为单位），等于该组地址所接收到的下游剪除消息的最小剩余生存期，如果没有下游剪除消息，就等于默认剪除生存期2小时。

•　源网络掩码（Source Network Mask）：被剪除多播组的源网络的网络掩码。该字段为可选字段，仅当上游邻居在其Probe消息中表明其理解网络掩码时才包括此字段。

5．DVMRP Graft（嫁接）消息格式

图5-29显示了Graft消息的格式。

图5-29　DVMRP Graft消息格式

DVMRP Graft消息的字段信息如下。

•　源主机地址（Source Hosting Address）：发信主机的IP地址。

•　组地址（Group Address）：被嫁接多播组的地址。

•　源网络掩码（Source Network Mask）：被嫁接多播组的源网络的网络掩码。该字段为可选字段，仅当上游邻居在其Probe消息中表明其理解网络掩码时才包括此字段。

6．DVMRP Graft Acknowledgement（嫁接确认）消息格式

图5-30显示了Graft Acknowledgement消息的格式。除了头部中的代码字段之外，该消息的格式与正在被确认的Graft消息完全一致。

图5-30　DVMRP Graft Acknowledgement消息格式

7．DVMRP Ask Neighbors 2（询问邻居2）消息格式

DVMRP Ask Neighbors 2消息是用于故障检测与排除的两条消息中的一条（另外一条是下一节将要描述的Neighbors 2消息），此处的数字“2”是为了区分已被废弃的Ask Neighbors消息。如图5-31所示，Ask Neighbors 2消息采取单播方式被传送给目的地，当路由器接收到一条Ask Neighbors 2消息之后，需要以单播方式向发信方响应一条Neighbors 2消息。从图中可以看出，该消息仅仅是将代码字段设置为0x5的DVMRP消息头。

图5-31　DVMRP Ask Neighbors 2消息格式

8．DVMRP Neighbors 2（询问邻居2）消息格式

DVMRP路由器以Neighbors 2消息来响应Ask Neighbors 2消息（如图5-32所示）。该消息是以单播方式传送给Ask Neighbors 2消息的发起者，指示发送方的DVMRP能力，并列出发送方的逻辑接口地址，对每个所列接口来说，均指定该接口的DVMRP参数，并列出在该接口上发现的DVMRP邻居。

图5-32　DVMRP Neighbors 2消息格式

DVMRP Neighbors 2消息的字段信息如下。

•　能力（Capabilities）：指定发信路由器的DVMRP能力，该字段与Prune消息的能力字段一样，其取值情况详见表5-8。

•　本地地址（Local Address）：路由器上的接口地址，如果接口处于无效或禁用状态，那么只有一个邻居表项与该接口相关联，且邻居表项的地址为0.0.0.0。

•　度量值（Metrics）：指定接口的DVMRP度量值。

•　阈值（Threshold）：指定接口的管理性定界阈值。

•　邻居计数（Neighbors Count）：指定该接口所列出的邻居数量。

•　邻居（Neighbor）：该接口所知晓的DVMRP邻居的IP地址。

•　标记（Flags）：一串描述接口操作参数的bit，表5-9列出了该字段的bit取值情况以及每个标记bit的含义。

5.4　MOSPF操作

MOSPF（Multicast OSPF，多播OSPF）从两个方面对DVMRP做了改进。首先，MOSPF是链路状态协议，而DVMRP是距离矢量协议，两者的不同之处实际上就是链路状态协议与距离矢量协议相比所具备的优势——更好的收敛特性、更好的环路避免能力以及更少的周期性控制流量。其次，MOSPF在密集拓扑结构下具备更好的扩展性，这一方面归结于链路状态算法，另一方面与MOSPF通过泛洪/剪除机制使用显式加入（而不是隐式加入）有关。

顾名思义（如RFC文件名所描述的那样^10），多播OSPF并不是一个无OSPF完全独立的路由协议，而是对OSPF协议的扩展。为支持多播能力，对OSPF进行了3个方面的扩展。首先，定义了一个新的LSA，被称为组成员关系LSA（Group Membership LSA），该LSA为 LSA类型6。

扩展后的选项（Options）字段包含一个被称为MC bit的标记，用来指示支持IP多播。在《TCP/IP路由技术（第一卷）》的第9章中描述的选项字段被携带在OSPF Hello包、数据库描述（Database Description）包以及所有的LSA中，MC bit的含义是OSPF和MOSPF路由器可以在同一个互联网络中混合使用，MOSPF路由器利用MC bit来表示其支持IP多播。虽然MC bit不匹配的路由器仍然处于邻接状态，但只有在数据库描述包中设置了MC bit的邻居才能在数据库同步进程中交换组成员关系LSA，并且只有设置了MC bit的LSA才被用于计算多播最短路径树。

最后，扩展后的路由器LSA（Router LSA）中的rtype字段包含了一个被称为W bit的标记，该标记表示发信路由器是一个万能多播接收路由器（wildcard multicast receiver），万能多播接收路由器的定义请参见5.4.2小节。

就像单播OSPF使用基于Dijkstra的SPF算法计算去往单播目的地的最短路径树一样，MOSPF也要计算从多播源到多播目的地的最短路径树。单播树和多播树都是从同一个链路状态数据库中计算得到的，但两者之间有一些差异，单播SPF树的根是源路由器，而多播SPF树的根是源多播子网。

5.4.1　MOSPF基础

描述MOSPF的最好环境就是连接了组成员的本地多路接入介质，与单播OSPF相似，MOSPF会选举一个DR（Designated Router，指派路由器）和一个BDR（Backup DesignatedRouter，备份指派路由器）。虽然连接在该介质上的所有MOSPF路由器都在本地链路上运行 IGMP以发现组成员，但只有DR发送IGMP成员关系查询消息并侦听IGMP成员关系报告消息。

回顾表5-4，MOSPF使用的是显式加入机制，当组成员发送一条指示其希望加入某多播组的IGMP消息时，MOSPF DR会在其本地组数据库（local group database）中创建一条表项，本地组数据库记录的是多播组以及组成员所驻留的网络。例如，图5-33中的路由器连接了3个子网，其中的两个子网上有3个组成员，位于不同子网的两个组成员属于同一个组，路由器只需要知道多播组以及该多播组成员所在的子网即可，而无需了解每个单独的组成员。

图5-33　本地组数据库记录的是所连接的组以及组成员所驻留的子网信息

之后，DR会向每个所连接的多播组发送一个组成员关系LSA，该LSA指定了组地址和发信路由器ID，并列出该路由器连接的驻留了组成员的所有网络。在某些情况下，路由器本身也可以运行某些多播应用程序，让其也成为组成员。LSA中包含了一个类型字段，路由器可以通过该字段来表示其正将自己宣告为组成员。

然后LSA被泛洪到发信路由器所在的整个区域，组成员关系LSA（类型6 LSA）在以下两个方面类似于网络LSA（类型2 LSA）。

•　只有一个指派路由器能够发起组成员关系LSA；

•　组成员关系LSA仅在区域范围内有效，也就是说，组成员关系LSA不能被泛洪到发信路由器的区域之外。

LSA泛洪的目的是确保区域内的所有MOSPF路由器都能得到源自本区域的所有组成员关系LSA。与单播OSPF类似，一个区域内的所有MOSPF路由器都有相同的链路状态数据库，OSPF链路状态数据库与给定区域内MOSPF数据库之间的惟一差别就是包含类似类型6 LSA。

通过同步化的数据库，区域内的每台MOSPF路由器都能计算出相同的最短路径树。该路径树的根是源网络，树枝扩展到每个包含了组成员的网络，但是，该最短路径树无法立即被计算出来，而是在多播组的第一个多播包到达的时候进行“按需”计算。这一点很清楚，因为虽然同步化路由器能够知道所有的目的地，但是并不知道多播源位于何处。

SPF计算过程根据组成员关系LSA可以了解所有连接了组成员的路由器的位置，根据该组第一个到达的数据包的源和目的地址还可以了解多播源的位置，之后就可以通过普通的单播路由器LSA和网络LSA（其MC bit被置位）来计算从源到每个目的地的最小代价路径。

基于组成员关系LSA的显式加入机制（结合按需SPF计算）的最大好处就是，路由器在计算路径之前就已经知道了目的网络的位置。因而与泛洪/剪除协议（如DVNRP）不同，从不会将多播包转发到路由域中的所有角落，因此可以说，MOSPF树是“预剪除”的多播树。

根据SPF计算结果，会在每台路由器的多播转发表中生成相应的表项。最短路径树是无环路的，每台路由器都知道哪些接口是上行接口，哪些接口上下行接口，因而无需像DVMRP那样进行RPF检查。对特定（S，G）来说，转发表项指示应该从哪个上游邻居接收匹配的数据包以及必须将数据包转发给哪些下游邻居。此外，本地组数据库也被用来为本地连接的包含组成员的网络在转发表中创建表项。

关于MOSPF有一些注意事项。首先，虽然单播OSPF支持等价多路径，但MOSPF不支持。MOSPF最短路径树描述的是源与所有包含组成员的网络之间的单一路径。

其次，如果OSPF和MOSPF路由器共存于同一个多路接入网络中，一定要注意将MOSPF选举为DR。如果OSPF路由器成为DR，那么将不可能为网络中的所有组成员发起组成员关系LSA，因而该组的多播包也就无法被转发到本网络。

最后，如果MOSPF域内的拓扑结构发生了变化，那么MOSPF路由器必须清除其转发表项并重新计算其最短路径树。因而，非常重要的一点是，尽可能地保持MOSPF域的稳定性。

5.4.2　区域间MOSPF

前一小节描述了源和所有组成员均位于同一区域中时MOSPF的操作方式，重点强调的是组成员关系LSA不会被泛洪到发起该LSA的区域之外。那么，当组成员与源位于多个不同区域时将会如何呢？

《TCP/IP路由技术（第一卷）》的第9章中说过，区域间OSPF的通信由ABR（Area Border Router，区域边界路由器）管理。ABR既是主干区域的成员，也是一个或多个非主干区域的成员。与区域内的其他路由器一样，ABR也是通过路由器LSA和网络LSA来学习每个所连接区域内的所有目的地。之后，ABR创建网络汇总LSA（类型3 LSA），将ABR所连接的某个区域内的目的地宣告到该ABR所连接的其他区域。与类型1和类型2 LSA相似，类型3 LSA从来也不会被泛洪到发起该LSA的区域之外。当某台ABR通过主干区域从其他ABR接收到网络汇总LSA（Network Summary LSA）后，会创建自己的网络汇总LSA，将这些信息宣告给其所连接的非主干区域。图5-34从概念上解释了ABR对类型1、2、3 LSA的使用情况。

MOSPF ABR被不恰当地称为域间多播转发路由器（inter-area multicast forwarder），MOSPF ABR的工作方式与单播ABR有相同之处，也有不同之处。通过从非主干区域接收到的组成员关系LSA，域间多播转发路由器可以了解其所连接的非主干区域中有哪些多播组的成员。对每个已知多播组来说，转发路由器都会创建一个新的组成员关系LSA，并将该LSA泛洪到主干区域（如图5-35所示）。到目前为止，上述操作方式与ABR使用类型3 LSA将学习自类型1和类型2 LSA的汇总信息宣告到主干区域的操作方式非常类似。

图5-34　单播OSPF使用网络汇总LSA将学习自某个其所连接的区域的目的地宣告给其他所连接区域

图5-35　域间多播转发路由器利用组成员关系LSA将非主干区域中组成员的信息宣告给主干区域

MOSPF ABR与单播ABR之间的相似性就是这些。与单播使用类型3 LSA的方式不同，域间多播转发路由器并不将类型6 LSA发送到非主干区域，从而将组成员的情况宣告到本区域之外。例如，图5-35中的RT1接收到由RT2发起的类型6 LSA（宣告组C），但并不创建一个将组C宣告到区域1（Area 1）的类型6 LSA。

结果就是在主干区域中为每个组计算一个SPF树，而且该SPF树的树枝延伸到每个区域（包含了组成员）的域间多播转发路由器，而非主干区域则不知道本区域之外的组成员情况。

但是，如果图5-35中组C的源位于区域1，那么其多播包该如何到达区域2和区域3的成员呢？答案就是万能多播接收路由器（wildcard multicast receiver），这些路由器通过设置其路由器LSA中的W bit来宣告自己。每个区域中的多播流量都要被转发给万能多播接收路由器，对非主干区域来说，域间多播转发路由器（即多播ABR）总是万能多播接收路由器。

当图5-35中组C的源发起一个组C数据包时，该多播包先被转发给RT1——即区域1的万能多播接收路由器。RT1本身又是主干区域的成员，因而会计算出到所有域间多播转发路由器（其所连区域中包含组C的成员）的最短路径树。由于RT2正在宣告组C的成员，因而将多播包通过主干区域转发给该路由器，作为区域2和区域3的成员，RT2为每个区域中的组C计算单独的SPF树，并将多播包拷贝转发到组C的目的地。

注意：　当然，如果区域1中有组C的成员，那么除了将多播包拷贝转发给RT1之外，还要通过本地SPF树转发给这些组成员。

请注意，对域内（intradomain）流量来说，主干区域中并不需要万能多播接收路由器。对MOSPF域中的每个组来说，都会在区域0中计算一个SPF树，该SPF树的树枝要么通向位于该区域的组成员，要么通向连接到其他区域的域间多播转发路由器。因此，如果多播源位于主干区域中，那么其数据包将能沿着正确的SPF树进行转发。

5.4.3　AS间 MOSPF

RFC 1584描述了多播包进出MOSPF域的路由机制，《TCP/IP路由技术（第一卷）》的第 9章中说过，将来自其他路由协议的路由重分发到OSPF域的路由器被称为ASBR（Autonomous System Boundary Router，自治系统边界路由器）。ASBR使用AS外部（AS-External）类型5）LSA来宣告OSPF域之外的目的地，而利用ASBR汇总LSA（ASBR Summary LSA，类型4 LSA）来宣告自己的位置，除了末梢区域（stub area）之外，这些LSA会被泛洪到OSPF域中的所有区域。

负责将MOSPF域连接到其他多播路由域（目前最可能的是DVMRP，将来也可能是其他多播EGP）的路由器被称为AS间多播转发路由器（inter-AS multicast forwarder）。这些路由器的操作行为与域间多播转发路由器类似，为了将多播包转发到MOSPF域之外的目的地，AS间多播转发路由器需要在其路由器LSA中设置W bit，以成为万能多播转发路由器。当路由器将来自外部多播源的数据包转发到MOSPF域时，路由器将成为“代理源（proxy source）”，且它们的外部链路将充当该多播组SPF树的树根。

与ASBR类似，AS间多播转发路由器可以位于任何区域，但需要注意的是，万能多播转发能力是由类型1 LSA中的W bit来指示的，而类型1 LSA又不会被泛洪到区域之外。如果AS间多播转发路由器位于区域0，那么不存在任何问题，因为此时的域间多播转发路由器已经将多播流量引入到了主干区域；但是，如果AS间多播转发路由器位于非主干区域，那么该区域的域间多播转发路由器也必须成为主干区域的一台万能多播转发路由器。因而，建议将AS间多播转发路由器设置于区域0。

由于多播域中的所有多播流量都要转发到AS间多播转发路由器，因而建议慎重选择这些路由器在MOSPF域中的摆放位置，否则，到这些路由器的链路很容易就会产生拥塞。

5.4.4　MOSPF 扩展格式

本小节仅描述OSPF进行多播扩展后的格式，有关OSPF包和LSA的完整描述请参见 《TCP/IP路由技术（第一卷）》第9章。

1．组成员关系LSA格式

组成员关系LSA携带标准的LSA头部，其类型号为6，图5-36显示了组成员关系LSA的格式。只有MOSPF指派路由器才可以发起组成员关系LSA，请注意，从该LSA的格式中可以看出，该LSA没有相关联的度量值。

图5-36　MOSPF组成员关系LSA格式

组成员关系LSA的各字段定义如下。

•　链路状态ID（Link State ID）：携带被宣告多播组的地址。

•　宣告路由器（Advertising Router）：总是多路接入网络中MOSPF指派路由器的路由器ID，这是因为只有DR才能发起类型6 LSA。

•　顶点类型（Vertex Type）：指定目的地是路由器（类型=1）或转接网络（类型=2），如果发信路由器正在运行的某些应用程序需要其成为多播组的成员，那么就指定类型1；转接网络指的是发信路由器直连的网络，只有穿越该网络，多播包才能到达所连接的组成员。

•　顶点ID（Vertex ID）：发信路由器的路由器ID。

2．扩展的路由器LSA格式

图5-37显示了为支持MOSPF而扩展后的路由器（类型1）LSA的格式，除了在rtype字段中增加了W bit之外，其格式与《TCP/IP路由技术（第一卷）》中的图9.55完全相同。rtype字段由域间多播转发路由器和AS间多播转发路由器进行设置，以便向区域中的其他 MOSPF路由器指示其为万能多播转发路由器。

3．扩展的选项字段格式

如图5-38所示，选项字段是所有OSPF Hello包及数据库描述（Database Description）包的一个组成部分，也是所有LSA头部的一部分。除了与本章内容相关的MC bit之外的本字段的其他标记都已经在《TCP/IP路由技术（第一卷）》第9章中进行了详细描述。当置位WC bit时，表示发信路由器支持多播功能。

图5-37　路由器LSA的格式，在rtype字段中增加了W bit以支持MOSPF

Hello包中的MC bit仅指示多播能力，即使两台路由器中一台设置了MC bit，另一台没有设置MC bit，这两台路由器仍然是邻接状态。MC bit真正起作用的是在数据库描述包和 LSA中。

图5-38　选项字段的格式

在数据库同步过程中，如果邻居的DD包设置了MC bit，那么MOSPF路由器将向邻居发送其数据库中的类型6 LSA。与此类似，只有设置了MC bit的LSA才被用于MOSPF的SPF计算。

5.5　CBT操作

DVMRP和MOSPF都有两个限制条件。首先，它们都是密集模式协议，在稀疏拓扑结构下的扩展性不好，也就是说，当互联网络中的组成员仅占全部主机的一小部分且分布于整个互联网络之内时，为了达到这些组成员，DVMRP和MOSPF都要消耗大量难以承受的网络资源，大部分资源消耗都是计算和维持每个多播树（以每个多播源为根）所必需的开销。其次，这两种协议在确定多播树时被局限于单一单播路由协议——DVMRP被局限于基于RIP的协议，而MOSPF被局限于OSPF协议。与此相反，CBT（Core-Based Trees，核心树）是一种与协议无关的、稀疏模式的共享树协议。

与协议无关（Protocol-independent）意味着CBT可以使用任何底层的单播路由协议来发现多播源，发现其他CBT路由器，构建其多播树。由于CBT可以使用现有路由协议（而不是为支持多播而增加其他路由协议），因而除了提高了灵活性之外，还可以达到降低所需的开销。此外，CBT树以核心（core）CBT路由器为根，而不是以多播源网络为根。核心CBT路由器可以位于互联网络中的任何位置，而且很多多播源都可以以同一个核心CBT路由器为根，使得CBT更适用于稀疏多播拓扑结构。

目前有3种版本的CBT, CBTv2（在RFC 2189中描述）替代了CBTvl，还有一个处于提议状态的CBTv3。这3种版本都属于试验性版本，都没有得到大规模的部署应用，出于试验性状态，CBTv2和CBTv3都不具备与先前版本的后向兼容性。本章重点关注CBTv2，在提及术语“CBT”时，指的都是CBTv2。

5.5.1　CBT 基础

CBT使用以下9种类型的消息。

•　JOIN_REQUEST（加入请求）；

•　JOIN_ACK（加入应答）；

•　ECHO_REQUEST（回应请求）；

•　ECHO_REPLY（回应应答）；

•　QUIT_NOTIFICATION（退出通告）；

•　FLUSH_TREE（清除多播树）；

•　Candidate Core Advertisement（候选核心路由器宣告）；

•　Bootstrap（引导）；

•　HELLO。

除了将在5.5.3小节中讨论的一个例外情况之外，所有的CBT消息都被发送给保留的多播地址224.0.0.15（见表5-1），且TTL为1，这意味着所有的CBT信息都要在多播域中进行逐跳传递。有关这些消息的格式将在5.5.5小节中进行详细描述。

与其他IP多播路由协议类似，在主机希望加入多播组时，是通过IGMP成员关系报告消息来通知CBT的。CBT使用显式加入机制，因而当CBT路由器必须向特定多播组转发数据包时，必须首先将自己嫁接到该多播组的多播树。CBT首先要检查其单播路由表，找到该特定多播组的核心路由器的位置，之后沿路径向上游方向的核心路由器转发JOIN_REQUEST消息，该消息包含以下3部分重要信息。

•　多播组的地址；

•　核心路由器的地址；

•　消息发起者的地址。

注意：　路由器如何发现核心路由器是5.5.2小节的主题。

当下一跳路由器接收到JOIN_REQUEST消息之后，会检查组地址和核心路由器地址。根据这些信息，该路由器会知道自己属于下面的某一种情形。

•　核心路由器；

•　连接在该多播组的多播树上（属于on-tree[树上]路由器）；

•　既不是核心路由器，也不是on-tree路由器。

如果该路由器是核心路由器或on-tree路由器，那么就会向JOIN_REQUEST消息的发起者发送一条JOIN_ACK消息，表示发起者已经已经成功加入多播树。该路由器还会将收到JOIN_REQUEST消息的接口加入到该多播组的转发表项中，并开始在该接口上转发多播包。

如果该路由器既不是核心路由器，也不在多播树上，那么就必须加入该多播树，这样就要检查其单播路由表，以找出核心路由器的位置，并将JOIN_REQUEST消息的拷贝转发给上游邻居。该路由器还会开始进入瞬时加入状态（transient join state），包括该多播组、接收到JOIN_REQUEST消息的接口以及传送JOIN_REQUEST消息的接口在内的信息都被记录下来，并启动一个定时器。如果在7.5秒（瞬时超时（transient timeout）周期）之内仍未收到JOIN_ACK消息，那么就会删除瞬时加入状态，表示加入不成功。

在CBT的术语中，面向核心路由器的上游接口是父接口（parent interface），而面向组成员的下游接口是子接口（child interface）。与此类似，上游邻居是父路由器，而下游邻居则是子路由器。通过接收JOIN_ACK消息而建立了多播树之后，子路由器会每隔60秒向其父路由器发送一条ECHO_REQUEST消息，ECHO_REQUEST消息中仅包含发起该消息的子路由器的地址，父路由器会响应以ECHO_REPLY消息，该消息会列出父路由器在该链路上转发多播包的所有多播组。

如果在70秒之内仍未收到ECHO_REPLY消息，那么该父路由器就会被宣告为不可达。与此类似，如果在90秒之内，某特定多播组都没有被列在ECHO_REPLY消息之中，那么该多播组就会被宣告为无效。之后，子路由器会向其上游父路由器发送一条QUIT_NOTIFICATION消息，并向其下游每个子路由器各发送一条FLUSH_TREE消息。其中，FLUSH_TREE消息中列出了所有无效的多播组地址，接收到该消息的所有子路由器都会将FLUSH_TREE消息中列出的无效多播组信息从其转发表中清除掉，然后这些子路由器又继续向其子路由器发送FLUSH_TREE消息，一直持续下去，直至该失效路由器以下的多播树树枝都被删除。

QUIT_NOTIFICATION消息还被用于剪枝，如果某台路由器通过IGMP离开组消息学习到其不再连接某特定多播组的成员，那么就会向其父路由器发送一条QUIT_NOTIFICATION消息，在该消息中列出将要被剪除的多播组地址。以此类推，如果该父路由器也没有连接该多播组的成员，而且也没有该多播组的子接口，那么也要向其上游路由器发送QUIT_NOTIFICATION消息。以此往复，该树枝一直会被剪除，直到到达一台活动的on-tree路由器或核心路由器。

5.5.2　发现核心路由器

CBT路由器构建到核心路由器的多播树的先决条件是要知道哪台路由器是核心路由器。一种解决方法是在所有路由器上预先配置每个多播组的核心路由器地址，该方法对小型多播网络来说可能很好，能够提供很好的网络控制能力，但相应的管理需求导致难以适应较大规模的互联网络。

另一种解决方法就是Bootstrap（引导）机制。使用该方法时，要将CBT域中的一组路由器配置为候选核心路由器（candidate core）。这些路由器之间交换Candidate Core（候选核心路由器）消息，根据优先级，将其中的某台路由器选举为BSR（Bootstrap Router，引导路由器），如果所有路由器的优先级均相等，那么就选举IP地址最大的路由器为BSR，其余的候选核心路由器将每隔60秒向BSR发送一条单播Candidate Core消息，作为保持激活消息。根据这些Candidate Core消息，BSR会组建一个CC-set（Candidate Core set，候选核心路由器集合），并通过Bootstrap消息将CC-set宣告为域中的所有CBT路由器。当某路由器被要求加入某多播组时（通过IGMP），会对CC-set进行哈希运算，以正确确定该多播组的核心路由器。

CBT和PIM-SM使用相同的Bootstrap协议，由于本章的重点内容是PIM-SM协议，因而本小节仅简要叙述引导机制，有关细节内容将在5.8节进行详细描述。

5.5.3　CBT 指派路由器

CBT使用HELLO消息来选举多路接入网络中的指派路由器，CBT DR的使用方式与 DVMRP指派转发路由器及MOSPF DR相同。由于CBT在转发多播包时不进行RPF检查，因而当存在多条上行路径去往核心路由器时，DR在预防环路方面就显得非常重要（如图5-39所示）。

图5-39　CBT需要在多路接入网络中选举一台指派路由器，以管理去往核心路由器的多条路径

每个CBT路由器接口均被配置一个0〜255的优先值，该优先值被携带在HELLO消息中。其中，1〜254表示该路由器可以成为DR，值越小表示优先级越高，也就是说，优先值为10的路由器比优先值为20的路由器“更合格”，优先值0则表示该路由器为DR。

当CBT路由器首次在多路接入链路上激活时，会连续发送两条HELLO消息，以宣告其的存在以及优先值。之后，该路由器会侦听HELLO消息，结果为以下情形之一。

•　侦听到来自本网络其他路由器的HELLO消息中的优先值小于其优先值；

•　侦听到来自本网络其他路由器的HELLO消息中的优先值均大于其优先值；

•　没有侦听到来自本网络的其他HELLO消息。

对第一种情形来说，该新加入路由器知道优先值较小的路由器将被选举为DR。对其他两种情形来说，该新加入路由器将承担DR的角色，并在其HELLO消息中将优先值设置为0以宣告该事实。如果所有HELLO消息中的优先值均相同，那么IP地址最小的路由器将被选举为DR。

在稳定状态时，DR会每隔60秒发送一条HELLO消息，一方面宣告其状态，另一方面作为保持激活消息。此外，DR还会用HELLO消息作为来自其他新加入路由器的HELLO消息的响应消息，而其他路由器则不发送HELLO消息，也不响应来自新加入路由器的HELLO消息。

在某些情况下，选出的DR可能不在去往核心路由器的路径上。假设图5-39中的RTA被选举为DR，但RTB是去往核心路由器的最佳下一跳路由器，此时，当RTC向RTA转发JOIN_REQUEST消息时，RTA会以单播方式通过多路访问链路将JOIN_REQUEST消息转发给RTB。这种重定向操作仅仅针对于JOIN_REQUEST消息，当RTB发送JOIN_ACK消息时，该消息会被直接发送给RTC。

5.5.4　成员源和非成员源

读者可能已经注意到，到现在为止仍然只字未提多播源如何将自己的多播流量传送给核心路由器。在很多多播应用中，发送方本身也是组成员，CBT就是如此，即CBT的发送方也是组成员——即成员源（member source）。由于成员源直连的路由器是on-tree路由器，因而可以到达核心路由器。图5-40解释了这个概念，图中标记为SG1的主机是多播组1的成员源，由于该主机是一个组成员，因而其本地路由器已加入多播组1的CBT树，这样一来，当SG1发起多播组1的多播包时，本地路由器能够沿多播树向上将多播流量转发到核心路由器。

图5-40　SG1是多播组1的成员源，其本地路由器已加入多播组1的多播树，能够将多播包沿多播树向上进行转发

该操作行为描述了CBT的一个基本特性，即CBT使用双向树（bidirectional trees）。换句话说，多播流量不仅能够沿着自核心路由器至组成员的多播树下行方向进行传送，还可以沿着自成员源至核心路由器的多播树上行方向进行传送。这一点与另一种共享树协议PIM-SM不同，PIM-SM使用的是单向树。

当然，并不是所有的多播源都是组成员，因而，CBT必须有相应的机制来适应这些非成员源（nonmenber source），该机制就是IP-in-IP隧道，如图5-41所示。图中的主机正在生成多播组1的多播流量，但该主机本身并不是多播组1的组成员，当其本地路由器接收到该多播流量时，会创建一条去往核心路由器的隧道（假定该路由器正运行CBT，因而知道核心路由器的地址），之后就通过单播方式将多播流量传送给核心路由器，再由核心路由器将多播流量传送到多播树上。

图5-41　如果源主机不是组成员，那么其本地CBT路由器会将该多播源的多播流量封装在IP-in-IP隧道中，并以单播方式将多播流量传送给核心路由器

5.5.5　CBT 消息格式

CBT消息被封装在IP头部之中，协议号为7。除了本节前面所说的单播例外，数据包都被传送到目的地址224.0.0.15，且TTL为1。图5-42显示了CBT消息所共享的通用头部格式。

图5-42　CBT消息头格式

CBT消息头的字段定义如下。

•　版本（Version）：指定CBT版本号，虽然有被废弃的版本1和处于提议状态的版本3，但本字段专门指定版本2。

•　类型（Type）：消息类型，表5-10显示了不同CBT消息所使用的类型号。

•　地址长度（Address Length）：指定相关消息中携带的单播或多播地址的长度（以字节为单位）。

•　校验和（Checksum）：采用的是标准算法，是整个CBT消息的反码和的反码。

表5-10 CBT消息类型

1．CBT HELLO消息格式

HELLO消息的格式如图5-43所示，该消息被用于在多路接入网络中选举指派路由器，DR路由器会每隔60秒发送一次HELLO消息，以用于保持激活消息。

图5-43　CBT HELLO消息格式

CBT HELLO消息的字段定义如下。

•　优先值（Preference）：取值范围为0〜255。其中，1〜254表示发信路由器成为DR的“合格程度”，优先值越低，表示越合格；0表示该HELLO消息由DR发起。当路由器首次在网络中被激活时，会连续发送两条包含其优先值的HELLO消息，以触发DR选举进程。优先值大于该新加入路由器优先值的路由器（较不合格）都不予以回应，而优先值小于该新加入路由器优先值的路由器将会响应一条携带其优先值的HELLO消息。这台新加入的路由器要么成为DR（如果其没有收到任何响应 HELLO消息），要么被明确告知其他具有较小优先值的路由器已经被选举为DR（通过停止发送HELLO消息）。

•　选项类型（Option Type）：指定选项值（Option Value）字段中的选项类型。CBTv2仅定义了一种选项BR（Border Router，边界路由器），本节一直没有描述该选项，BR是一种将CBT域连接到其他多播路由域的路由器，由BR发起的HELLO消息中的选项类型为0。

•　选项长度（Option Length）：指定选项值（Option Value）字段的长度（以字节为单位），由BR发起的HELLO消息中的选项长度为0。

•　选项值（Option Value）：是一个携带选项值的可变长字段，由BR发起的HELLO消息中的选项值为0。

2．CBT JOIN_REQUEST消息格式

由于IGMP成员关系报告消息的缘故，那些希望被嫁接到某特定多播组CBT树上的路由器会发起一条JOIN_REQUEST消息，该消息的格式如图5-44所示。

图5-44　CBT JOIN_REQUEST消息格式

CBT JOIN_REQUEST消息的字段定义如下。

•　组地址（Group Address）：所要加入的多播组的多播地址。

•　目标路由器（Target Router）：该多播组的核心路由器的地址。

•　发信路由器（Originating Router）：发起该消息的路由器的地址。

•　选项类型（Option Type）、选项长度（Option Length）和选项值（Option Value）：与 HELLO消息中的对应字段一样。

3．CBT JOIN_ACK消息格式

核心路由器或on-tree路由器在响应JOIN_REQUEST消息时发送的就是JOIN_ACK消息，其格式如图5-45所示。该消息被发送给发起JOIN_REQUEST消息的发信路由器，表示已成功加入该多播组。

图5-45　CBT JOIN_ACK消息格式

CBT JOIN_ACK消息的字段定义如下。

•　组地址（Group Address）：正在加入的多播组的多播地址。

•　目标路由器（Target Router）:JOIN_ACK消息所要发送到的路由器地址，也就是 JOIN_REQUEST消息（即JOIN_ACK所要响应的消息）中发信路由器字段中的地址。

•　选项类型（Option Type）、选项长度（Option Length）和选项值（Option Value）：与 HELLO消息中的对应字段一样。

4．CBT QUIT_NOTIFICATION消息格式

QUIT_NOTIFICATION消息的格式如图5-46所示，该消息被发送给父路由器（直连的上游路由器），以请求从某多播组树中剪除出去。当某路由器没有针对某特定多播组的下行接口时（收到了IGMP离开组消息，查询超时或者从其子路由器（直连的下游路由器）收到 QUIT_NOTIFICATION消息），就会发起QUIT_NOTIFICATION消息。

图5-46　CBT QUIT_NOTIFICATION消息格式

CBT QUIT_NOTIFICATION消息的字段定义如下。

•　组地址（Group Address）：正要推出的多播组的多播地址。

•　发信子路由器（Originating Child Router）：发起该消息的路由器地址。

5．CBT ECHO_REQUEST消息格式

子路由器负责维护去往父路由器的链路，为此，子路由器每隔60秒就发送一条ECHO_REQUEST消息。如图5-47所示，ECHO_REQUEST消息仅包含消息头和发信子路由器的地址。

图5-47　CBT ECHO_REQUEST消息格式

6．CBT ECHO_REPLY消息格式

父路由器发送ECHO_REPLY消息（其格式如图5-48所示）作为来自子路由器的 ECHO_REQUEST消息的响应消息，这两条消息合在一起就构成了父路由器与子路由器间链路的保持激活机制。

图5-48　CBT ECHO_REPLY消息格式

CBT ECHO_REPLY消息的字段定义如下。

•　发信父路由器（Originating Parent Router）：指定消息发起者的地址。

•　组地址（Group Address）：一个或多个列出了多播组地址（父路由器将这些多播组的多播包转发给链路上的子路由器）的字段。

7．CBT FLUSH_TREE消息格式

当CBT路由器失去与父路由器的连接时，会向其下游子路由器发送FLUSH_TREE消息（其格式如图5-49所示），子路由器收到FLUSH_TREE消息后，会清除该消息中列出的所有多播组的转发信息。

图5-49　CBT FLUSH_TREE消息格式

CBT FLUSH_TREE消息的字段定义如下。

组地址（Group Address）：一个或多个列出了多播组地址（发信父路由器与这些多播组失去联系，收到该消息的子路由器应清除这些多播组的转发状态）的字段。

5.6　PIM简介

如果读者正在准备CCIE考试，那么花费时间学习本章前面所介绍的Cisco不支持或部分支持（指的是DVMRP）的多播路由协议将是一种时间浪费，但每种协议都指出了多播路由协议所期望和不期望的内容。

DVMRP共享易于实现（只要打开该协议即可，无需做其他工作）的单播距离矢量协议，但这种简单性是以高开销为代价的，从而带来了严重的扩展性问题，仅适用于小型、高带宽且密集分布了大量组成员的网络。

MOSPF将链路状态协议的优点引入到路由表中，但带来的代价是设计复杂。MOSPF利用显式加入机制解决了DVMRP的topsy-turvy规则（即不转发特定多播组的数据包的路由器必须记住（保持状态）不转发该多播组的数据包），然而MOSPF的有源树仍然不适用于组成员稀疏分布的拓扑结构。虽然MOSPF对扩展性做了有限的提升，但是许多（如果不是大多数的话）网络设计者都不愿意接受MOSPF所带来的拓扑结构的复杂需求。

DVMRP是一种“自包含”协议，它使用自己内嵌的协议来定位用于创建和维护多播树所需的单播地址。从这种意义上来说，DVMRP协议与底层单播路由协议完全无关，但这种协议无关性的代价却是对网络资源（收集可能已经存在于单播路由表中的信息）的大量消耗。

注意：　这种代价也可能不像想象的那么高。如5.8.1小节所述，在没有内嵌式单播组件的情况下，代价与所运行的泛洪/剪除协议相关。

另一方面，MOSPF是单播协议的多播扩展，因而MOSPF虽然解决了独立单播协议的冗余性问题，但是不能脱离于OSPF独立运行。

CBT引入了真正的协议无关性特性，基于已有的单播路由表来确定单播目的地，根本不关心是哪种协议在维护这张路由表。虽然必须仔细规划核心路由器的放置位置，以尽量减少次优路径和流量瓶颈，但CBT具有足够的扩展能力来适应稀疏拓扑结构。目前，CBT正陷入Catch-22（第22条军规，寓意两难的尴尬境地），一方面，虽然现实生活中的多播应用都对该协议感兴趣，但始终受限于该协议的不成熟性；另一方面，由于该协议缺乏现实应用，因而始终难以成熟。除非CBT的设计者能够让CBT比当前广泛使用、也更灵活的PIM-SM更好，否则很难进入主流技术。

PIM（Protocol Independent Multicast，协议无关多播）是Cisco IOS惟一完全支持的IP多播路由协议（对于DVMRP来说，Cisco IOS仅仅支持将PIM连接到DVMRP网络上）。

与CBT类似，顾名思义，PIM具有协议无关性，也就是说，PIM利用单播路由表来定位单播地址，而不关心路由表是如何学习到这些单播地址的。

有一个标准的PIM消息格式列表，某些PIM消息仅用于PIM-DM（Protocol Independent Multicast,Dense Mode，协议无关多播—密集模式），某些消息仅用于PIM-SM（Protocol Independent Multicast, Sparse Mode，协议无关多播—稀疏模式），而某些消息则被两者所共用。所有的消息格式（包括仅用于PIM-DM的消息）都将在5.8节中进行详细描述。

目前的PIM版本是PIMv2,PIMv1将其消息封装在IP包中，协议号为2（IGMP），并使用多播地址224.0.0.2。PIMv2（Cisco IOSSoftware Release 11.3（2）T之后的版本均支持PIMv2）使用其自己的协议号103及保留的多播地址224.0.0.13，当PIMv2路由器与PIMv1路由器进行对等时，会自动将其接口设置为PIMv1．

5.7　PIM-DM 操作

到本书写作之时，仍然没有相应的RFC来描述PIM-DM，有关描述仅存在于Internet草案之中。除了通用的消息格式之外，读者可能会发现，PIM-DM与DVMRP之间的相似性甚至要多于PIM-DM与PIM-SM之间的相似性。

5.7.1　PIM-DM基础

PIM-DM使用以下5种PIMv2消息。

•　Hello；

•　Join/Prune（加入/剪除）；

•　Graft（嫁接）；

•　Grafl-ACK（嫁接确认）；

•　Assert（声明）。

PIMv2路由器使用Hello消息来发现邻居，当PIMv2路由器（PIM-SM或PIM-DM）被激活时，会在每个配置了PIM的接口上周期性地发送Hello消息；PIMv1路由器有类似的功能，只是使用的是Query（查询）消息。Hello（或Query）消息包含一个保持时间（holdtime），其指定邻居在宣称发信路由器无效之前需要等待收到下一条消息的最大时间。Cisco IOS Software中默认的PIMv2 Hello间隔和PIMv1 Query间隔均是30秒，可以利用命令ip pim query-interval来按照接口修改该默认间隔，保持时间被自动设置为Hello/Query间隔的3.5倍。

例5-3显示了命令debug捕获的PIM消息，请注意，该路由器同时拥有PIMv1邻居和 PIMv2邻居（如关键字Hello和Router-Query所示）。该路由器正在接口E0上发送Hello消息，但并没有从该接口上接收到任何Hello或Query消息，表明该子网上无PIM邻居。

例5-3：路由器Steel在接口E0、E1和S1.708上查询邻居，从接口E1和S1.708上侦听到邻居。

如例5-4所示，使用了命令debug ip packet detail（链接到访问列表来过滤无关数据包）来进一步查看PIM消息。可以看出，PIMv2消息被发送给224.0.0.13（使用的协议号是103），而PIMv1消息则被发送到224.0.0.2（使用的协议号是2）。

例5-4：命令debug的输出结果显示了PIMv1和PIMv2所使用的多播目的地址和协议号。

如例5-5所示，可以利用命令show ip pim neighbor来观察PIM邻居表的情况。

例5-5:PIM邻居表记录了例5-3中的侦听到邻居。

当多播源开始发送多播包时，PIM-DM利用泛洪/剪除协议来构建多播树。当每个PIM-DM路由器收到一个多播包时，都会在自己的转发表中增加一个表项，最终多播包被泛洪到所有叶子路由器——即没有下游PIM邻居的路由器。如果接收到多播包的叶子路由器未连接任何组成员，那么该路由器就必须将自己从多播树中剪除出去。为此，需要向沿着多播源方向的上游邻居发送Prune（剪除）消息，Prune消息的目的地址是224.0.0.13，上游邻居的地址也被编码在该消息之中。如果该上游邻居没有连接该多播包所属组的组成员，也没有其他下游邻居或从其所有下游邻居都接收到剪除消息，那么该路由器也会向沿着多播源方向的上游邻居发送Prune消息。

回顾本节前面列出的PIMv2消息类型可以看出，没有“Prune消息”，只有“Join/Prune消息”，该消息使用不同的字段分别列出所要加入的多播组和所要剪除的多播组。为了清楚起见，本节仍继续使用“Prune消息”和“Join消息”，但本节所说的Prune消息实际上就是将组地址列于剪除字段的Join/Prune消息。与此类似，Join消息实际上就是将组地址列于加入字段的Join/Prune消息。

例5-6显示了多播组239.70.49.238的转发表项，观察（S，G）表项，可以看出源地址为 172.16.1.1。路由器查询其单播路由表，以发现去往多播源的上行接口（即S1.708）以及去往多播源的上游邻居（即172.16.2.242），这些信息将进入多播转发表，并用于RPF检查。对 DVMRP来说，如果源地址为172.16.1.1、目的地址为239.70.49.238的数据包到达的接口不是S1.708，那么RPF检查将失败，该数据包也将被丢弃。

注意：　例5-6并没有显示转发表中与该多播组相关的全部信息。为了清楚起见，例5-6删除了部分信息，第6章将详细解释该转发表。

例5-6：命令show ip mroute显示的多播转发表。

（S，G）表项有两个定时器，第一个定时器指示该表项在转发表中存在的时间，第二个定时器指示该表项的到期时间。如果在2分59秒之内无任何多播包发送给该（S，G），那么该表项将被删除。

注意：　Cisco IOS Software使用的超时定时器的定时时间为2.5分钟，而Internet草案建议的超时定时器的时间为3.5分钟。

例5-6中的（S，G）表项也有两个相关标记，第一个标记（C）表示该路由器的直连子网上有一个组成员，第二个标记（T）表示该路由器是SPT（Shortest Path Tree，最短路径树）（即CBT中的术语“on-tree”）中的一个有效成员。

注意：　PIM将有源树最短路径树和共享树称为RPT（Rendezvous Point Tree，聚合点树）。SPT只是一个描述性名字，因为如本节后面内容所述，这些多播树有时会选择较短的路径（与RPT相比）去往多播源。

例5-6中的出站接口列表上出现了两个接口。第一个接口（E1）处于剪除状态和密集模式，因而可以知道该接口上的下游邻居发送了一条Prune消息，定时器显示该接口已启用了 1小时40分23秒，且剪除状态将在39秒后到期。接收到Prune消息之后，路由器会启动一个210秒的超时定时器，在该定时器到期之前，路由器会一直维持剪除状态。待定时器到期之后，该路由器的状态将被转换为“转发”状态，并重新将数据包转发给下游邻居，直至下游路由器向其上游邻居发送Prune消息，上述操作过程与DVMRP完全相似。

第二个接口（E0）处于转发状态，回顾例5-3可以知道，该路由器在接口E0上发送Hello消息，但没有在该接口上接收到任何来自邻居的Hello消息。基于上述信息以及例5-6可以知道，由于该子网上有一个组成员，因而该路由器在接口E0上转发多播包，例5-7证实了该结论。请注意，例5-6中有一个与接口E0相关联的正常运行时间（uptime），但是没有到期时间，这是因为没有邻居状态会到期。相反，当IGMP告诉该路由器子网中不再有组成员或例5-7中显示的超时定时器为0时，该路由器会从转发表中删除接口E0。

例5-7：命令show ip igmp group显示了记录在IGMP成员关系表中所连接的组成员。

例5-8显示了沿上游方向去往多播源的下一台路由器的转发表情况，在接口S1.803上对（172.16.1.1，239.70.49.238）和上游邻居172.16.2.254执行了RPF检查，并且只有一个下行接口。将该表项的标记与例5-6中的标记相比可以看出，该路由器位于最短路径树上，但没有直连的组成员。

例5-8：该表项的标记表明该路由器位于SPT上，但是没有直连的组成员。

注意：　虽然例5-8输出结果的格式与前一个转发表有少许不同（这是因为使用了不同的Cisco IOS软件版本），但可以看出两个转发表中的相关信息是相同的。

再次回到上游路由器，例5-9显示了该多播组的另一个转发表，其中的标记为“已连接”，但是该例中所连接的不是组成员。请注意，入站接口E0/0显示的RPF邻居地址为0.0.0.0，表明所连接的设备是多播组的源。

例5-9：从RPF邻居地址0.0.0.0可以看出，该路由器连接在多播源172.16.1.1上。

例5-9也显示了（172.16.1.1,239.70.49.238）表项的两个出站接口，其中一个处于转发状态，另一个处于剪除状态。与所有的泛洪/剪除协议一样，PIM-DM也必须为所有的接口维护剪除状态，原因是路由器将其从多播树剪除出去之后，还可以在需要的时候重新嫁接回该多播树。

举例来说，例5-10显示了某路由器的（172.16.1.1,239.70.49.238）表项情况，该路由器没有连接任何组成员，也没有下游邻居，因而出站接口列表为空，标记P表示该路由器向其上游邻居172.16.2.246发送了一条Prune消息。如果此时其所连接的某台主机发送了一条 IGMP消息，请求加入该多播组，那么该路由器会向其上游邻居（向着多播源的方向）发送一条PIM Graft（嫁接）消息，但是该路由器知道该多播源的地址的惟一方式就是通过最初的多播包泛洪，因而路由器必须维护例中所示的剪除状态。

例5-10：由于（S，G）表项（172.16.1.1，239.70.49.238）的出站接口列表为空，因而该路由器将自己从该多播树中剪除了出去。

Graft消息以单播方式被发送给多播树上的上游邻居。当上游路由器接收到该Graft消息后，会将接收到该消息的接口增加到其出站接口列表中，从而使该接口进入转发状态，并立即向其新下游邻居发送Graft-ACK（嫁接确认）消息。如果该路由器正在向其他下游邻居转发多播包，那么则无需做进一步操作；但是，如果该路由器也已经将自己从该多播树中剪除出去了，那么就必须也要向其上游邻居发送Graft消息。当路由器发送了Graft消息之后，会等待3秒钟，以等待Graft-ACK消息，但如果3秒内没有收到该确认消息，那么该路由器就需要重传Graft消息。

PIM-DM的这种泛洪/剪除机制与DVMRP非常相似，但两者之间的差别也很明显。在 5.3.2小节中曾经说过，DVMRP利用毒性反转机制向其上游邻居通告路由的相关性，该路由相关性的作用是告诉上游DVMRP路由器，某特定下游路由器需要依赖该路由来转发来自特定多播源的多播包。由于DVMRP有内嵌的路由协议，即便在多播源开始转发多播包之前，这一切也可以正常进行。因此，在某些拓扑结构中，DVMRP可以限制泛洪的范围，而PIM-DM则无此能力（因为PIM-DM无内嵌的路由协议），因而PIM-DM需要在整个PIM域中进行泛洪。该协议的设计者在规范中提出以下申明：

“不依靠特定的拓扑结构发现协议所带来的简单性和灵活性让我们能够接受本协议引入的额外开销。”

5.7.2　剪除覆盖

DVMRP下游相关性机制的另一个优点在剪除进程中是非常明显的。如图5-50所示，某路由器拥有多个下游邻居，上游路由器Mercury正将多播包泛洪到连接了这3台路由器的 LAN上；Copper的出站接口列表为空，因而向Mercury发送了一条剪除消息；但Silver连接了组成员，因而希望接收多播流量。

图5-50　由于Copper关于（172.16.1.1,238.70.49.238）的出站接口列表为空，因而发送了一条该（S，G）表项的Prune消息；Silver连接了一个组成员，因而希望接收多播流量

如果这3台路由器运行的是DVMRP，那么就没有问题。由于Mercury知道关于该多播组的源的下游相关性，也知道仅从Copper接收了Prune消息，因而继续向Silver转发流量。

但是，如果图5-50中的路由器运行的是PIM-DM，那么Mercury可以根据Hello消息知道其有两个邻居，但Hello消息中并没有描述任何路由相关性信息，因而当Copper发送Prune消息时，Mercury不知道是否要剪除该LAN接口。

PIM-DM利用剪除覆盖（prune override）进程解决了该问题。Copper向Mercury发送了 Prune消息，但Mercury的地址也被编码在该消息之中，携带该消息的IP包被寻址到ALL PIM Routers（所有PIM路由器）地址224.0.0.13。当Mercury接收到该Prune消息后，并不立即剪除该接口，而是设置一个3秒定时器。与此同时，Silver也接收到了该Prune消息（因为该消息使用的是多播目的地址），看到消息中所要剪除的多播组是其希望继续接收多播流量的多播组，而且该消息已经被发送给正在转发多播流量的其上游邻居，因而Silver向Mercury发送了一条Join消息（如图5-51所示）。这样一来，Silver就覆盖了由Copper发送的Prune消息，只要Mercury在3秒定时器到期前接收到一条Join消息，就不会中断多播流量。

图5-51　Silver利用Join消息来覆盖Copper发送的Prune消息

例5-11显示了剪除覆盖进程的运行情况。利用调试命令来捕捉图5-50和图5-51中 Mercury的PIM活动情况，第一条消息显示在接口E0上接收到了一条来自Copper（172.16.3.2）针对（S，G）（172.16.1.1，239.70.49.238）的Prune消息（实际上是在剪除字段中列出239.70.49.238的Join/Prune消息）。请注意，第一行显示该消息为“to us”，表明Mercury已经识别出被编码在该消息中的自己的地址。

第2行和第3行显示路由器Mercury已经计划将（S，G）表项从接口E0上剪除出去，也就是说，已启动了3秒定时器。在第4行，Mercury从Silver（172.16.3.3）接收到一条Join消息。在第5、6行，接口E0处于（S，G）表项的转发状态，Copper的Prune消息已被覆盖。

例5-11：图5-51中的路由器Mercury接收到来自Copper（172.16.3.2）的Prune消息，之后，Silver（172.16.3.3）发送的Join消息覆盖了Copper的Prune消息。

5.7.3　单播路由变化

当拓扑结构发生变化时，单播路由表也要随之发生变化；如果单播路由的变化会影响去往多播源的路由，那么PIM-DM路由表也会发生变化。一个明显的例子就是拓扑结构的变化导致去往某多播源的路径上出现不同的前一跳（previous-hop）路由器。

当多播源的RPF路由器发生变化后，PIM-DM会首先向旧RPF路由器发送一条Prune消息，之后再向新RPF路由器发送一条Graft消息，以构建新的多播树。

5.7.4　PIM-DM 指派路由器

PIM-DM会在多路接入网络中选举一台指派路由器。需要注意的是，PIM-DM协议本身并不需要DR，只是由于IGMPv1没有查询进程，为了管理IGMP查询，IGMP需要依赖该路由协议来选举DR，这也就是PIM-DM（及PIM-SM）指派路由器的作用。

DR选举进程非常简单，每台PIM-DM路由器每隔30秒就发送一条PIMv2 Hello消息或一条PIMv1 Query（查询）消息，以进行邻居发现。在多路接入网络上，IP地址最大的PIM-DM路由器将成为DR（如例5-12所示输出结果），其他的路由器则监控DR发出的Hello包。如果在105秒内都没有接收到该Hello包，则认为DR已失效，从而选举一个新的DR。

例5-12：例5-11中的PIMv邻居表显示Silver（其IP地址172.16.3.3最大）是指派路由器。

5.7.5　PIM 转发路由器选举

如图5-52所示，Mercury和Copper都有一条去往多播源172.16.1.1的路由，且都有一个下行接口去往多播组239.70.49.238（该多播组连接在一个公共多路接入网络中）的成员。由于Mercury和Copper都从该多播组接收到相同的多播包拷贝，因而很明显，如果这两台路由器都将该多播包转发到相同的网络上，那么效率将非常低下。

为了防止上述情况的发生，PIM路由器将在共享网络上选择一台转发路由器（forwarder）。前面说过，DVMRP也有类似的功能，DVMRP选举的是指派转发路由器（designated forwarder），DVMRP的指派转发路由器的选举进程是多路接入网络中路由交换的一部分。但是，由于PIM没有自己的路由协议，因而需要利用Assert（声明）消息来选择转发路由器。

图5-52　Copper和Mercury都从多播源172.16.1.1接收到相同的多播包拷贝，但只有一台路由器将该多播包转发到子网172.16.3.0/24上

当路由器在出站多路接入接口上接收到一个多播包时，会向网络发送一条Assert消息，该消息中包含了多播源的地址和多播组的地址、去往多播源的单播路由的度量值以及单播路由协议用来发现该路由的度量优先值（metric preference，即Cisco术语中的“管理性距离”）。制造数据包拷贝的这些路由器会比较这些消息，并根据以下规则来确定转发路由器。

•　所宣告的度量优先值（管理性距离）最低的路由器为转发路由器。如果这些路由器是通过不同的单播路由协议来发现这些去往多播源的路由，那么这些路由器仅宣告不同的度量优先值。

•　如果度量优先值均相等，那么所宣告的度量值最低的路由器为转发路由器。换句话说，如果这些路由器运行了相同的单播路由协议，那么在度量值上最靠近多播源的路由器就成为转发路由器。

•　如果度量优先值和度量值都相等，那么网络中IP地址最大的路由器就是转发路由器。

由转发路由器负责继续将多播流量转发到多路接入网络中，其他的路由器则停止转发该多播组的流量，并从各自的出站接口列表中删除该多路接入接口。

举例来说，当图5-22中的多播源开始向多播组239.70.49.238发送数据包时，Copper和 Mercury都将收到该数据包拷贝，并且都将该数据包转发到子网172.16.3.0/24上（如图5-53（a）所示）。当Copper在其以太网接口上从Mercury接收到（172.16.1.1,239.70.49.238）的多播包时，将看见该以太网接口位于该（S，G）的出站接口列表中，因而会向该子网发送一条 Assert消息。当Mercury在同一个接口上接收到来自Copper的多播包时，会执行相同的操作，如图5-53（b）所示。

图5-53　当Copper和Mercury在其下游多路接入接口上检测到（172.16.1.1，239.70.49.238）的多播包时，会发起Assert消息以确定该多播组的转发路由器

例5-13显示了 Silver的单播路由表和多播转发表。单播路由表显示了去往多播源 172.16.1.1的等价OSPF路径是经Copper（172.16.3.2）或经Mercury（172.16.3.1），由于这两条路由都是OSPF路由，因而管理性距离都是110；而且由于这两条路由的OSPF代价都是 74，因而IP地址最大的路由器将成为转发路由器。

例5-13：Silver的单播路由表显示了两个去往多播源172.16.1.1的下一跳路由器，多播路由表显示IP地址最大的路由器被选举为转发路由器。

5.8　PIM-SM 操作

通过前面的学习，已经知道了为什么共享树在稀疏分布的多播互联网络中的扩展性较好，也知道了为什么共享树可以应用于密集分布的多播互联网络。前面的讨论可能会给读者留下一个印象，那就是共享多播树总是优于有源树，但事实并非如此。

图5-54给出了一种有源树可能会优于共享树的应用场景。在图中所示的拓扑结构中，多播源与目的地之间的距离比各自到核心路由器（是共享树中的根部）的距离要近得多，因而直接在多播源和目的地之间建立有源树更好（如果可以降低相关开销的话）。

与CBT不同，PIM-SM同时支持共享树和有源树，这也是当前大多数现代互联网络广泛使用该协议的一个主要原因。有关PIM-SM的描述请参见RFC 2362^13。

图5-54　某些互联网络中的有源树可能会优于共享树

5.8.1　PIM-SM 基础

PIM-SM使用以下7种PIMv2消息。

•　Hello；

•　Bootstrap（引导）；

•　Candidate-RP-Advertisement（候选RP宣告）；

•　Join/Prune（加入/剪除）；

•　Assert（声明）；

•　Register（注册）；

•　Register-Stop（注册终止）。

其中的Hello、Join/Prune和Assert 3条消息在PIM-DM中也有，其余4条则是PIM-SM的特有消息（就像Graft和Graft-Ack是PIM-DM的特有消息一样）。

PIM-SM与PIM-DM有以下共同功能。

•　通过交换Hello消息来发现邻居；

•　单播路由表发生变化后需要重新计算RPF接口；

•　在多路接入网络中选举一台指派路由器；

•　在多路接入网络中使用剪除覆盖机制；

•　在多路接入网络中利用Assert消息来选举一台指派转发路由器。

上述功能都已在PIM-DM中介绍过了，本小节不再赘述。

与PIM-DM不同，PIM-SM采用的是显式加入机制，从而使得共享多播树和有源多播树的创建更加有效。

5.8.2　发现 RP

如前所述，共享树的根部是互联网络中的某台路由器，而不是多播源，CBT将该路由器称为核心路由器（core），而PIM-SM则将该路由器称为RP（Rendezvous Point，聚合点）。在建立共享树之前，加入的路由器必须知道如何发现RP。路由器可以通过以下3种方式来获知 RP的地址。

•　可以在所有路由器上静态配置RP的地址；

•　可以利用开放的标准Bootstrap（引导）协议来指定和宣告RP；

•　可以利用Cisco专有的Auto-RP协议来指定和宣告RP。

有关上述方法的使用方法将在第6章进行详细介绍。

对静态路由来说，在所有路由器上静态配置RP地址的好处是可以非常精确地控制互联网络，但代价是要付出较高的管理开销。静态RP配置方式一般仅适用于小型多播互联网络。

1．Bootstrap协议

Cisco IOS Software从Release 11.3T开始支持Bootstrap协议，该协议与CBT用来宣告核心路由器的协议相同，只是在消息名称和消息格式上有所区别。要想运行Bootstrap协议，就必须在互联网络中指派C-BSR（Candidate BootStrap Router，候选引导路由器）和C-RP（Candidate Rendezvous Point，候选聚合点）。通常情况下，一般将同一组路由器同时配置为 C-BSR和C-RP，通过IP地址（通常配置为环回接口的地址）来区分C-BSR和C-RP。

首先要从C-BSR中选出BSR（BootStrap Router，引导路由器），每台C-BSR都被指定了一个0～255之间的优先级（默认为0）和一个BSRIP地址。当路由器被配置为C-BSR后，会启动一个130秒的引导定时器并侦听Bootstrap消息。

Bootstrap消息的作用是宣告发信路由器的优先级和BSR IP地址。当C-BSR收到Bootstrap消息后，会将自己的优先级与发信路由器的优先级进行对比，如果发信路由器的优先级较高，则接收路由器会重置自己的引导定时器并继续侦听；如果接收路由器的优先级较高，则将自己宣称为BSR并开始每隔60秒发送一条Bootstrap消息；如果两者的优先级相等，则BSR IP地址较高的路由器成为BSR。

当C-BSR的130秒引导定时器到期时，该路由器将认定网络中无BSR，则将自己宣称为BSR，并开始每隔60秒发送一条Bootstrap消息。

Bootstrap消息使用ALL PIM Routers（全部PIM路由器）地址224.0.0.13，且TTL为1。当PIM路由器接收到一条Bootstrap消息后，会通过所有接口（接收到该消息的接口除外）向外发送该消息的拷贝。该处理过程不仅可以保证将Bootstrap消息泛洪到整个多播源，还可以确保每台PIM路由器都能接收到一份消息拷贝并知道哪台路由器是BSR。

每台C-RP都会被分配一个RP IP地址和一个0～255之间的优先级，可以将路由器配置为某些特定多播组的C-RP，也可以配置为所有多播组的C-RP，当通过接收到的Bootstrap消息知道了BSR之后，C-RP就开始向BSR单播发送Candidate-RP-Advertisement（候选RP宣告）消息，这些消息中包含了发信路由器的RP地址、组地址（发信路由器是该组的候选RP）及其优先级。

BSR将所有C-RP的优先级及相关的多播组都编译成RP-Set，并通过Bootstrap消息在整个 PIM域中宣告该RP-Set。此外，Bootstrap消息中还包括一个8bit哈希掩码（hash-mask）。由于 Bootstrap消息使用的是地址224.0.0.13，因而所有的PIM路由器都将收到该Bootstrap消息。

当某台路由器接收到IGMP消息或PIM Join消息而要加入某共享树时，需要检查接收自 BSR（通过Bootstrap消息）的RP-Set。

•　如果该多播组只有一个C-RP，则该路由器将被选为RP。

•　如果该多播组拥有多个C-RP，且优先级不同，则优先级最低的路由器将成为RP。

•　如果该多播组拥有多个C-RP，且优先级均相同，则需要运行哈希函数。该函数的输入是组前缀、哈希掩码和C-RP地址，输出是某些度量值。函数输出值最大的C-RP将成为RP。

•　如果多个C-RP的哈希函数输出值完全相同，则IP地址最大的C-RP将成为RP。

注意：　哈希函数如下。Value（G,M,C）=（1103515245 *（（11035515245 *（G&M）+ 12345）XOR C）+12345）mod 2^31
其中，G=组前缀，M=哈希掩码，C=C-RP地址。

上述处理过程可以确保PIM域中的所有路由器都能为同一个多播组选出相同的RP。需要哈希函数的惟一原因就是要融入哈希掩码，哈希掩码可以将多个连续的组地址映射为同一个RP。有关哈希掩码的使用方法将在第6章进行详细描述。

2．Auto-RP协议

Cisco IOS Software从Release 11.1（6）开始支持Auto-RP协议，在PIM-SM所用的Bootstrap协议出现之前，Cisco开发了该协议以提供RP的自动发现功能。与Bootstrap协议类似，Auto-RP也需要在PIM-SM中指派C-RP，并通过指派的IP地址（通常是环回接口的地址）来标识C-RP。此外，还需要指定一个或多个RP映射代理（RP mapping agent），RP映射代理的作用与BSR相似。Auto-RP协议与Bootstrap协议之间的主要差别如下。

•　Auto-RP是Cisco专有协议，因而通常不能用于多厂商拓扑结构，不过现在也有部分厂商开始支持Auto-RP协议。

•　与BSR需要从一组候选BSR中选举出来不一样，RP映射代理是直接指派的。

•　RP映射代理是将多播组映射到RP，而不是宣告RP-Set以及在整个多播域中发布选举进程。

•　与Bootstrap协议使用多播地址224.0.0.13且能被所有PIM路由器理解不一样，Auto-RP使用的是两个保留的多播地址224.0.1.39和224.0.1.40。

当某台Cisco PIM-SM路由器被配置为一个或多个多播组的C-RP时，它会在RP-Announce（RP通告）消息中宣告自己是这些多播组的C-RP，并每隔60秒将这些消息多播到保留的Cisco-RP-Announce地址224.0.1.39。PIM域中已配置的RP映射代理将侦听该地址，并从接收到的全部RP-Announce消息中为该多播组选出一个RP（该多播组的所有C-RP中IP地址最大者将成为RP）。

然后，RP映射代理在RP-Discovery（RP发现）消息中宣告完整的group-to-RP（组到 RP）映射列表，并以60秒为间隔将这些消息多播到保留的Cisco-RP-Discovery地址224.0.1.40。所有的Cisco PIM-SM路由器都会侦听该地址，因而可以掌握每个多播组的RP情况。

5.8.3　PIM-SM 与共享树

共享树路由表项与有源树或SPT路由表项之间的主要区别在于，共享树路由表项中没有指定多播源——这与共享树中多个多播源共享同一个多播树相一致。因而，共享树路由表项是一个（*，G）对，其中的星号为通配符，表示发送给多播组G的任意或全部源地址。

当PIM-SM DR从某台希望加入某多播组的主机接收到IGMP成员关系报告消息之后，首先检查其多播表中是否已经存在该多播组的路由表项，如果存在，那么接收到该IGMP消息的接口将被加入到路由表项中作为出站接口，无需再做其他操作。

如果多播表中无相应的表项，那么就需要为该多播组创建一个新的（*，G）表项，并加入出站接口。之后该路由器会查找group-to-RP映射列表中的该多播组（如例5-14所示），查询单播路由表以找到去往特定RP的路由，并将去往RP的上行接口加入到入站（RPF）接口中。

例5-14：命令show ip pim rp mapping显示了路由器的group-to-RP映射列表，所有的多播组都被映射到RP 172.16.224.1。

例5-15给出了图5-55中路由器Iron中的一个（*，G）路由表项示例。

例5-15：本例中的（*，G）表项显示出多播树上的多播组236.82.134.23的上游邻居是 172.16.224.1，通过出接口S1.708可达，且该多播组的RP为172.16.224.1。与该路由表项相关的标记表示该多播网络为稀疏模式且连接了一个组成员（在接口E0上）。

图5-55　路由器Brass是本PIM-SM域的RP，在其环回接口上配置了RP地址（172.16.224.1）

之后，该路由器将通过上行出接口向224.0.0.13发送一条Join/Prune消息（如图5-56所示）。该消息中包含了将要加入的多播组的地址和RP的地址，消息中的剪除字段为空。此外，还设置了两个标记——WC-bit（wildcard bit，通配符bit）和RPT-bit（RP-tree bit，RP树bit）。

•　WC-bit=1表示加入地址是RP地址，而不是源地址。

•　RPT-bit=1表示该消息沿多播树被传播到RP。

图5-56　Join/Prune消息以多播方式逐跳传送到RP

当上游路由器接收到Join/Prune消息后，可能会执行以下4种操作中的一种。

•　如果该路由器不是RP，但位于共享树上，那么该路由器会将接收到Join/Prune消息的接口加入到该多播组的出站接口列表中；

•　如果该路由器不是RP，且不位于共享树上，那么该路由器将创建一个（*，G）表项，并沿着RP的方向向上游邻居发送自己的Join/Prune消息；

•　如果该路由器是RP，且其路由表中已经存在该多播组的路由表项，那么该路由器会将接收到Join/Prune消息的接口加入到该多播组的出站接口列表中；

•　如果该路由器是RP，但其路由表中没有该多播组的路由表项，那么该路由器将创建一个（*，G）表项，并将接收到Join/Prune消息的接口加入到该多播组的出站接口列表中。

最后一种情形包含了一层隐含意义，那就是一个多播组并不需要有一个用于多播树（构建自RP成员）的多播源。

多播树建立之后，路由器就开始周期性地向上游邻居发送Join/Prune消息，以保持激活。这些Join/Prune消息中列出了目的邻居是前一跳路由器的所有路由表项，默认的发送周期是 60秒，也可以利用Cisco IOS命令ip pim message-interval修改该周期。保持时间则是 Join/Prune消息间隔的3倍或默认值3分钟，该时间也要通过Join/Prune消息进行宣告。如果在保持时间内，PIM-SM路由器都没有从下游邻居接收到某多播组的Join/Prune消息，则将下游邻居从其多播组表项的出站接口列表中剪除。例5-16显示了图5-55路由器Tin中多播组236.82.134.23的路由表项。去往路由器Iron的出站接口是S1.805，如果在2分11秒之内都没有收到Iron发送来的Join/Prune消息，则Tin会将该接口从出站接口列表中剪除。

例5-16：图5-55路由器Tin中多播组236.82.134.23的路由表项显示了与下游路由器Iron相关联的剩余保持时间。请注意，由于Tin没有直连的组成员，因而该表项没有设置C标记。

剪除过程与前面所述一样，当路由器希望将自己从共享树中剪除出去时（因为该路由器已经无直连的组成员或下游邻居），会从RPF接口向上游邻居发送一条Join/Prune消息，组地址和RP地址位于该消息的剪除字段，且设置了WC-bit和RPT-bit。之后，上游路由器就从该多播组的出站接口列表中删除接收到该消息的接收接口，如果该上游路由器也没有下游邻居且未连接组成员，则也要剪除自己。

注意：　PIM-SM也使用PIM-DM中描述的剪除覆盖机制，以确保多路接入网络中的下游邻居不会被意外剪除。

5.8.4　源注册

前面已经多次提到过共享树的基本概念，即多播树的根部是核心路由器或聚合点，而不是多播源，但随之而来的问题是多播源如何将多播包分发给RP，再由RP分发到多播树的所有树枝？回顾一下CBT的解决方法，CBT使用了双向树（即多播包可以从核心路由器往下传送到树枝，也可以从树枝往上传送到核心路由器）。这样一来，与多播源直连的路由器加入去往核心路由器的共享树之后，就可以将多播流量从树枝发送到核心路由器。但双向树的缺点是很难保证无环路拓扑结构，原因是此时没有“上游”和“下游”之分，也就无法执行RPF检查。

与CBT不同，PIM-SM使用了RPF检查，因而其多播树必须是单向树，即多播流量只能从RP向下传送到树枝，单向流量可以清晰地定义入站或RPF接口。但是，如果只能从RP向外发送多播流量，那么多播源如何将自己的多播流量分发给RP呢？

当PIM-SM路由器首次接收到其直连多播源的多播包时，会在其group-to-RP映射表中查找目的多播组的RP（如例5-17所示），该步骤与组成员通过ICMP消息告知其希望加入某多播组类似。

例5-17：图5-55中路由器Aluminum的group-to-RP映射表。与例5-14相比，Iron有一个静态RP映射，而Aluminum则是动态学习RP地址。

确定了多播组的RP之后，路由器就将多播包封装在PIM Register（注册）消息中，并将该消息发送给RP。需要注意的是，Register消息是以单播方式（而不是多播方式）发送到RP地址的（如图5-57所示）。

图5-57　第一个多播包被封装在PIM Register（注册）消息中，并以单播方式传送给RP

RP接收到Register消息之后，就将多播包解封装出来，如果其多播路由表中已存在该多播组的路由表项，则在其出站接口列表中的所有接口上转发该多播包（如图5-58所示）。

图5-58　从Register消息中解封装出多播包，并在出站接口列表中的所有接口上转发该多播包的拷贝

如果需要将大量的多播包传送到RP，那么继续将多播包封装到Register消息中再传送到 RP，效率将非常低下。因而，RP在其多播表中创建了一个（S，G）表项，并通过多播传送一条Join/Prune消息来建立一个去往源DR的SPT（如图5-59所示），这条消息中包含了多播源地址，WC-bit=0且RPT-bit=0，表示该路径是有源SPT，而不是共享RPT。

图5-59　RP创建了一个去往多播源的DR的有源最短路径树

建立了SPT之后，RP就可以通过该多播树接收多播流量。此时，路由器需要向多播源的DR发送一条Register Stop（注册终止）消息，告诉DR停止在Register消息中发送多播包（如图5-60所示）。

图5-60　RP发送一条Register Stop消息来终止Register消息，此时多播源的多播包开始通过SPT被发送给RP

如果多播源开始向RP发送多播流量的时候没有组成员，那么RP将不构建SPT，而是向多播源的DR发送一条Register Stop消息，让其停止在Register消息中发送被封装的多播包。RP有该多播组的（*，G）表项，当有组成员加入时，RP就可以启动SPT。

一种被称为注册抑制（Register Suppression）的机制可以阻止DR持续不断地向失效RP发送数据包。当DR接收到Register Stop消息之后，会启动一个60s注册抑制定时器（Register-Suppression timer）。当定时器到期时，该路由器会再次通过Register消息发送多播包，但是在这之前的5s，DR会发送一条携带Null-Register（空注册）bit标记的Register消息。如果该消息触发了一条来自RP的Register Stop消息，那么就会重置注册抑制定时器。

例5-18中的调试消息显示了路由器Aluminum开始向多播组236.82.134.23发送多播流量时的事件顺序。对本例来说，此时还没有组成员加入该多播包，因而RP（Brass）立即向 Aluminum发送一条Register Stop消息，作为Register消息的响应消息。

例5-18：该RP没有多播组236.82.134.23的成员，因而立即向Aluminum（172.16.2. 233）发送一条Register Stop消息，作为Register消息的响应消息。请注意，这两条消息都是以单播方式（而不是多播方式）进行传送。

例5-19显示了该多播组的路由表项。可以看到，该多播组同时拥有（*，G）和（S，G）表项，其中，（*，G）表项显示的入站接口为Null（空），RPF邻居为0.0.0.0，表明该路由器是共享树的根部；（S，G）表项显示去往多播源的上游邻居Platinum（172.16.2.246）是RPF邻居，由于出站接口列表中无任何接口，因而该表项被剪除。

例5-19：RP上多播组236.82.134.23的路由表项，此时无任何成员加入该多播组。

例5-20显示了Aluminum（为该多播源的DR）上该多播组的路由表项，其中也存在（*，G）表项，出站接口列表中显示以太网接口连接到多播源，而入站接口列表为Null（空）。（S，G）表项显示该以太网接口在入站接口列表中。这两个表项有两个相同的标记，其中的一个标记（C）表示该多播源是直连在该路由器上，另一个标记（F）表示该路由器必须发送一条Register消息以传送多播流量。

（S，G）表项中的标记T表示该表项为SPT，标记P表示出站接口列表中无接口，如果有一个RPF邻居，那么该路由器将向该邻居发送一条该多播组的Prune（剪除）消息。

（*，G）表项中的标记J表示在共享树上接收到一个多播包后，路由器会切换到SPT，至于路由器如何从共享树切换到SPT将在下一小节进行描述。

例5-20：多播组源的DR的相关路由表项显示了一个被剪除的SPT项。

例5-21给出的调试消息显示了连接在路由器Iron上的主机加入该多播组后发生的一系列事件，接收自Tin的Join/Prune消息被Iron再生后以多播方式逐跳发送给RP。然后将去往 Tin的接口加入到（*，G）表项中，同时该接口也会被加入到（S，G）表项中（因为将使用去往Aluminum的SPT）。接下来，就是将SPT Join消息发送给Aluminum。

例5-21：这些debug消息显示连接在路由器Iron上的组成员正在加入多播组236.82.134.23。

例5-22显示了RP的路由表项，例5-23显示了多播源的DR的路由表项。

例5-22：当组成员加入时，其接口将被加入到（*，G）表项中。由于要使用去往Aluminum的SPT，因而该接口也被加入到（S，G）表项中。

例5-23：去往RP的接口已被加入到Aluminum的（S，G）表项的出站接口列表中，该表项也不再处于剪除状态。

5.8.5　PIM-SM 与最短路径树

如图5-61所示，路由器Lead已经被加入到PIM-SM域中，且Lead连接了一个组成员。根据基本的共享树规则，Lead将加入根部为Brass的共享树。但是从这个例子中可以很明显地看到，去往Aluminum的直连链路是多播包从多播源到Lead的组成员更有效路径。

图5-61　Lead与Aluminum之间的直连链路是多播包去往Lead所连组成员的更优路由（与Aluminum-Platinum-Brass-Lead路径相比）

读者已经了解了PIM-SM如何在RP和源DR之间建立SPT，而且该协议也允许在任何连接了组成员的路由器到源DR之间建立SPT，从而解决了拓扑结构的低效问题（如图5-61所示情形）。

例5-24显示了路由器Lead在其组成员通过IGMP请求加入某多播组之后的SPT构建情况。首先，Lead向RP发送Join消息（通过出接口S1.605），多播包到达后，Lead就查看多播源的IP地址，通过查找其单播路由表可以知道，需要通过其他接口（S1.603，不是去往 RP的接口S1.605）可以到达多播源IP地址。接着，Lead向Aluminum发送一条Join消息，并在这两台路由器之间直接建立SPT。当Lead开始通过SPT接收（172.16.1.1，236.82.134.23）的多播流量时，会向RP发送一条Prune消息，以便将自己从共享树中剪除出去。

例5-24：Lead加入了共享RPT，但开始接收多播流量之后就加入了直接从源到DR的 SPT，并将自己从RPT中剪除出去。

例5-25显示了Lead针对多播组236.82.134.23的多播路由表项。仍然存在共享树的（*，G）表项，只要该路由器连接了组成员或者有该多播组的下游邻居，那么该表项将一直存在。但是，需要注意的是，（S，G）表项显示了一个不同的入站接口和一个不同的RPF邻居。

例5-25：Lead中关于多播组236.82.134.23的多播路由表项显示该路由器已经从RPT切换到了SPT。

例5-26显示了Aluminum的路由表项，例5-27显示了Brass的路由表项，可以看出，Aluminum正通过SPT树将多播流量转发给Lead和Brass。对Brass来说，去往Lead的接口没在（S，G）表项的出站接口列表中（因为RP没有向Lead转发多播流量）。

例5-26：Aluminum中关于多播组236.82.134.23的多播路由表项，显示了一个去往Lead和Brass的SPT。

例5-27：Brass中关于多播组236.82.134.23的多播路由表项，去往Lead的接口（S1.506）仍然位于（*，G）表项的出站接口列表中，但不在（S，G）表项的出站接口列表中。

RFC 2362规定，当“数据速率很高时”，路由器应该从RPT切换到SPT，那么何谓高数据速率呢？这个问题没有确定的答案。因为这可能与该路由上的累计可用带宽、拥塞情况以及路由器的性能等多种因素相关，所以需要网络管理员根据自己互联网络的特征做出决定。

Cisco使用一种简单的默认机制，Cisco路由器首次从共享树上接收到某（S，G）的多播包后就立即加入SPT。可以使用命令ip pim spt-threshold来更改这种默认机制，其中，切换到SPT的速率阈值以kbit/s为单位（默认值为Okbit/s），路由器按秒来测量多播包的到达速率，如果多播包（任意多播组或某特定多播组）的到达速率超出了阈值，那么路由器就切换到SPT。路由器切换到SPT之后，就开始监控该有源树上的到达速率。如果该多播组的速率低于预配置阈值超过60秒，路由器就会切换回该多播组的共享树。

可以在命令ip pim spt-threshold中使用关键字infinity，以阻止路由器切换到SPT。

有意思的是，即使去往多播源的最短路径通过RP，路由器也要切换到SPT。在前面的示例中，路由器Iron位于RPT上，原因是在Iron的配置中加入了语句ip pim spt-threshold infinity。例5-28显示了Iron中关于多播组236.82.134.23的路由表项，然后从Iron的配置中删除命令ip pim spt-threshold infinity并重新观察该路由，可以看到，将SPT阈值重置为默认值之后，路由器就立即切换到SPT。由于去往路由器Iron的接口已经位于（S，G）表项的出站接口列表中，因而RP中的路由表项与例5-27保持一致。

例5-28：Iron中关于多播组236.82.134.23的路由表项，显示了将SPT切换阈值重置为默认值前后的情况。

在例5-28中以及前面的一些示意图中，标记J与（*，G）表项或（S，G）表项或两者有关，该标记为加入SPT标记。当标记J与（*，G）相关联时，表示沿共享树向下传送的多播流量超出了SPT阈值，如果没有加入SPT，则将在下一次接收到多播包的时候加入 SPT。当标记J与（S，G）相关联时，表示该路由器已经加入SPT（因为RPT流量已经超出了SPT阈值）。

表5-11列出了与多播路由标记相关联的全部标记，该列表直接引用自Cisco IOS Software Command Reference（软件命令参考指南）。

表5-11 多播路由标记

5.8.6　PIMv2 消息格式

PIMv2消息被封装在IP包中，协议号为103，除了以单播方式传送这些消息之外，IP目的地址都使用保留的多播地址224.0.0.13，且TTL为1。通过多播地址和TTL，可以确保仅将这些消息转发给邻居路由器。

虽然PIMv2是当前版本，但PIMv1的应用仍然相当普遍，PIMv1使用的IP协议号是2，为IGMP协议的一个子集，PIMv1使用的多播地址是224.0.0.2。

Cisco IOS自11.3（2）T之后开始支持PIMv2，并提供了与PIMv1的后向兼容性，PIMv2路由器在任何接口上检测到PIMv1邻居之后，都会自动切换到PIMv1。此外，还可以利用命令ip pim version以手工方式将某接口设置为PIMv1或PIMv2。

出于篇幅考虑，本书仅讨论PIMv2的消息格式，有关PIMv1的消息格式请参考相关的 Internet草案。

读者可能已经注意到，某些类型的消息中包含了用来引用被编码地址的字段标签，有关编码格式及这些字段的详细信息，请参考RFC 2362的第4.1节。

以下消息中的所有保留（Reserved）字段都被设置为全0，并在接收时予以忽略。

1．PIMv2消息头格式

所有的PIMv消息都有一个标准的消息头（如图5-62所示）。

图5-62　PIMv2消息头格式

PIMv2消息头的字段定义如下。

•　版本（Version）：指定版本号。虽然PIMv1目前仍在广泛使用，但目前的版本号是2。

•　类型（Type）：指定封装在头部后面的PIM消息类型，表5-12列出了PIMv2消息类型。

表5-12 PIMv2消息类型

•　校验和（Checksum）：一个标准的IP式校验和，长16bit，是PIM消息（除了Register消息中的数据部分）的反码的反码。

2．PIMv2 Hello消息格式

PIMv2的Hello消息用于邻居发现和邻居保持激活，其消息格式详见图5-63。在默认情况下，每隔30秒发送一次Hello消息，可以利用命令ip pim query-interval来修改该发送间隔。

图5-63　PIMv2 Hello消息格式

PIMv2 Hello消息的字段定义如下。

•　选项类型（Option Type）：指定选项值（Option Vlaue）字段中的选项类型，目前仅使用了选项类型1，表示选项值字段为保持时间，选项值2〜16保留。

•　选项长度（Option Length）：指定选项值字段的长度（以字节为单位），当选项值为保持时间（选项类型=1）时，选项长度为2。

•　选项值（Option Vlaue）：一个可变长字段，携带由选项类型指定的各种类型的值。保持时间（选项类型=1，选项长度=2）是路由器在宣称邻居路由器无效之前等待从 PIM邻居接收到Hello消息的时间，保持时间是Hello间隔的3.5倍。

从Hello消息的格式可以看出，单个Hello消息中可以携带多种选项TLV（类型/长度/值）。

3．PIMv2 Register（注册）消息格式

Register消息仅用于PIM-SM，其消息格式如图5-64所示。Register消息以单播方式从多播源的DR传送到RP，并携带来自多播源的初始多播包，也就是说，当自多播源的 DR至RP的SPT尚未建立的时候，由Register消息负责以隧道方式将多播流量从多播源传送到RP。

图5-64　PIMv2 Register（注册）消息格式

PIMv2 Register消息中的字段定义如下。

•　校验和（Checksum）：计算Register消息中的校验和字段时仅计算消息头，不包括数据部分。

•　B：边界（Border）比特。如果发信路由器是直连多播源的DR，则该bit被设置为0；如果多播源是PMBR（PIM Multicast Border Router，PIM多播边界路由器），则该bit被设置为1。有关PMBR及其他域间多播问题将在第7章进行讨论。

•　N：Null-Register（空注册）比特，DR在其本地注册抑制定时器到期之前探测RP，则将该bit设置为1。

•　多播数据包（Multicast Data Packet）：单个来自多播源的数据包，该多播包在Register消息中以隧道方式被传送给RP。

4．PIMv2 Register Stop（注册终止）消息格式

Register Stop消息由RP发送给发起Register消息的DR，其消息格式如图5-65所示。该消息用于以下两种情形。

•　RP开始通过SPT接收多播源发出的多播包，不再需要将这些多播包封装在Register消息中进行接收；

•　RP没有需要转发多播包的组成员（直连或通过SPT/RPT连接的组成员）。

PIMv2 Register Stop消息的字段定义如下。

•　已被编码的组地址（Encoded Group Address）：多播组IP地址，接收方应该停止向该地址发送Register消息。

•　已被编码的单播源地址（Encoded Unicast Source Address）：多播源的IP地址，通过将字段的地址设置为全0，就可以为（*，G）表项指定所有多播源。

图5-65　PIMv2 Register Stop（注册终止）消息格式

5．PIMv2 Join/Prune（加入/剪除）消息格式

Join/Prune消息沿上游方向发送给RP或多播源，用于加入和剪除RPT或SPT，其消息格式如图5-66所示。Join/Prune消息由多个多播组列表组成，对每个多播地址来说，有一个或多个源地址，这些列表合起来就可以指定将要加入或剪除的（S，G）和（*，G）表项。

图5-66　PIMv2 Join/Prune（加入/剪除）消息格式

PIMv2 Join/Prune消息中的字段定义如下。

•　被编码的单播上游邻居地址（Encoded Unicast Upstream Neighbor Address）：RPF的地址或该消息所要发往的上游邻居的地址。

•　多播组数量（Number of Groups）：指定该消息中包含的多播组数量。

•　已被编码的多播组地址（Encoded Multicast Group Address）：指定某多播组的IP地址。

•　将要加入的多播源数量（Number of Joined Sources）：指定该多播组地址下所列出的已被编码的将要加入的多播源地址（Encoded Joined Source Addresses）数量。

•　被剪除的多播源的数量（Number of Pruned Sources）：指定该多播组地址下所列出的已被编码的将要被剪除的多播源地址（Encoded Pruned Source Address）数量。

•　已被编码的将要加入的多播源地址（Encoded Joined Source Address）：指定（S，G）中的源地址或（*，G）中的通配符，此外，也可以在该字段中指定（*，*，RP）（详见第7章）中的两个通配符。除了源地址之外，该字段中还包含了以下3个标记。

— S是稀疏（Sparse）bit，对PIM-SM来说该bit为1，用来与版本1保持兼容性。

— W是WC（WildCard，通配符）bit，如果W bit为1，则已被编码的将要加入的多播源地址字段为（*，G）和（*，*，RP）表项中的通配符；如果W bit为0，则已被编码的将要加入的多播源地址字段为（S，G）表项中的源地址。向RP发送加入消息时，必须将W bit设置为1。

— R是RPT bit，如果R bit为1，则表示向RP发送加入消息，如果R bit为0，则表示向多播源发送加入消息。

•　已被编码的将要被剪除的多播源地址（Encoded Pruned Source Address）：指定将要被剪除的多播源的地址。编码方式与已被编码的将要加入的多播源地址字段一致，而且也使用S、W、R bit。

6．PIMv2 Bootstrap（引导）消息格式

Bootstrap消息由BSR（Bootstrap Router，引导路由器）每隔60秒发送一次，并泛洪到整个PIM-SM域，以确保所有的路由器都能为同样的多播组确定相同的RP。Bootstrap消息的格式如图5-67所示，消息中包含了一个或多个多播组地址列表，对其中的每个多播组地址来说，都有一个C-RP及相应的优先级。该地址列表实际上就是多播组的RP-Set，接收路由器会使用一种通用算法从C-RP列表中确定该多播组的RP，该算法可以确保PIMv域中的所有路由器都能得出相同的RP地址。此外，Bootstrap消息还被用来选举BSR（如“Bootstrap协议”一节所述）。

PIMv2 Bootstrap消息中的字段定义如下。

•　片段标签（Fragment Tag）：当Bootstrap消息长度超出了最大包尺寸而必须分割成多个片段时就需要使用本字段。片段标签是一个随机生成的数值，被分配给同一条消息的所有片段，也就是说，每条Bootstrap消息的所有片段的该字段值都一样。

•　哈希掩码长度（Hash Mask Length）：描述哈希算法中使用的掩码，利用命令ip pim bsr-candidate可以设置掩码的长度。

•　BSR优先级（BSR Priority）：取值范围为0〜255，用来指定发信C-BSR的优先级，优先级最高的C-BSR将成为BSR，利用命令ip pim bsr-candidate可以设置该优先级。

•　已被编码的单播BSR地址（Encoded Unicast BSR Address）：该多播域的BSR的IP地址。

图5-67　PIMv2 Bootstrap（引导）消息格式

•　已被编码的多播组地址（Encoded Group Address）：多播组的IP地址。

•　RP数量（RP Count）：用来指定某特定多播组的C-RP数量，即RP-Set的大小。考虑到Bootstrap消息可能会被分段，如果某个片段出现丢失，那么整个PIM域中确定的RP就可能会出现不一致，因而描述RP-Set的大小非常重要。如果所接收到的 RP-Set中的RP数量与本字段中的RP数量不一致，则丢弃整个RP-Set。

•　片段RP数量（Fragment RP Count）：指定该多播组片段中包含的C-RP数量。

•　已被编码的单播RP地址（Encoded Unicast RP Address）：C-RP的IP地址。

•　RP保持时间（RP Holdtime）：在从RP-Set中删除C-RP之前，BSR应该等待该字段所指定的时间来接收Candidate-RP-Advertisement（候选RP宣告）消息。

•　RP优先级（RP Priority）：取值范围是0～255，用于RP选举算法，“最高”优先级为0。

7．PIMv2 Assert（声明）消息格式

PIMv2 Assert消息用于为多路接入网络选举一台指派转发路由器，其消息格式如图5-68所示。PIM路由器在某接口上接收到一个多播包（该接口为该多播包所属多播组的出站接口）之后，会认定该数据链路层上连接了另一台正在转发该多播组流量的路由器。因而该PIM路由器会发送一条Assert消息，以便让共享该多路接入网络的其他路由器能确定由谁负责转发该多播组的流量。

图5-68　PIMv2 Assert（声明）消息格式

PIMv2 Assert消息中的字段定义如下。

•　已被编码的多播组地址（Encoded Group Address）：触发Assert消息的数据包的多播 IP目的地址。

•　已被编码的单播源地址（Encoded Unicast Source Address）：触发Assert消息的多播包的IP源地址。

•　度量优先值（Metric Preference）：分配给单播路由协议（提供去往多播源的路由）的优先值，该优先值的使用方式与管理性距离相似，为来自不同路由协议的路由进行比较提供统一的尺度。

•　度量值（Metric）：与发信路由器单播路由表中去往多播源的路由相关联的度量值。

8．PIMv2 Graft（嫁接）消息格式

PIM-DM路由器通过向其上游邻居发送PIMv2 Graft消息，来请求重新加入先前被剪除的多播树，其消息格式与图5-66所示的Join/Prune消息格式类似，区别在于类型=6。

9．PIMv2 Graft-ACK（嫁接确认）消息格式

PIM-DM路由器向其下游邻居发送Graft-Ack消息以响应Graft消息，其消息格式与图 5-66所示的Join/Prune消息格式类似，区别在于类型=7。

10．PIMv2 Candidate-RP-Advertisement（候选RP宣告）消息格式

C-RP周期性地向BSR以单播方式发送Candidate-RP-Advertisement消息，BSR利用该消息中的信息构建其RP-Set，而RP-Set又通过Bootstrap消息宣告给域中的所有PIM-SM路由器。图5-69显示了Candidate-RP-Advertisement消息的格式情况。

PIMv2 Candidate-RP-Advertisement消息中的字段定义如下。

•　前缀数量（Prefix Count）：指定该消息中包含的多播组地址数量。如果发信路由器是该多播域中全部多播组的C-RP，那么该字段为0。

图5-69　PIMv2 Candidate-RP-Advertisement（候选RP宣告）消息格式

•　优先级（Priority）：取值范围为0～255，用于指定发信C-RP的优先级。该优先级用于选举RP的算法之中，实际的优先级与优先级数值大小正好相反，即0代表最高优先级，255代表最低优先级。

•　保持时间（Holdtime）：指定该消息的有效时间。

•　已被编码的单播RP地址（Encoded Unicast RP Address）：C-RP地址。该地址是本路由器某个接口的IP地址，通常情况下使用的是环回（loopback）接口地址。

•　已被编码的多播组地址（Encoded Group Address）：指定一个或多个发信路由器是 C-RP的多播组地址。

5.9　附 注

1Steve E. Deering, “RFC 988：针对IP多播的主机扩展”，1986年7月，本RFC已经被废弃，目前最新的版本是RFC 1112。

2Tomas Pusateri，“RFC 1469：令牌环局域网上的IP多播”（仍在发展中），本文档虽然建议了三种支持多播的方法，但第三种方法未得到使用。

3Steve Deering，“RFC 1112：针对IP多播的主机扩展”，1989年8月，在RFC 988中描述了目前已被废弃的“IGMPv0”。

4William C. Fenner，“RFC 2236: Internet组管理协议版本2”（仍在发展中）。

5Brad Cain, Steve Deering, Ajit Thyagarajan, “Internet组管理协议版本3”，<draft-ietf-idmr- igmp-v3-01.txt>,1999年2月。

6Dave Katz，“RFC 2113：IP路由器告警选项”（仍在发展中）。

7David Meyer, “RFC 2365：管理性IP多播定界”（仍在发展中）。

8D. Waitzman, C. Partridga,和 S. Deering, “RFC 1075：距离实例多播路由协议”，（仍在发展中）。

9Thomas Pusateri, “距离实例多播路由协议”，draft-ietf-idmr-dvmrp-v3-09, 1999年9月。

10John Moy, “RFC 1584：OSPF的多播扩展”（仍在发展中）。

11Tony Ballardie, “RFC 2189：核心树（CBT版本2）多播路由”（仍在发展中）。

12Stephen Deering et al., “协议无关多播版本2密集模式规范” draft-ietf-pim-v2-dm-03.txt, 1999年3月。

13Deborah Estrin et al., “RFC 2362：协议无关多播—稀疏模式（PIM-SM）：协议规范”（仍在发展中）。

5.10　展 望

本书第一卷和第二卷已经讨论了所有的路由协议，对大多数读者来说，多播路由协议可能是最陌生的。虽然本章较为详细地描述了5种多播路由协议以及相关的支撑协议，但仍然无法穷举，还有许多IP多播知识都不在本书的写作范围之内，如果大家希望增加知识面，请参考“推荐读物”。

迄今为止，已经介绍了5种多播路由协议的工作方式，第6章将以Cisco为例，说明如何配置IP多播以及如何检测和排除IP多播故障。

可以将本章所讨论的多播路由协议理解为多播IGP，因为这些协议都运行于单一多播域中。第7章将进一步探讨AS间多播路由协议的相关问题。

5.11　推荐读物

Beau Williamson所著的《IP多播网络设计开发》，由电子工业出版社于2000年出版。

5.12　命令汇总

表5-13汇总了本章用到的所有命令。

5.13　复习题

附录D中提供了以下复习题的答案。

（1）请说明为什么重复性单播无法代替大规模网络中的多播？

（2）IP多播保留的地址范围是什么？

（3）单个D类地址前缀能够创建多少个子网？

（4）对目的地址在224.0.0.1～224.0.0.255范围内的数据包来说，路由器会采取哪些与其他多播地址不一样的处理方式？

（5）请写出与下列IP地址相关的MAC地址。

（a）239.187.3.201

（b）224.18.50.1

（c）224.0.1.87

（6）MAC地址0100.5E06.2D54代表的多播地址是什么？

（7）为什么令牌环介质不适宜分发多播包？

（8）什么是加入等待时间？

（9）什么是离开等待时间？

（10）什么是多播DR（或查询路由器）？

（11）由什么设备发送IGMP Query（查询）消息？

（12）由什么设备发送IGMP Membership Report（成员关系报告）消息？

（13）IGMP Membership Report（成员关系报告）消息的作用是什么？

（14）IGMP General Query（常规查询）与Group-Specific Query（特定组查询）消息之间有何功能性区别？

（15）IGMPv2与IGMPv1是否兼容？

（16）IGMP的IP协议号是什么？

（17）Cisco CGMP协议的作用是什么？

（18）与CGMP相比，IP Snooping的优点是什么？可能的缺点是什么？

（19）由什么设备发送CGMP消息：路由器、以太网交换机或两者？

（20）什么是反向路径转发机制？

（21）多少台主机可以构成一个密集拓扑结构？多少台主机可以构成一个稀疏拓扑结构？

（22）与隐式加入相比，显示加入的主要优点是什么？

（23）有源多播树与共享多播树之间的主要结构性差异是什么？

（24）什么是多播定界？

（25）IP多播定界的两种方法是什么？

（26）从多播路由器的观点来看，上游和下游的含义是什么？

（27）什么是RPF检查？

（28）什么是剪枝？什么是嫁接？

（29）什么是剪除生存期？剪除生存期到期时会发生什么？

（30）什么是路由相关性？DVMRP如何通告路由相关性？

（31）DVMRP是密集模式协议还是稀疏模式协议？

（32）MOSPF是密集模式协议还是稀疏模式协议？

（33）MOSPF专用LSA的名称及类型是什么？

（34）MOSPF路由器是否能与不支持MOSPF的OSPF路由器建立邻接关系？

（35）请定义如下MOSPF路由器类型。

（a）域间多播转发路由器

（b）AS间多播转发路由器

（c）万能多播接收路由器

（36）CBT是密集模式协议还是稀疏模式协议？

（37）什么是CBT父路由器？什么是CBT子路由器？

（38）请描述两种CBT DR从多播源向核心路由器分发多播包的方法以及各自的应用场合。

（39）什么是PIM剪除覆盖？

（40）什么是PIM转发路由器？如何选择PIM转发路由器？

（41）PIM选择DR的规则是什么？

（42）什么是PIM SPT？什么是PIM RPT？

（43）Cisco路由器自动发现PIM-SM RP的两种可用机制是什么？

（44）对问题（43）中的两种发现机制来说，哪种机制用于多厂商路由器拓扑结构？

（45）什么是C-RP？

（46）什么是BSR？

（47）什么是RP映射代理？

（48）（S，G）多播路由表项与（*.G）多播路由表项之间有何区别？

（49）与自RP至多播源的PIM-SM单向多播树相比，多播源与核心路由器之间的双向 CBT树有何重要缺陷？

（50）什么是PIM-SM源注册？

（51）Cisco路由器何时从PIM-SM RPT切换到SPT？

本章将主要讨论以下主题。

•　IP多播路由的配置：本节将介绍如何利用Cisco IOS软件进行基本的PIM-DM和 PIM-SM配置，并通过一些案例研究来进一步讲解这些协议的配置过程。

•　IP多播路由的故障检测与排除：本节将介绍Cisco IOS软件提供的各种检测及排除IP多播故障的方法和工具，并给出相应的故障检测与排除技巧。

第6章
IP 多播路由的配置
及故障检测与排除

第5章中已经介绍了各种IP多播路由协议的情况，以及Cisco及大多数厂商选择的多播路由协议都是PIM（密集模式或稀疏模式）。既然已经明白了PIM的操作方式，那么本章将详细探讨如何利用Cisco IOS软件来配置 PIM-DM和PIM-SM，并进行故障检测与排除。

6.1　IP 多播路由的配置

在配置某特定IP多播路由协议之前，必须将路由器设置为通用、协议中立的多播路由选择方式。

注意：　虽然术语“协议无关（protocol-independent）”比“协议中立（protocol-neutral）更好，但是在PIM中可能会引起混淆。

例6-1所示配置中包含了一些可能要用到的命令，这些命令中只有ip multicast-routing是必需的。就像由默认命令（因而被隐藏了）ip routing启用单播路由一样，该命令的功能也是启用IP多播路由功能。

例6-1中接口E1的配置中包含了命令ip cgmp,该命令会向路由器所连接的Catalyst交换机发送CGMP（Cisco Group Management Protocol, Cisco组管理协议）消息。另一个选项是ip cgmp proxy,当子网中存在其他不支持CGMP的路由器时就可以使用该命令，该命令的作用是让路由器在其 CGMP消息中宣告这些非CGMP路由器。如果要将某台Cisco路由器配置为CGMP proxy（代理服务器），就必须确保将该路由器选举为IGMP查询路由器。

例6-1：命令ip multicast-routing是启用多播路由的必需命令，本基本配置中的其他命令可能会用于某些特殊实现。

有意思的是，本例中没有使用命令来启用IGMP。这是因为在路由器上启用IP多播路由之后，就自动在LAN接口上启用了IGMPv2，本例使用的惟一一个IGMP命令就是在接口 E0上应用的ip igmp version，将默认版本值更改为IGMPvl。表6-1列出了所有更改某接口默认值的IGMP命令，其他IGMP命令则在本章后续内容中进行介绍。

例6-1中的另一条有意义的命令是在接口SO上应用的no ip mroute-cache，该命令的作用是禁止IP多播包的快速交换，与no ip route-cache禁止IP单播包进行快速交换一样。禁用多播包快速交换的理由与禁用单播包快速交换一样，如希望实施按数据包在多条并行路径上进行负载分担，而不是按目的地进行负载分担。

接口TO0的配置中包含了命令ip multicast use-functional，而TO1的配置中则没有使用该命令，因而TO0将多播IP包映射到令牌环功能地址0xC000. 0004. 0000，而T01则将多播 IP地址映射到广播地址0xFFFF.FFFF.FFFF。

6.1.1　案例研究：配置 PIM-DM

在Cisco路由器上启用IP多播路由之后，通过命令ip pim dense-mode即可在路由器的所有接口上启用PIM-DM。图6-1给出了一个简单的PIM-DM拓扑结构，例6-2则给出了路由器Porkpie的配置文件，其他路由器的配置与Porkpie类似。

图6-1　用来示范PIM-DM基本功能的拓扑结构

例6-2：利用命令ip pim dense-mode在接口上启用PIM-DM.

通过分析例6-2可以看出，在配置PIM-DM时要着重考虑两个因素。第一个也是最明显的考虑因素就是必须运行单播路由协议（即本例中的OSPF），否则PIM将无法确定RPF（Reverse Path Forwarding，反向路径转发）接口。通过对比例6-2中的配置文件与图6-1中的拓扑结构，可以看出第二个考虑因素，即配置PIM的时候，必须在每个接口上都启用该协议，否则可能会出现RPF故障。

例6-3显示了多播源10.1.1.88开始传送多播流量，组成员10.1.2.113已经加入多播组之后，路由器Porkpie关于多播组228.13.20.216的多播路由表项。为了清楚起见，本例中仅显示了第5章PIM-DM部分的（S,G）多播路由表项，实际上，除了（S,G）之外还会创建（*,G）表项，不过（*,G）表项不是PIM-DM规范的一部分，也不用于转发多播包，Cisco IOS软件创建该表项的目的是作为（S,G）数据结构的“父类”。所有连接PIM邻居的接口以及所有直连了组成员的接口都被加入到（*,G）表项的出站接口列表中，如果仅运行了PIM-DM，那么该表项的入站接口列表将始终为空。（S,G）表项中的入站和出站接口均取自于该列表。

注意：　在开始写作本章内容的时候，Cisco已经发布了IOS Software Release 12. 1，并在示范路由器上安装了该软件版本，因而与前面的章节相比，本章中的某些命令在字段格式上存在一些差异，如show ip mroute和show ip route.

例6-3：Porkpie关于多播组228.13.20.216的多播路由表项。

如例6-3所示，E0、S1.609和S1.605都在（*,G）的出站接口列表中，之后S1. 605进入（S, G）表项作为RPF接口，多播包从接口E0被转发出去。虽然S1. 609也位于出站接口列表中，但被剪除了。

如第5章所述，PIM（以及其他使用RPF检查的多播路由协议）可以仅有一个入站接口。例6-4显示了Porkpie的单播路由表，去往多播源子网10.1.1.0/24存在两条等价路径，而PIM会选择IP地址较大的去往邻居的接口作为RPF接口，对例6-4来说，就是接口S1. 605上的地址10.2.4.2。回过头来看一下例6-3，可以看到接口S1.605的确位于入站接口列表中。

例6- 4: Porkpie的单播路由表。

图6-2在互联网络中增加了其他路由器。该路由器Bowler连接在以太网交换机上，与路由器Porkpie共享同一条多路接入链路，因而第5章讨论过的IGMP查询路由器、PIM指派路由器以及PIM转发路由器都将出现。

•　IP地址最小的路由器将成为IGMPv2查询路由器。

•　IP地址最大的路由器将成为PIM指派路由器，仅当子网中运行IGMPvl时才能显出 DR的重要性。

•　拥有去往多播源、管理性距离最小的路由的路由器将成为PIM转发路由器。如果管理性距离相等；那么拥有去往多播源、度量值最小的路由的路由器将成为PIM转发路由器，如果管理性距离和度量值均相等，那么IP地址最大的路由器将成为PIM转发路由器。

图6-2　在图6-1所示的互联网络中增加了路由器Bowler,Bowler、Porkpie以及组成员都通过Catalyst交换机连接在同一个多路接入网络中

例6-5显示了IGMPv2查询路由器和PIM指派路由器规则的应用情况。Porkpie（10.1.2.1）在子网中的IP地址较小，因而成为IGMPv2查询路由器，而 Bowler（10.2.1.25）的IP地址较大，因而成为PIM指派路由器。由于Porkpie和Bowler运行的都是IGMPv2，因而此处的DR没什么意义。

例6-5：Porkpie（10.1.2.1）是IGMPv2查询路由器，Bowler（10.2.1.25）是PIM指派路由器。

例6-6显示了Porkpie和Bowler中去往多播源子网10. 1. 1. 0/24的单播路由。已知图6-2中的互联网络仅运行了OSPF，因而这两条路由的管理性距离均为110，而且可以看出这两条路由的OSPF代价（cost）均为138，因而子网10. 1. 1. 0/24上关于（10. 1. 1. 88, 228. 13. 20. 216）的PIM转发路由器将是IP地址最大的路由器Bowler，例6-7的显示结果证实了该结论。与例6-3中Porkpie的（S,G）表项相比，可以看出接口E0已经被剪除，Bowler的接口E0处于转发模式，表示其正负责将多播流量转发到本子网上。

例6-6：Porkpie和Bowler中去往多播源子网10.1.1.0/24的单播路由拥有相同的管理性距离和度量值，因而IP地址最大的路由器将成为子网10.1.1.0/24的PIM转发路由器。

例6-7：对比（10.1.1.88,228.13.20.216）的多播路由可以看出，Bowler目前是子网 10.1.1.0/24上该多播组的转发路由器。

有意思的是，Porkpie正在该子网上查询组成员，而Bowler正在转发多播组228. 13. 20. 216的多播包，回顾第5章有关IGMP的操作规则可以知道，这种情形是毫无冲突的。Porkpie向组地址发出的组成员查询操作会让子网中的组成员回应IGMP Membership Report（成员关系报告）消息，而Bowler接收到Membership Report消息之后就开始转发多播流量。如果组成员希望离开该多播组，则向All Multicast Routers（所有多播路由器）地址224.0.0.2发出IGMP Leave（离开）消息，该 Bowler也会接收到消息，如例6-8所示。

例6-8：虽然Porkpie（10.1.2.1）是IGMP查询路由器，但Bowler仍然能够从其所连接的组成员接收IGMP Leave（离开）消息。作为该多播组的转发路由器，Bowler从其出站接口列表中删除了该多播组的接口。

重新回到例6-5，命令show ip igmp interface显示Bowler的接口EO正在使用默认的60秒IGMP查询间隔和120秒IGMP查询路由器超时间隔，而且Porkpie也使用着相同的默认时间。例6-9中带有时间戳的调试消息显示这些定时器正处于工作状态，前3条消息显示Porkpie正每隔60秒发送一次IGMP查询消息，但之后发生了某些事情而导致停止查询操作。第4~5两条消息显示120秒之后Bowler接管了查询路由器的角色，并立即发送了自己的查询消息，随后就以60秒为间隔周期性地发送查询消息。最后2条消息显示Porkpie重新称为查询路由器并再次发送查询消息，这是因为Porkpie的IP地址较小，因而Bowler知道Porkpie是查询路由器，从而不再发送查询消息。

例6-9：利用debug命令来显示IGMP查询路由器失效并重新生效所发生的事件。

第5章中曾经提到，PIM默认每隔50秒向其邻居发送一条Hello消息，而保持时间为Hello间隔的3.5倍，如果在保持时间内没有收到来自其邻居的Hello消息，那么将认定该邻居失效。在下面的例6-10中，Bowler和Porkpie最初均处于在线状态，且Bowler正将多播组228.13.30.216的多播包转发到以太网上，例6-10显示了Bowler失效后所发生的事件情况。

例6-10：由于在预设的保持时间内Porkpie都没有收到来自Bowler的Hello消息，因而将接管为多播组228.13.30.216的PIM转发路由器。

由于Porkpie在保持时间内都没有收到来自Bowler的Hello消息，因而知道必须承担PIM转发路由器的职责，其接管了DR的角色并向其邻居发送PIM Graft（嫁接）消息。对比例6-11中Porkpie关于（10.1.1.88,228.13.20.216）的路由表项与例6-7中最上面的内容可以知道，Porkpie现在正将多播包转发到以太网上，但是在成为转发路由器之前Porkpie已剪除了该接口。此外需要注意的是，例6-11中该多播路由表项中已经没有了例6-7中该表项的剪除标记。

例6-11：Bowler失效后，Porkpie开始将多播流量转发到以太网上。

6.1.2　配置 PIM-SM

在学习了如何在接口上启用PI-DM的配置操作之后，读者肯定希望了解如何在接口上启用 PIM-SM，这非常简单，使用命令ip pim sparse-mode即可。有关PIM-SM的多数配置都没有什么新意，也不需要完全独立的示例，惟一的要求（也是比较有意思的配置工作）就是RP（Rendezvous Point，聚合点）的标识。第5章是曾经提到，既可以静态配置RP，也可以利用Cisco的Auto-AP协议或开放的引导协议自动发现RP，以下案例研究将逐一示范这3种配置方法。

1．案例研究：静态配置RP

图6-3所示的互联网络与本章前面的拓扑结构一样，只是现在的路由器运行的都是 PIM-SM，路由器Stetson被选为RP，网络中的其他路由器都被静态配置了该信息。Stetson的RP地址为10.224.1.1，只要通过单播路由协议宣告该地址，该地址就可以存在于所有接口上，因而其他路由器都知道如何到达该地址。不过在实际应用中，应该使用环回接口，这样做的次要原因是可以更容易地管理RP地址，主要原因是不用将RP地址链接到任何可能会失效的物理接口，这也是建议IBGP对等端点使用环回接口的原因。

例6-12显示了Bowler的配置文件，原先配置为密集模式的接口都已被配置为稀疏模式。

例6-12：图6-3中Bowler的配置。

图6-3　互连网络中运行的是PIM-SM，RP位于10.224.1.1

例6-12中的另一个需要注意的是命令ip pim rp-address 10.224.1.1，其作用是告诉路由器如何发现RP。当静态配置RP之后，所有连接了多播组或组成员的路由器都得有一个这样的配置语句，以便让它们知道RP在什么地方。需要注意的是，Stetson的环回接口本身并不需要运行PIM（如例 6-13所示），除了提供RP地址之外，无需环回接口提供任何PIM功能，该RP地址将通过OSPF被宣告给本互联网络。虽然Stetson没有连接多播源或组成员，但其配置文件中也出现了语句ip pim rp-address 10.224.1.1，这样做的原因是让该路由器知道其就是RP。在实际应用中，为互联网络中的所有路由器都静态配置RP地址是非常明智的，这样做的好处是不必担心是否在不需要的地方配置了该语句，从而可以避免在需要配置该语句的地方遗漏了该语句。

例6-13：图6-3中Stetson和RP的配置。

前面的PIM-DM案例研究中对比了Porkpie和Bowler中关于多播组228.13.20.216的多播路由表项。这些路由表项之所以重要，就在于这些路由器与组成员共享同一个以太网子网，因而产生了IGMP查询和PIM转发等问题。例6-14又重新对比了Porkpie和Bowler关于多播组228.13.20.216的多播路由表项，但此时的路由表项看起来比例6-7中密集模式表项要更模糊一些。例如，Porkpie的（*,G）表项显示E0位于出站接口列表并处于转发状态，而其（S, G）表项的出站接口列表为空。但Bowler的接口E0位于（*,G）表项的入站接口列表中，且该表项的出站接口列表为空，此外，E0位于（S,G）表项的出站接口列表中且处于转发状态。那么，究竟是哪台路由器在转发多播包呢？

例6-14：对比Porkpie和Bowler中关于多播组228.13.20.216的多播路由表项。

只要仔细研究第5章中的PIM-SM操作过程即可明白哪台路由器正在转发多播包。首先知道Bowler是DR（因为其IP地址在子网10.1.2.0/24中较大），也可以通过命令show ip pim interface来验证DR（如例6-15所示）。

例6-15：子网10.1.2.0/24上的PIM指派路由器是Bowler（10.1.2.25）。

当主机首次请求加入某多播组时，DR将加入共享RPT（RP Tree, RP树）。查看例6-16中Bowler的单播路由表可以知道，从Bowler到RP需要经过Porkpie（通过子网10.1.2.0/24），这也是Porkpie的接口E0位于（*,G）表项的出站接口列表中的原因。该表项表示RPT将Bowler链接到Stetson, Bowler的（*,G）表项的出站接口列表为空且带有一个剪除标记（因为其是 RPT树枝的端点）。

例6-16：从Bowler到RP的最短路由是通过其连接的以太网到Porkpie。

其次，接收到第一个多播包之后，在默认情况下连接了组成员的PIM-SM路由器将试图切换到去往多播源的SPT（Shortest Path Tree，最短路径树），而不论该路径是否经由RP。Bowler的单播路由表显示出去往多播源子网10.1.2.0/24的最短路由是经由Fedora（如例6-17所示）。再回过头来看一下例6-14，Bowler的（S,G）表项显示Fedora（位于10.2.5.2）是上游邻居或RPF邻居，E0位于该表项的出站接口列表中且处于转发状态（因为多播包理所当然地要被转发到其组成员）。由于Porkpie没有为该多播组转发多播包，因而其（S,G）表项的出站接口列表为空且带有被剪除标记。

例6-17：Bowler去往多播源子网10.1.2.0/24的最短路由是经由Fedora，出接口为S1.705。

同样，可以利用调试命令来查看多播包的转发过程。例6-18显示了Bowler正在接口 S1.705上经Fedora从多播源10.1.1.88接收多播组228.13.20.216的多播包，并将这些多播包从接口E0向外转发给其所连接的组成员。

例6-18：利用命令debug来捕捉IP多播包（mpacket），可以看到Bowler正在接口S1.705上接收（10.1.1.88, 228.13.20.216）的多播包，并通过接口EO向外转发。

在路由器Porkpie上使用相同的命令也能看到有趣的结果（如例6-19所示），从输出的调试消息中可以看出路由器Porkpie并没有从RP或Fedora接收多播组228.13.20.216的多播包，而是正在接收Bowler转发到以太网子网10.1.2.0/24上的多播包。例6-14中Porkpie的多播路由表项显示该多播包的RPF接口为S1.609，由于这些多播包是在接口E0上被接收到的，因而RPF检查失败，从而丢弃这些多播包。

例6-19：Porkpie没有转发多播组228.13.20.216的任何多播包。

如前所述，本例所基于的一个事实是Cisco路由器在接收到第一个多播包后将切换到该多播组的SPT。第5章中曾经说过，可以利用命令ip pim spt-threshold来更改这种默认操作，其中的阈值以kbit/s为单位。这样一来，只有当该多播组的多播包的到达速率超出该阈值时，路由器才切换到SPT。此外也可以使用关键字infinity，这样就可以让路由器永远也不切换到 SPT。通过观察在图6-3的Bowler的配置文件中增加命令ip pim spt-threshold infinity之后的情况很有启发意义。例6-20显示了重新配置Bowler之后的Porkpie和Bowler的多播路由表项情况，Bowler的RPT以E0为出接口，穿过子网10.1.2.0/24并经由Porkpie，因而Porkpie现在必须转发来自RP的多播包，但Bowler的接口E0也是该多播组的RPF接口，而PIM路由器又无法通过多播组的RPF接口向外转发该多播组的多播包，这只是水平分割规则（不能通过数据包的接收端口向外转发该数据包）的多播版本。因而Bowler的（*,G）表项被加入了被剪除标记，而Porkpie则开始向组成员转发该多播组的多播包。有意思的是，虽然因Bowler必须使用RPT而让Porkpie承担了多播包转发职责，但Porkpie本身却没有这方面的约束，因而将切换到SPT，从而经由Fedora而不是RP。

例6-20：将Bowler被配置为永远不切换到SPT之后，转发多播组228.13.20.216流量的职责就传递给了Porkpie。

有时可能需要为不同的RP分配不同的多播组，这通常发生于多播域中的多播组数量增加较多的场合，从减少对路由器的内存和CPU需求的角度出发，应划分RP的职责。图6-4所示互联网络的拓扑结构与前面相同，只是现在的Fedora也被指定为RP（地址为10.244.1.2）。结合访问列表，就可以配置多个RP并指定哪些多播组使用哪个RP。

图6-4　Stetson和Fedora都是RP，通过访问列表和静态配置RP地址，可以告诉多播域中的所有路由器哪些多播组应该使用哪个RP

例如，考虑例6-21中的配置文件。

例6-21：Bowler的RP过滤配置。

可以看出，access-list5指定多播组允许使用RP10.224.1.2（Fedora）,而access-list 10则指定多播组允许使用RP 10.224.1.1（Stetson）,多播组地址与上述两个访问列表都不匹配的多播组则没有被指定RP，因而无法加入任一个共享树。将例6-21所示配置增加到Bowler的配置文件中之后，例6-22显示了配置结果，可以看出，所列出的多播组（都是该路由器上的活动多播组）都按照access-list 5和access-list 10被映射到某个RP上。

例6-22：命令show ip pim rp可以显示路由器上的活动多播组以及被映射到的RP。

2．案例研究：配置Auto-RP

对一个稳定的PIM域来说，静态配置RP是非常直观的，当在该域中增加新路由器时，都要配置一个或多个RP的位置。但是对以下两种情形来说，静态配置RP将会带来一些问题。

•　需要更改RP地址（如更改现有RP的地址或安装了一个新RP）时，网络管理员必须修改所有PIM路由器上的静态RP配置，从而会对大型多播域造成长时间的网络中断。

•　RP失效时，静态配置的PIM域无法轻易地切换到备用RP上。

因而除了最小型PIM域之外，为了简化管理并提高冗余性，都部署了两种自动RP发现机制中的一种：Auto-RP或Bootstrap协议。本案例研究将说明Auto-RP的配置操作，而下一小节将介绍Bootstrap协议的配置操作。

如第5章所述，Auto-RP是在Bootstrap协议成为PIMv2组成部分之前，由Cisco开发的专有协议，Auto-RP必须用于Cisco IOS Software Release 11.3之前的版本（该版本第一次支持PIMv2）。

配置基本的Auto-RP需要以下两个步骤。

•　第1步：必须配置所有C-RP（Candidate RP，候选RP）。

•　第2步：必须配置所有映射代理。

利用命令ip pim send-rp-announce即可配置C-RP。在使用该命令时需要指定接口（路由器通过该接口取得其RP地址）和TTL值（该值将被加入到宣告消息中）, TTL提供了定界功能，可以确保多播包不会被转发到多播源的边界之外。当路由器被配置为C-RP之后，该路由器将会每隔60秒向保留地址224.0.1.39发送一条RP-Announce（RP通告）消息。

映射代理负责侦听来自C-RP的RP-Announce消息并选出RP，之后通过RP-Discovery（RP发现）消息（每隔60秒将该消息发送到保留地址224.0.1.40）将RP宣告到PIM域中。

图6-5显示了一个示例拓扑结构，其中的路由器Stetson和Fedora都是C-RP，地址分别为10.224.1.1和10.224.1.2，Porkpie是映射代理，其标识地址为10.224.1.3。

图6-5　Stetson和Fedora都是C-RP，Porkpie是映射代理

例6-23显示了Fedora配置中的相关内容。

例6-23：将Fedora配置为C-RP。

Stetson的配置与此类似，RP地址取自于接口LO，关键字scope则用于设置RP-Announce消息的TTL值。

例6-24显示了将Porkpie配置为映射代理的配置情况。

例6-24：将Porkpie配置为映射代理。

上例中的接口LO被用于导出映射代理地址，且TTL被设置为5。需要注意的是，在例 6-24的配置中，必须在环回接口上配置PIM-SM。对映射代理来说必须如此，如果未能首先在环回接口上启用PIM-SM，那么将会得到与例6-25相似的错误消息。

例6-25：未能在映射代理的环回接口上启用PIM-SM而产生的错误消息。

相应的配置语句将与如下语句相似：
ip pim send-rp-discovery scope 5

由于指定的接口未被接受，因而映射代理无法工作。与映射代理不同，PIM无需在C-RP的环回接口上进行配置，当然，无论是映射代理还是C-RP，都必须在所有连接了PIM邻居的物理接口上配置PIM-SM。

当初次为某Cisco路由器配置PIM-SM之后，该路由器将侦听地址224.0.1.40。如果必须变更C-RP或映射代理，那么将由被更改设备自动宣告这些变更，整个域中的路由器都将知晓该变更情况。不过，最重要的功能特性是可以为任何或全部多播组配置多个RP，映射代理将基于RP地址最大的规则为多播组选择RP，如果该RP出现故障，那么映射代理将选择地址次大的RP并宣告该变更情况。

例6-26给出了一个RP发生故障倒换时的例子，使用了命令debug ip pim auto-rp来显示 Auto-AP的全部操作情况。可以看到Porkpie（图6-5中的映射代理）正在接收来自Stetson（10.224.1.1）和Fedora（10.224.1.2）的RP-Announce消息，由于Fedora的IP地址较大，因而被宣告为域中所有多播组（224.0.0.0/24）的RP。当Porkpie从Fedora接收到第一个RP-Announce消息之后，路由器Fedora就出现了故障，当Porkpie在180秒（通告间隔的3倍）内都没有收到来自Fedora的RP-Announce消息之后，将宣称该RP无效，选择Stetson为新的RP，并开始宣告该新RP。为清楚起见，上述事件均以高亮方式在调试消息中加以标识。

例6-26：利用debug命令来观察图6-5中映射代理上发生的RP故障倒换情况。

如例6-27所示，在Bowler上应用了命令show ip pim rp之后，可以显示出该路由器正在接收的多播组以及这些多播组所映射到的RP情况。第一个显示结果取自Fedora失效之前，可以看出所有的多播组均被映射到其RP地址；第二个显示结果取自Fedora失效之后映射代理开始宣告新RP，可以看出此时所有的多播组均被映射到Stetson。

例6-27：在Fedora失效之前，Bowler的全部多播组均被映射到该RP（10.224.1.2）；在Fedora失效之后，Bowler的全部多播组都被重新映射到Stetson（10.224.1.1）（基于映射代理提供的信息）。

要想更改C-RP发送RP-Announce消息的60秒默认间隔，可以在命令ip pim send-rp- announce中加入关键字interval。例如，下述命令将会让Fedora每隔10秒发送一条 RP-Announce消息。

ip pim send-rp-announce LoopbackO scope 5 interval 10

保持时间（是映射代理等待从C-RP接收到RP-Announce消息的时间）始终是宣告间隔的3倍，因而上述命令可以将Fedora的故障倒换时间缩短到30秒，当然要以路由器发出6倍数量的RP-Announce消息为代价。

C-RP在其RP-Announce消息中向多播组宣告其可以充当RP的角色，默认为宣告到224.0.0.0/24（表示全部多播组）。不过与前一个案例研究中所说的静态配置RP一样，有时可能希望将不同的多播组映射到不同的RP。例如，假设希望将224.0.0.0～231.255.255.255的多播组（224.0.0.0/5）全部映射到Stetson，而将232.0.0.0～239.255.255.255的多播组（232.0.0.0/5）映射到Fedora，则这两台路由器的C-RP配置情况将如例6-28所示。

例6-28：将Stetson和Fedora配置为C-RP。

关键字group-list将语句ip pim send-rp-announce与访问列表绑定在一起，该访问列表描述了哪台路由器可以成为多播组的RP。在映射代理Porkpie根据RP-Announce消息中的约束信息宣告了RP之后，Bowler中的group-to-RP映射情况如例6-29所示，239.255.255.254被映射到Fedora，而其他3个多播组（其地址均落于224.0.0.0/5范围之内）则被映射到Stetson。

例6-29：Bowler中的group-to-RP映射情况，显示了在Stetson和Fedora上配置的约束条件。

假设希望将228.13.0.0到228.13.255.255的多播组映射到Fedora，那么Fedora的配置将如例6-30所示。

例6-30：将Fedora配置为多播组228.13.0.0〜228.13.255.255的C-RP。

例6-31显示了Bowler的配置结果，可以看出Stetson的配置没有发生变化，该C-RP正在将多播组224.0.0.0/5宣告为其允许的多播组范围，其中就包含了228.13.0.0/16。此时，映射代理有了两个关于多播组228.13.0.0/16的C-RP，由于Fedora的IP地址较大，因而将其选择为RP。

例6-31：多播组228.13.0.0/16原先被映射到例6-29中的RP 10.224.1.1，现在已被映射到RP 10.224.1.2.

通过命令show ip pim rp的多种应用形式可以观察到group-to-RP映射情况，该命令的基本应用形式（如前面的几个例子）只能显示路由器上的活动多播组以及每个多播组地址所映射的RP情况。如果要观察映射到某个RP的所有多播组，就要使用show ip pim rp mapping（如例6-32所示）。

例6-32：通过接收来自映射代理10.224.1.3的RP-Discovery（RP发现）消息，Bowler将3个多播组地址范围映射到2个不同的RP上。

另一个相似的命令是show ip pim rp mapping in-use（如例6-33所示）。除了例6-32中显示的信息之外，该命令还显示了该路由器上正在使用的多播组地址范围。请注意，例6-32和例6-33的输出结果中都显示了映射代理的源10.224.1.3，在拥有多个映射代理时该信息将非常有用。

例6-33：关键字in-use显示了该路由器上正在使用的多播组地址范围。

有时，当某多播地址在路由器上被激活之前，就可能希望知道该多播地址将要映射到哪个RP。例如，假设希望知道路由器Bowler上多播组235.1.2.3将会被映射到哪个RP，那么首先应使用命令show ip pim rp-hash（如例6-34所示），显示多播组235.1.2.3将被映射到RP 10.224.1.2，该结果与前面在访问列表中配置的约束条件保持一致。

例6-34：命令show ip pim rp-hash可以显示某特定多播组将要被映射到哪个RP。

通过设置RP通告过滤器（announcement filter），可以防止映射代理接受未经授权的路由器（这些路由器可能被有意或无意地配置为C-RP）。例6-35以Porkpie为例给出了配置示范。

例6-35：为Porkpie配置RP通告过滤器。

例6-35中的配置建立了一个RP通告过滤器，要求路由器仅接收access-list 1所指定的 C-RP，并仅接收由这些C-RP宣告的、由access-list 11所指定的多播组。在上述配置中，access-list 1允许Stetson和Fedora，并允许这些路由器成为所有多播组的C-RP。

在整个案例研究中，为了清楚起见，图6-5中的Stetson和Fedora为C-RP，而Porkpie为映射代理。但在实际应用中，配置多个RP（以提高冗余性）和单个映射代理是毫无意义的，因为映射代理失效后，RP将无法被宣告给多播域，PIM-SM也将失效。更为现实的方法是将Stetson和Fedora同时配置为C-RP和映射代理。Auto-AP可以确保这两个映射代理都能导出并宣告相同的RP，当其中的一台路由器失效后，另一台路由器仍能保持服务状态，并将RP宣告给多播域。

3．案例研究：配置稀疏—密集模式

前一个案例研究中的例子有点“使诈”，回顾图6-5可以看出，C-RP被直连到映射代理，而映射代理被直连到Bowler。图6-6中的Homburg现在被配置为Auto-AP映射代理，该拓扑结构将会产生进退两难的有趣局面：Homburg在RP-Discovery（RP发现）消息中将RP宣告给域中的所有路由器（使用保留地址224.0.1.40），所有的PIM-SM路由器都会侦听该地址，但是在稀疏模式应用环境中，多播包必须首先在共享树上进行转发，这就意味着侦听 224.0.1.40的路由器为了接收RP-Discovery消息，就必须向它们的RP通告希望加入该多播组。但是，如果这些路由器连RP-Discovery消息都没有接收到，那么又如何得知谁是RP呢？

图6-6　Homburg现在被配置为映射代理

如果C-RP没有直连到映射代理，也同样会出现这种矛盾情形。映射代理要想选择RP就必须从C-RP接收RP-Announce消息，为此就必须加入多播组224.0.1.39，但是，如果映射代理不知道RP位于何处，就无法加入该多播组，而映射代理只有接收到RP-Announce消息之后才能知道RP位于何处。

为此，创建了PIM稀疏—密集模式以解决上述问题。当某接口被配置为此模式时，如果知道了该多播组的RP，就使用稀疏模式；如果不知道RP，则使用密集模式。对224.0.1.39和224.0.1.40来说，多播组被认为处于密集模式下。例6-36显示了Homburg的稀疏—密集模式配置情况。

例6-36：路由器Homburg的PIM稀疏—密集模式配置。

在所有物理接口上都应用了命令ip pim sparse-dense-mode，并且在图6-6所示拓扑结构的所有路由器的所有物理接口上也做了相似的配置。由于仅需要将环回接口作为映射代理地址，而无需做出稀疏／密集模式决策，因而环回接口仅用于稀疏模式。接口E0/0也可以被用于稀疏模式，这是因为其没有连接任何下游路由器，而且也无需做出稀疏/密集模式决策。但是为了保持一致性，建议在实际应用中将所有接口都置于稀疏—密集模式下。事实上，只要所有的路由器都支持稀疏—密集模式，那么一般都建议在所有的现代PIM域中都使用该模式。

例6-37给出了重新配置之后的Homburg的多播路由表，可以看出（*,224.0.1.39）和（*，224.0.1.40）的路由表项都带有D标记，表示它们运行于密集模式，其他（*,G）表项则被标记为稀疏模式。

例6-37：Homburg多播路由中与（*,224.0.1.39）和（*,224.0.1.40）相关的路由表项显示这些多播组都运行于密集模式。

除了这两个Auto-AP多播组之外，有时可能希望某些多播组运行于稀疏模式，而让其他多播组运行于密集模式。通过在C-RP上应用命令ip pim sendrp-announce group-list（如前面的案例研究所述），可以控制将哪些多播组映射到RP，从而让这些多播组运行于稀疏模式，其他没有被映射到RP的多播组则运行于密集模式。

4．案例研究：配置Bootstrap协议

RFC 2117在首次描述PIMv2时，将Bootstrap协议指定为自动RP发现机制，Cisco IOS软件在Release 11.3T之后开始支持PIMv2，并支持Bootstrap协议。

配置Bootstrap协议的两个步骤与配置Auto-AP协议的两个步骤相似。

•　第1步：必须配置所有C-RP。

•　第2步：必须配置所有C-BSR（Candidate Bootstrap Router，候选引导路由器）。

图6-7显示了与前两个案例研究中一样的PIMv拓扑结构，只是此时运行的不再是 Auto-AP协议，而是Bootstrap协议。为了提供更强壮的网络设计，此时的Stetson和Fedora不但是C-RP，而且都是C-BSR，使得RP和BSR都具备故障倒换能力。

例6-38给出了Stetson和Fedora的相关配置。

例6-38：将Stetson和Fedora同时配置为C-RP和C-BSR。

图6-7　Stetson和Fedora同时充当C-RP和C-BSR的角色

首先，需要从所有可用C-BSR中选出一个BSR，这些C-BSR会向整个PIM域发送 Bootstrap消息（目的地址为224.0.0.13），消息中包含了发信路由器的BSR地址和优先级。到目前为止的配置文件中，都没有更改默认优先级O和默认哈希掩码长度O，因而这两台 C-BSR的相应值均相等，从而BSR地址将成为决定因素。由于Fedora的BSR地址（10.224.1.2）大于Stetson的BSR地址（10.224.1.1），因而Fedora成为BSR，例6-39证实了该推论。通过在域中的路由器上使用命令show ip pim bsr-router，不但可以观察到活动BSR，还可以观察到BSR的地址、运行时间、优先级、哈希掩码长度以及保持时间等参数。

例6-39：命令show ip pim bsr-router显示了PIMv2域的BSR。

C-RP接收到Bootstrap消息并确定了BSR的地址之后，将以单播方式向BSR发送 Candidate-RP-Advertisement（候选RP宣告）消息，这些消息中包含了C-RP的地址和优先级。BSR将C-RP集合到一个RP-Set中，而RP-Set又被包含到Bootstrap消息中，这里就是Bootstrap与Auto-AP存在重大区别的地方：与Auto-AP映射代理不同，BSR并不选择RP。PIMv2路由器接收到Bootstrap消息之后将选择RP，用于做出选择决策的算法可以确保所有路由器都会为相同的多播组选择相同的RP。

例6-40显示了Bowler上的group-to-RP映射情况，可以看出RP是Stetson，这是因为其 IP地址较小，因而被选为RP（本例中C-RP的优先级都相同）。

例6-40：Bowler的所有活动多播组都被映射到Stetson，与Auto-RP不同，RP地址最小的C-RP被选为RP。

例6-41显示了被映射到RP的全部多播组地址范围。与例6-33的输出结果相对比可以看出，本例所显示的映射关系可以从Bootstrap消息中推导出来，并且路由器通过RP-Set知道了所有的C-RP。

例6-41：Bowler知道Stetson和Fedora都是C-RP。

可以更改BSR和RP的默认行为。例如在例6-39中，BSR是Fedora（因为其IP地址较大），如果希望Stetson成为BSR，而将Fedora设置为Stetson失效后的备用BSR，可以将Stetson的优先级设置为大于默认值0。为了将Stetson的优先级设置为100，可以参照例6-42来配置Stetson。

例6-42：将Stetson的优先级配置为100，让其成为BSR。

例6-43显示了重新配置后的结果，Bowler的输出结果显示Stetson已成为BSR（优先级为100），当Stetson失效后Fedora将承担该角色。

例6-43：Stetson（10.224.1.1）的优先级为100，因而成为BSR。

与Auto-AP一样，也可以利用访问列表在多个RP之间分配RP职责。例如，假设希望Fedora成为地址位于228.13.0.0/16范围内的多播组的RP，而Stetson成为其他多播组的RP，可以参照例6-44来进行配置。

例6-44：在Fedora和Stetson之间分配RP职责。

例6-45显示了这些配置的输出结果，BSR在其Bootstrap消息中宣告了这些约束条件，Bowler根据这些约束条件将其多播组映射到RP。当然，并不建议在实际互联网络中进行如此配置，因为某个RP出现故障后，其他路由器将无法承担备用角色。更有效的实现方式是利用访问列表将多播组分配到多个C-RP，至少要通过访问列表为每个多播组创建两个C-RP。

例6-45通过访问列表对Stetson和Fedora的RP映射施加了约束条件之后，Bowler将多播组228.13.20.216映射到Fedora，而将其他多播组映射到Stetson。

使用PIMv2 Bootstrap协议时，一种更好的分配RP职责的方法是利用哈希掩码。哈希掩码是一个分配给BSR的32bit数值，其使用方式有点类似于标准的IP地址掩码。BSR在其 Bootstrap消息中宣告该哈希掩码，接收路由器运行哈希算法，将一定数量的连续多播组地址分配给某个C-RP，再将另一组连续的多播组地址分配给另一个C-RP。

举例来说，如果哈希掩码为30bit，那么将屏蔽所有IP多播地址的前30bit，最后2bit描述的是4个多播组地址区间。这4个地址将被分配给RP，因而多播组地址225.1.1.0、225.1.1.1、 225.1.1.2和225.1.1.3属于一个地址区间，将被分配给某个RP；而225.1.1.4、225.1.1.5、225.1.1.6、225.1.1.7则属于另一个地址区间，将被分配给另一个RP。如此反复，会将整个IP多播组地址区间进行”打包”并分配给所有可用C-RP，其结果就是将所有IP多播组地址都均匀分配给了所有C-RP。通过掩码可以灵活地决定将多少个连续的多播组地址打包成单个地址区间，以便让这些相关地址共享同一个RP。如果哈希掩码为26bit，那么每个地址区间将包括64个连续的多播组地址。

可以通过命令ip pim bsr-candidate来指定哈希掩码长度。本案例研究中前面的例子中，默认的掩码长度为0，意味着单个多播组地址区间涵盖了整个IP多播地址空间。例6-46显示了为图6-7中的Stetson和Fedora分配长度为30的哈希掩码的配置情况。

例6-46：为路由器Stetson和Fedora分配长度为30的哈希掩码。

例6-47使用了命令show ip pim rp-hash来验证上述结果。可以看到，从231.1.1.0开始，后面3个连续的多播组地址都被映射到了Fedora，接下来的4个多播组地址则被映射到了 Stetson，因而整个IP多播组地址区间都被平均分配给了两个RP。

例6-47：哈希算法可以将多播组地址平均分配给所有可用C-RP。

6.1.3　案例研究：多播负载均衡

有时可能希望通过多条并行的等价路径均衡多播流量，目的是希望更充分地利用可用带宽或防止单条路径因多播流量过大而出现拥塞。但是RPF检查却阻止直接在多条物理链路上实施多播负载均衡。

图6-8解释了该问题，除了删去了Bowler且Homburg同时是Auto-AP映射代理和RP之外，图6-8中的拓扑结构与前面案例研究中的完全相同。

图6-8　多播源和组成员之间存在两条等价路径

从连接到Homburg的多播源至连接到Porkpie的组成员存在两条等价路径：一条路径穿越Fedora，另一条路径则穿越Stetson。问题是RPF要求只能有一个入站接口进行工作，这就意味着如果Fedora被选为RPF邻居，那么如果多播流量来自Stetson，由于该流量没有到达 RPF接口，这些多播流量将会被丢弃。与此相似，如果Stetson被被选为RPF邻居，那么如果多播流量来自Fedora，那么RPF检查将失败，从而丢弃这些多播流量。RPF要求所有流量都要到达同一个上行接口。

解决该问题的方法是使用隧道机制（如图6-9所示）。也就是在Homburg的Porkpie的环回接口之间建立隧道，让所有自多播源到组成员的多播流量都通过该虚拟隧道接口进行传送（而不是任一条物理链路），之后被封装的多播组将以常规IP包的方式进行转发，此时，被封装的多播组就可以通过两条物理链路实现负载均衡了。如《TCP/IP路由技术（第一卷）》所述，此时既可以基于目的地（per-destination）进行负载均衡，也可以基于数据包（per-packet）进行负载均衡。

注意：　要想实现基于数据包的负载均衡，需要关闭快速交换功能，或者在需要进行负载均衡的接口上应用命令no ip route-cache。

图6-9　为了通过两条等价路径实施负载均衡，需要在Homburg和Porkpie之间创建一条隧道

当数据包到达Porkpie之后，由于其目的地都是隧道的出口，因而根本不关心来自Fedora还是来自Stetson，并在虚拟隧道接口上移除多播包的封装。从Porkpie上的PIM处理过程来看，所有多播包看起来都是通过同一个接口TU0接收到的，而且都接收自同一个上游邻居Homburg。

例6-48显示了Homburg和Porkpie的配置情况。

例6-48：在Homburg和Porkpie间配置一条隧道，以通过等价路径实现负载均衡。

对Homburg和Porkpie来说，隧道接口的源都被配置为该路由器本身的环回接口，而目的地则被配置为另一台路由器的环回接口。使用的隧道机制是GRE（Generic Route Encapsulation，通用路由封装），并被分配了一个IP地址，从而让路由进程将其视为一个物理IP接口，最后，需要在隧道接口上启用PIM协议。请注意，上述配置中并没有在连接Stetson和Fedora的任何子接口上启用PIM，而且这两台路由器也根本没有启用多播路由。例6-49显示了Porkpie已经通过该隧道与Homburg建立了PIM邻接关系。

例6-49：Porkpie与Homburg通过GRE隧道成为邻居。

但是，仍然存在其他RPF问题需要解决，即Porkpie接收到多播源10.1.1.88发出的多播包之后会检查其单播路由表以查看上游邻居。例6-50显示了检查结果。

例6-50：单播路由表仍然显示10.2.3.1或10.2.4.2为到达10.1.1.88的下一跳地址。

Porkpie的OSPF配置文件中将接口TU0设置为被动模式，虽然这可以确保单播流量不会经过该隧道（仅允许多播流量穿越该隧道），但不幸的是，这也意味着OSPF仍然将Stetson（10.2.3.1）或Fedora（10.2.4.2）视为去往10.1.1.88的下一跳，这样一来。来自10.1.1.88的数据包到达隧道接口后，RPF检查将失败，如例6-51所示。

例6-51：由于单播路由表没有将TU0视为去往10.1.1.88的上行接口，因而从10.1.1.88发出的数据包经隧道到达该接口后会出现RPF检查失败。

为了解决这个RPF问题，需要使用静态多播路由。静态多播路由与静态单播路由类似，都会覆盖/忽略任何动态路由表项，两者的区别在于静态多播路由从不被用于转发操作，而只是被用于静态配置某多播源的RPF接口，以覆盖单播路由表中的信息。命令ip mroute与IP地址和掩码一起使用，用以指定单个地址或一个地址区间。就像静态单播路由可以指定出站接口或下一跳邻居一样，静态多播路由也可以指定一个RPF接口或RPF邻居。例6-52给出了Porkpie的静态多播路由配置情况。

例6-52：为Porkpie配置静态多播路由。

例6-53再次利用debug命令来进行配置验证，可以看到多播包已经通过了Porkpie上的RPF检查，并被转发给了组成员。

例6-53：来自多播源10.1.1.88的多播组已通过了RPF检查并被正确转发。

例6-54显示了关于多播组228.13.20.216的多播路由表项，可以看到Homburg正在其接口E0/0上接收来自多播源10.1.1.88的多播流量，并将这些流量转发到隧道上。而Porkpie正在从隧道上接收这些多播流量，并通过其接口E0转发给组成员。

例6-54：（10.1.1.88,228.13.20.216）的多播路由表项显示该多播组的流量正通过GRE隧道进行转发。

6.2　IP 多播路由的故障检测与排除

解决IP多播互联网络问题的主要武器就是彻底理解IP多播路由协议，否则没有任何故障检测与排除工具能够有助于从混乱（有时甚至更复杂）的IP多播行为中找出问题的根源。而且，仅了解一种多播路由协议根本不够，还必须理解PIM、IGMP以及单播路由之间的相互作用及关系。

如果读者已经学习了《TCP/IP路由技术（第一卷）》和本卷每章中的故障检测与排除内容，那么应该较好地掌握了解决路由式互联网络问题的方法和所需的技术知识。因而本节不再给出更多的案例研究来解释故障检测与排除技术，而是解释如何使用为多播互联网络提供的一些专用分析工具。

本章中已经出现了很多show和debug命令，这些命令对观察Cisco路由器上的IP多播路由非常有用。表6-2列出了主要可用show命令，表6-3则列出了主要的多播debug命令。在检测和排除IP单播路由故障时，命令show ip route是主要信息源，与此类似，在检测和排除IP多播路由故障时，命令show ip mroute是主要信息源。

6.2.1　使用 mrinfo

命令mrinfo可以观察路由器的多播连接和这些连接的细节情况。该命令最初是作为 Mbone中用于测试路由器的mrouted工具的一部分，因而该命令对多厂商混合域来说非常有用，下面就以图6-10中的拓扑结构为例加以说明。

如例6-55所示，在路由器Sombrero上应用了命令mrinfo，输出结果的第一行显示了用作查询消息源的地址、路由器上运行的Cisco IOS软件版本以及标记的情况，表6-4列出了各种可能的标记及其含义。接下来的两行输出结果显示了路由器上的多播接口以及该路由器的所有对等体。第二行0.0.0.0表示Sombrero的接口192.168.10.1没有对等体，1/0表示该接口的度量值为1且没有设置TTL阈值，该接口上运行的是PIM，该路由器是所连子网的IGMP查询路由器，且该子网为叶子网络（也就是说，没有多播流量经该子网穿越到其他多播路由器）。第三行显示Sombrero的接口192.168.200.1有一个对等体192.168.200.2（路由器Betet），该接口的度量值为1，没有设置TTL阈值，且运行了PIM。

图6-10　整个故障检测与排除案例中所要使用的拓扑结构

例6-55：图6-10中Sombrero的IP多播连接信息。

但mrinfo的真正用处是利用该命令查询阈值的其他路由器，如例6-56所示，通过在该命令中指定Boater的某个IP地址（本例中为环回地址），Sombrero就可以利用该命令来查询Boater。从显示的标记可以知道，路由器Boater启用了SNMP（而Sombrero则未启用），该路由器有5个启用了多播功能的接口，其中2个接口位于叶子网络上，其余3个接口有PIM对等体。检查一下图6-10即可知道上述信息都是正确的。

例6-56：Sombrero利用mrinfo来查询Boater的多播对等体。

例6-57显示了路由器Derby和Fez的查询情况。这两台路由器共享同一个以太网连接，对比这些查询结果，可以看出Derby（192.168.224.4）是子网上的IGMP查询路由器。

例6-57：通过Sombrero来查询Derby（192.168.224.4）和Fez（192.168.224.5）。

6.2.2　使用 mtrace和 mstat

另一个有用的工具是命令mtrace，该命令可以跟踪从指定目的地到指定源之间的RPF路径。与mrinfo类似，mtrace也是一个基于UNIX的MBone工具，可用于多厂商混合域，也可以从域中的任一台路由器发起该命令，而无需通过RPF路径上的路由器发起该命令。

使用该命令时，需要指定一个源地址和一个目的地址，该命令会向目的地发送一条跟踪请求。该请求使用单播方式跟踪所指定的源，由路径上的第一跳路由器以单播方式将跟踪结果反馈给查询路由器。

例6-58显示了Sombrero利用该命令跟踪从Derby的接口192.168.12.2到Turban的接口192.168.11.1的RPF路径的情况。请记住，由于这是一种反向路径跟踪，因而Turban的接口是源，而Derby的接口为目的地。输出结果首先显示了目的地址，以及到达源所经过的每个中间路由器，还显示了从源开始的跳数（因为在该跳上使用了多播路由协议）。

例6-58：利用mtrace来检查从目的地192.168.12.2到源192.168.11.1的RPF路径。

除了隔离多播路由故障之外，mtrace还有一个重要功能，那就是将实时多播包引导到互联网络之前观察多播的行为。请注意，图6-10中没有标示多播源或多播组成员，假设希望找到连接在Boston上的多播源（地址为192.168.14.35），该多播源将发起多播组235.100.20.18的多播流量，组成员的地址为192.168.12.15、192.168.10.8、192.168.11.102。例6-59给出了相应的结果。

例6-59：mtrace可用于测试多播域中暂时不存在的RPF源、目的地和组地址。

例6-59中的跟踪操作指定了包括源地址和目的地址在内的多播组，虽然正常情况下所有多播组的RPF路径都相同，但指定多播组在多播定界或RP过滤等情况下却非常有用。如果没有指定多播组（如例6-58），则默认使用多播组地址224.2.0.1（MBone音频多播组地址）。

命令mstat是mtrace的改良版本，不仅能提供从多播源到多播组目的地路径的踪迹信息，还能提供该路径的统计信息。例6-60重新发起从源192.168.14.35到目的地192.168.10.8路径上多播组235.100.20.18的跟踪操作。对比例6-60与例6-59中的跟踪操作输出结果，可以看出mstat不仅提供了多播包统计情况，还提供了更为详细的整条路径情况。

例6-60：命令mstat提供了更为详细的从源到目的地的多播流量跟踪信息。

从下往上看，例6-60显示了查询源和响应目的地，对本例来说都是192.168.200.1（Sombrero）。请注意，输出结果中用ASCII码表示了箭头符号，显示Sombrero曾向192.168.10.01（在本例中是其自己的接口），然后跟踪了去往路由器Boater接口（多播组连接在上面）的反向路径，之后向Sombrero发送了该查询的响应消息。在输出结果的最左侧，ASCⅡ箭头还表示了多播流量所选取的从源至目的地的路径。在每一跳显示的信息中，ttl和hop的统计值很容易让人误解，因为ttl显示的实际上是从源点开始的跳数，而hop显示的则是跳与跳之间的时延（以毫秒为单位）。需要注意的是，在响应目的地下面还显示了rtt（Round-Trip Time，往返时间）。之后显示了所有多播流量以及命令中所指定的（S,G）对的统计信息，第一条统计信息对比了已丢弃多播包数量和已发送多播包数量，第二条统计信息显示了整体流量速率（以pps[packet-per-second，包/秒]为单位）。对例6-59来说，由于从源至目的地没有任何多播流量，因而这些统计信息均为0，事实上，源和目的地根本就不存在。

如例6-61所示，已经安装了相应的主机，多播源也正在生产多播流量，且组成员也已经加入了多播组，此时可以观察流量速率（pps）和丢包统计情况。在使用命令mstat时请记住，只有实现了路由器的时间同步之后，路由器之间的时延才有效。

例6-61：源和目的地之间开始有多播流量之后再次使用命令mstat。

例6-62给出了路由器之间未实现时间同步时的显示结果，其中的路径跟踪信息及包速率仍然有效，但各跳之间的时延却毫无意义。从例6-62中还可以看到Turban和Beret的路由跳之间丢失了一个多播包，这可能是一个问题，也可能不是一个问题。此时只能多次迭代运行mstat以观察该多播组丢失情况是否正常，如果不正常，那么就需要使用debug命令进行进一步的研究和分析。

例6-62：如果路由器的时钟没有实现同步，那么输出结果中显示的路由跳之间的时延将毫无意义。

最后，可能会在mstat的输出结果中看见负的丢包数（如-3/85）。“负丢包”实际上表示的是获得的多播包，也就是说收到了额外的多播包，此时表明可能出现了环路，需要做进一步的研究和分析。

6.3　展 望

经过本章的学习，读者应该已经很好地掌握了IP多播路由的配置方法，但是与单播路由一样，随着多播域的不断增大，也会带来扩展性和控制等问题。第7章将详细介绍从域定界到域间多播在内的各种解决大规模多播路由的工具及策略。

6.4　配置练习题

（1）启用IP多播路由的全局Cisco IOS软件命令是什么？

（2）请给出在接口上启用PIM密集模式、稀疏模式以及稀疏—密集模式的命令。

（3）请给出将RP地址静态指定为172.18.20.4的命令。

（4）请按以下要求给出所需的配置语句：将多播组239.1.2.3和228.1.8.0～228.1.8.255静态映射到RP 192.168.15.5，将多播组239.6.7.8映射到RP 192.168.20.10，将其他多播组映射到RP 192.168.25.1。

（5）图6-11中所示路由器的接口运行的均是稀疏—密集模式，请按以下要求给出所需的配置语句：让R1成为起始地址为226.13.0.0/24的多播组的RP,R2成为起始地址为239.0.0.0/8的多播组的RP。R3是映射代理，要确保映射代理仅承认R1和R2为指定多播组的RP。此外，所有Auto-RP消息的TTL均为20。

图6-11　配置练习题（5）～（8）的拓扑结构

（6）在给定配置练习题（5）所示的配置情况下，假如某多播源发起多播组228.23.14.135的多播流量，并且有一个组成员希望加入该多播组，将会发生什么事件？

（7）如图6-11所示，请按如下要求写出相应的配置文件：启用Bootstrap协议，让R1和R2同时成为配置练习题（5）所述多播组地址的C-RP，让R3成为BSR,R4成为备用BSR。

（8）如图6-11所示，请按如下要求写出相应的配置文件：在多播源172.16.1.75与组成员172.16.2.100之间实现多播流量均衡。隧道接口使用无编号IP地址，参考接口为E0，假设IGP正在宣告这些地址。

（9）查看6.1.3小节中Homburg和Porkpie的配置可以知道，这两台路由器都在隧道接口上运行OSPF的被动模式，为什么？

（10）命令ip pim spt-threshold 100 group-list 25的作用是什么？

6.5　故障检测与排除练习题

（1）请说明例6-63输出结果的含义。

（2）请说明例6-64输出结果的含义。

例6-63：故障检测与排除练习题（1）的输出结果。

例6-64：故障检测与排除练习题（2）的输出结果。

（3）请说明例6-65输出结果的含义。

例6-65：故障检测与排除练习题（3）的输出结果。

（4）图6-12所示4台路由器中，哪台路由器是PIM指派路由器？

（5）图6-12中的哪台路由器正向组成员发送IGMPv2查询消息？

（6）表6-5列出了去往图6-12中多播源172.16.12.18的所有单播路由，请问哪台路由器是PIM转发路由器？

（7）例6-66显示了图6-10所示PIM域的RPF跟踪情况，该路由器运行的单播IGP是RIP-2。请问该跟踪信息指出了什么问题？

图6-12　　故障检测与排除练习题（4）、（5）、（6）的拓扑结构

例6-66：故障检测与排除练习题（7）的mtrace输出结果。

本章将主要讨论以下主题。

•　多播定界——本节将探讨限制IP多播流量范围的原因，并说明两种多播定界实现方法：TTL定界和管理性定界。

•　案例研究：穿越非多播域的多播技术——本案例研究将探讨如何让IP多播流量穿越不支持IP多播的路由器。

•　连接到DVMP网络——本节将探讨如何将Cisco路由器连接到DVMRP网络上，并说明Cisco IOS软件对DVMRP的支持/不支持情况。

•　域间多播——本节将阐述在自治系统之间路由IP多播流量所带来的问题，并讨论作为部分问题解决方案的MBGP和MSDP的操作行为。

•　案例研究：配置MBGP——本案例研究将示范多协议BGP的配置方法。

•　案例研究：配置MSDP——本案例研究将示范MSDP的配置方法。

•　案例研究：MDSP网状多播组——本案例研究将示范MSDP网状多播组的配置方法。

•　案例研究：任播RP——本案例研究将示范任播RP的配置方法。

•　案例研究：MSDP默认对等体——本案例研究将示范MSDP默认对等体的配置方法。

第7章
大规模多播路由

前两章解释了IP多播路由协议的当前发展状态以及Cisco IOS软件关于多播路由的基本配置方法。与单播协议一样，随着多播域的不断增大，需要采取额外的措施来维持网络的稳定性、可扩展性和可控性，本章将解释实现上述目标的一些可用技术和可用协议。

7.1　多播定界

在处理大规模多播域时的主要考虑点是如何控制多播域的范围。第5章中曾经提到，目前存在如下两种多播域定界方法。

•　TTL定界

•　管理性定界

对TTL定界来说，就是设置多播包的TTL值，在TTL递减到0之前可以一直向外传送多播包，待TTL递减为0时就丢弃该多播包。可以利用命令ip multicast ttl-threshold在接口上设置阈值边界，以便对这种粗放的控制方法实施精细化控制。例如，如果在某接口上配置了语句ip multicast ttl-threshold 5，那么只有TTL值大于5的多播包才会从该接口上转发出去，任何TTL值小于等于5的多播包都会被丢弃。表7-1列出了各种TTL定界值示例（与表5-6完全相同），表中所列TTL值都是MBone建议使用的TTL值。

在第6章中已经涉及了一些用于TTL定界而设置协议消息TTL值的命令，如启用Auto-RP C-RP和映射代理的命令等，本章还将出现更多的提供类似功能的命令。但是如第5章所述，由于在某个接口上设置的TTL边界会应用于所有多播包，因而TTL定界缺乏灵活性，虽然这对绝对的边界来说很好，但有时可能希望只阻塞某些多播包，而继续转发其他多播包。

为此，管理性定界提供了更好的灵活性能力。管理性定界实质上就是将多播组地址区间224.0.0.0〜239.255.255.255进行分区，让部分地址区间落入某范围内，然后通过过滤这些地址区间即可创建不同的域边界。有关管理性定界的描述请参见RFC 2365，表7-2列出了该RFC所建议的分区情况。读者已经看见了如何使用224.0.0.0/24的链路本地（link-local）范围，路由器从不转发多播地址位于该区间内的多播包，如IGMP（224.0.0.1和224.0.0.2）、OSPF（224.0.0.5和224.0.0.6）、EIGRP（224.0.0.10）和PIM（224.0.0.13），因而将这些多播包限制在发起这些多播包的数据链路范围之内。

只要在接口上应用命令ip multicast boundary即可创建一个管理性边界。该命令只引用IP访问列表，由该访问列表来指定该接口所允许或拒绝的多播组地址区间（如例7-1所示）。

例7-1：在接口上应用命令ip multicast boundary以创建管理性边界。

其中的接口E0被标记了一个边界，所有组织机构本地（organization-local）范围内的多播包都会被阻塞，而全局（global）范围内的多播包都可以通过。接口E1上的边界则仅允许所有目的地址位于239.135.0.0/16区间内的多播包通过（而拒绝其他多播包），由于该地址区间位于表7-2的未定义区间，因而可以由本地网络管理员赋予其特殊的含义。

7.2　案例研究：穿越非多播域的多播技术

读者今后可能要面对的一个挑战就通过一个不支持多播的域来连接不同的多播域，这通常发生在一个大型路由域中只有某些特定区域需要多播路由的场合，这时候一般不希望为少量多播路由器的连接而在整个单播域的每台路由器上都启用多播协议。另一种非常普遍的应用场合就是通过单播Internet互联不同的多播域。

如图7-1所示，两个PIM域被一个仅支持单播的IP域所隔离，该单播IP域可能是一个骨干网，也可能是一个企业网，甚至是Internet本身。但目前的要求是这两个多播域必须通过该单播域进行互联，解决方案很简单，那就是在携带PIM流量的两台路由器之间创建一条隧道。

图7-1　两个PIM域被一个仅支持单播的IP域所隔离

例7-2显示了图7-1中这两台路由器的隧道配置情况。

例7-2：配置Godzilla和Mothra以通过单播域来提供两个多播域之间的连通性。

第6章曾提到过利用隧道在多条等价路径之间实现多播流量的负载均衡，此处的隧道配置与此类似。隧道源是每台路由器上的以太网接口，需要注意的是，该物理接口上并没有配置PIM，仅仅在隧道上配置了PIM。此处使用的隧道机制是GRE封装（默认的隧道模式）。为了确保单播流量不经过该隧道，在接口TU0上配置了工作于被动模式下的OSPF。最后还配置了静态多播路由，引用了来自对方多播域的所有可能的源地址，并显示它们的上行接口为TU0。回顾第6章可以知道，该路由的作用是预防RPF检查失败，如果没有该路由，RPF检查将使用OSPF路由并将上行接口确定为路由器的接口E0，这样一来，到达接口TU0的所有多播包的RPF检查都将失败。

注意：　如果DVMRP路由器不支持GRE封装，也可以使用IP-in-IP。

例7-3给出了上述配置的结果。

例7-3：通过GRE隧道建立了PIM邻接关系。

7.3　连接到DVMP网络

读者可能偶尔会碰到需要将PIM路由器连接到某台DVMRP路由器的应用需求。虽然这本身并不是一个大规模IP多播路由问题（因为在任何规模的互联网络中都可能存在仅支持DVMRP的路由器），但最可能的应用需求就是将自己的PIM路由器连接到MBone上。

在Cisco路由器的某个接口上启用了PIM之后，该路由器就将侦听DVMRP Probe（探测）消息，一旦接收到Probe消息（如例7-4输出结果所示），Cisco IOS软件就会自动在该接口上启用DVMRP。无需做任何配置，PIM路由就会通过DVMRP Report（报告）消息宣告给DVMRP邻居。虽然学习自邻居的DVMRP Report消息都会被保存在一个独立的DVMRP路由表中（如例7-5所示），但仍然由PIM来控制Cisco路由器的多播转发决策。虽然Cisco路由器可以正常发送和接收DVMRP Graft（嫁接）消息，但Cisco IOS软件对Prune（剪除）和Probe消息的处理方式使其与完整的DVMRP实现仍存在着一定的差异。

例7-4：路由器正在接口E0上接收来自邻居10.224.1.1的DVMRP Probe（探测）消息。

例7-5：命令show ip dvmrp route显示了DVMRP路由的相关信息。

完整的DVMRP实现与基于Cisco IOS软件的DVMRP实现之间的第一个差异是对Probe消息的处理方式。如前所述，Cisco路由器通过检测Probe消息来发现DVMRP邻居。但是，假设该DVMRP邻居位于某个多路接入网络上，而且有多台Cisco路由器也连接在该网络上，如果其中的某台Cisco路由器发起一条Probe消息，那么邻接的Cisco路由器将会错误地认为该消息的发起者是DVMRP路由器，而不是PIM路由器（如图7-2所示）。因而，Cisco路由器仅侦听Probe消息，而不会发起Probe消息。

第二个差异是对Prune消息的处理方式。第5章中曾经谈到，DVMRP路由器需要维护每个下游邻居的状态，如果某个下游邻居发出了Prune消息，那么仅剪除该邻居的状态，DVMRP路由器仍然要通过该接口转发多播流量（除非所有的DVMRP邻居都发送了Prune消息）。这种方式解决的是一个多路接入网络中存在多个下游邻居的应用场合，这样做的目的是防止某个下游邻居发出Prune消息后导致其他邻居也被剪除。

图7-2　如果顶部的Cisco路由器会生成DVMRP Probe消息，那么底部的Cisco路由器将会误认为该消息的发起者是一个DVMRP邻居，因而Cisco路由器从不生成DVMRP Probe消息

注意：　第5章中曾经提到，PIM-DM使用剪除覆盖机制来解决该问题，而无需维护邻居的状态信息。

但是Cisco路由器并不维护DVMRP邻居的状态，因而为了避免某个下游邻居发出的Prune消息剪除了其他下游邻居所需的多播流量，Cisco路由器将忽略多路接入接口上接收到的DVMRP Prune消息。由于点到点接口只有一个下游邻居，因而可以正常处理该接口上接收到的Prune消息。此外，Cisco路由器可以在连接了DVMRP邻居的多路接入和点到点接口上正常发送Prune消息。

该方法的难点也很明显，如果经多路接入网络连接到上游Cisco路由器的DVMRP路由器无法剪除自己，那么Cisco路由器就会将非期望的多播流量转发到DVMRP域中。解决该难点的方法仍然是隧道。

如图7-3所示，一台Cisco路由器经多路接入网络连接到两台DVMRP路由器上，与每台DVMRP路由器创建了隧道之后，Cisco IOS软件将认为是通过点到点链路（而不是多路接入链路）连接到DVMRP邻居。之后，Cisco路由器就可以正常接收剪除消息。

图7-3　利用隧道在多路接入网络中创建点到点连接，以便让DVMRP的剪除操作正常运行

例7-6显示了图7-3中Cisco路由器的配置情况。

例7-6：配置图7-3中的Cisco路由器以通过点到点链路接收剪除消息。

与前面的隧道配置相比，本例隧道配置的最大区别在于将隧道模式设置为DVMRP（而不是默认的GRE），而且是在隧道（而不是物理接口）上配置PIM。如果多路接入网络中存在Cisco PIM路由器，那么就要在以太网接口上配置PIM，以便让DVMRP路由器通过隧道进行连接，而PIM路由器则通过以太网进行连接。

注意：　请记住，如果通过DVMRP路由器可达多播源，那么就必须配置静态多播路由，以免RPF检查失败。

7.4　域间多播

所有多播路由协议（也包括所有单播路由协议）都面临着扩展性问题，也就是如何有效地将数据包分发给一组主机。通过前面的学习已经知道，密集模式协议（如PIM-DM和DVMRP）的扩展性都不是很好，根据定义，这类协议假定多播域中的多数主机都是组成员。作为稀疏模式协议的PIM-SM的扩展性相对较好，因为该协议假定多播域中的大多数主机都不是组成员。不过，无论是密集模式协议还是稀疏模式协议，它们的假定条件都局限于单个多播域，也就是说，迄今为止遇到的多播路由协议都可以被认为是多播IGP。

那么在保持每个AS独立性的同时，如何让多播包穿越AS边界呢？

PIM-SM的Internet草案通过定义PMBR（PIM Multicast Border Router, PIM多播边界路由器）来解决该问题。PMBR位于PIM域的边缘，并在域中构建去往所有RP的特殊树枝（如图7-4所示），每个树枝都以一个（*,*,RP）表项加以表示，其中的两个通配符表示映射到该RP的所有多播源地址和多播组地址。RP从多播源接收到多播流量之后，将其转发给PMBR，再由PMBR转发到邻居域中。对非期望的多播流量来说，由邻居域向PMBR发送剪除消息，再由PMBR发送给RP。

PMBR的主要缺点在于其泛洪/剪除操作机制。事实上，PMBR主要被建议用作将PIM-SM域连接到DVMRP域，由于这种方法的扩展性较差，因而Cisco IOS软件并不支持PMBR。

由于PIM-SM是事实上的IP多播路由协议标准，因而如何在自治系统之间路由多播流量的问题就可以简化为如何在PIM-SM域之间路由多播流量。此时必须解决以下两个问题。

图7-4　PMBR与域中的每个RP都建立一个被称为（*,*,G）的多播树枝，RP沿着这些树枝将多播流量转发给PMBR

•　当多播源和组成员位于不同域中时，RPF进程必须保持有效；

•　为了维持独立性，一个域不能依赖于另一个域中的RP。

PIM-SM是与协议无关的，因而第一个问题看起来非常容易解决，就像PIM使用单播IGP路由来确定域内的RPF接口一样，此时可以使用BGP路由来确定去往其他自治系统中的多播源的RPF接口。不过在域间传送多播流量时，可能会希望使用与单播流量不同的链路（如图7-5所示），如果多播包到达链路A，BGP显示去往该多播包的源的单播路由是通过链路B，那么RPF检查将失败。虽然静态多播路由可以解决该问题，但很明显不适合大规模应用，因而必须对BGP进行扩展，让BGP路由指示被宣告的前缀是用于单播路由，还是多播RPF检查，或者是两者。

图7-5　AS间流量工程需求可能要求多播流量与单播流量使用不同的链路

碰巧PIM可以利用现有的BGP扩展协议，该扩展后的BGP版本被称为MBGP（Multiprotcol BGP，多协议BGP），有关描述请参见RFC 2283。虽然该BGP扩展的目的是让BGP携带IPv6和IPX等协议的可达性信息，但是也可以让MBGP宣告多播源，因而有时也会不准确地将MBGP中的“M”理解为“多播（Multicast）”而不是“多协议（Multiprotcol）。

MBGP的最常见应用是在同意交换多播流量的服务提供商的NAP中构建对等连接，如图7-6所示，虽然各自治系统可以按图中所示建立单播流量的对等连接，但多播流量必须共享同一个对等点。由于某些前缀可能会同时通过单播和多播NAP进行宣告，因而必须利用MBGP来区分多播RPF路径与单播路径。

注意：　图7-6中所示的多播NAP常常是某些非交换介质，如FDDI。

第二个AS间PIM问题（为了维持独立性，一个域不能依赖于另一个域中的RP）的主要原因是AS不希望依赖于其不能控制的RP。但是如果每个AS都放置自己的RP，那么就必须有相应的协议让不同AS内的每个RP都能与其他RP共享多播源信息（穿越AS边界）并发现其他RP所知道的多播源（如图7-7所示），该协议就是MSDP^3（Multicast Source Discovery Protocol，多播源发现协议）。

以下各小节将详细介绍MBGP扩展及MSDP的相关操作。

图7-6　当需要为多播和单播提供不同的对等点时就可以使用MBGP

图7-7　在RP之间运行MSDP之后就可以让每个RP都能发现其他RP所知道的多播源

7.4.1　MBGP

RFC 2283中定义了以下两种新属性，从而将BGP扩展为支持多协议。

•　MP_REACH_NLRI（Multiprotocol Reachable NLRI，多协议可达NLRI），类型14；

•　MP_UNREACH_NLRI（Multiprotocol Unreachable NLRI，多协议不可达NLRI），类型15。

注意：　有关BGP属性类型代码的详细列表请见第2章的表2-7。

这两个属性都是可选非传递性属性。第2章中曾经提到，可选非传递性属性意味着BGP发言者并不需要支持该属性，不支持该属性的BGP发言者不会将它们传递给其对等体。

MP_REACH_NLRI属性用于宣告可行路由，而MP_UNREACH_NLRI用于撤销可行路由，包含在这些属性中的NLRI（Network Layer Reachability Information，网络层可达性信息）是与协议相关的目的地信息，当MBGP用于IP多播时，NLRI总是一个描述一个或多个多播源的IPv4前缀。需要记住的是，PIM路由器并不使用该信息进行包转发，而仅仅用来决定去往某特定多播源的RPF接口。通过这两个新属性，就可以告知BGP对等体某特定前缀是否仅用于单播路由、多播RPF或用于两者。

MP_REACH_NLRI包含一个或多个（地址族信息，下一跳信息，NLRI）三元组，MP_UNREACH_NLRI则包含一个或多个（地址族信息，不可行路由长度，被撤销的路由）三元组。

注意：　MP_REACH_NLRI的完整格式比较复杂，某些字段也与IP多播无关，要想详细了解相关内容请参见RFC 2283。

地址族信息（Address Family Information）包括一个AFI（Address Family Identifier，地址族标识符）和一个Sub-AFI（Subsequent AFI，次AIF）。IPv4的AFI为1，因而对IP多播来说AFI总是被设置为1。Sub-AFI描述的是NLRI是否仅用于单播路由、仅用于多播RPF信息或用于两者（如表7-3所示）。

7.4.2　MSDP的操作

顾名思义，MSDP的作用是发现其他PIM域中的多播源。运行MSDP的好处是本域中的RP可以与其他域中的RP相互交换多播源信息，本域中的组成员则无需直接依赖于其他域中的RP。

注意：　在随后的案例研究中读者将可以了解到为何MSDP对单个域中的多播源信息共享也非常有用。

MSDP使用TCP（端口639）作为其对等连接，与BGP一样，MSDP使用点到点TCP对等连接就意味着必须显式配置每个对等体。如图7-8所示，当PIM DR将某个多播源注册到其RP时，该RP将向其所有的MSDP对等体发送一条SA（Source Active，源有效）消息。

SA消息中包含以下信息。

•　多播源地址。

•　多播组（多播源正向该多播组发送多播包）地址。

•　发信RP的IP地址。

每个收到该SA的MSDP对等体都将该SA泛洪到其对等体（发信路由器的下游邻居）。在某些情况下（如图7-8中AS 6和AS 7的RP），一个RP可能会从多个MSDP对等体接收到同一份SA拷贝，为了防止出现环路现象，RP会检查BGP下一跳数据库以确定去往SA发信路由器的下一跳。如果同时配置了MBGP和单播BGP，那么会首先检查MBGP，之后再检查单播BGP；如果下一跳邻居是该发信路由器的RPF对等体，而且不是在去往RPF对等体的接口上接收到该发信路由器发出的SA消息，那么就丢弃该SA消息。因而将SA泛洪称为对等体RPF泛洪（peer RPF flooding），由于存在对等体RPF泛洪机制，BGP或MBGP必须与MSDP同时运行。

RP接收到SA后，通过查看该多播组的（*,G）出站接口列表中是否有接口来确定其域中是否有该SA的多播组的成员。如果没有组成员，RP就不做任何操作；如果有组成员，则RP将向该多播源发送一条（S,G）加入消息，从而建立起一个穿越AS边界去往RP的该多播源树的树枝。当多播包到达RP之后，就会沿着自己的共享树被转发到该RP所在域的组成员，之后这些组成员的DR就可以利用标准的PIM-SM进程选择加入去往该多播源的RPT树。

图7-8　RP通过SA消息向其MSDP邻居宣告多播源

只要多播源一直向多播组发送多播包，发信RP就会一直以60秒为周期发送（S,G）的SA消息，其他RP接收到SA消息后可以选择缓存该消息。例如，假设某RP从发信RP 10.5.4.3接收到一条关于（172.16.5.4,228.1.2.3）的SA消息，该RP查看其多播路由表之后发现没有多播组228.1.2.3的有效组成员，那么该RP将不再缓存该SA消息，而是将其传送给其对等体（10.5.4.3的下游邻居）。之后，如果该域中的某台主机向该RP发送了一条加入多播组228.1.2.3的请求消息，那么该RP会将去往该主机的接口加入其（*.228.1.2.3）表项的出站接口列表中。但由于没有缓存之前的SA消息，该RP并不知道该多播源，所以在RP向多播源发起加入消息之前必须等待接收下一条SA。

另一方面，如果RP缓存了SA消息，那么该路由器就有了（172.16.5.4,228.1.2.3）表项，从而可以在主机提出加入请求时即可加入该多播源的多播树。这里就有一个折衷问题，一方面是降低加入等待时间，另一方面是缓存可能需要也可能不需要的SA而耗费的内存资源。如果RP属于某个大型MSDP网状网，并且有大量的SA消息，那么应该将内存消耗摆在重点考虑之列。

在默认情况下，Cisco IOS软件不缓存SA，可以使用命令ip msdp cache-sa-state来启用SA的缓存功能，为了减轻可能的内存压力，可以考虑将该命令连接到一个访问列表，指定缓存某些特定（S,G）对的SA消息。

如果某RP有一个正在缓存SA的MSDP对等体，那么通过SA Request（SA请求）和SA Response（SA响应）消息，该RP在不开启SA缓存功能的情况下也能降低加入等待时间。当主机请求加入某多播组之后，该RP会向其缓存对等体发送一条SA Request消息，如果该对等体缓存了该多播组的源信息，那么就在SA Response消息中将该多播源信息发送给该请求RP，该请求RP只是使用SA Response消息中的信息，而不会将该信息转发给其他对等体。如果非缓存RP接收到SA Request消息，则向请求RP发送一条差错消息。

如果希望Cisco路由器能发送SA Request消息，则需要使用命令ip msdp sa-request来指定缓存对等体的IP地址或名字；如果需要指定多个缓存对等体，那么就需要多次使用该命令。

7.4.3　MSDP消息格式

MSDP消息携带于TCP报文段中。两台路由器被配置为MSDP对等体之后，IP地址较大的路由器将侦听TCP端口639，而IP地址较小的路由器则试图主动连接到端口639。

MSDP消息使用TLV（类型/长度/值）格式，一共有5种类型（如表7-4所示），下面将详细描述每种类型的MSDP消息。

1. SA TLV

MSDP RP从IP多播源接收到一条PIM Register（注册）消息之后，会向其对等体发送一条SA消息（图7-9显示了MSDP SA消息的TLV格式），之后每隔60秒就发送一条SA消息，直至多播源不再有效。单条SA消息可以同时宣告多个（S,G）表项。

图7-9　MSDP SA TLV格式

MSDP SA TLV格式的字段定义如下。

•　表项数量（Entry Count）：指定由给定RP地址所宣告的（S,G）表项的数量。

•　RP地址（RP Address）：发信RP的IP地址。

•　保留（Resvered）：被设置为全0。

•　源前缀长度（Sprefix Length）：指定相关联的多播源地址的前缀长度，该长度始终为32。

•　组地址（Group Address）：多播IP地址（相关联的多播源向该多播组发送多播包）。

•　源地址（Source Address）：有效源的IP地址。

2. SA Request TLV

SA Request消息（其格式如图7-10所示）用于向正在缓存SA状态的MSDP对等体请求（S,G）消息，应该仅向缓存对等体发送SA Request消息（非缓存对等体接收到该消息后会返回一条差错通告），并且只能由显式配置的RP发送该消息。

图7-10　MSDP SA Request TLV格式

MSDP SA Request TLV格式的字段定义如下。

•　组前缀长度（Gprefix Length）：指定多播组地址前缀的长度。

•　组地址前缀（Group Address Prefix）：指定多播组地址（该多播组的源信息需要被请求）。

3. SA Response TLV

SA Response消息（其格式如图7-11所示）由缓存对等体发送，它作为SA Request消息的响应消息，向请求对等体提供多播源地址以及与指定组地址相关联的RP地址，其格式与SA消息相同。

图7-11　MSDP SA Response TLV格式

4. Keepalive TLV

图7-12　MSDP Keepalive TLV格式

MSDP连接的主动方（即IP地址较小的对等体）会以一个75秒Keepalive定时器来跟踪MSDP连接的被动方。如果Keepalive定时器到期时仍未从被动方收到MSDP消息，那么主动对等体会重置TCP连接，如果接收到MSDP消息，则重置Keepalive定时器。如果被动对等体没有其他消息需要发送，则发送Keepalive消息，以免主动对等体重置TCP连接。如图7-12所示，Keepalive消息是一个只包含类型和长度字段的24bit TLV。

5. Notification TLV

检测到差错之后路由器会发送Notification消息，图7-13显示了Notification消息的格式。

图7-13　MSDP Notification TLV格式

MSDP Notification TLV格式的字段定义如下。

•　长度=x+5：TLV的长度。其中，x是数据字段的长度，5是前5个8位组。

•　O：打开比特（open bit）。如果该比特被清除，则接收到Notification消息之后就必须关闭该连接。表7-5列出了不同差错子代码的O比特情况。MC表示必须关闭（must close）,O比特始终被清除。CC表示可以关闭（can close）,O比特可以被清除。

•　差错代码（Error Code）：一个表示Notification类型的7比特无符号整数，表7-5列出了差错代码的情况。

•　差错子代码（Error Subcode）：一个提供更详细差错代码信息的8比特无符号整数，如果某差错代码无子代码，则该字段为0。表7-5列出了与差错代码相关联的各种可能的差错子代码。

•　数据（Data）：一个包含了与差错代码和差错子代码相关信息的可变长字段。本章没有完全介绍该数据字段，有关该字段的详细信息可参见MSDP Internet草案。

7.5　案例研究：配置MBGP

如图7-14所示，AS 200正在向转接AS 100宣告前缀172.16.226.0/24和172.16.227.0/24，并用于正常的AS间路由。此外，AS 200也拥有少量多播源，分别是IP地址为172.16.224.1和172.16.225.50的主机。子网172.16.227.0/24上也有少量多播源，而且该前缀同时被宣告为单播前缀和多播源前缀。

图7-14　AS 200正在宣告部分前缀和地址。某些是单播，某些是多播，某些同时是单播和多播

例7-7显示了图7-14中Gorgo和Rodan的配置情况。

例7-7：图7-14中Gorgo和Rodan的配置情况。

这两台路由器BGP配置中的单播部分与第3章中的配置没什么区别。与Gorgo将两个单播前缀宣告到了AS 100中一样，配置中标识了它们的邻居及相应的AS号。

注意：　本章假设读者已经熟悉了单播BGP的配置方法。如果对next-hop-self和update-source等IBGP工具还不清楚的话，请复习第3章的相关内容。

命令address-family ipv4 multicast的作用是激活MBGP。回顾7.4.1小节中的内容，MBGP使用了两个新属性（MP_REACH_NLRI和MP_UNREACH_NLRI），而且这些属性的AFI代码对IPv4来说始终为1，关键字multicast将这些属性的Sub-AFI设置为多播。命令address-family之后的MBGP配置情况与单播BGP的配置非常相似，标识了MBGP邻居，也标识了被宣告为多播的前缀。关键字activate表示已经为该邻居激活了MBGP，仅在BGP下指定（MBGP不指定）对等体的AS号。需要注意的是，IBGP配置中的next-hop-self等命令在MBGP下的使用方式与BGP一样，也可以为MBGP邻居单独配置策略。最后的命令exit-address-family是由Cisco IOS软件自动输入的，作为MBGP配置内容的结束标记。

使用了命令address-family ipv4 multicast之后就隐含了启用命令address-family ipv4 unicast。虽然该命令从不显示在配置文件，但的确应用到了单播BGP配置中，其结果就是该配置片段中指定的前缀被赋予了属性MP_REACH_NLRI和一个单播Sub-AFI。请注意，前缀172.16.227.0/24出现在Gorgo的BGP和MBGP配置中，之后该前缀同时作为单播和多播前缀（Sub-AFI=3）被宣告出去。

如例7-8所示，命令show ip bgp ipv4显示了上述配置结果，第一次使用了关键字unicast，第二次使用了关键字multicast，显示了所有Sub-AFI与关键字相匹配的前缀。请注意，由于前缀172.16.227.0/24被同时配置为单播和多播前缀，因而出现在两个输出结果中。

注意：　命令show ip bgp ipv4 unicast与命令show ip bgp的输出结果相同。

例7-8：命令show ip bgp ipv4 unicast所显示的前缀情况（根据它们的Sub-AFI值）。

由于图7-14中的Megalon和Kong为单播BGP和MBGP使用了不同的链路，因而它们的配置相对较为复杂。例7-9显示了这两台路由器的配置情况。

例7-9：Megalon和Kong为单播和多播使用不同数据链路的配置情况。

从上例的MBGP配置中可以看出，只有子网192.168.1.8/30被建立了MBGP对等关系，在单播BGP配置中出则现了一些新命令。请记住，在调用命令address-family ipv4 multicast的时候会隐式地自动调用命令address-family ipv4 unicast，对子网192.168.1.8/30来说，由于不期望存在单播BGP流量，因而使用命令no ip default ipv4-unicast来阻止这种自动配置行为。之后，利用命令neighbor activate在所期望的链路上显式启用单播BGP。请注意，子网 192.168.2.1/30和192.168.1.4/30上激活了BGP，而子网192.168.1.8/30上却没有。由于本链路只有在BGP中指定的AS号，因而可以建立对等关系。

例7-10显示了例7-9的配置结果，该输出结果与例7-8相似。例7-8对单播和多播前缀做了正确划分，但本例中单播前缀的下一跳地址是192.168.1.6，而多播前缀的下一跳地址（RPF邻居）却是192.168.1.10。

例7-10：AS 300已接收到AS 200宣告的前缀，为Kong与Megalon之间的仅单播链路（unicast-only link）和仅多播链路（multicast-only link）使用了正确的下一跳地址。

例7-11以172.16.227.0/24（该前缀被同时宣告为单播和多播前缀）为例给出了实际的BGP和MBGP宣告应用示例，对172.16.227.1执行了路由查找操作，输出结果显示该路由携带了下一跳地址192.168.1.6（是图7-14中的仅单播链路）。接下来，对该地址执行了RPF查找操作，查找结果返回了下一跳地址192.168.1.10（图7-14中的仅多播链路）。因而可以看出，按照地址的不同使用功能，同一个地址可以引用两条不同的链路。

例7-11：对172.16.227.1执行路由查找显示的下一跳为192.168.1.6，而对该地址执行 RPF查找显示的下一跳则是192.168.1.10。

最后需要强调的是，MBGP并不会影响多播流量的转发操作。对图7-14所示存在多条并行链路的应用环境来说，需要进行额外的配置来强制多播流量只通过仅多播链路进行转发，而MBGP的作用仅仅是允许RPF信息穿越AS边界进行分发。

7.6　案例研究：配置MSDP

图7-15再次显示了前一个案例研究中的路由器，此时的4台路由器都是各自自治系统的RP，图中还给出了它们的RP地址。

图7-15　在4台RP之间配置了MSDP会话

只要通过命令ip msdp peer指定对等体的IP地址即可启用MSDP，例7-12显示了图7-15中4台路由器的MSDP配置情况。

例7-12：在图7-15中的4台路由器之间配置MSDP会话。

Gorgo和Rodan、Kong与Megalon之间的对等关系很明显，因为它们之间只有一条链路连接到对方，因而直接在两个物理接口地址之间配置MSDP会话即可。但是Rodan与Megalon的对等会话却配置在环回地址之间，与IBGP对等一样，在环回接口之间配置MSDP会话能提供更好的弹性。当图7-15中Rodan与Megalon之间的链路出现故障时，如果这两台路由器之间还存在其他路径（图中未画出），那么该TCP会话仍然可以被重路由。默认情况下，携带MSDP会话的TCP包的源地址是发信路由器的物理接口，因而如果与不属于直连子网的地址建立对等会话，就需要使用选项connect-source来更改默认源地址。

例7-13使用命令show ip msdp peer显示了Megalon的两个MSDP会话的情况，给出了相应的连接状态、运行时间、已发送/已接收的消息等信息。

例7-13：命令show ip msdp peer显示了MSDP对等会话的状态。

例7-13还显示了为SA和SA Request消息配置的过滤信息，为了控制和定界MSDP的活动情况，可以使用某些过滤机制来完成以下功能。

•　控制被允许注册到RP的本地多播源；

•　控制RP向其MSDP对等体发送的SA消息或从其MSDP对等体接收到的SA消息；

•　控制RP向其对等体发送的SA Request消息或从其对等体接收到的SA Request消息。

大型MSDP应用环境的其他选项还包括为每个对等体添加描述及MSDP消息中的可配置 TTL值。例7-14给出了图7-15中路由器Megalon的更为复杂的配置文件。

注意：　例中所示配置仅用于示范目的，并不要求用作实际配置。

例7-14：更为复杂的MSDP配置。

如例7-12所示，首先利用两条语句为Rodan和Kong启用了MSDP。命令ip msdp decription为每个对等体的配置都加入了文本描述，这些描述信息总是紧随特定对等体的命令ip msdp peer之后，这对存在大量MSDP对等体的情况来说非常有用。

命令ip msdp cache-sa-state的作用是启用SA缓存功能，并且在上例配置中引用了一个可选的访问列表。access-list 101指定Megalon仅缓存源地址以10.254.0.0/16为起始的（S，G）对的SA消息，多播组地址为任意多播地址（224.0.0.0/3）。

为了降低加入等待时间，为每个对等体都配置了语句ip msdp sa-request，当路由器接收到关于某多播组的加入消息时，会向其两个邻居发送SA Request消息。如前所述，这里假定这两个邻居都被配置为缓存SA消息。

向Rodan（192.168.254.1）发送的SA Request消息被命令ip msdp filter-sa-request施加了进一步的限制条件。该过滤器引用了access-list 1，仅允许229.50.0.0/16，这样Megalon仅向Rodan请求多播组地址位于前缀229.50.0.0/16之内的多播源信息。

接下来，Megalon被配置为仅向可能的多播源子集（向其发送PIM-SM Register消息）发送SA消息，命令ip msdp redistribute引用了access-list 102，该访问列表又反过来允许多播源前缀192.168.224.0/24和多播组地址前缀224.0.0.0/3（所有多播组）。在RP的PIM-SM配置限制下，虽然所有的多播源都能注册到RP，但仅在SA消息中宣告前24个地址bit为192.168.224的多播源。

向MSDP对等体转发SA消息的操作受命令ip msdp sa-filter out的控制，该过滤器应用于所有SA消息（无论该消息是由本地发起的还是接收自其他MSDP对等体），而命令ip msdp redistribute仅应用于本地发起的SA消息。Megalon被配置了其中的两条语句，对邻居Rodan（192.168.254.1）来说，按照access-list 101的要求，仅转发来自源前缀10.254.0.0/16的SA消息。Megalon仅向Kong（192.168.1.9）转发access-list 103所允许的SA消息，该访问列表允许源前缀为172.16.0.0/16且组地址属于230.0.0.0/8或源前缀为192.168.224.0/24且向任意多播组发送多播包的SA消息。

可以利用ip msdp sa-filter in来过滤入站SA消息，使用了该命令之后，仅当（S，G）被access-list 101允许之后，Megalon才接收来自Kong的SA消息。请注意，该限制条件同样应用于发送给Rodan的出站SA消息。

最后，利用命令ip msdp ttl-threshold来控制MSDP消息的TTL值，发送给Rodan的消息的TTL被设置为5，而发送给Kong的消息的TTL被设置为2。

例7-15显示了上述配置的结果，与例7-13相比，可以看到变化后的文本描述、过滤器及TTL阈值。

例7-15：输出结果反应了Megalon的MSDP配置变化。

除了访问列表之外，可以将入站和出站SA过滤器链接到路由映射，以便实施更好的策略控制和策略应用。就像AS_PATH访问列表一样，也可以结合使用路由映射和MSDP重分发。

7.7　案例研究：MDSP网状多播组

在前面的案例研究中，路由器Rodan和Megalon都是同一AS中的RP，通常大规模多播域中都会有多个RP来分担相应的工作或将多播树局部化。虽然到目前为止MDSP都被描述为共享AS间多播源信息的工具，但是在单个多播域中存在多个RP且多播源总是注册到某些RP，当多播域中的成员必须发现任一多播源时，MSDP也非常有用。

从冗余性和健壮性的角度出发，域中的每个RP通常都会与域中的其他RP建立MSDP对等会话。图7-16给出了一个示例，图中的4个RP都位于同一个AS之中，并且每个RP都与其他3个RP建立了对等会话，这4台路由器之间可能是直连的，也可能不是直连的（可能在物理位置上相距较远）。

图7-16　4台路由器之间建立了全网状MSDP对等会话

例7-16给出了图7-16中4台路由器的配置情况。

例7-16：在图7-16中的4台路由器上配置MSDP。

如前所述，上述配置中的一个问题就是某台路由器生成的SA消息将被泛洪到其他所有路由器，从而导致大量的对等RPF泛洪失败并产生大量的MSDP通告消息。但是，如果每个RP都与其他RP建立了MSDP连接，那么就无需泛洪了，此时每个RP都只要从其直连的发起路由器接收一条SA消息即可。因此，为了解决泛洪问题，需要构建一个MSDP网状多播组。

如例7-16所示，MSDP网状多播组就是一组全网状连接的MSDP对等体，不会出现SA消息的转接现象。也就是说，RP从其对等体接收到SA消息之后，不会将该消息转发给其他任何对等体。

可以利用命令ip msdp mesh-group来配置MSDP网状多播组，其中的多播组可以是任意名称（因而在需要的时候，同一个RP可以属于多个网状多播组），同时需要在命令中指定网状多播组的组成员。如例7-17所示，图7-16中的RP被加入一个名为Boogeymen的网状多播组中。

例7-17：将图7-16中的RP加入网状多播组Boogeymen。

7.8　案例研究：任播RP

对地理区域分布辽阔的大型PIM-SM域的设计者来说，他们常常遇到的难题是如何最有效地放置RP。由于PIM-SM仅允许有一个group-to-RP映射，因而对大型多播源来说可能会引起以下问题。

•　可能的流量瓶颈；

•　缺乏可扩展的Register消息解封装（使用共享树时）；

•　活动RP失效后的故障倒换很慢；

•　可能存在多播包的次优转发行为；

•　依赖远程RP。

第5章和第6章曾经介绍过解决上述部分问题的一些解决方案，如用于PIMv2 Bootstrap协议的哈希算法以及Auto-RP过滤，但这些工具都无法提供一个完整的解决方案。任播（anycast）RP是一种可以将单个多播包映射到多个RP的方法，这些RP可以分布于整个多播域中，并且全部使用相同的RP地址，因而创建了一个”虚拟RP”，而MSDP则是创建虚拟 RP的基础。

注意：　通常来说，任播意味着可以将数据包发送给单个地址，而多台设备中的任一台设备都可以响应该地址。

图7-17中的路由器与前一个案例研究类似，但此时的4台路由器都在运行Auto-RP，并且都在宣告RP地址10.100.254.1。该多播域中的源DR知道只有一个RP地址，并注册到物理上最靠近的RP，这通常会导致PIM域的分区，但使用了MSDP网状多播组之后，任播RP就可以在多播组中交换源信息。

图7-17　4台路由器组成一个虚拟RP，宣告单个RP地址10.100.254.1，并使用MSDP来交换已注册到每台路由器的源信息

由每个任播RP的单播路由协议负责宣告公共RP地址，从多播源和组DR的角度来看，该地址上只有一个RP，但是有多条路由去往该地址。DR会从中选择最短路由，通过该路由可以去往最近的任播RP，如果此任播RP出现故障，单播路由协议会将去往该RP的路由宣告为不可行路由，此时DR将看到该不可行路由，从而选择次优路由。通过该路由可以去往次最近任播RP，因而RP的故障倒换被链接到单播路由协议，而且与单播路由的重收敛时间一样快。

虽然MSDP的对等关系建立在接口LO0之间，但却使用了其他环回接口来配置这些路由器所宣告的RP地址。通常情况下，MSDP在其SA消息中使用的是RP地址，由于这4台路由器都在宣告相同的RP地址，因而必须将MSDP配置为在其SA消息中使用一个惟一的地址，命令ip msdp originator-id就可以完成该要求。例7-18显示了这4台路由器使用网状多播组和ip msdp originator-id的相关配置。

例17-18：为Frankenstein、Wolfman、Mummy和Dracula配置任播RP。

在例7-18中，这4台路由器都被配置为Auto-RP C-RP和映射代理，也可以为任播RP使用静态映射或PIMv2 Bootstrap。此外，这4台路由器都被配置为缓存SA消息。

每台路由器都使用接口LO5来配置虚拟RP地址，而LO0则是MSDP会话的端点。需要注意的是，上述配置中的Auto-RP命令引用的是接口LO5，而命令ip msdp originator-id引用的则是接口LO0，这一点非常重要，因为MSDP要求其对等会话的端点必须使用惟一的IP地址。

上例中的OSPF和BGP配置出于一个非常重要的原因：前面说过，OSPF和BGP会将配置在环回接口上的最大IP地址作为其路由器ID，但不幸的是，这些路由器的接口LO5上的IP地址都大于接口LO0上的IP地址。因而每台路由器上的OSPF和BGP进程在默认情况下都会将10.100.254.1作为路由器ID，从而会产生大量的非期望结果，其中一种结果就是OSPF数据库将出现系统震荡（thrashing），这是因为每台路由器的LSA都试图覆盖其他路由器的LSA。一种解决方案就是总使用一个数值上小于所有环回地址的虚拟RP地址，但很明显这种方法不切实际，而且也很容易出现配置失误。本例使用了一种更好的解决方案，即在OSPF和BGP的配置中利用router-id来强制每台路由器都使用其惟一的LO0地址。

需要注意的是，这些路由器的接口LO0都没有运行PIM，这些接口都不需要PIM功能，只要为MSDP对等会话提供与路由器相关的IP地址即可。

7.9　案例研究：MSDP默认对等体

如果某AS是末梢（stub）AS或非转接（non-transit）AS，特别是如果该AS无多归属情况，那么几乎没有任何理由需要与其转接AS之间运行BGP。通常来说，只要在末梢AS中配置静态默认路由，在转接AS中配置指向末梢前缀的静态路由就足够了。但如果该末梢AS是一个多播域，且其RP必须与相邻域中的RP建立对等关系时该如何处理呢？在7.4.2小节中已经说过，MSDP需要依赖BGP下一跳数据库来进行其对等体RPF检查。

利用命令ip msdp default-peer就可以停用对BGP的依赖性，此时MSDP将从默认对等体接受所有的SA消息。图7-18给出了一个简单示例，图中的末梢AS通过单链路与转接AS建立对等关系，由于它们之间只有一条路径，不存在环路的可能性，因而无需进行RPF检查。

图7-18　通常不需要在末梢AS与其转接AS之间运行BGP，但这会给MSDP带来问题

例7-19给出了图7-18中2台路由器的MSDP配置情况。

例7-19：路由器Jason和Freddy的MSDP配置。

出于冗余性考虑，末梢AS也可能希望与多个RP建立MSDP对等关系（如图7-19所示）。由于没有RPF检查机制，因而不能同时从两个默认对等体接收SA消息，而只能从其中的一个对等体接收SA消息，当该对等体失效后，再从另一个对等体接收SA消息。当然，这里存在一个假设前提，那就是这两个对等体都在发送相同的SA消息。

图7-19　Jason被连接到多个默认的MSDP对等体

例7-20给出了Jason的配置情况。

例7-20：将Jason配置为同时与Freddy和Noeman建立冗余对等关系。

在正常情况下，活动的默认对等体就是配置中的第一个对等体，对本例来说就是 172.16.224.1，仅当172.16.224.1出现故障之后才会接收来自172.16.224.2的SA消息。

转接AS中的RP可能存在多个默认MSDP对等体（如图7-20所示）。由于只能接受来自某一个对等体的SA消息，因而如果像例7-20那样仅仅列出默认对等体是无法正常工作的。为此，一方面希望在缺少对等体RPF检查的情况下仍能提供环路避免功能，另一方面还要让RP接受来自多个对等体的SA消息，此时就需要使用BGP类型的前缀（BGP-style prefix）。之后RP就可以接受来自其所有默认对等体的SA消息，但仅限于每个对等体的关联前缀列表中所允许的源前缀。当然这里也存在一个假设前提，那就是每个AS使用的前缀都是截然分开的，这样就可以确保不会出现环路。

例7-21显示了Freddy的配置情况。

例7-21：让RP接收来自多个对等体的SA消息。

图7-20　转接AS中的RP有3个默认MSDP对等体

7.10　命令汇总

表7-6汇总了本章用到的所有命令。

7.11　附　注

1David Meyer，“RFC 2365:IP多播的管理性定界”（仍在发展中）。

2Tony Bates, Ravi Chandra、Dave Katz和Yakov Rekhter，“RFC 2283:BGP-4的多协议扩展”（仍在发展中）。

3Dino Farinacci等，“多播源发现协议（MSDP）”，draft-ietf-msdpspec-05.txt,2000年2月。

4Dorain Kim、David Meyer、Henry Kilmer和Dino Farinacci，“使用PIM和MSDP的任播RP机制”，draft-ietf-mboned-anycast-rp-05.txt,2000年1月。

7.12　展　望

到目前为止，已经花费了大量时间学习了IP路由的各种细节信息以及现代IP网络复杂度不断增大所带来的各种问题，这些问题的多数解决方案都是围绕着IPv4及其相关路由协议的局限性而展开的。下一章将展示为解决IPv4的不足而创建的最新IP协议版本——IPv6。大多数人在想到IPv6时，更多的是想到其拥有128bit的地址长度，能够彻底解决IPv4的地址限制问题。但将如你所见，IPv6所包含的内容远不止如此，它还具有更好的安全性、更好的AS间质量以及更好的多播支持能力，同时也从根本上解决了IPv4的很多不必要的复杂性。

7.13　复　习　题

附录D中提供了以下复习题的答案。

（1）在7.1节中给出了一个管理性定界的示例，接口E0上的边界阻塞了组织机构本地多播包（目的地址前缀与239.192.0.0/14相匹配的多播包），但允许全局范围的多播包，那么请问组地址224.0.0.50能够穿越该边界吗？

（2）Cisco IOS软件如何处理运行了PIM协议的点到点接口以及多路接入接口上的DVMRP Prune（剪除）消息？

（3）为什么Cisco IOS软件可以接收DVMRP Probe（探测）消息，但却不能发送该消息？

（4）什么是PIM（*，*，RP）表项？

（5）MBGP与普通的BGP之间有何区别？

（6）什么是MBGP AFI？

（7）MSDP携带了不同PIM域中RP之间的多播源和多播组成员信息。这种说法是否正确？

（8）MSDP的传送协议是什么？

（9）什么是MSDP SA消息？

（10）MSDP RP如何确定某SA消息是在RPF接口上接收到的？

（11）什么是SA缓存？

（12）在不启用SA缓存功能的情况下，有没有办法降低加入等待时间？

本章将主要讨论以下主题。

•　IPv6设计目的：本节将讨论IPv6的设计目的——提高扩展能力、简化配置以及提高安全性。

•　IPv6当前状态：本节将讨论当前各种可用的IPv6标准及草案。不但厂商已开始支持或已宣告支持IPv6，而且用户驱动的网络应用也开始加速IPv6的实现。

•　IPv6包格式：本节将介绍IPv6的包格式，包括现以让路由器更有效地处理数据包的大型层次化IPv6地址及头部。

•　IPv6功能：本节将介绍IPv6的各种功能，包括自动路由器发现、失效邻居检测、自动主机配置及多播能力。

•　从IPv4向IPv6迁移：IPv4仍将长期存在，本节将介绍各种IPv4向IPv6迁移并提供共存的机制（包括双栈、隧道和地址/协议转换机制）。

第8章
IPv6

IPv6是继IPv4之后的新一代IP协议，版本号5已被分配给其他Internet协议，即定义在RFC 1190中的Internet流协议（Internet Stream Protocol）版本II。虽然详细描述IPv6的全部组件已经超出了本书的写作范围，但本章仍将全面概括IPv6的设计目标和协议的当前状态。此外，本章还将介绍 IPv6的包格式、IPv6的功能以及IPv4互联网络向IPv6互联网络迁移的方法。由于本章列出的Cisco路由器配置均基于 IOS 12.0的测试版软件，因而某些命令可能会被修改、增加、删除，最终输出结果也可能不完全一样（虽然改动可能会比较小）。Cisco宣称将在Cisco IOS Software Release 12.1及以后的版本中推出正式的IPv6商用产品版本。

8.1　IPv6 设计目的

Internet的巨大成功得益于企业互联网络的几大成功，现在几乎没有哪家公司没有自己的Web站点（甚至在酒瓶的软木塞上也印制着URL）,电子邮件已经成为与电话一样重要的商业工具。但IPv4限制了Internet的进一步发展，其32bit的地址空间限制了全局可路由主机（可以连接到Internet上）的数量，也限制了可以创建的层次化数量。在本书的通篇描述中，读者可以看出可扩展的互联网络要求层次化的路由结构，必须严格维持层次化的路由结构，以便让网络能扩展到应用开发者和Internet用户现在所能想象的规模之外。为了维持层次化,要求连接到Internet上的站点必须遵守编址和汇聚规则。但是，连接到ISP或电话局的站点通常都必须使用ISP或电话局所分配的地址，并在站点内进行再次分配，这就意味着重新编号（第2章中提及的各种困难都不可避免）将仍然是一个问题。

Internet的成功也提高了数据完整性、真实性和机密性的需求。

IPv4的网络设计者们利用各种不同的技术解决了部分上述问题。如第4章中所讨论的那样，网络可以在内部使用私有地址，通过网络地址转换与Internet或其他企业网进行通信，从而在一定程度上减轻了地址空间的压力问题，允许大量的节点访问外部互联网络。但NAT的实施及维护并不总是很简单，某些应用程序会对NAT设备带来很严重的处理需求，而某些应用程序则根本就不支持NAT。此外，将来的Internet设备（如个人数字助理、家庭安全系统或汽车维护电脑）都可能需要全局可路由的地址，以便能够在任何Internet位置访问 Internet。

利用CIDR可以大大减轻因有类别地址而引起的严重的IPv4层次化问题（如第2章所述），CIDR提供了更为灵活的地址组合和分割能力，但整体的层次化能力仍然受限于32bit的地址空间。

IPv6可以提供足够的地址空间，足以满足快速增长的全局可路由地址的需求，并能提供更多的地址层次。IPv6的地址空间不但被增加到128bit,还将层次化要求设计到了全局可路由地址的格式之中。

ISP一般会给其客户分配一段地址区间，如果客户希望更换ISP，最可能的情况就是必须对其进行重新编址。IPv4网络设计者们为了简化为PC重新编址的工作量，在网络中实现了 DHCP（Dynamic Host Configuration Protocol,动态主机配置协议）。DHCP也可以工作于IPv6之中，并且很可能继续应用于IPv6之中，IPv6主机可以使用DHCP或内嵌的自动配置方法来配置自己的地址，这两种方法都能利用IPv6主机的能力，为新连接使用新地址，而为现有连接使用旧地址，利用这种同时维护两个地址的能力，可以顺利地迁移到新的网络前缀。

8.1.1　提高扩展能力

第2章中曾经介绍过IPv4地址是如何限制互联网络的扩展性的，本小节将扼要重述这些扩展性问题，第一个IPv4问题就是32bit地址空间，这也是设计一种新协议的主要源动力。学者们认为，如果不做任何改进工作，IPv4地址将在20世纪90年代被耗尽，但这一切并没有发生，是NAT技术（可以让企业使用隐藏于公共Internet之后的私有地址）延长了IPv4的使用寿命。IPv6的128bit地址空间允许将更多的全局可路由设备连接到Internet上，此外，IPv6也定义了私有地址空间。

IPv4的另一个问题是大规模的Internet路由表问题。为此引入了CIDR技术，通过地址聚合来提供更多的地址层次，从而实现路由表规模的最小化。但实际应用中很多地址都无法被聚合，如CIDR出现之前被分配的地址以及用于某些多归属Internet连接的地址都无法被聚合。

因为吸取了IPv4的经验教训，所以IPv6在设计之初就是要解决扩展性、易于配置性和安全性等问题，而不是要解决Internet路由表爆炸问题。不过，通过一开始就严格执行的地址分配规则和程序，并坚持用于地址聚合的层次化格式，完全可以将路由表的规模控制到可接受的大小。IPv6的目标就是要实现最大程度的地址聚合，而IPv6所定义的全局可路由地址空间的格式则完全可以实现该目标。

8.1.2　简化配置

IPv6引入了简化主机到路由器的通信管理以及主机配置的相应机制，这些机制也是IPv6走向成功的重要因素。随着越来越多的人、学校和商业机构希望连接到Internet或组建自己的互联网络，要求必须简化其中所包含的工作任务。并不是所有的人都希望成为CCIE,能够推算出如何运行一张网络，普通大众所期望的仅仅是让网络正常工作。IPv6提供了主机自动配置机制，可以让主机自动获得IP地址、发现邻居和默认路由，还可以使用多台默认路由器以实现冗余性。

连接到Internet上的大企业希望能灵活的变更服务提供商，而不至于给其网络带来混乱。虽然IPv6也需要进行重新编址，但IPv6下的重新编址工作变得很简单，因为IPv6可以在所有节点上维护多个地址，并且可以维护两种不同的地址状态——一种用于有效地址，而另一种则用于将要被淘汰的地址。此外，由于路由器向主机宣告网络前缀，因而主机可以自动配置自己的IPv6地址。企业因更换ISP而需要对其网络进行重新编址时，可以配置路由器，让其同时宣告新的网络前缀和旧的网络前缀。接收到路由器宣告后的主机可以自动用新的网络前缀信息来配置自己的IPv6地址，并且在新的IP连接完成后就开始使用新地址，而现有的连接将继续使用旧地址。

8.1.3　提高安全性

任何人、任何企业都不希望整天担忧网络安全问题，而是希望不用过多地考虑安全问题就可以保证其数据的安全性。为此，IPv6引入了验证和加密机制，从而可以让IPv6数据包在网络层安全地承载于网络协议中。

8.2　IPv6 当前状态

对绝大多数组织机构来说，在讨论网络技术时，IPv6只不过一组字母和数字而已。不过现在已经有很多IPv6规范都已定稿，其中有许多是IETF草案标准，更多的则是建议草案标准。IANA已经开始向RIR（Reginal Internet Register,地区Internet注册机构）分配IPv6地址空间，RIR也开始向ISP分配IPv6地址空间。越来越多的网络设备和终端设备厂商已开始发布支持IPv6的软件，或者发布将在近期支持IPv6的计划。已有的大型测试网络（6bone）也允许各大组织机构测试其IPv6实现情况、了解如何迁移他们的网络以及如何管理其网络。此外，还存在一个公众生产网络6REN,可以让研究机构和教育机构能随时部署其生产性IPv6网络。因而网络规划师们应该比以往更关注IPv6,因为IPv6已更加成熟，也更易于部署，准CCIE们也应该随时做好准备以应对IPv6。

8.2.1　IPv6 规范（RFC）

IPv6规范目前已经是被正式批准的Internet草案标准，许多厂商都依据该规范发布（或预发布）了大量IPv6产品。目前已有的草案标准有如下几种。

•　RFC 2373:IPv6编址体系架构。

•　RFC 2374：一种IPv6可聚合的全局单播地址格式。

•　RFC 2460:Internet协议版本6（IPv6）规范。

•　RFC 2461：IPv6的邻居发现。

•　RFC 2462:IPv6无状态地址自动配置。

•　RFC 2463:用于IPv6规范的IGMPv6。

还有许多IPv6正处于待批准的建议草案标准阶段，包括如下所示。

•　RFC 1886：扩展DNS以支持IPv6。

•　RFC 1887：一种IPv6单播地址分配体系架构。

•　RFC 1981：用于IPv6的路径MTU发现。

•　RFC 2080：用于IPv6的RIPng。

•　RFC 2473:IPv6规范中的通用包隧道机制。

•　RFC 2526：保留的IPv6子网任播地址。

•　RFC 2529：无显式隧道的情况下经IPv4域传送IPv6。

•　RFC 2545：利用BGP-4多协议扩展进行IPv6域间路由选择。

•　RFC 2710：用于IPv6的MLD（多播侦听者发现）。

•　RFC 2740：用于IPv6的OSPF。

实际上，还有许多其他建议草案标准和相关的草案文档，而且还有许多将在近期推出，因而全部列出是不可能的，读者可以在www.isi.edu或其他RFC储存站点找到这些RFC。

8.2.2　厂商支持情况

IPv6及其相关组件的协议开发在标准化进程中已经走过了很长的时间，各大厂商都实施了大量的开发和测试项目。Cisco路由器目前已经在基于IOS Release 12.1的测试版本中支持了IPv6,并宣布将在之后的IOS版本中全面支持IPv6。不过，并不是所有厂商都支持IPv6的全部组件，某些正在等待标准的进一步成熟，而某些则在投入大量研发资源之前等待来自用户的压力。由于即将到来的大规模应用（如手持无线计算机）可能需要IPv6,因而厂商至少要有计划能在短期内实现IPv6。目前Cisco的IPv6实现支持以下功能特性。

•　RIPv6;

•　用于IPv6的BGP-4+;

•　IPv6静态路由；

•　流量过滤；

•　自动和静态隧道；

•　EUI-64编址；

•　邻居发现；

•　在以太网、FDDI、Cisco HDLC和ATM PVC上运行IPv6;

•　Telnet、DNS和TFTP的双栈支持；

•　ICMPv6和Ping;

•　traceout命令和debug命令。

8.2.3　实现情况

目前存在两个公用的IPv6实现网络，一个是6bone，被用做IPv6问题的测试床，包括协议实现、IPv4大批IPv6的迁移以及操作规程在内的问题都在利用6bone网络进行测试。另一个网络是6REN（IPv6 Research and Education Networks,IPv6研究和教育网），为各组织结构提供可运行的IPv6网络，以转接到其他IPv6网络。这两个实现网络在IPv6的发展过程中起到了非常重要的作用，为厂商和网络架构师们提供了大规模的IPv6网络平台，可以进行软件测试、网络配置和设计，从而使IPv6被不断地理解和熟悉。

1. 6bone

6bone是一个全球性的IPv6网络,它为IPv6产品及网络的测试和预商用部署提供测试环境，目前已支持了39个国家的260个组织机构。6bone被设计为一个类似于全球性的层次化的IPv6网络，包括伪（pseudo）顶级（Tier I）转接提供商、伪次级（Tier II）转接提供商和伪站点级组织机构。由伪顶级提供商负责连接全球范围的组织机构，顶级提供商之间通过用于IPv6的BGP-4扩展来进行通信，次级提供商也通过BGP-4连接到区域性顶级提供商，站点级组织机构则连接到次级提供商。站点级组织机构可以通过默认路由或BGP-4连接到其提供商，最初的连接是将IPv6包以隧道方式封装在IPv4中经Internet进行传送，后来逐渐建立了纯IPv6连接。6bone已被证明是一个非常有帮助的IPv6标准和产品测试床，目前也被用于测试迁移方案和操作规程。

图8-1　给出了6bone的骨干网情况。

2. 6REN

出于非官方的协调目的，6REN作为一个生产性的IPv6网络，被设计用来提供转接IPv6服务，根据其Web站点www.6ren.net/overview.htm所述，6REN的目标是：

“……提供生产性的IPv6转接服务，以推动高质量、高性能和运行能力强壮的IPv6网络的发展。”

任何研究和教育机构以及赢利性或非赢利性组织机构都可以享受6REN提供的IPv6转接服务，以纯IPv6 over ATM的方式互联所有的网络。同样，6REN也可以为6bone的参与者提供IPv6网络的连接性。

8.3　IPv6 包格式

IPv6的包格式中包含大量层次化IPv6地址和头部，从而可以让路由器能够有效地处理数据包。IPv6的地址空间非常大，足以满足Internet的飞速增长要求并能提供更多的分级层次。

IPv6删除了部分IPv4头部字段，删除了选项（Options）字段，要求所有路由器都必须处理选项内容，从而提高了数据包的处理效率。IPv6仍然有网络选项，但是在大多数情况下，仅需要目的节点处理选项内容。IPv6将选项处理移到了扩展报头部，从而只有那些需要该信息的节点才会去处理这些选项。

本节将详细介绍IPv6地址的类型、用法、结构及IPv6的头部等内容。

8.3.1　IPv6 地址

20世纪70年代首次出现IP的时候，Internet世界与现在有着天壤之别，当时的Internet完全用于研究和教育目的，32bit的地址空间看起来绰绰有余（至少在IP的生命期内是如此）。，但Internet获得了令人无法想象的成功，IP被嵌入了绝大多数商业和家庭的运行之中，IP网络也成为许多极其成功的组织机构日常运行的一部分，随着组织机构的不断扩大以及希望连接到Internet上的站点数越来越多，人们越来越关心可扩展的IP网解决方案。由于大量的设备需要使用（或在不远的将来即将使用）IP地址来接入互联网络，即使NAT和CIDR等技术在一定程度上延长了IP地址的耗尽时间，但这一切还远远不够，包括移动电话、PDA、电子邮件设备、家用照明系统、汽车、公共仪表等在内的设备都将需要IP地址，IP的异常成功以远远超出了当初的设计意图。

IPv6地址解决了上述问题，不但增大了地址空间，定义了更多的地址层级，而且定义了地址分配的管制规则，以维护分层汇聚能力。

1. 地址空间

目前被广泛使用的地址空间到底应该多大才合适？地址空间应该是固定的还是可变的？地址空间过小会限制其扩展能力，但地址空间过大也会形成巨大的包头，使得路由器（和人们）难以管理这些地址。而可变长地址则会提高软件的复杂性、降低包处理速度。IPng（the next generation of IP,下一代IP）的一种建议就是使用NSAP（Network Service Access Point,网络服务接入点）地址，其地址长度在1〜20个8位组之间可变；另一种建议就是使用64bit的定长地址空间。虽然64bit地址空间看起来足以满足IP节点的编址需求，但需要增加更多的地址来解决因Internet规模急剧扩大而带来的额外复杂性，因而从将来的网络扩展和地址分配的层次化要求等角度考虑，最终选择128bit的地址空间。

理论上，128bit地址空间可以为340 282 366 920 938 463 463 374 607 431 768 211 456个节点分配地址，如果全球人口按100亿计算，那么每个人可以分得的IP地址数将达到约 3.4×10^27个.即便考虑到将来的快速发展，需要完全连接到Internet上的远程工作者，加上 Internet移动电话、IP手表、带有路由设备和公共仪表的家庭网络以及网络化汽车，都无法用完这么多的IP地址。

2.地址的文本表示方法

IPv6的地址长128bit,以用冒号“：”分隔的8个16bit片段来书写，每个片段以4个十六进制数字来表示。下面给出了两个IPv6地址示例。

•　FEDC:BA98:7654:3210:FEDC:BA98:7654:3210

•　1080:0000:0000:0000:0008:0800:200C:417A

这些地址都非常巨大，能够为大量节点提供编址能力。它们具备良好的层次化灵活性，但写起来很不方便，更别提记住这些地址了，因而提供了某些方法来压缩这些地址，以方便人们来处理这些地址。

任一个IPv6地址中都包含了很多的0,因而对任一个16bit字段来说，都可以删除其前导数字0,只要在每个字段中保留至少一个数字即可，但也有例外。上例中的第一个地址的所有16bit字段中都没有前导数字0,因而无法被压缩，而第二个地址则可以压缩为如下所示。

1080：0：0：0：8：800：200c：417A

还可以进一步压缩多个连续的0字段，这是每个字段都必须至少有一个数字的规则的例外情况。可以用两个冒号（：：）来代替多个连续的0字段，表8-1列举了一些地址压缩实例。

前导或尾部0字段都可以被压缩。请注意，：：只能代替一组连续的0字段，多个::则会给地址带来混乱。例如，1080::3245::200c:417A就是一个错误的地址写法，因为它没法提供两个8位组Ox3245正确位置的足够信息。

也可以用IPv6和IPv4混合的方式来表示IPv6地址，该表达方式包括多个以冒号分隔的 IPv6十六进制字段和一个以点号分隔的十进制IPv4地址，如下所示：

X:X:X:X:X:X:d.d.d.d

其中，X表示IPv6地址的十六进制数字，d.d.d.d以点分十进制记法表示了该地址的最后 32bit数字。表8-2给出了这种混合模式的地址格式示例。

这种混合的IPv6/ IPv4地址表达方式为IPv6和IPv4节点在同一个网络中的共存提供了方法。8.5节将详细讨论迁移和共存方法。

3. 地址前缀的文本表示方法

IPv6地址前缀的表示方法与IPv4 CIDR表示法相似，IPv6前缀的表示方法如下。

其中,IPv6-address是任何有效地址,prefix-length是组成前缀的连续bit数。

以下前缀都是56bit前缀200F00000000AB的合法文本表达形式。

•　200F::AB00:0:0:0:0/56

•　200F:0:0:AB00::/56

需要记住的是，对IPv6主机来说，每个地址表达式中最多只能出现一次：：。

而下面则是56bit前缀200F00000000AB的无效文本表达形式。

•　200F:0:0:AB/56

•　200F::AB00/56

•　200F::AB/56

由于第一个表达式丢弃了某个16bit字段中的尾部0,导致地址的长度无效，”/”左前方的IPv6地址应该是完整长度或压缩后的IPv6地址，因而该表达式无效。第二个和第三个表达式虽然都是有效的IPv6地址，但它们无法扩展为正确的IPv6地址，它们所代表的不是 200F:0000:0000:AB00:0000:0000:0000:0000,而分别是200F:0000:0000:0000:0000:0000:0000: AB00和200F:0000:0000:0000:0000:0000:0000:00AB。

4. 地址类型分配

在前面的CIDR中曾经介绍过，IPv4地址的类型由地址中的高阶bit来定义，分为A、B、 C、D和E类地址。地址类型标识了固定长度的网络地址和主机地址，地址所有者可以自由使用该地址，这也是IPv4地址中惟一定义的地址结构。而IPv6则定义了更多的地址结构，有关详细内容将在8.3.2小节中进行介绍。IPv6地址的类型由地址的高阶bit来定义，由这些 bit组成的变长字段被称为FP（Format Prefix,格式前缀）。表8-3列出了这些前缀的初始分配情况。

续表

目前,部分IPv6地址空间已被分配给可聚合全局可路由地址、本地应用地址和多播地址，已分配的地址空间约占15%左右。

某些地址空间被保留，目的是保留给将来NSAP和IPX路由实现使用，某些被保留的地址空间（特别是0x00）被用作专用地址，如环回地址和未指定地址（如下一小节所述）。

大部分IPv6地址空间仍未被分配，可以留给现有应用或其他新应用将来的扩展使用。

可聚合全局单播地址与全局可路由IPv4地址类似，它们被成块地分配给Internet服务提供商和交换中心，再由他们分配给商业用户和终端用户。该类型的IPv6地址定义了多级层次和聚合机制，虽然这部分地址是目前已分配的最大地址空间，但也仅占IPv6地址空间的1/8。

从表8-3可以看出多播地址均以0xEF为起始，其余地址均为单播地址。表8-4提供了IP地址类型的快速识别参考。

8.3.2　地址结构

IPv6的地址结构用于指派和分配，与IPv4一样，其包转发操作也是基于最长匹配前缀。单播地址可以是可聚合全局地址，也可以是链路本地地址、站点本地地址或专用格式地址。可以为 IPv6接口指派多个地址——单播、任播或多播地址。下面将逐一说明IPv6的地址结构类型。

1. 可聚合全局地址格式

可聚合全局地址用于连接公共Internet以及其他任何需要全局惟一和可路由功能的场合，该地址结构支持目前的基于提供商的聚合（provider-based aggregation）以及新的基于交换中心的聚合（exchange-based aggregation）。基于交换中心的聚合是将地址空间分配给交换中心，之后再细分地址空间并分配给其客户。这里所说的交换中心（exchange）就是第2章所说的NAP的另一个名称，是一台互联ISP和顶级服务提供商的二层交换机。可能需要在交换中心使用路由仲裁服务器来收集路由信息并在服务提供商之间提供一个对等点。不过基于交换中心的聚合有待进一步完善。通过这些聚合点，按照已定义的可聚合全局地址的格式就可以实现扩展Internet所需的层次化要求。有关层次化问题将在下一小节详细描述。

（1）层次化。

聚合地址按照公共（public）、站点（site）和接口（interface）3个层次进行组织。其中，公共拓扑包括服务提供商（提供公共Internet转接服务）和交换中心，由最顶级公共拓扑组成所谓的默认自由区（default-free zone）——Internet路由器的路由表中无默认路由表项，这些站点知道如何去往其他网络前缀。站点拓扑指的是不提供公共转接服务的本地站点或组织机构（虽然也可能提供某些更小规模的私有转接服务），而接口拓扑则用于标识网络上的接口。图8-2解释了可聚合地址的Internet寻址分层结构。

图8-2　Internet寻址分层结构

ISP1、ISP2、ISP3和ISP4表示公共空间，它们之间不但有直连链路，而且通过交换中心进行互联，而更小的ISP（P1和P2）及终端用户站点（S1〜S5）则构成站点空间。前面已定义的地址类型（将在后面详细讨论）即可反映上述Internet分层结构。

（2）地址格式。

图8-3显示了可聚合全局单播地址的格式。

图8-3　可聚合全局单播地址的格式

从图中可以看出，公共级字段包括FP、TLA、RES和NLA,SLA是站点级字段，而接口ID则是接口级字段。该类地址的网络部分占据前64位，后64位为地址的节点部分。可聚合全局单播地址的各字段定义如下。

•　FP：格式前缀（001）。

•　TLAID：顶级聚合标识符。

•　RES：保留给将来使用。

•　NLAID：次级聚合标识符。

•　SLA ID：站点级聚合标识符。

•　接口 ID:接口标识符。

格式前缀FP是二进制数001,用于标识可聚合全局单播地址，如图8-3所示，FP、TLA、 RES和NLA等字段构成公共拓扑，SLA ID构成站点拓扑，而接口ID是接口标识符。还可以对公共拓扑和站点拓扑做进一步的细分以创建更多的层次结构。FP、TLA、RES、NLA和 SLA等字段属于该类地址的网络部分，而接口ID是该类地址的节点部分。下面将详细讨论图8-3中所示的各字段信息。

①TLA ID。

TLA ID（Top-Level Aggregation Identifiers,顶级聚合标识符）是路由分层架构中的顶级字段。对默认自由区中的路由器来说，每个TLA ID都必须有一个路由表项，而且还可能有描述其自身拓扑的路由表项。TLA ID字段长13bit,如果需要多个TLA,那么还需要分配其他的FP,或者将TLA字段扩展到右侧的保留字段。

就像IANA（Internet Assigned Numbers Authority, Internet编号分配机构）给不同区域IP注册机构分配的地址区间一样，IPv6 TLA ID也会被分配给全球的区域IP注册机构，再由区域IP注册机构将TLA ID分配给大型ISP。通常来说，这些收到TLAID的大型ISP都是转接服务提供商和交换中心。

IANA初始分配的TLA是0x0001,然后将细分后的sub-TLA（子SLA）块分配给RIR,接着再由RIR将所分配到的sub-TLA块中的SLA分配给提供IPv6服务的组织机构——TLA注册机构。TLA 0x0001包括13个sub-TLA bit,紧接着是6个sub-TLA保留bit、13个NLA bit、16个SLA bit和64个接口ID bit。每个sub-TLA最初最多有13 bit NLA ID分配给NLA注册机构，组织机构完全分配完其NLA空间之后就可以申请新的地址空间。虽然每个 sub-TLA都会被保留给每个组织机构，但每次只为每个组织机构分配一个sub-TLA,如果某个组织机构需要多个sub-TLA，那么就需要提供足够的工程资料或配置计划以证明该要求的合理性。此外，还可以利用6个保留bit在一个sub-TLA中分配更多的地址空间。

例如，如果分配给ARIN的是2001:0400::/23，那么ARIN就可以分配2001:0400::/29〜 2001:05FF::/29之间的sub-TLA。但为了鼓励慢启动（slow-start）编址方案，通常RIR分配的都是带有35bit前缀的地址，如2001:0408::/35。实际上，sub-TLA是29bit加上6bit保留NLA空间。分配给VBNS的是2001:0408::/35, VBNS可以采用任何分配方法将13bitNLA空间分配给其用户，可以将2001:0408:0010::/40分配给一个小型ISP用户，之后该小型ISP可以将 2001:0408:0010::/48〜2001:0408:001F::/48分配给其用户。

②RES。

除了在前面所说的TLA 0x0001应用场合之外，暂时还未使用RES（resvered,保留）字段，该字段的所有bit都会被设置为0，将来使用时可以扩展TLA ID和NLA ID。

③ NLA ID。

获得TLA ID的组织机构可以利用NLA ID（Next-Level Aggregation Identifier,次级聚合标识符）来创建分层寻址结构并标识各个站点，从NLA空间接收到地址分配的组织机构被称为NLA注册机构。NLA IS有些类似于分配给顶级ISP的IPv4 CIDR地址块，之后会由该 ISP向其用户分配带有更长前缀的地址。

组织机构在向其用户分配地址空间时，如果该组织机构被分配了一个TLA，那么将有24bit NLA可用；如果该组织机构被分配的是一个sub-TLA,那么将有13bit NLA可用。其用户可以是ISP（NLA注册机构），也可以是终端用户。TLA注册机构可以使用高位NLA bit来创建地址层次结构，并将低位NLA bit分配给NLA注册机构，NLA注册机构将被分配足够的地址空间并为其自己的用户提供相应的地址。NLA注册机构可以分配的最小地址空间是 48bit前缀（/48）,此时该用户的子网编址方案应至少可以使用16bit SLA。虽然一个站点可以申请多个/48地址，但是用户必须提供其当前的地址部署统计情况以及工程资料或配置计划以证明其要求的合理性。

④SLA ID。

每个站点可以根据自己的需要在SLA ID（Site-Level Aggregation Identifier,站点级聚合标识符）内创建任意等级的分层地址结构，可以是无任何细分的平面编址方案，也可以将SLA ID进一步细分为多个子网，从而创建SLA ID地址的分层结构。

⑤接口ID。

接口 ID的作用是标识指定链路上的接口，对每条链路来说都是惟一的。所有高位bit在 001〜111之间的地址（不包括多播）都必须有EUI-64格式的接口ID,目前只有专用格式地址、NSAP分配的地址空间以及IPX分配的地址空间不在该范围之内。

EUI-64格式可以从接口MAC地址（如果有）衍生得到，只要在公司ID和节点ID之间插入FFFE,并将全体/本地bit设置为1以表示全局值，即可得到EUI-64格式（如图8-4所示）。

图8-4　MAC地址到EUI-64的转换

如图8-4所示，通过在MAC地址的公司ID之后插入FFFE,并将全体/本地bit设置为1之后，即可将MAC地址0000:0C0A:2C51转换为EUI-64地址0200:0CFF:FE0A:2C51。

2. 专用格式地址

某些地址使用专用格式,这些地址是从保留的FP 0x00中分配的,未指定地址（unspecified address）、环回地址（loopback address）和内嵌IPv4地址（embedded IPv4 address）都是专用格式地址。

（1）未指定地址。

未指定地址由全0组成，即0:0:0:0:0:0:0:0。永远不能将未指定地址分配给任何节点，实际上，未指定地址表示的是无地址。未指定地址的一种应用场合就是在初始化主机的源地址字段中，此时的主机还没有被分配任何有效地址。在任何情况下，都不能将未指定地址用作 IPv6包或IPv6路由头（routing header）的目的地址。

（2）环回地址。

环回地址是0: 0:0:0:0:0:0:1。该地址与IPv4的环回地址127.0.0.1类似，节点可以使用该地址向其自己发送IP包，不能将环回地址分配给物理接口，所有去往环回地址的流量都不会离开该流量发送节点。

（3）与IPv4兼容的IPv6地址。

从IPv4向IPv6迁移的一种转换机制是自动隧道技术，IPv6包会被自动封装到IPv4包中并经IPv4网络进行传送。该机制要求使用专用格式的IPv6地址，使用该技术的节点都运行在双栈模式（同时运行IPv4和IPv6协议栈）下，给支持自动隧道技术的IPv6/IPv4节点分配的IPv6地址，必须将IPv4地址内嵌在该IPv6地址的低32位中，其他bit均为0。这种类型的地址就被称为与IPv4兼容的IPv6地址（IPv4-compatible IPv6 addresses），其格式如下。

::d.d.d.d

其中，d.d.d.d是以点分十进制方式表示的IPv4地址。有关与IPv4兼容的IPv6地址以及自动隧道技术将在8.5节中做进一步论述。

3．本地使用地址

IPv6地址中有两类地址是本地有效的：链路本地地址仅对某个链路上的节点有效，站点本地地址仅对某个站点内的节点有效。这些地址都不是全球惟一的，它们只是在其作用域内具有惟一性。

（1）链路本地地址。

链路本地地址用于单条链路上的节点，自动配置（autoconfiguration）、邻居发现、无路由器链路上的节点以及路由协议都使用链路本地地址。路由器不能将源地址或目的地址是链路本地地址的数据包转发到该链路之外，因而对任何协议来说，如果希望将数据包发送给某链路上的设备，同时又希望该数据包不被路由到该链路之外，那么就可以在IP头中使用链路本地地址。链路本地地址的FP为1111111010，后面是54个0和接口ID，该类地址无TLA、 NLA或SLA信息，因而不存在任何分层结构信息，图8-5给出了链路本地地址的格式。

图8-5　链路本地地址格式

每个节点都会给每个有效IPv6接口分配一个链路本地地址，既可以利用自动配置机制来自动配置这些地址，也可以采取手工方式配置这些地址。

下面是一些链路本地地址的示例。

FE80::5ABC:01FF:FE01:1111

FE80::0060:08FF:FEB1:7EA2

FE80::200:CFF:FE0A:2C51

（2）站点本地地址。

一个站点就是一个组织机构或一个组织机构的一部分，它既可以是一个确定的拓扑位置，也可以是以某种方式互连起来的多个拓扑位置。对配置了站点本地地址的网络来说，无法从该站点之外的任何位置访问该站点，该站点的边缘路由器必须能将站点本地流量限制在本站点范围之内并负责控制路由的传播。除了站点本地FP以及接口ID之外，站点本地地址还有一个子网标识字段。但是需要注意，该类地址也没有TLA或NLA ID。这类地址仅被设计用于单个站点之内，因而不需要全局前缀，这类地址的使用方式类似于私有IPv4地址，都不是全球惟一的地址。建议在路由器接口上使用站点本地地址，而不是全局可聚合地址。

站点本地地址的FP为1111111011，后面是38个0和一个16bit子网字段以及一个64bit接口ID（如图8-6所示）。

图8-6站点本地地址格式

可以利用子网字段在站点内创建多个网络并创建本地范围内的分层结构，可以利用这种层次化能力在本地范围内实现地址聚合。请注意，不能将站点本地地址传播到站点边界之外。

下面是一些站点本地地址的示例。

FEC0::1:5ABC:1FF:FE01:1111

FEC0::CAB:60:8FF:FEB1:7EA2

（3）任播地址。

任播路由是一种对多个接口（通常是在不同的节点上）用同一个IP地址进行编址的机制，去往该地址的流量会被路由到最近的节点。有关任播的内容将在8. 4. 5小节做进一步讨论。任播地址的格式与单播地址的格式完全一样，并没有为任播地址定义特殊的FP。

任播地址是从单播地址空间分配的，事实上任播地址取自接口ID字段，目前已经预定义了Subnet-Router（子网路由器）任播地址，所有连接到某链路的路由器接口都要被分配该地址。该地址实质上就是接口标识符为全0的单播地址，图8-7给出了Subnet-Router任播地址的格式。

图8-7　Subnet-Router任播地址

Subnet-Router任播地址的一个例子就是以单播地址FEC0:0:0:A:200:CFF:FE0A:2C51在路由器接口上分配的FEC0:0:0:A::。

最高的128个接口ID被保留给已分配的子网任播地址，保留的子网任播地址是每个IPv6子网上可用的任播地址（而不管该地址前缀的类型或格式）。图8-8给出了保留的任播地址的结构。

如图8-8所示，保留的任播地址空间完全取自接口ID字段，每个IPv6子网都可以使用保留的任播地址，最高的128个接口ID被保留给任播地址使用，该类地址的最后7bit用于标识特殊的任播地址。

在写作本书的时候，惟一指定的任播地址就是移动IPv6家乡代理（mobile IPv6 home-agent），其任播标识符为二进制1111110。也就是说，每个IPv6子网中与EUI-64接口 ID FDFF: FFFF: FFFF: FFFE相关联的地址都被保留为移动IPv6家乡代理任播地址，前缀为FEC0:0:0:A::/64的移动IPv6家乡代理使用的任播地址为FEC0:0:0:A:FDFF:FFFF:FFFF:FFFE。

图8-8　　任播地址结构

其余的任播地址（十六进制值0〜7D和7F）被保留给将来使用。

由于无法从格式上区分任播地址与单播地址，因而必须在接口上显式配置其地址为任播地址。

（4）多播地址。

多播地址用于表示接口组，每个接口组都可以包含多个多播地址。由于多播地址总是以 0xFF开头，因而很容易与单播地址进行区分。在IPv6的网络层中没有广播机制，由于广播会给那些对广播包不感兴趣的节点带来大量的额外开销，接收到广播包的IP接口都必须进行处理以确定其是否是所期望的接收者，但大多数时候，这些节点都不是期望的接收者。每个 IPv6都知道其所属的多播组，这样一来，只有那些属于该多播组的接口才会去处理这些多播包。因而，IPv6不使用广播，而使用多播。

IPv6多播地址既可以由官方编址机构进行分配（周知地址），也可以采取临时分配方式（即本地分配用于非全局作用域），初始的IPv6多播地址分配基于已分配的IPv4多播地址，所有的相关IPv4多播地址都被转换为IPv6多播地址。读者可以参考RFC 2375以获取当前已分配的IPv6多播地址完整列表，随后的表8-6中列出了一些多播地址实例。

IPv6多播地址也被限定了作用域，该类地址有一个用于标识作用域（节点本地、链路本地、站点本地、组织机构本地或全局范围）的字段。在特定作用域内定义的临时地址（transient address）仅对该作用域内的节点有意义，同样的地址可以在不同的作用域内或不同的网络内重复定义，并且可以拥有完全不同的含义。

图8-9给出了多播地址的格式。

图8-9　多播地址格式

最前面的8位组11111111标识了该地址为多播地址。

其中各字段的定义如下。

•　figs（标记）：该字段有4bit，其中前3bit暂时保留并被设置为0，最后lbit表示该多播地址是由Internet编号机构永久分配的地址或不是永久分配的地址（即“临时”地址），值为0时表示该多播地址为周知地址，即是由全球Internet编号机构分配的地址。

•　scop（作用域）：该字段有4bit，用于限定多播地址的作用域，表8-5列出了各种作用域值。

无论是周知地址还是临时地址，都可能存在上述作用域值，给定作用域内的临时地址仅对该作用域有效，在其他作用域内则毫无意义。

•　组ID（Group ID）：用于标识给定作用域内的多播组——周知多播组或临时多播组。表8-6列出了一些常用多播组以及分配给它们的地址及作用域。

在接口初始化以及多播协议和多播应用初始化后，节点就会立即加入多播组。节点加入 FF01: : 1和FF02: : 1的所有节点（all-nodes）多播地址，从地址的格式可以看出，该地址属于周知地址，且分别是节点本地作用域和链路本地作用域地址。路由器则加入FF01: : 2、FF02: : 2，和FF05: : 2的所有路由器（all-routers）多播地址，这些地址也都是周知地址，且分别属于节点本地作用域、链路本地作用域和站点本地作用域地址。

从表8-6可以看出，能够运行于多个作用域之内的多播组拥有多个IPv6地址，这与周知 IPv4多播地址不同，它们没有被定界。第5章中曾经讨论过两种多播定界机制，TTL定界需要网络管理员在多播边界上设置TTL阈值，当多播包到达边界时，如果该多播包中的TTL值低于预设的阈值，那么将丢弃该多播包。这种方法的一个缺点就是缺乏灵活性，某个接口的TTL阈值会被应用于离开该接口的所有多播包，另一个缺点就是在大型网络中很难预测正确的TTL阈值。另一种IPv4多播定界方法就是管理性定界，即定义一个私有多播地址区间，以便在企业内部定义多播作用域，包括的地址区间是239. 0. 0. 0〜239. 255. 255. 255，建议定界区间是239. 255. 0. 0/16（用于本地或站点作用域）和239. 192. 0. 0/14（用于组织机构作用域）。这些仅仅是建议定界区间，企业可以根据需要自行使用这些地址。虽然管理性定界可能能够很好地工作于组织机构内部，但无法在全局作用域内使用，因为这些地址都是私有地址。

所有的IPv6多播地址都内嵌了多播定界机制，目前已经定义了5级作用域，对IPv4的 TTL定界来说，只要将所有链路本地多播包中的TTL值设置为1，即可得到链路本地作用域。其余的IPv6作用域可以为不同的多播定界策略提供工具，使用IPv6的多播应用可以被包含在链路、站点或组织机构内。多播地址中为将来的作用域保留了相应的地址。被限定作用域的周知多播地址可以在确保相同地址不被用于不同多播组的同时实现多播作用域定界功能。对两家公司来说，为两种不同的多播应用使用相同的多播地址毫无问题，但是当这两家公司今后要融合时就会出现地址冲突现象。

一种特殊的多播地址是“请求节点（solicited-node）”多播地址，各种IPv6功能都使用请求节点多播地址来与 IPv6节点进行通信，有关使用该地址的功能将在8. 4节中进行详细描述。除了链路本地地址之外，还为分配给接口的每个单播和任播地址创建并分配了请求节点多播地址。利用接口ID的最后24个bit并将其附加到前缀 FF02: 0: 0: 0: 0: 1: FF00: : /104之后，即可创建请求节点多播地址。图8-10解释了请求节点多播地址的构造过程。

图8-10　请求节点多播地址的构造过程

MAC地址为0000. 0C0A. 2C51的接口构成EUI-64接口ID: : 200: CFF: FE0A: 2C51，该接口 ID又创建了链路本地地址FE80: : 200: CFF: FE0A: 2C51。子网0上的站点本地前缀FEC0: : /64创建了站点本地地址FEC0: : 200: CFF: FE0A: 2C51，由于该接口上已经有了一个站点本地地址，因而可以构造一个请求节点多播地址，该请求节点多播地址从接口ID中取最后24bit（0A:2C51），并将其附加到请求节点前缀，即可构造出请求节点多播地址FF02::1:FF0A:2C51。

每个接口都可以拥有多个前缀以及多个与其相关的IPv6地址，对所有地址来说，其接口 ID很可能都是一样的，因而通过接口ID的最后24bit来创建请求节点多播地址可以最小化该节点必须加入的多播地址数。

4．节点所需要的地址

要求节点能够识别多种地址，为了保持正常工作，IPv6要求节点必须维护这些地址。有关每种地址的使用将结合特定的IPv6功能做进一步讨论。

要求主机能够识别以下地址。

•　每个接口的链路本地地址；

•　所有已分配的单播地址；

•　环回地址；

•　所有节点（all-nodes）多播地址；

•　关于每个已分配的单播地址和任播地址的请求节点多播地址；

•　该主机所属的其他多播组的多播地址。

除了上述地址之外，路由器还需要能够识别以下地址。

•　该路由器每个路由接口的子网路由器任播地址；

•　配置在该路由器上的其他任播地址；

•　所有路由器（all-routers）多播地址；

•　该路由器所属的其他多播组的多播地址。

表8-7总结了各种类型的地址情况。

8.3.3　IPv6 头部

IPv6的设计目标之一就是改善IPv4的头部，IPv6的头部更简洁、更灵活，而且在使用可选项时也更有效。IPv6头部删除了IPv4头部中的部分字段，并对其他字段进行了重新命名，其地址长度是IPv4的4倍，但其头部仅是IPv4头部的2倍。此外，IPv6头部可选项的编码方式做了更改，使得包处理更加有效，并且在大小和选项的增加上更为灵活。

1．头部格式

IPv6头部很简单，一共有8个字段，包括源地址和目的地址字段。图8-11给出了IPv6头部格式。

IPv6头部格式中的各字段信息定义如下。

•　版本（Version）：指示IP版本号（此处为6）。

•　净荷长度（Payload Length）：除去头部之外的IP包长度（以8位组为单位），扩展报头（将在后面讨论）属于净荷的一部分，因而也包含在该长度之内。

•　下一报头（Next Header）：标识紧随IPv6基本头部之后的报头类型的值，下一个报头既可以是上层报头（如ICMPv、TCP或UDP），也可能是一个IPv6扩展报头。

•　跳数限制（Hop limit）：被数据包所经过的每个节点所递减，跳数限制字段值为0时该数据包就要被丢弃。某些IPv6功能（如路由器宣告、邻居宣告和请求以及IPv6重定向）都只用于单条链路的两端设备，IPv6用于验证某数据包没有被发送到链路之外的节点（可能是某种恶意地对流量进行重定向）的技术要求将该字段设置为255（是跳数限制字段的最大值）。这是因为数据包穿越了路由器并由该链路外的节点发送而来，那么接收到的该数据包的跳数限制字段值必将小于255，这样一来，接收到该数据包的IPv6节点就知道该数据包无效并予以丢弃。

图8-11　IPv6头部格式

•　源地址/目的地址（Source Address/Destination Address）：该字段的长度均为128bit，其内容分别是128bit的IPv6源地址和目的地址。

流量类别和流标签字段将在8.4.7节进行描述。

图8-12列出了IPv4头部以作对比。可以看出，只有那些需要由路径中的每个IP节点处理的IPv4头部字段被保留在了IPv6头部中，由于其余字段所包含的信息对给定IP包来说可能相关也可能不相关，因而都被移至IPv6头部中的扩展报头。

图8-12　IPv4头部格式

2．扩展报头

IPv6基本头部中不含可选的网络层信息，这些可选信息被放置在IPv6基本头部与上层协议报头之间的独立报头中。在数据包的传送路径上，并不是每个节点都会处理扩展报头（但是有一个例外），只有IPv6基本头部中目的地址字段所标识的节点（或者多播目的地的节点）才处理这些扩展报头。由于不再需要每台IP路由器都处理那些可能仅针对目的节点的头部信息，因而可以大大提高选项的处理效率。不过逐跳选项头是一个例外，因为逐跳选项头中包含了分发路径上每台路由器都需要的信息。

（1）扩展报头次序。

通过检查前一个头部中的相关信息，节点就可以确定其是否要检查并处理扩展报头，因而在处理扩展报头时，需要按照它们在数据包中的出现次序依次处理。如果所有的扩展报头都出现在某个数据包中，那么它们的次序将如表8-8所示，该表显示了标识该扩展报头的 Next-Header值。表8-8中的扩展报头应该按照表中的顺序进行排列，但实际中也可能不完全如此（逐跳选项头除外，其必须紧随IPv6基本头部之后），无论接收顺序如何，节点都需要处理这些扩展报头。

需要注意的是，表8-8中出现了两次目的选项头，但这两个位置的目的选项头的含义是不同的。如果目的选项头出现在路由头之前，那么IPv6头部中目的地址字段中的第一个目的地以及路由头中列出的所有地址都要检查该头部；如果目的选项头出现在路由头之后或者没有路由头，那么只有该数据包的最后目的地才处理该目的选项头。图8-13解释了扩展报头的使用方式。

每个头部中的Next-Header值的作用是标识紧接在IPv6基本头部之后的报头的类型。在读取了IPv6基本头部之后，如果该处理节点不是最终的目的地，而且下一个报头也不是逐跳报头，那么将转发该数据包；如果该节点是最终的目的地，那么将按照所接收顺序逐一处理每个报头。

（2）选项

目前已定义的两个扩展报头（逐跳选项头和目的选项头）包含一个或多个TLV（Type- Length-Value，类型—长度—值）选项。这些选项包括一个指示数据在传送过程中是否可变的标记，这对认证头来说是有意义的，如果该数据可变，那么认证头在计算认证信息时必须将该字段视为全0。目前仅定义了Padl和PadN两个选项，这两个选项都被用来填充头部，以便让整个头部的长度成为8个8位组的整数倍。

（3）逐跳选项头。

在数据包向目的地分发的路径上，所有的路由器都必须处理逐跳选项头。逐跳选项头必须紧随IPv6基本头部之后，这就使得分发路径上的路由器只要处理该报头即可，而无需处理其他扩展报头。

图8-13　扩展报头的使用

（4）路由头。

列在路由头中的地址的作用是标识数据包在分发到目的地的路由中所必须经过的节点。IPv6基本头部中包含的是路由中的第一个节点，而路由头中包含的则是剩余节点的列表（包括最后一个节点）。

路由头中包含Next-Header（下一报头）、Length（长度）Type（类型）、Segments Left（剩余段）和Address（地址）等字段。其中，类型字段包含一个已定义值type 0，剩余段字段是已被明确列出、在到达目的地之前还要经过的节点的数量。

由IPv6头部中目的地址字段所标识的节点来处理路由头。该节点将检查路由头，如果发现所列节点还没有被访问，那么该处理节点将通过对比路由头所列全部节点数与剩余段的数量来标识下一个要访问的节点，下一个节点的地址将被放置在目的地址字段，并将剩余段字段值减1，然后再转发该数据包。

（5）分段头。

当IPv6源节点希望发送的数据包大于去往目的地所经路径的MTU时，就需要使用分段头。如果路径上所有链路的MTU均小于该数据包，那么就需要由源节点负责对该数据包进行分段。但路由器本身并不对IPv6包进行分段，而是由源节点将数据包分段后通过多个数据包进行发送，并在目的地重组这些分段数据包。源节点可以利用MTU路径发现进程来确定去往目的地的路径上的最小MTU，确定了最小MTU之后，源节点就知道了该路径所能传送的最大包尺寸。如果源节点没有运行MTU路径发现进程，那么将假设其所能使用的最大MTU是IPv6最小MTU（即1280字节），有关该进程的详细信息将在8. 4. 5节的“MTU路径发现”中进行介绍。数据包的所有分段都会被标记上一个由源节点生成的标识值。

（6）目的选项头。

对目的选项头所包含的选项来说，IPv6包的目的地都必须加以检查。如果目的选项头紧靠在路由头之前，那么路由头中所包含的每个节点都必须处理目的选项头中的选项；如果目的选项头紧靠在上层协议报头之前，那么只有最终目的地才处理目的选项头中的选项。

（7）认证头。

IPv6中增加了AH（Authentication Header，认证头），其目的是为IPv6包提供完整性检查和身份验证。在IP包向目的地传送过程中，所有不发生变化的字段都会被用来计算认证信息，对那些发生变化的字段或选项（如跳数限制字段）来说，在计算认证信息时都要被视为0。

（8）封装安全净荷头。

ESP（Encapsulating Security Payload，封装安全净荷）可以提供完整性和机密性机制，可以结合使用AH和ESP来提供认证机制。ESP对数据进行加密并将加密后的数据放置在ESP头部中的数据（Data）部分。加密模式分为隧道模式（Tunnel mode）和传送模式（Transport mode）两种。在隧道模式下，ESP头会对整个IPv6包进行加密，并将加密后的数据放置在加密字段中，之后将ESP头放在一个新的未加密的IPv6包中。在传送模式下，ESP仅加密传送层报文段（TCP、UDP、ICMP），并将加密后的数据放置在加密字段中，之后再放入原始数据包中（位于传送层协议报头之前）。

有关安全机制的问题已超出了本书的讨论范围，更多IPv6的安全信息请参考RFC 2401、 RFC 2402和RFC 2403。

8.4　IPv6 功能

对任何支持IPv6的节点来说，必须实现以下IPv6功能。

•　ICMPv6。

•　邻居发现。

•　无状态自动配置。

•　任播。

•　多播。

•　MTU路径发现（建议）。

这些都是IPv6的基本功能，其中大多数都是对IPv4的功能增强。

IPv6的另一个功能特性就是可以为任何接口分配多个地址。该功能简化了前缀重新编址的问题，不仅任意IPv6接口都可以拥有多个前缀的多个地址，同一个链路上的两个节点之间也可以进行直接通信（与这两个节点的地址前缀无关）。

本节将详细讨论上述功能，为了帮助理解IPv6的功能，本节还将给出具体的Cisco路由器配置及命令。

8.4.1　在 Cisco路由器上启用 IPv6 能力

默认情况下，Cisco路由器是禁用IPv6的，因而需要利用以下全局命令在Cisco路由器上启用IPv6。

ipv6 unicast-routing [table-count num]

Cisco路由器支持启用多路由表机制，在默认情况下仅启用一个路由表。多路由表可以为网络管理员在路由表查询方面提供更多的控制手段，最长匹配路由不再是惟一的路由查找规则，如果启用了多路由表，那么转发算法将以增量顺序来查找路由表，直至找到可用路由。

配置IPv6的下一步工作就是启用一个IPv6接口，并启用自动配置机制或为该接口手工配置一个IPv6地址，下面将讨论自动配置机制。

启用IPv6接口并为该接口配置IPv6地址的接口子命令如下。

ipv6 address ipv6address/prefix-length[link-local]

启用IPv6接口但不指定接口地址的接口子命令如下。

ipv6 enable

路由器会自动配置一个链路本地单播地址作为该IPv6接口的一部分。

路由器Falcon和Eagle都连接在同一条以太网链路上，它们的配置情况如例8-1所示。

例8-1：在连接到同一条以太网链路上的两台路由器上启用IPv6。

请注意，例8-1中两台路由器的配置完全相同。

显示接口的IPv6状态以及相关接口信息的命令如下。

show ipv6 interface interface-type number

例8-2显示了命令show ipv6 interface的部分输出结果，显示了以太网接口的MAC地址以及该接口的IPv6状态和链路本地地址。

例8-2：使用命令show ipv6 interface ethernet 0来查看IPv6接口的信息。

请注意，Falcon的MAC地址0000. 0C0A. 2C51创建了链路本地地址FE80: : 200: CFF: FE0A: 2C51, Eagle的MAC地址0000. 0C76. 5B7C创建了链路本地地址FE80: : 200: CFF: FE76:5B7C。此外，可以看出接口上已经启用了IPv6。

8.4.2　ICMPv6

ICMPv6是IPv6的一部分，每个实现了IPv6的节点都必须完全实现ICMPv6。ICMPv6是IPv4 ICMP的修改版本，差错报告以及许多IPv6功能（如MTU路径发现和邻居发现）都需要用到ICMPv6。本节将讨论差错消息。

ICMPv6包位于IPv6头部之后或某个扩展报头之后，由前一个报头中的IPv6下一报头值 58来标识（该值与IPv4中标识ICMP的值不同），通知消息和差错消息由ICMP类型字段中的高位bit加以标识。对差错消息来说，ICMP类型字段中的高位bit为0, ICMP差错消息中包含了尽可能多的不合规数据包，只要ICMP消息的长度不超过IPv6的最小MTU（即1 280字节）即可。

本小节将讨论以下差错消息。

•　目的地不可达；

•　包过大；

•　超时；

•　参数问题。

当节点因拥塞之外的某种原因不能转发数据包时将发送目的地不可达差错消息，该节点向数据包源发送的差错消息中包含以下内容。

•　没有去往目的地的路由（0）；

•　访问行为被管理性禁止（1）；

•　地址不可达（3）；

•　端口不可达（4）。

当数据包大小超过了链路MTU时，节点将发送包过大差错消息。与IPv4—样，IPv6中的路由器也不执行分段操作，只有源节点才对数据包进行分段，产生该差错的链路MTU将包含在该数据包中，无论IPv6目的地是单播目的地还是多播目的地，都会发送包过大消息。该消息将被用于MTU路径发现进程。

当IPv6跳数限制字段值减为0时，将会发送一条ICMP超时消息。通常来说，跳数限制为0则表明存在路由环路。

当节点发现IP头部或扩展报头有问题时，将发送ICMP参数问题消息，其中的差错代码可以标识所出现的问题。

•　出现了不正确的头部字段（0）；

•　出现了无法识别的下一报头类型（1）；

•　出现了无法识别的IPv6选项（2）。

8.4.3　邻居发现

ND（Neighbor Discovery，邻居发现）协议解决了很多与单一链路上的节点有关的问题，提供了无服务器的自动配置（Serverless Automatic Configuration）、路由器发现（Router Discovery）、前缀发现（Prefix discovery）、地址解析（Address Resolution）、邻居不可达检测（Neighbor Unreachability Detection）、链路MTU发现（Link MTU Discovery）、下一跳确定（Next-hop Determination）以及重复地址检测（Duplicate Address Detection）等功能。对IPv4来说，联合使用多种协议（包括DHCP、IGMP路由器发现、路由协议以及ARP等）才能提供上述功能中的部分功能，而ND仅利用ICMPv6即可完成上述功能。ND希望将这些功能全部整合到ICMPv6（IPv6的一个必需组件）中以改善IPv4的相关进程。

节点初始化之后，必须了解以下信息才能进行通信。

•　必须知道自己的IP地址；

•　必须知道自己的前缀信息，以便计算出如何向位于其他前缀的节点发送数据包；

•　必须知道该链路上的所有路由器；

•　必须知道如何确定去往目的地的路径上的下一跳；

•　必须知道如何获得与已知网络层地址相关联的链路级地址；

•　必须知道自己可以发送多大的数据包。

为了让通信更加顺畅，节点还应该了解以下信息。

•　在邻居不可达时应该有相应的检测机制，以便不再向该邻居发送数据包；

•　应该了解其链路上的邻居；

•　应该知道其试图使用的地址是否已被链路上的其他节点占用；

•　需要了解已分配给同一链路上其他节点的其他前缀；

•　应该能够将流量重定向到更好的下一跳节点（如果存在）。

ND定义了5种ICMPv6数据包，以在IPv6节点进行通信之前提供其必须知道和应该知道的信息。

•　RS（Router Solicitation，路由器请求）——当节点希望路由器立即发送路由器宣告而不是等待下一个预定宣告时，由该节点以多播方式发送该消息。初始化节点可以发送RS消息，这样就可以立刻了解配置参数以及链路上的路由器情况。

•　RA（Router Advertisement，路由器宣告）——周期性地发送该消息或作为RS的响应，路由器通过该消息宣告它们的存在并提供节点配置自己所需的信息。

•　NS（Neighbor Solicitation，邻居请求）——使得节点可以确定邻居的链路层地址或确定该邻居是否仍然可以通过已缓存的链路层地址到达，还能让节点确定链路上是否存在重复的IP地址。

•　NA（Neighbor Advertisement，邻居宣告）——作为NS的响应消息，或者在节点的链路层地址发生变化时主动发送该消息。

•　重定向——由路由器发出的消息，目的是将流量重定向到链路上更优的下一跳。

上述每条消息都是一个已定义类型的ICMP包，ICMP包中包含了与类型相关的信息，每种类型的消息都包含了一个或多个TLV选项。

ND 为无状态自动配置（即无配置服务器的自动配置）提供了基本条件，RA提供了节点配置所需的相关信息。有关自动配置的详细信息将在8.4.4小节讨论。

1．RS

如果主机希望立即接收到RA（而不用等待周期性宣告），那么就会发送RS消息，初始化主机通过发送RS可以立即学习到其所需的配置信息。

RS 消息是类型为133的ICMP包，其源地址是分配给发送主机的接口的地址，如果仍未分配地址，那么其源地址将是未指定地址0: 0: 0: 0: 0: 0: 0: 0，目的地址通常情况下是所有路由器（all-routers）地址。RS中也可以包含一个发送方链路层地址的选项，如果源地址是未指定地址，那么将不能包含链路层地址。

2．RA

路由器通过该消息宣告它们的存在并提供节点配置自己所需的信息，RA以多播方式被发送给链路作用域内的所有节点（all-nodes）多播组。

RA 消息是类型为134的ICMP包，其源地址是发送路由器的链路本地地址，目的地址是发送RS的节点的地址或链路作用域内的所有节点多播地址。跳数限制字段必须被设置为 255，这样一来就不再使用跳数限制来阻止路由器转发数据包。如果跳数限制值为1，那么就可以确保该数据包不再被转发，这是因为接收到该数据包的路由器会将跳数限制值减1，并在跳数限制值为0时丢弃该数据包；而跳数限制值为255则可以确保没有链路之外的设备试图发送RA以破坏流量流，这是因为如果链路之外的设备发送了RA，那么该RA每穿越一台路由器之后，其跳数限制值都将被自动减1，那么就表明该RA无效。接收节点验证该数据包是否有效的一种方法就是验证其跳数限制值是否为255，而IPv4则没有使用该方法来确保数据包没有穿越路由器。

接收RA消息的主机会构建一个默认路由器列表，所有宣告了RA且RA中的路由器生存期（Router Lifetime）值非0的路由器都将出现在默认路由器列表中。位于默认路由器列表中的路由器的路由器生存期值会被随后接收到的RA包所更新，如果某RA包含的路由器生存期值（是默认路由器列表中的某台路由器）为0，那么主机会立即从默认路由器列表中删除该路由器（这是对IPv4的一大改善），而IPv4主机则必须手工配置默认路由器列表。某些 IPv4主机通过路由协议（如RIP）来动态学习该信息，而某些IPv4主机则通过IRDP（ICMP Router Discovery Protocol, ICMP路由器发现协议）来学习这些信息，但并不是每台IPv4主机都实现了RIP或IRDP。

RA 中包含一个可达时间（Reachable Time）和一个重传定时器（Retransmit Timer）。其中，可达时间的作用是告诉主机从邻居接收到可达性确认之后多长时间可以认为该邻居有效，该信息被用于邻居不可达检测进程。重传定时器就是连续两条NS消息之间（以毫秒为单位）的间隔时间，被用于地址解析和邻居不可达检测进程。

RA 消息中包含两个用来告知主机如何配置自己的bit，一个是Mbit（Managed Address，被管地址），另一个是O bit（Other Stateful Configuration，其他状态化配置）。如果M bit被置位，主机将使用状态化自动配置协议（如DHCP）来配置自己的地址（除了无状态自动配置所配置的地址）；如果O bit被置位，则主机在使用状态化自动配置协议来配置地址之外，还用状态化自动配置协议来配置其他信息。IPv4则需要采用手工配置方式来表明是否通过 DHCP来学习它们的IP配置信息，通过RA消息自动向链路上的主机提供这方面信息可以最大化地减少主机中所包含的静态配置信息量，从而可以大大简化将来可能存在的重新配置工作。有关自动配置方法的详细描述请参见8.4.4小节。

RA 中的可能选项是源链路层地址、MTU以及前缀信息。在RA中包含路由器的源链路层地址可以让主机无需在默认路由器上执行地址解析协议，可以选举一台路由器不包含链路层地址。MTU选项的作用是集中控制主机在链路上所使用的MTU，该值在路由器中进行设置，然后在该链路上的所有主机上启用该配置。前缀信息的作用是向其他节点告知在链前缀（on-link prefix）信息并进行地址的自动配置。如果主机能了解链路上已配置的所有前缀信息，将大大提高其流量转发能力。多归属主机可以选择最近的接口去往任何已知的链路上的目的前缀，而非多归属主机则可以利用前缀列表来协助进行下一跳检测。

前缀信息选项中包含的数据可以用于在链决策（on-link determination）和无状态自动配置，不但包含了实际的前缀及前缀长度（1〜128bit之间）等信息，还包含了用来表示该前缀是否被用于在链决策或地址配置的指示bit。如果Lbit被置位，就表示可以使用该前缀进行在链决策；如果L bit未被置位，那么将无法确定在链（on-link）或离链（off-link）信息；如果A bit被置位，那么就表示可以利用该前缀进行无状态地址配置。

前缀信息选项中还包含了一个有效生存期（Valid Lifetime）值和一个优选生存期（Pref- erred Lifetime）值。有效生存期值（以秒为单位）表示该前缀用于在链决策的有效时间，该生存期相对于数据包被发送的时间而言，如果所宣告的有效生存期为0，那么表明该前缀不再有效。优选生存期（以秒为单位）表示的是从前缀信息中自动配置的地址能保持“优选”的时间，其中，接口的优选地址（preferred address）指的是任何节点都可以用其进行通信的地址。优选生存期为0表示必须贬抑从前缀信息中配置的地址，贬抑地址（deprecated address）指的是仅用于维护现有连接而不用于发起新连接（如果存在优选地址）的地址。如果生存期为全1，则表示无穷大，可以为在链决策和地址配置使用同一个前缀。有关这两类地址的详细情况将在8.4.4小节详述。

3．NS

NS 消息被用于获取邻居的链路层地址，并用来提供链路层地址、验证邻居的可达性。NS消息是类型为135的ICMP包，其源地址是请求节点（soliciting node）的链路本地地址，目的地址是被请求节点的多播地址（在链路层决策中与目标IP地址相关联）或单播地址（在可达性验证中与目标IP地址相关联）。NS的跳数限制值为255，与RA一样，跳数限制值255可以确保该数据包没有穿越路由器，因为一旦该数据包穿越了路由器，那么跳数限制值就必然小于255。此外，NS消息中还包含了一个指示目标地址的字段。

NS 消息中可以包含源链路层地址选项。如果NS试图发现一个目标链路层地址，将会在该链路上多播发送NS，因而该数据包中必须包含源链路层地址，从而最大程度地减少了该链路上的地址解析包。

4．NA

NA 作为NS的响应消息或者主动发送该消息以传播新信息（如节点的链路层地址发生变化）, NA消息是类型为136的ICMP包，其源地址是任何有效的分配给发送接口的单播地址。对所请求的宣告来说，目的地址是请求方的源地址，如果请求方的地址是未指定地址，那么目的地址将是所有节点（all-nodes）多播地址，主动宣告通常被发送给所有节点多播地址。NA包含一个S bit（Solicited flag，请求标记），当NA作为NS的响应消息时就置位该S bit。NA的跳数限制值为255，目标地址与来自请求方的目标地址相同，该地址就是链路层地址所定位的地址，对主动宣告来说，该地址是链路层地址发生变化的 IP地址。NA可以包含目标链路层地址选项，在所发送的主动宣告中向各节点告知宣告路由器的新链路层地址（新链路层地址就位于该选项中）。请求NA消息与IPv4 ARP应答消息类似，而主动NA则是IPv6的一个附加特性，通过将NA以多播方式发送给所有节点地址（目的是向其他节点告知链路层地址已发生变化），就可以取代IPv4网络上的大量 ARP请求和应答广播。

5．重定向

路由器通过发送重定向消息来告知主机存在一个更优的去往目的地的下一跳，该更优的下一跳可能是一台不同的路由器，也可能是目的地本身。如果目的地是源节点的一个邻居（即使源节点和目的节点属于不同的前缀），那么路由器就可以重定向流量以便进行直接通信（这一点是对IPv4 ICMP的增强）。当同一链路上存在其他可选路由器作为源主机去往目的主机或目的网络的更优路径时，IPv4路由器将发送ICMP重定向消息，但如果该更优下一跳是目的地本身，那么将不重定向流量。该功能特性可以让同一数据链路上拥有不同前缀的主机进行直接通信，而无需经过路由器。

重定向消息的源地址是路由器的链路本地地址，目的地址是被重定向数据包的源地址，跳数限制值为255。

ICMP包中也包含目标IP地址和目的地址，如果更优的第一跳是一台路由器，那么目标地址是该路由器的链路本地地址，如果更优的第一跳是实际的目的地，那么目标地址就是该目的地的地址。ICMP目的地址是被重定向的流量的目的IP地址，请注意，如果更优的第一跳是目的地本身，那么这两个字段所包含的地址完全相同。

重定向消息中可以包含目标链路层地址选项，其作用是让主机在不依赖地址解析进程的情况下发现链路层地址。

此外，导致生成重定向消息的IP包的一部分也可以作为可选项，重定向消息可以尽可能多地包含IP包的内容，只要重定向数据包的大小不超过1 280字节即可。

6．下一跳发现

主机在发送数据包之前必须首先确定其所要使用的下一跳，如果之前向该目的地发送了数据包，那么下一跳信息可能会存储在目的缓存中。如果这是发送给该目的地的第一个数据包，则需要将目的地址与该主机的在链前缀列表进行对比以找到下一跳。发送给在链目的地的数据包可以被直接发送到目的节点，而离链目的地则需要先发送给默认路由器。但是对IPv4节点来说，只要流量的目的地不在本子网之内，就需要发送到默认路由器。如果目的地与源位于同一条链路上，但属于不同的子网，那么路由器将会把流量转发回该链路，从而使得该流量需要穿越两次该链路。

无论下一跳是目的地本身还是默认路由器，都需要识别下一跳的链路层地址。

7．地址解析

节点执行地址解析进程的作用是寻找与已知IP地址相关联的链路层地址，地址解析进程使用NS和NA消息。在将数据包发送到目的IP地址之前，主机必须首先检查其邻居缓存，以确定是否已存在该表项，如果没有，那么该节点将会为该目的IP地址创建一条表项（状态为INCOMPLEMETE），之后该节点会向该IP地址的被请求节点（solicited-node）多播地址发送一条NS消息。该请求消息的源地址是单播地址（要么是发起该流量的节点的源地址，要么是在源节点的远程链路上查询目的地的路由器的源地址），而且数据包中可以包含源链路级地址（如果有的话）。

节点从某单播地址接收到NS消息之后（目的地是分配给其接口的地址），将响应NA消息，以指示其链路级地址。

当请求节点接收到响应NA消息之后，会以目标的链路级地址来更新其邻居缓存表项，并将该表项的状态从INCOMPLETE更改为REACHABLE。

注意：　有关各种不同反应的完整描述请参见RFC 2461_3。

8．邻居不可达检测

如果正与其他节点进行通信的某节点出现了故障，那么在上层协议之前检测到该故障并没有多大用处。但如果去往目的地的路径上的某台路由器出现了故障，由于可能还存在其他可用路由器，因而在上层协议之前检测到该故障将非常有用。

可以利用以下两种方法来验证邻居的可达性：通过来自上层协议的提示，或者通过NS的响应消息。如果某邻居可达，那么在转发方向上（forward-direction）就必然能进行通信，如果转发操作是由上层协议决定的，那么就可以验证邻居的可达性。例如，如果转发操作是在TCP连接中决定的（如收到数据发送后的新确认消息或收到作为发送确认响应的新数据），那么就可以验证邻居是可达的。如果转发操作是端到端决定的（也是由下一跳路由器决定的），那么就可以证实路由器的可达性。

某些上层协议并不提供类似的提示信息（如UDP通信），如果无法从上层协议收到相应的验证信息，那么节点会主动探查邻居以确定其可达性状态。节点会向已缓存的邻居链路层地址发送NS消息并等待NA消息，节点接收到NS消息之后会发送一条将S bit置位的NA消息。如果节点接收到一条S bit被置位的NA消息，那么就可以确认其邻居已经接收到其所发送的NS消息，因而表明转发方向上的通信正常。这些探查消息是随流量一起发送的，如果没有要发送给对端节点的流量，就不会向该节点发送探查消息。

邻居缓存中存储了邻居的相关信息，包括IP地址、链路层地址和可达性状态。表8-9列出了各种可能的可达性状态。

邻居缓存中的表项最初状态为INCOMPLETE，在学习到该表项的链路层地址之后，就验证了转发方向的通信。该表项的状态也将更改为REACHABLE，只要转发方向通信一直被验证，该表项的状态就一直处于REACHABLE状态。

如果没有从REACHABLE邻居接收到可达性信息，那么其状态将被更改为STALE。从某个节点接收到主动RA或NA消息之后，会在邻居缓存中加入一条INCOMPLETE表项，而该表项的状态会立即转变为STALE。请注意，主动宣告并不会提供任何有关转发通信的信息，在将流量发送给邻居之前，其表项将始终处于STALE状态。

一旦将数据包发送给了邻居，其状态就会更改为DELAY，并在邻居缓存中为该表项设置一个5秒定时器。该数据包将会被发送给已缓存的链路层地址（即使其状态为STALE），如果在接收到任何可达性验证之前定时器超时了，那么表项的状态将更改为PROBE；如果证实了邻居的可达性，那么该表项的状态将被更改为REACHABLE。

进入PEOBE状态之后，会向已缓存的邻居的链路层地址发送一条NS消息，如果没有收到响应消息，那么每秒钟都会发送请求消息（即便没有发送其他数据包）。如果在发送了3条请求消息之后的1秒钟内仍未收到响应消息，那么就会从该邻居缓存中删除该表项。

例8-3显示了命令debug ipv6 icmp和debug ipv6 nd的输出结果，以及状态从 INCOMPLETE变更为REACHABLE（经历了所有中间状态）的路由器邻居缓存。此外，例 8-3还显示了命令show ipv6 neighbor的输出结果（该命令的作用是显示邻居缓存），命令show ipv6 neighbor的输出结果中提供了IPv6地址、寿命（Age）、链路层地址（如果知道的话）、状态以及接口（通过该接口了解到邻居）等信息。

例8-3：命令debug的输出结果显示了邻居可达性状态的变更过程。

路由器Falcon从Eagle的链路本地地址FE80::200: CFF: FE76: 5B7C接收了一条RA消息，之后Falcon的邻居缓存中就创建了一条INCOMPLETE表项，该表项的状态将立即转换为 STALE（因为 RA 是主动消息），此时对邻居缓存进行查询，可以发现该地址的状态确实为 STALE。Eagle的链路层地址是已知的。

几分钟之后，Eagle向Falcon发送了ping（如接收到的回应请求所示）, Falcon通过向已存储的链路层地址发送回应响应来应答Eagle，但是由于数据包被路由器发送给了STALE表项，因而该路由器必须将状态更改为DEALY，以查看其是否能验证转发方向的通信路径。由于该路由器无法通过ICMP包来加以验证，因而将状态更改为PROBE并发送NS消息，以便通过探查Eagle来确定是否能得到可达性验证，Eagle会回应NA消息，debug命令并没有显示NA消息中的S bit被置位。在接收到NA消息并验证了通信路径之后，Falcon会将Eagle的表项状态更改为REACHABLE。

利用邻居不可达检测进程，可以让主机在默认路由器失效的情况下将流量重定向到其他可选路由器，主机在检测到默认路由器故障后会选择另一台路由器来转发流量，这一切都可以在上层协议或上层应用超时之前完成。而IPv4主机则可能从来都不会检测到默认路由器出现故障，在路由器出现故障的情况下，上层协议或上层应用则将会超时。IPv4主机很可能会试图使用该停用路由器来重建连接，这是因为某些IPv4主机可能会知道多台默认路由器，从而可以利用第二台路由器来重建该连接。

9．默认路由器选择

当目的地位于链路之外并且主机中没有关于该目的地的缓存表项或现有默认路由器看起来似乎已失效时，主机都会从其默认路由器列表中选择一台路由器（可能从很多台路由器中选择）。通常在第一次向某特定目的地发送流量时需要选择一台默认路由器，主机将缓存该信息并用于随后的流量。

默认路由器选择进程使用默认路由器列表和邻居缓存，任何非不可达路由器（也就是说，这些路由器不处于INCOMPLETE状态）在成为默认路由器时都拥有相应的优先级。如果有多台路由器都处于INCOMPLETE之外的其他状态，那么默认路由器选择进程将得到同样的路由器或以循环方式从默认路由器列表中得到路由器（这与实现方式有关）。

如果下一跳路由器看起来似乎已失效，邻居不可达检测进程将会加以检测；如果该路由器确实已失效，那么将会从邻居缓存中删除该路由器表项，接着再次执行下一跳检测和地址解析操作，并使用其他可用的下一跳路由器。

案例研究：默认路由器失效和通信恢复，如下所示。

某主机利用FTP从远程服务器传送一个文件，该主机向其在链默认路由器发送流量，由于该主机能够连续接收到所发送数据的ACK消息，因而主机确认其默认路由器可达。但是在会话中间该默认路由器出现了故障，那么该主机将无法接收到ACK，也就无法再从来自TCP层的提示信息中验证转发方向通信了，因而将该路由器的状态更改为STALE。由于此时仍在试图发送数据包，因而状态被接着更改为DELAY，但5秒钟之后该主机仍未接收到有关该路由器可达性状态的肯定证实消息，因而又将该路由器的状态更改为 PROBE并发送NS消息，由于该路由器无法做出响应，因而该主机将从邻居缓存中删除该路由器。

此时的主机仍在试图发送数据包，但由于没有去往目的地的下一跳表项，因而该主机将查看目的地前缀，了解到该目的地位于链路之外，接着从其已存储的默认路由器列表中选择一台默认路由器，并将该路由器（状态为INCOMPLETE）放在其邻居缓存中。如果不存在该表项，那么就需要通过发送NS消息来解析其链路层地址。当接收到该新路由器响应的NA消息之后，就可以证实该路由器的可达性，接下来就可以通过这台新路由器来转发流量了。

10．重复地址检测

所有节点在给接口分配单播地址时都要执行重复地址检测进程，但不需要对任播地址执行该操作。需要注意的是，无论该地址是通过无状态配置、状态化配置还是手工配置的，都要执行重复地址检测操作，需要在将地址分配给接口之前以及接口初始化时进行该操作。在执行重复地址检测进程的过程中，将所要分配给接口的地址称为“不确定地址”。

在发送请求消息之前，该接口会加入所有节点多播组，以确保该节点能够从任何正在使用该地址的节点接è到NA消息，并加入关于该不确定地址的请求节点多播组，以确保是否有其他节点正在使用该地址，这两个节点都将知道对方的存在。

节点向外发送NS消息，将不确定地址作为目标地址。源地址是未指定地址，目的地址是该不确定地址的请求节点多播地址，默认情况下只发送一条请求消息。

任何已分配了该地址的邻居在接收到请求消息之后，都会发送一条NA消息作为应答，宣告消息中的目标地址就是该不确定地址，目的地址是该不确定地址的请求节点地址。如果节点接收到该NA消息，且目标地址是该接口的不确定地址，那么就表明该地址是重复地址，不能分配给该接口。某些IPv4主机在将IP地址分配给接口之前也会执行重复地址检测进程，但并不是所有的IPv4主机都会执行该进程，因而存在接口使用重复地址的可能性，从而对现有流量流造成破坏。

8.4.4　自动配置

由于网络的可管理性是网络成功的关键因素，因而IPv6协议必须内嵌相应的进程机制。如果网络中的主机采取静态配置方式（以手工方式输入），那么在发生变更时将难以管理。虽然IPv4网络中有许多简化管理工作的工具（如DHCP可以大大简化静态配置的工作量），但这一切并不是IPv4协议的必需组件。而IPv6节点则可以对自己进行自动配置（有无DHCP服务器均可），从而使得主机配置变更操作变得非常简单。

RA消息被用来告诉主机如何配置自己。RA消息中包含了两个bit，其作用是告诉主机是否使用配置服务器的bit，如果需要使用配置服务器，则告诉主机是否从该配置服务器获取除地址之外的其他信息。如果M bit（Managed Address Configuration，被管地址配置）被置位，那么主机将使用状态化地址配置协议（如DHCP）来配置其地址，其实主机也可以进行无状态的地址自动配置。O bit（Other Stateful Configuration，其他状态配置）的作用是让主机使用状态化配置协议来配置除地址之外的其他信息。与此相对，在IPv4中，若要自动获取IP地址和其他配置信息，就需要静态配置IPv4主机使用指定DHCP服务器，否则就需要全部采取手工方式输入配置信息。

1．无状态自动配置

只要知道了节点所了解的信息（其接口标识符）以及路由器所了解的信息（分配给链路的前缀），该节点就可以配置其IP地址，而无需服务器来建立基本的IP连接性，这对所有支持多播的接口上都是可行的。

接口初始化之后，节点就会立即为该接口生成一个链路本地地址。该链路本地地址就是级联了周知链路本地前缀FE80: :的接口标识符，以接口ID来代替链路本地地址最右边的0即可构成128bit地址。请注意，接口ID通常为64bit（但并不始终如此）。

链路本地地址FE80: 0: 0: 0: 200: CFF: FE0A. 2C51的链路本地前缀和接口ID分别为 FE80:0:0:0:0:0:0:0和200:CFF:FE0A.2C51。

如果接口ID的长度超过了118bit，那么将无法附加链路本地FP（其长度为10bit），也就无法进行自动配置，此时就需要进行手工配置。

节点并不会立即将所生成的链路本地地址分配给接口，而是首先确定是否存在重复地址，即发起重复地址检测进程。

如果节点发现其所生成的地址并不是惟一的，那么就必须进行手工配置。一种配置方式是为该节点配置一个替代接口ID，此时该节点仍然可以参与到无状态自动配置进程中，并自动配置其所需的每个地址以及任何已分配的单播和多播地址。另一种可选的接口ID配置方式就是在接口上手工配置IPv6地址，但这种方式将会带来大量的管理性工作量。

如果该节点没有发现重复地址，那么就会将该地址分配给该接口。

此时就建立了基本的IP连接性，同一条链路（无路由器）上的IPv6主机之间就可以进行相互通信了。如果只需要进行这种通信，那么就不需要在主机上手工配置网络层信息。

例8-4给出了Falcon和Eagle的最小基本配置。

例8-4：Falcon和Eagle进行IPv6通信的最小基本配置。

从Eagle向Falcon的链路本地地址进行ping操作，可以看出，可以进行通信（如例8-5输出结果所示）。

例8-5：通过Falcon的链路本地地址来验证Falcon与Eagle之间的通信。

为了启用基本的IP连接性，路由器和主机都要执行前面所讨论的无状态自动配置进程中的所有步骤，每个接口都必须创建一个链路本地地址。除了下面各段将要讨论的例外情况之外，在将单播地址分配给每个接口之前都要进行重复地址检测操作（而不论该IPv6地址是通过无状态自动配置、状态化自动配置或是手工配置）。

主机（不是路由器）继续自动配置进程。主机发送一条“所有路由器”多播请求以发现链路上的路由器，所有路由器都会响应以 RA 消息。RA 消息可能告诉主机使用状态化自动配置来配置地址和其他信息，主机使用被标记为地址配置的前缀信息来创建站点本地地址，为了创建一个站点本地地址，需要将站点本地FP、前缀和接口ID级联在一起。主机在分配其站点本地地址时无需执行重复地址检测进程，其理论基础是该进程只是被用来验证链路本地地址的惟一性，这就意味着对链路来说，接口标识符是惟一的。由于站点本地地址为相同的接口标识符分配了不同的前缀，因而站点本地地址也是惟一的。利用同样的方法也可以生成和分配全局可聚合地址。

RA 消息还提供了在链前缀信息，该信息是一个前缀及前缀长度列表（被标记为在链前缀），主机利用该信息来构造其前缀列表。主机使用前缀列表来确定目的节点是在链节点还是离链节点，进而确定是否需要使用默认路由器来发送流量。

主机还可以根据RA中的信息来配置其MTU大小。

需要采取状态化自动配置方式来配置其他信息（如DNS服务器）。

利用下列接口子命令可以配置路由器宣告携带指定值的前缀、设置被管配置标记（managed-confíg-flag）以及其他配置标记（other-config-flag）。

ipv6 nd prefix-advertisement 2001: ABAB: : /48 3000 3000 onlink autoconfig
ipv6 nd managed-config-flag
ipv6 nd other-config-flag

可以看出，被宣告前缀2001: ABAB: : /48携带的有效生存期为3 000秒，优选生存期为3 000秒（被用作在链宣告和自动配置）。

节点上的每个接口都要执行自动配置进程（无论在什么时候启用接口），多归属节点会在每个接口上独立执行自动配置进程。在下列情形下将会启用接口。

•　系统启动时的接口初始化；

•　接口失效或被系统管理员临时禁用后又被重新启用；

•　接口第一次连接到链路上；

•　接口被管理性关闭之后又被启用。

2．状态化自动配置

状态化自动配置可以与无状态自动配置联合使用。DHCP为IPv4提供了状态化自动配置，用于IPv6的改进型DHCP可以充分利用IPv6的各种功能特性，从而大大增强了DHCP的能力。

注意：　动态主机配置（Dynamic Host Configuration）工作组已经发布了题为“draft-ietf- dhc-dhcpv6-15.tx”的用于IPv6的DHCP草案。

配置服务器可以向请求主机分配地址和其他信息（如DNS服务器地址）。与用于无状态自动配置的前缀一样，这些地址也都有相关联的有效生存期和优选生存期，如果服务器能够要求所有主机重新验证分配给它们的地址，那么就可以利用生存期值对网络进行重新编号。

3．重新编号

虽然IPv6的地址数量极其丰富，但站点重新编号也是在所难免的。虽然可以严格维护地址前缀，但是可能需要偶尔召回分配给某个站点的地址，或者某站点希望更换ISP，而该ISP要求更该前缀，这一点与目前IPv4网络中用户更换ISP—样。不过，IPv6虽然并不能消除该现象，但却可以让重新编号工作变得相当简单。

地址的状态有优选（preferred）状态和贬抑（deprecated）状态。主机总是试图使用优选地址来进行通信，只是当使用优选地址会破坏现有连接时才将贬抑地址作为源地址。例如，如果两台主机使用优选地址建立了TCP连接，并且其中的某台主机的地址变成了贬抑地址，如果该主机切换到一个新的优选地址，那么该连接将失效。

通过使用优选地址和贬抑地址可以大大简化主机重新编号工作。可以在RA消息中设置和修改地址保持优选状态的时间，该消息会周期性地在链路上发送，而且链路上的每个节点都会处理该消息，因而只要将新前缀添加到RA消息中，就可以为接口增加新地址，并将原先的地址变为贬抑状态并予以删除。同样，也可以利用配置服务器来对主机进行重新编号，配置服务器可以向所有节点多播一条请求，要求大家重新确认分配给它们的地址，主机将查询配置服务器并获取生存期已更改的地址，贬抑现有地址或重新分配新的优选地址。这种重新编号机制的健壮性依赖于到达链路上所有主机的RA消息和状态消息。下面看一下RFC 2641中给出的案例研究。

案例研究：对网络进行重新编号，如下所示。

假设宣告了一个生存期为2个月的前缀，8月1日决定更改该前缀，并且从9月1日起不再使用该前缀。可以更改前缀宣告以使其生存期为2周，随着日期不断接近9月1日而不断减小生存期，直至将该前缀的生存期宣告为0，从而使得该地址无效。但是，如果某主机在7月31日与网络断开连接，在9月1日又重新接入网络，那么该主机将认为旧前缀在9月30日之前仍是有效前缀。强制主机不再使用之前宣告的生存期很长的前缀的惟一方法就是发送一条生存期较短的RA消息，因而要求路由器在10月1日之前持续发送生存期值为0的 RA消息，以确保在变更地址之前与网络断开连接，在2个月生存期到期之前又重新连接到网络上的主机使用无效前缀。

通常来说，路由器应该持续发送生存期值为0的RA消息，发送时间周期应该是确保任何主机在断开连接之后再次连接到网络上时不会使用旧前缀。请注意，如果路由器将前缀的生存期宣告为无穷大，那么在对链路进行重新编号以及主机频繁地建立/断开与网络的连接时将会出现问题。

若要保持通信不中断，就需要做大量的规划工作才能对路由器进行重新编号。路由器之间需要相互通信，主机也要通过路由器的链路本地地址与路由器进行通信，该通信与任何所分配的前缀都无关，因而无论分配给该链路的全局地址是什么，节点都能继续与路由器的链路本地地址进行通信。

对DNS来说，IPv6与IPv4下的重新编号工作都是一样的，要么在新地址可用之前利用手工方式将新地址输入到DNS数据库中，要么就实现DDNS（dynamically updated DNS，动态更新的DNS）服务器。

8.4.5　路由

前面的章节讨论了IPv6节点如何发现将数据包转发给邻居和下一跳路由器（如果目的地不在链路上）所需的信息，本小节将讨论IPv6的路由问题，以说明如何在大型网络中路由IPv6包。

1．MTU路径发现

IPv6网络要求每条链路上的MTU最小为1 280字节，但建议大小为1 500字节或更大，任何无法处理这样大小的数据包的链路都必须提供链路级的分段功能。只有源节点才执行IP级的分段操作，数据包传送路径上的路由器则不执行IP级的分段操作。虽然并不强制要求所有节点都实现MTU路径发现机制，但建议如此。没有实现MTU路径发现机制的节点所能使用的MTU等于最小IPv6 MTU，即1280字节，而实现了MTU路径发现机制的源节点则可以使用最大可能的数据包，从而可能获得更高的性能。路径发现可以用于单播目的地和多播目的地。

MTU路径发现机制使用ICMP Packet Too Big（ICMP包过大）差错消息。发送流量的节点初始假定PMTU（path MTU，路径MTU）等于其所连接链路的MTU，数据包分发路径上的任何节点如果检测到其无法按照该MTU发送数据包，则发送一条包含了其链路MTU大小的ICMP Packet Too Big差错消息，并丢弃该超大数据包，接收到该差错消息的源节点会将所要发送的数据包大小减小为该差错消息中所包含的MTU值。该进程会一直持续下去，直至整个分发路径上的所有节点都协商一致。图8-14给出了PMTU的发现过程。

图8-14　PMTU发现进程

如图8-14所示，连接在令牌环上的PC开始发送的数据包大小为4 500字节，当数据包到达位于分发路径上的某台路由器（其链路MTU为1 500字节）时，该路由器将会发送ICMP Packet Too Big差错消息（包含其MTU值1500字节），并丢弃该数据包；之后，该PC创建更小的数据包（大小为1 500字节），第一台路由器会予以通行，但去往分发路径的下一台路由器的链路MTU值为1280字节，那么该路由器将发送一条ICMP Packet Too Big差错消息（包含其MTU值1280字节），并丢弃该数据包；之后，该主机将进一步减小数据包的大小（为 1280字节），从而可以确保该数据包能穿越这两台路由器。

与单播目的地址一样，MTU路径发现机制也可以用于多播目的地址。多播包会同时进入多条路径，这些路径上的所有节点都可以发送ICMP Packet Too Big差错消息，PMTU的最小值将决定源节点所发送的数据包大小。

2．RIPng

RIPng（其中的ng表示“next generation”，即“下一代”）基于RIP-2，它没有改变RIP-2的任何可操作进程、定时器或稳定功能，而只是对RIP-2做了一定的修改，以支持更多的IP地址以及每个IPv6接口的多地址功能。用于RIPng的UDP端口号为521, RIPng不能同时支持IPv4和IPv6，因而不与RIP-2后向兼容。

注意：　有关RIP-2的详细信息请参见《TCP/IP路由技术（第一卷）》第7章。

图8-15给出了RIPng的消息格式，其基本结构与RIP-2非常相似。

RIPng消息的字段定义如下（长度单位为字节）。

•　命令（Command）：该字段要么为1（表示请求），要么为2（表示响应）。

•　版本（Version）：该字段目前为1。

RIPng消息的其余部分是RTE（Route Table Entry，路由表项）列表，图8-16给出了RTE的格式。

RTE格式中的各字段定义如下。

•　IPv6前缀（IPv6 Prefix）: 128bit IPv6地址前缀。

图8-15　RIPng消息格式

图8-16　RIPng的路由表项格式

•　路由标记（Route Tag）：与RIP-2相同，用于标记外部路由或者被重分发到RIPng进程中的路由。

•　前缀长度（Prefix Length）：指定地址前缀的有效部分。

•　度量值（Metric）：与RIP-2相同，是1~15（含1和15）的跳数值。

一条RIPng更新消息所能包含的路由数与链路MTU、RIPng消息之前的头部信息8位组数、RIPng头部大小以及每个RTE的大小都相关。每条更新消息中所能包含的RTE数的计算公式如下。

RTE的数量与链路MTU及IP头部长度、UDP头部长度和RIPng头部的长度都直接相关。

每个RIP-2 RTE都包含一个与其相关的下一跳（Next-Hop）字段，用于指定更优下一跳地址（与路由器所宣告的地址相比）。由于IPv6的地址过大，几乎是RTE的2倍，因而RIPng只指定了单个下一跳RTE（应用于随后的所有 RTE，直至消息结束或遇到另一个下一跳RTE）。图8-17显示的下一跳RTE表明路由标记字段和前缀字段必须为全0，度量值为OxFF，地址字段值 0:0:0:0: 0: 0: 0: 0表示下一跳是RIPng宣告的发起路由器。

图8-17　下一跳RTE

下一跳地址必须是下一跳路由器的链路本地地址，如果该地址不是链路本地地址，那么宣告消息的接收方将会认为该数据包的地址前缀值为0:0:0:0:0:0:0:0。

无论是周期性的RIPng响应，还是被触发的RIPng响应，都必须保持在链路本地——即不能穿越路由器。周期性更新和触发性更新都必须将路由器的链路本地地址作为宣告的源地址，并且IPv6的跳数限制值等于255，跳数限制值为255可以确保该宣告消息没有穿越路由器（因为路由器会递减每个数据包的跳数限制值）。目的多播地址则为all-rip-routers（所有 RIP路由器）多播地址FF02::9。

Cisco路由器能够运行多个RIPng进程，需要在接口子命令下启用路由进程，如下所示。

ipv6 rip tag enable

任何接口如果希望在RIPng更新消息中宣告前缀，就必须在接口上启用该命令。多个进程之间通过标记来加以区分，目前最多支持4个进程，每个进程都必须使用一个惟一的UDP端口号，如果是单一进程，则可以使用默认端口号521，必须修改后续进程的端口号，否则新进程将无法启动。RIPng用来修改UDP端口号和多播地址的全局命令如下。

ipv6 rip tagport udp-portmulticast-group multicast-address

多个进程可以共用同一个多播地址，如果没有启用该命令，则使用默认端口号521和默认多播地址FF02::9。

与RIP-2不同（RIP-2要求使用全局命令router rip来启用路由协议），无需使用全局命令来启用RIPng。

可选的全局命令可以控制整个RIPng进程并影响所有已配置接口，可以利用全局命令禁用或启用水平分割和毒性反转机制，修改UDP端口号和RIPng多播地址，更改默认定时器和管理性距离，重分发静态路由等等。RIP-2也可以提供其中的绝大多数功能。

表8-10列出了各种可用的RIPng全局命令。

RIPng中还有一些可用的接口子命令，这些接口子命令可以让更新消息通过指定接口向外宣告默认路由，汇总接口向外宣告的路由，对接口上接收到的更新消息或者从接口向外发送的更新消息应用输入和输出过滤器，以及更改接口上接收到的路由的度量值偏移（metric- offset）。这些功能在RIP-2中也都有，表8-11列出了这些接口子命令。

下面通过一个简单的网络图和路由器配置来帮助读者掌握路由器运行RIPng所需的最少配置（如图8-18所示）。

图8-18　一个简单的RIPng网络

图8-18中所示的两台路由器上都配置了RIPng（在以太网链路和串行链路上），例8-6给出了路由器的配置情况。

例8-6：在路由器Falcon和Eagle上配置RIPng。

这两台路由器共享两个相同的前缀FEC0: : /64和FEC0: : 2: 0: 0: 0: 0/64，每台路由器都配置了第3个前缀。为了让这两台路由器向对方宣告非公共前缀，需要禁用水平分割，在以太网接口和Eagle的串行接口上启用RIPng。进程名为birdbath。

例8-7显示了Falcon的路由器情况。

从例8-7中的路由表可以看出，连接了配置在Falcon的以太网端口上的前缀，并且通过 RIPng进程学习到Eagle的以太网前缀FEC0::3:0:0:0:0/64和串口前缀FEC0::A:0:0:0:0/126。

RIPng仍然是一个非常容易实现的路由协议，引入多进程的目的是在RIP-2的基础上增加一定的灵活性，但是其缺点仍然存在（如《TCP/IP路由技术（第一卷）》第7章所述）。例如，该协议的最大跳数限制值仍然很小，从而限制了运行该协议的网络的规模。

例8-7: IPv6路由器显示了学习自RIPng的路由。

3．IPv6 0SPF

为了支持更大的IPv6地址，需要对OSPFv2做出很多修改，并在IPv4与IPv6之间修改相应的协议语义。Cisco IOS目前不支持用于IPv6的OSPF。OSPF中的基本机制，如泛洪、 DR选举、支持域的划分、SPF等都没有变化，IPv6 OSPFv直接运行于IPv6之上，前一个头部的下一报头值为89。以下OSPF功能在IPv6中未做任何改动。

虽然IPv6 OSPF修改了Hello包，但这两种版本的OSPF协议都支持相同的数据包类型，即Hello包、数据库描述包、链路状态请求包、链路状态更新包和链路状态确认包。

•　通过交换Hello包来发现邻居信息；

•　邻接性选择和建立机制；

•　接口状态机，包括接口所经历的状态以及指派路由器选举进程；

•　邻居状态机，包括在成为邻接关系之前邻居所经历的状态；

•　链路状态数据库老化机制。

注意：　有关OSPFv2的详细描述请参见《TCP/IP路由技术（第一卷）》第9章。

某些OSPF机制发生了变化，原因是希望让OSPF与网络协议无关（因而更具扩展性），如新的地址格式、显式指定泛洪区域、接口支持多个地址和多个前缀等。OSPF协议已成为与网络协议无关的协议，其协议版本号也从2变为3，所以本章后续内容将称IPv6下的OSPF为OSPFv3。本小节将详细讨论该协议的变动情况。

（1）是链路而不是子网。

IPv6节点通过链路进行通信，而不是子网。每个IPv6节点都可以为连接到链路上的接口配置多个地址和前缀，并且能与链路上的其他节点进行通信，而与所使用的子网无关。OSPFv3关注的是链路，这一点与OSPFv2中关注的是子网不同，此时不再要求发送OSPF包的路由器接口与接收该数据包的路由器接口位于同一个子网中。这是因为，IPv6 OSPF的运行基础是链路，而不是子网。

（2）删除了寻址语义。

OSPFv3删除了OSPFv2包和LSA中的寻址语义，因而在OSPFv3创建了一个与网络协议无关的核心，为将来的多播OSPF提供了基础。许多OSPFv2包和LSA都包含了IPv4地址，表示路由器ID、域ID或LSA链路状态ID，但是由于OSPFv3中的路由器ID、域ID和 LSA链路状态ID仍然用32bit数字来表示，因而无法再用IP地址来表示（虽然可以用IP地址的一部分来表示）。OSPFv2广播和NBMA网络利用IP地址来列举邻居，OSPFv3的邻居仅以路由器ID来标识。其他OSPFv2 LSA（如路由器LSA[Router-LSA]和网络 LSA[Network-LSA]）都包含了IP地址，这些IP地址在链路状态数据库中被用来表示网络拓扑结构，而OSPFv3的路由器LSA和网络LSA仅表示拓扑信息，按照与网络协议无关的方式来描述网络拓扑结构。IPv6利用接口ID来标识链路，而不再使用IP地址来标识链路，路由器上的每个接口都被分配一个惟一的接口ID，某些协议实现可能利用MIB-II iflndex值。邻居和指派路由器都以路由器ID加以标识，也不再使用IP地址来表示。只有在链路状态更新包所携带的LSA净荷中才包含IPv6地址。

（3）LSA泛洪作用域和未知LSA类型。

LSA包的泛洪作用域已经很普遍化，LSA类型决定了OSPFv2的泛洪作用域，每种LSA类型都与其泛洪作用域相关联。对OSPFv3来说，需要在LSA头部中显式配置泛洪作用域，无法识别LSA类型的OSPFv3路由器仍然知道如何泛洪该数据包，泛洪作用域可以是链路本地、区域（Area）或AS。OSPFv3允许路由器具有不同的能力，路由器接收到未知类型的LSA包时也不再要求丢弃该数据包。泛洪作用域、未知LSA类型的处理方式以及LSA类型都被编码在头部中的扩展LSA类型字段，最上面的3bit用来编码泛洪作用域和未知LSA类型的处理方式，由处理bit告知路由器要么泛洪未知LSA（泛洪作用域为链路本地），要么像已知 LSA类型那样存储并泛洪该未知LSA，因为有了已编码的泛洪作用域，所以路由器可以按照后面的方式进行处理。表8-12和表8-13分别显示了泛洪作用域值以及与未知LSA处理方式相关的值。

将泛洪作用域进行显式编码，可以将新的OSPF功能特性集成到现有网络中。

（4）每链路多OSPF实例。

单条链路上可以同时运行多个OSPFv3实例，这在多个区域需要共享同一条链路时非常有用（如图8-19所示）。OSPFv3包头中的实例ID（instance ID）即可实现该功能。

如图8-19所示，Area 1和Area 2各有4台路由器，Area 1中的2台远程路由器的主用链路连接到路由器A，备用链路连接到路由器B, Area 2中的2台远程路由器的主用链路连接到路由器B，备用链路连接到路由器A, Area 1和Area 2都必须经同一条以太网链路在路由器A和B之间运行。上述要求在OSPFv3中完全可以实现，但是在OSPFv2中则无法实现。

还有另一种应用场景，多个运行OSPF的公司或同一家公司的多个运行OSPF的独立分支机构需要共享同一条链路，并需要使用该链路进行相互通信。该链路可能属于某一家公司，该公司利用该链路连接到所有独立的组织机构。部分公司可能希望建立对等关系，而不与其他公司建立对等关系。一种更为常见的实践方法是使用BGP来互连这些独立的组织机构，但是，如果某组织机构拥有OSPF专家但没有BGP专家，那么很有可能希望使用OSPF作为互连协议，图8-20解释了该应用场景。

图8-19　两台路由器共享同一条链路，两个区域需要运行在同一条链路上。每链路多OSPF协议进程机制可以实现该要求

图8-20　OSPF路由器共享同一条链路，部分路由器共享同一个OSPF进程

如图8-20所示，路由器Poodle和Label为对等体，且共享同一个OSPFv3进程，路由器 Lab、Terrier和Collie也是对等体，且共享一个不同的OSPFv3进程，Lab的链路被配置了两个OSPFv3进程标识符。

（5）OSPF对链路本地地址的使用。

由于每条有效的IPv6链路都配置了链路本地地址，因而OSPFv3将这些链路本地地址用作协议包的源地址以及链路LSA（Link-LSA）的内容（将在下面的“新LSA和LSA变化”中描述）。根据定义，链路本地地址都共享相同的IPv6前缀（FE80: : /64），因而OSPFv3节点之间可以很容易地进行相互通信并构建邻接关系（而不管分配给这些节点的地址前缀是站点本地地址还是全局可聚合地址）。将链路本地地址用于LSA中来标识路由器上的链路，就不再需要将链路与某个特定的IP地址相关联，从而使得拓扑信息与所使用的网络协议无关。

（6）取消认证。

IPv6中的OSPF取消了认证机制，这是因为IPv6已经将完整性、真实性和机密性机制内嵌于该协议的网络层，而OSPFv3则直接运行于该层之上。从头部中取消了认证信息之后，可以提高OSPFv3的效率，不需要路由安全性的网络就无需处理这些头部，而那些需要路由安全性的网络则可以使用IP层的认证和安全加密净荷扩展头。

（7）新LSA和LSA变化。

虽然OSPF中的大部分功能都没有做任何变化，但仍然修改了某些OSPFv2 LSA字段，并且在OSPFv3中重新命名了这些LSA，而且还在OSPF中增加了某些新的LSA以携带IPv6地址和下一跳信息。

OSPFv2 LSA头部中包含了以下字段：寿命（Age）、选项（Options）、类型（Type）、链路状态ID（Link State ID）、宣告路由器（Advertising Router）、序列号（Sequence Number）、校验和（Checksum）和长度（Length）。OSPFv3 LSA将选项字段从8bit扩展到了24bit，并从头部移至路由器LSA（Router-LSA）、网络LSA（Network-LSA）、区域间路由器LSA（Inter-Area-Router-LSA）和链路LSA（Link-LSA）的消息体中。类型字段被扩展到16bit，并用空格来代替原先被选项字段占用的位置，其余头部字段则保持不变。

LSA类型字段包括未知类型处理方式、泛洪作用域和LSA类型bit，图8-21显示了LSA类型字段的结构。

其中的U bit指示未知LSA类型的处理方式，S2和S1则用来指示泛洪作用域。

图8-21　OSPFv3 LSA类型字段

对未知LSA类型的处理方式做了调整，IPv4 OSPF直接丢弃未知LSA类型数据包，由于 OSPFv3希望在同一条链路上允许不同能力的路由器共存，因而不希望丢弃未知LSA类型数据包。如果指派路由器比链路上的其他路由器支持更少的选项，那么将无法获得全部功能。

表8-14列出了每种LSA的链路类型值

从表8-14可以看出，两个OSPFv2汇总LSA被重新命名了，并且增加了两个新的LSA：链路LSA和区域内前缀LSA。此外，还可以看到每种LSA类型的泛洪作用域和处理方式。所有列出的类型的U bit都被设置为0，表示如果LSA类型对任何接收路由器来说是未知的，那么应该按照泛洪作用域为链路本地的方式来处理该LSA，如果路由器无法识别该LSA类型，那么将根据S2和S1 bit来泛洪该LSA。例如，路由器LSA类型0x2001的S2S1值为01（二进制），则表示将该LSA泛洪到区域中的所有路由器，AS外部LSA的S2S1值为10（二进制），则表示将该LSA泛洪到AS中的所有路由器。

OSPFv2中的类型3网络汇总LSA（type-3 Network Summary-LSA）被重新命名为区域间前缀LSA，请记住，这些LSA被区域边界路由器（Area Border Router）用来宣告区域外的网络。

OSPFv2中的类型4ASBR汇总LSA（type-4 ASBR Summary-LSA）被重新命名为区域间路由器LSA，这些LSA由AS边界路由器负责宣告，并宣告区域外的ASBR。

OSPFv3将LSA选项字段从8bit扩展到24bit，该字段位于Hello包、数据库描述包和某些LSA（路由器LSA、网络LSA、区域间路由器LSA、链路LSA）中。选项字段的作用是让路由器相互说明其所支持（或不支持）的选项能力，允许混合能力的路由器共存于同一个 OSPF路由域中。当路由器不支持同样能力的时候如何处理完全取决于选项。

目前已经定义了选项字段中的以下6个bit。

•　V6：如果该bit被清除，那么该路由器将参与拓扑结构分发，但不用来转发转接（transit）IPv6包。

•　E：与OSPFv2中一样，当发信路由器能够接受AS外部LSA时置位该bit，末梢区域中发起的所有LSA的E都等于0。该bit也用于Hello包中，用来指示该接口发送和接收AS外部LSA的能力。E bit不匹配的邻居路由器之间无法建立邻接关系，以确保同一个区域中的所有路由器都支持同等的末梢（stub）能力。

•　MC：当发信路由器能够转发IP多播包时就置位该bit, MOSPF使用该bit。

•　N：仅用于Hello包，N bit被置位表示发信路由器支持NSSA外部LSA（NSSA External LSA）o如果N=0，表示发信路由器不发送或接收这些NSAA外部LSA。N bit不匹配的邻居路由器之间无法建立邻接关系，以确保同一个区域中的所有路由器都支持同等的NSSA能力。如果N=1，那么E必须等于0。

•　R：R（路由器）bit被置位表示该路由器有效，如果R bit被清零，那么OSPF发言者就可以参与到拓扑分发中，而不用转发转接流量。这一点可以用于多归属节点希望参与路由选择而不希望充当路由器（即在其接口之间转发流量）的应用场合。如果R bit被置位，但V6 bit被清零，那么该节点将不转发IPv6数据报，但仍然转发属于其他协议的数据报。

•　DC：当发信路由器在需求电路上支持OSPF时就置位该bit。

对比上述bit与OSPFv2选项字段中已定义的6个bit（T、E、MC、N/P, EA、DC），可以看出做了一定的变更。由于OSPFv3不支持TOS（Type of service，服务类型），因而替换了T bit; N bit仍然仅用于Hello包；P bit是OSPFv3选项集中的一部分，是与每个被宣告前缀相关联的前缀选项；OSPFv2 EA bit指示对外部属性LSA（External Attribute LSA）的支持。外部属性LSA被建议为运行iBGP（Internal BGP，内部BGP）以便在整个OSPF域中传递 BGP信息的可选项，目前不但没有实现外部属性LSA，也没有发布任何相关的草案或RFC。虽然没有任何选项bit来定义EA能力，但OSPFv3仍然支持外部属性LSA，作为一种额外的 LSA类型，其拥有指定的泛洪作用域和未知LSA类型处理方式。

新链路LSA不但被用于在同一链路上的路由器之间交换IPv6前缀和地址信息，而且被路由器用来宣告选项集，从而与为该链路而发起的网络LSA建立关联关系。链路LSA提供了路由器的链路本地地址和前缀列表，从而与该链路建立关联关系。LSA以多播方式传送给链路上的所有路由器，由网络LSA所宣告的选项是选项（由所有路由器在链路LSA中进行发送）的逻辑OR。

另一个新LSA是区域间前缀LSA，该LSA携带IPv6前缀信息，这些信息在OSPFv2中是由路由器LSA和网络LSA负责携带的。该前缀被路由器用来宣告分配给路由器本身的地址前缀，如所附属的末梢网络和所附属的转接网络。

包含前缀信息的OSPFv3 LSA都要携带前缀长度、前缀选项和前缀地址等信息，前缀选项字段长8bit，用于描述与前缀相关的能力。目前定义了以下4种选项。

•　NU： “no-unicast（非单播）” bit被置位表示将该前缀从单播路由计算中剔除出来。

•　LA： “local-address（本地地址）” bit被置位表示该前缀实际上是宣告路由器的IPv6地址。

•　MC： “multicast-capable（具备多播能力）” bit被置位表示应该将该前缀纳入多播路由计算之中。

•　P： “propagate（传播）” bit被置位表示应该在NSSA区域边界上重新宣告NSSA前缀。

每个前缀都在8bit前缀选项字段（充当不同路由计算的输入）中加以宣告，前缀选项可以用来指示特定前缀是否要被剔除或不应该对外传播。

4．BGP-4多协议扩展

对BGP-4所作的扩展并不专用于IPv6，也包括了对IPX等协议的支持，这里仅讨论与 IPv6相关的BGP-4多协议扩展，有关MBGP的详细信息已经在第7章中讨论过了。

以下3点是与IPv4相关的BGP-4信息。

•　下一跳属性；

•　AGGREGATOR属性；

•　NLRI（Network Layer Reachability Information，网络层可达性信息）。

截止本书写作之时，假定每个BGP-4发言者都至少维护一个IPv4地址，AGGREGATOR属性将继续使用该地址（可以回顾第2章以获取更多有关AGGREGATOR属性的知识），因而对BGP-4的扩展主要集中在下一跳属性和NLRI。此外，由于下一跳信息被用来向一组目的地转发数据包，并且仅在增加NLRI时才使用该信息（在撤销路由时不使用该信息），下一跳信息已经被加入到可达的NLRI更新中。

为了让BGP支持多协议，增加了两个新属性，分别是MP-REACH-NLRI（MultiProtocol-Reachable NLRI，多协议可达 NLRI）和 MP-UNREACH-NLRI（MultiProtocol-Unreachable NLRI，多协议不可达NLRI），这两个属性都是可选和非传递性属性。也就是说，如果BGP进程无法识别这两个属性，那么就可以直接忽略包含这些属性的更新消息，而不将这些信息宣告给其对等体。

顾名思义，MP-REACH-NLRI属性描述的是可达目的地，该属性包含了地址所属网络层的信息以及用来转发数据包（去往目的前缀列表中所包含的目的地）的下一跳信息。每条MP-REACH-NLRI更新消息都包含一个下一跳地址和一个相关的NLRI列表，NLRI是一个 <length/prefíx>形式的二元组，其中的length是前缀的长度，prefix是可达的IPv6地址前缀。

下一跳是BGP发言者在将数据包转发到相关地址前缀时使用的一个地址，回顾第2章可以知道，下一跳属性的默认规则如下。

•　如果宣告路由器与接收路由器位于不同自治系统（外部对等体），则NEXT—HOP是宣告路由器的接口IP地址；

•　如果宣告路由器与接收路由器位于同一个自治系统（内部对等体），且更新消息的NLRI指向的目的地位于同一个自治系统中，则NEXT—HOP是宣告该路由的邻居的IP地址；

•　如果宣告路由器和接收路由器是内部对等体，且更新消息的NLRI指向的目的地位于不同自治系统中，则NEXT—HOP是外部对等体（该路由学习自该外部对等体）的IP地址。

对IPv6来说，由于IPv6地址定义了作用域，因而上述规则将更加精细。IPv6 BGP路由器宣告下一跳路由器的全局地址，后面也可能包含其链路本地地址。仅当BGP发言者与下一跳字段中所标识的节点以及更新消息所要发送到的对等体共享同一个数据链路时才包含链路本地地址，在其他场合下，下一跳字段中仅包含全局地址。

下面通过网络图、路由器配置以及命令输出结果示例来说明使用IPv6的MBGP的配置及输出情况，所有这一切都与IPv4非常相似。

图8-22给出了一个简单的BGP路由器拓扑结构。

路由器Maple和Aspen为EBGP对等体，Oak和Aspen也是EBGP对等体，这3台路由器都位于同一个快速以太网网段。此外，Oak和Pine是IBGP对等体。

图8-22　一个简单的BGP网络

Aspen将学习自Maple的NLRI宣告给Oak，包括Maple的地址（作为下一跳信息），因而Oak可以直接将流量发送到Maple，而不用再经过额外的一跳Aspen。由于3台路由器共享同一个快速以太网网段，因而Maple的全局地址和链路本地地址都被包含在该更新中。

Oak将Maple的NLRI信息宣告给Pine，下一跳地址是Maple的全局地址，链路本地地址被删除了。例8-8显示了Oak和Aspen的配置情况。

例8-8：BGP路由器配置。

Oak的FastEthernet（快速以太网）地址是200A::2:0:0:0:1/64。从接口子命令中可以看出，Oak是Aspen的EBGP邻居，Oak还有一条IGP链路（前缀为200A:0:0:1::/124）。例8-9显示了BGP邻居的状态、从Oak发送给Aspen有关IGP前缀的BGP更新以及Aspen路由表中的表项。

例8-9：BGP命令输出结果。

从上述输出结果中可以看出，这些信息与IPv4非常相似。事实上，由于该路由协议是 MBGP，而不是用于IPv6的新版本BGP，输出结果中惟一增加的内容就是表示IPv6和IPv6地址格式的地址族类型——加入了地址族值，而且地址类型不一样；而TCP端口号则一致，还是179。

8.4.6　任播进程

任播是一种将数据包路由到多个拥有相同地址的节点中的某个节点的机制。地址相同的多个节点可能是向客户提供周知服务的一组服务器或是属于某个ISP的一组路由器，其目的是希望流量穿越被分配了任播地址的某个路由器。节点将IP包寻址到单个任播组地址，学习该地址的下一跳（就像是单播地址一样）。如果任播地址是在链（on-link）地址，那么节点就要执行地址解析进程，第一次响应会被添加到邻居缓存中；如果任播地址是离链（off-link）地址，那么就根据路由协议的距离度量将数据包转发到最近的目的地。需要有一个包含域中任播节点集的前缀，如所有使用任播地址FEC0：：A:FDFF：FFFF：FFFF：FFFE/64的节点都驻留在前缀FEC0:0:0:A：：/64中，这些任播节点都要在域中被宣告为主机路由（以该前缀进行编址），节点利用该主机路由的度量值来确定最近的任播节点。可以看出，如果有很多任播组且组中有很多任播节点，而且包含的域又非常大，那么域中的路由表将非常庞大。

虽然IPv6中规定了任播机制，但目前的使用非常有限，几乎还没有广泛使用任播的服务经验，而且还存在一些周知的复杂因素，如需要确保会话的所有数据包都要到达同一个任播节点或要求任播节点共享状态信息^4，随着应用经验的增加会出现更多需要解决的问题。除了所有任播子网路由器（all anycast subnet-router）之外，惟一已定义的任播组就是移动IPv6家乡代理（Mobile IPv6 home-agent）。除非能就所有问题的解决方案达成一致，否则任播的应用将仅局限于路由器。

8.4.7　多播

IPv6提供多播功能并推进了多播应用，在具备多播能力的链路上使用多播（而不是广播）可以减小请求、宣告、更新等消息对网络带来的影响。因为IPv6支持带作用域的多播地址并内嵌支持数据链路组成员关系协议——侦听者发现协议（Listener Discovery Protocol），所以能够大力推动多播的广泛应用。利用PIM（Protocol Independent Multicast，协议无关多播）路由协议，链路上的IPv6主机可以加入整个网络范围内的多播组。

1. 限定了作用域的地址

IPv6的多播地址空间加入了多播作用域，可以创建全球范围公共使用的多播应用，也可以创建某个组织机构或站点内部或单条链路上使用的多播应用。需要设置管理策略以标识站点和组织机构的边界并有效使用多播的作用域，可以在已定义的作用域内包含周知多播组，从而使得多播应用的范围控制更加简单。

2. 侦听者发现

利用源于IGMPv2的MLD（Multicast Listener Discovery，多播侦听者发现）协议，路由器可以发现链路上的哪个节点希望接收多播包以及这些节点所属的多播组，然后将这些信息传递给网络中正在使用的多播路由协议（如PIM）。MLD的功能主要包括主机功能和路由器功能两大部分。

（1）主机功能。

这里所说的主机功能与第5章中所说的IGMPv2的主机功能相似，定义了如下两种类型的报告消息。

•　Membership Report（成员关系报告）消息

•　Done Report（已完成报告）消息

当主机开始侦听链路上的某特定多播地址时，需要发送一条报告消息以告知路由器链路上有一个侦听者。主机将该报告发送到多播组地址并在报告包的MLD多播地址字段中包含该地址，该报告的源地址是该主机的链路本地地址，使用链路本地源地址可以防止数据包传递到本地链路之外。

路由器会周期性地发送查询消息以确定链路上的主机属于哪个多播组。如果主机接收到的是常规查询（未指定任何特定多播地址），那么就会为每个其正在侦听的多播地址都设置一个延时定时器，链路作用域所有节点（link-scope all-node）多播地址以及作用域为0（保留）或1（节点本地）的多播地址除外。如果主机接收到的是关于某特定多播地址的查询消息，那么仅为该地址设置一个延时定时器。延时定时器值是0至最大响应时间值（是查询消息的一部分）之间的任一个随机值，每个地址的定时器都被设置为一个不同的随机值。

在某多播地址的延时定时器到期时，如果主机仍然没有收到链路上其他主机发送来的报告消息，那么该主机将发送自己的报告消息；如果该主机在定时器到期之前接收到了报告消息，则将终止该延时定时器且不向外发送报告消息。虽然该链路没有因此被该多播组每个成员的报告消息所泛洪，但知道了至少存在一个组成员。

路由器接收到关于某指定多播地址的报告消息后，如果该地址没在该路由器的多播地址列表中，那么该路由器会将该多播地址加入到列表中，并告知该网络正在运行的路由协议；如果该地址已经位于多播地址列表中，那么该路由器会将该地址的定时器值重置为多播侦听者间隔（Multicast Listener Interval）值。如果该定时器到期时仍未收到关于该多播地址的报告消息，那么就会从路由器的列表中删除该地址。

图8-23所示的流程图为MLD进程的主机功能。

主机功能流程图

图8-23　MLD进程的主机功能

主机停止侦听多播组后，会发送一条Done（已完成）消息。该消息类似于IGMPv2中的 Leave（离开）消息，会被发送给链路作用域所有路由器（link-scope all-routers）多播组FF02：：2，该消息的多播地址字段中携带了该主机停止侦听的多播组地址。但是如果主机发送的关于该地址的报告消息被来自其他节点的报告消息所中断，那么就不需要再发送Done消息，这是因为该链路上的其他节点极有可能正在侦听同一个多播地址。

（2）路由器功能。

MLD的路由器功能也非常类似于第5章中所说的IGMPv2路由器功能，只是术语有些不同。此时路由器发送的是Multicast Listener Query（多播侦听者查询）消息，该消息包括以下两种子类型消息。

•　General Query（常规查询）

•　Multicast-Address-Specific Query（特定多播地址查询）

查询路由器和非查询路由器的概念仍然存在，路由器为其每条多播链路都假定查询路由器和非查询路由器的状态。与IGMPv2相似，初始化路由器会假定其为查询路由器并立即发送一条General Query（常规查询），如果该路由器接收到来自其他路由器的查询消息，那么就会检查所接收到的查询消息的IPv6源地址。如果该源地址在数值上比其小，那么该路由器会将查询路由器的角色释放给其他路由器；如果地址比其大，那么该路由器将继续充当查询路由器。

查询路由器会在启动时以及周期性地利用General Query消息轮询其所连接的链路，以发现是否存在组成员。查询消息的源地址是该路由器的链路本地地址。查询消息会被发送给链路作用域所有节点（link-scope all-nodes）多播地址FF02::1。

查询路由器接收到“已完成”消息之后，如果“已完成”消息中所指定的地址在其多播地址列表中，则向该多播地址发送一条Multicast-Address-Specific Query（特定多播地址查询）消息，以确定该链路上是否还存在其他侦听者。如果在最大响应时延内都没有接收到主机的响应消息，该路由器就会从其多播地址列表中删除该地址，并告知网络中正在运行的多播路由协议。

图8-24所示的流程图为MLD进程的路由器功能。

路由器功能流程图

图8-24　MLD进程的路由器功能

3．PIM多播路由

与单播路由协议一样，为了支持IPv6，也要对多播路由协议进行一定的修改，但从功能角度来说，这些协议的运行方式是完全一样的，所做修改主要是为了支持更大的地址空间。PIM是目前惟一已定义了IPv6修改内容的多播路由协议，有关PIM及其他多播路由协议的讨论请参见第5章内容。

为适应IPv6，对PIM所作的修改主要有：定义了PIM消息中必须使用的地址，并说明了带作用域的多播地址以及集中式Bootstrap（引导）机制等内容。

对IPv4来说，每种不同的PIM消息都使用目的地址字段中的多播或单播地址以及其所分配的接口IP地址作为源地址。借助于IPv6带作用域的地址以及可以为每条链路分配多个地址的特点，可以进一步定义使用哪个地址的选择。

大多数PIM消息都将全局IPv6所有PIM路由器（all-PIM-routers）多播地址FF02：：D作为 IPv6目的地址，将发送接口的链路本地地址作为源地址，其他PIM消息则使用它们所要通信的服务的特殊全局IPv6单播地址作为目的地址，将它们自己的全局单播地址作为源地址。

在多播接口上发送Hello消息，可以发现PIM邻居。Hello包的目的地址是所有PIM路由器（all-PIM-routers）多播地址，源地址是接口的链路本地地址，因而链路本地地址被用来构建邻居表并选举指派路由器。

路由器通过某接口（路由器将该接口视为（源，组）或（S，G）的出站接口）接收到一个多播包后就会发送Assert（声明）消息。回顾第5章的内容可以知道，多播路由器为每个特定多播源（去往某特定多播组（S，G））都维护了一个带有上行和下行接口的多播转发表，如果路由器在出站（下行）接口上接收到该（S，G）的一个多播包，那么该多播包将由连接到该下行链路上的其他路由器进行转发（如图8-25所示）。

图8-25　在下行接口上接收到的多播包

路由器SJ中关于特定（S，G）的多播转发表显示出E0是离开源的下行接口，因而是出站接口。SJ通过其以太网接口接收到该（S，G）的一个多播包，利用Assert消息为该多路接入网络确定一个PIM转发路由器，由以太网上的SJ发送的Assert消息来确定哪台PIM路由器应该是PIM转发路由器，该消息被发送给所有PIM路由器（all-PIM-routers）多播地址且源自接口的链路本地地址。以链路本地地址的值作为判断依据，链路本地地址数值最大的路由器将成为转发路由器，下行路由器将转发路由器的链路本地地址保存起来以解决将来的RPF需求。

Join/Prune（加入/剪除）、Graft（嫁接）以及Graft-Ack（嫁接确认）等消息（被用来构建并剪除多播路由器的转发表）也将所有PIM路由器（all-PIM-routers）多播地址作为目的地址，并将链路本地地址作为源地址，这些消息也都包含一个上行邻居地址。上行邻居地址被设置成该邻居的链路本地地址，利用RPF查找可以获得该地址，如果无法获得该邻居的链路本地地址，那么就需要为该邻居使用一个已知的全局地址。

将所有PIM路由器（all-PIM-routers）多播地址作为目的地址，并将链路本地地址作为源地址的另一条消息是Bootstrap（引导）消息。Bootstrap消息被BSR（BootStrap Router，引导路由器）以多播方式发送给所有的PIM路由器，该消息中包含了BSR地址。由于所有PIM路由器都要能访问该地址，因而该地址是BSR在整个域范围内均可达的地址。

Register（注册）和Register Stop（注册终止）消息被用于PIM-SM，如果源DR（Designated Router，指派路由器）希望向某多播组发送流量，那么首先要将多播包封装在Register消息中并发送给RP（Rendezvous Point，聚合点），由RP向DR发送Register Stop消息，以告诉源不要再将多播包封装在Register消息中，这些事件并不要求按顺序进行。第5章描述了这些事件的完整顺序，由Register和Register Stop消息将多播包寻址到RP路由器在整个域范围内均可达的地址，源地址是DR路由器在整个域范围内均可达的地址。源DR可以从RP-set信息（由BSR以多播方式发送给所有PIM路由器（all-PIM-routers）多播地址）中获得RP地址，而RP则可以从接收自DR的Register消息的源地址中获得DR的全局IPv6地址。

每个候选RP都要将Candidate-RP-Advertisement（候选RP宣告）消息以单播方式发送给BSR，该消息中不但包含了一个多播组地址（宣告路由器是候选RP），而且包含了被用作该路由器RP地址的IPv6地址。该消息的目的地址是BSR在整个域范围内均可达的单播地址，源地址是候选RP在整个域范围内均可达的单播地址。BSR从这些宣告消息中可以构建RP-seto

虽然带有作用域的多播地址解决了多播定界问题，但是也给PIM和Bootstrap机制带来了一个问题：由于Bootstrap进程是PIM-SM域中的一个集中式进程，如果该PIM域不是某多播地址（带有作用域）域的一个子集，那么Bootstrap机制将无法正常工作。这样一来，位于某个被限定了作用域的多播地址域中的多播包将无法穿越到另一个被限定了作用域的多播地址域中。如果希望Bootstrap机制能够正常运行，就要求PIM域必须是被限定了作用域的多播地址域的子集，或者要求所有的多跳消息都必须使用全局可达的IPv6地址。

8.4.8　QoS

虽然IPv6中并没有内嵌QoS功能，例如，IPv6中没有描述通过路由器进行排队和转发不同流量等级的方法，也没有描述对多个流量流进行优先级划分的方法，但IPv6定义了允许QoS协议与其进行协同操作的相关机制，也就是下面即将讨论的IPv6头部中的流量流（Traffic Flow）和流量等级（Traffic Class）字段。

1. 流量流

发起流量的节点可能希望请求对特定流量流采取特殊处理方式，此时该节点就可以标记该流量流，从而请求IPv6路由器为该流量流采取非默认QoS处理方式。例如，呼叫中心应用要求响应时间非常快，这样使用该呼叫中心应用的呼叫中心客户代表才可以将获得自服务器的信息通过电话机顺畅地告诉客户。为此需要节点来标记该流量流，请求IPv6路由器为该流量流采取不同于其他流量流的差异QoS处理方式。

2. 流量等级

IPv6头部中的流量等级bit为源节点和/或中间路由器提供了区分不同等级或不同优先级 IP包的机制，流量等级bit的使用与IPv4中的ToS（Type-of-Service，服务类型）bit及优先级bit相似，目前仍处于实验性应用阶段。DiffServ（Differentiated Services，差分服务）重新定义了流量等级bit并将其命名为DS字段。DS字段的定义对IPv6及IPv4来说都是一样的，最左侧的6个bit被用作DiffServ的代码点（codepoint），数据包在网络边缘被标记上某个代码点，在对数据包进行排队和转发时，由代码点来确定每台路由器的处理行为，该处理行为就被称为PHB（Per-Hop Behavior，每跳行为）。

8.5　从 IPv4向 IPv6 的迁移

如果没有明确的迁移方法的话，将无法实施一种新的路由协议，迁移过程越简单，就越可能实施新协议。IPv6与IPv4之间的互操作性是势在必行的，IPv6节点需要与IPv4节点进行通信，至少在初始阶段是这样，而且在互通时间上还可能非常不确定。NGTRANS IETF工作组制定了多种迁移方法来推动从IPv4向IPv6的迁移工作，并确保IPv4与IPv6之间的兼容性。

与IPv4保持兼容的方式有多种，运行双栈的节点能够完全支持IPv4和IPv6，可以使用IPv4和IPv6进行通信。这样的节点可以将IPv6包封装到IPv头部中，从而在现有的IPv4网络中创建一条隧道，使得两个IPv6节点可以经IPv4网络进行通信。目前定义了以下两种隧道机制。

•　自动隧道（Automatic Tunnels）

•　配置隧道（Configured tunnels）

IPv6中定义了与IPv4兼容的IPv6地址，该IPv6地址的前96个bit为全0，剩余的32bit构成一个IPv4地址，如：：172.69.1.1就是一个与IPv4兼容的IPv6地址。如果节点配置了与IPv4兼容的地址，那么就可以使用自动隧道机制。

如果IPv4和IPv6共存于同一个网络之中，那么就必须规定相应的机制来正确解决名字与IP地址的解析问题。为了确保DNS服务器能够正确返回IPv4地址、IPv6地址或IPv和IPv6地址，对DNS做了一定的修改，这也是协议共存的一个关键能力要求。

也可以在IPv6网络和IPv4网络之间部署NAT-PT（Network Address Translation Protocol Translation，网络地址转换一协议转换）设备。下面将首选讨论双栈机制。

8.5.1　双栈

对一个节点来说，如果希望既实现IPv6，又能与IPv4节点保持兼容，可以采取的一种方法就是在该节点上同时实现IPv4和IPv6。同时实现了IPv4和IPv6两种协议栈的节点被称为IPv6/IPv4节点，IPv6/IPv4节点可以使用IPv6数据包与IPv6节点进行通信，并使用IPv4数据包与IPv4节点进行通信。

每个IPv6/IPv4节点都必须同时配置IPv6地址和IPv4地址，这两种地址可能相关也可能毫无关系。可以将与IPv4兼容的IPv6地址视为单个地址，其既可以被用作IPv6地址，也可以被用作IPv4地址，完整的128bit就代表IPv6地址，低32bit则代表IPv4地址。

可以采取以下方式来配置地址。

•　使用无状态或状态化（IPv6 DHCP）自动配置方式来配置IPv6地址，该地址既可以是与IPv4兼容的地址，也可以是一个单纯的IPv6地址。

•　采用任何IPv4机制来分配节点的IPv4地址。

•　在配置与IPv4兼容的IPv6地址时，使用IPv4地址配置机制来分配该地址的IPv4部分，通过在IPv4地址前附加96bit前缀0:0:0:0:0:0，节点即可将IPv4地址映射到与IPv4兼容的IPv6地址。如果网络中存在IPv6/IPv4节点，但暂时没有IPv6路由器或地址配置服务器时，这种地址配置方法特别有用。

同时配置了IPv4地址和IPv6地址的节点必须拥有相应的机制来确定应该使用哪个地址，这样的工作就由DNS来完成。

8.5.2　DNS

在DNS中为IPv6定义了一种新的资源记录类型——AAAA记录，该记录可以提供名字到IPv6地址的映射关系。IPv6/IPv4节点上的DNS解析器必须能够同时处理IPv4的A资源记录和IPv6的AAAA资源记录，当节点向DNS服务器查询某个地址时，DNS就可以返回一条A记录或一条AAAA记录。返回的地址类型决定了所使用的协议类型，如果返回的是A记录，则该节点应该使用IPv4地址和IPv4协议来与所请求的目的地进行通信；如果返回的是AAAA记录，则应该使用IPv6。

为IPv6/IPv4主机分配了与IPv4兼容的IPv6地址之后，就在DNS中定义了AAAA记录和A记录，AAAA记录列出了完整的128bit IPv6地址，A记录则列出32bit的IPv4地址。由于列出了两种类型的IP地址，因而纯IPv6（IPv6-only）节点可以查询服务器并接收IPv6地址，而纯IPv4（IPv4-only）节点则可以接收IPv4地址。

如果AAAA记录和A记录中都列出了与IPv4兼容的地址，那么DNS解析器在返回哪种地址以及返回哪种地址会影响通信中所使用的协议类型上存在以下选择。

•　仅向应用返回IPv6地址；

•　仅向应用返回IPv4地址；

•　同时向应用返回IPv4和IPv6地址

DNS服务器返回的地址类型或地址返回的顺序将影响所生成的IP流量的类型。

8.5.3　在 IPv4中隧道化 IPv6

大多数IPv6实现都要沿着IPv4网络进行建设，IPv6主机可能主要通过IPv4网络进行通信，将IPv6包封装到IPv4包中即可支持该功能。目前可以创建以下4类隧道。

•　路由器到路由器；

•　主机到路由器；

•　主机到主机；

•　路由器到主机。

IPv6/IPv4路由器可以封装IPv6流量以通过IPv4网络基础设施进行传送，该方法既适用于位于路由器任一侧的纯IPv6节点，也适用于端到端的IPv6路径穿越IPv4网络进行通信的应用场合。源节点向IPv6路由器发送IPv6包后，该路由器充当隧道的源点，负责将IPv6包封装到IPv4包中，并将IPv4发送到隧道端点，由隧道远端的路由器负责解封装数据包并将其转发至IPv6目的地。

IPv6/IPv4节点可以发起一条去往IPv6/IPv4路由器的隧道，从而为IPv6路径的第一个网段创建隧道。隧道发起节点负责将IPv6包封装到IPv4包中，并将IPv4包发送到隧道端点路由器，由端点路由器解封装数据包，并将IPv6包转发到最终目的地。

IPv6/IPv4主机可以创建去往其他IPv6/IPv4主机的隧道，这完全是一条端到端的隧道。IPv6/IPv4源节点将IPv6包封装到IPv4包中，并通过纯IPv4网络将IPv4包发送到目的地，由目的主机负责解封装该数据包并处理IPv6包。

路由器到主机隧道创建在IPv6路径的最后一个网段，路由器接收到IPv6包之后就创建一个隧道，以便通过其所连接的IPv4网络将该数据包转发给目的主机，目的主机接收到该IPv4包之后，负责解封装该数据包并处理IPv6包。

路由器到路由器隧道以及主机到路由器隧道这两种方法并没有将隧道建立到最终的目的地，远端隧道端点与数据包的最终目的地是不同的，也与最终目的地址不同。虽然需要知道隧道远端的IPv4地址，但无法从真实的IPv6目的地址中得到该信息。这两种方法需要使用配置隧道。

对其余两种隧道方法（主机到主机隧道和路由器到主机隧道）来说，远端隧道端点与数据包的最终目的地相同，因而可以从与IPv4兼容的IPv6目的地址的低32bit中获得远端隧道端点的IPv4地址，从而可以为这两种隧道方法创建自动隧道。

1. 配置隧道

通过在分隔IPv4与IPv6网络的Cisco路由器上创建隧道接口即可在路由器之间创建隧道。需要在两端路由器上定义隧道端点，为该隧道创建一个IPv6子网，并为两端路由器分配IPv6地址；如果使用了某种IPv6动态路由协议（如RIPng或BGP），那么还需要在隧道接口上启用该协议。如图8-26所示，两个IPv6网络连接在一个IPv4网络上，在这两个IPv6网络之间创建了一条隧道以进行通信。

图8-26　IPv6网络经IPv4网络创建隧道

路由器Tulip和Lily是纯IPv6路由器，它们通过Daisy和Rose之间的IPv6-over-IPv4隧道进行通信。

例8-10显示了路由器Daisy和Rose的配置情况。

例8-10：配置隧道的路由器配置。

上例中所示的隧道接口是一个通用隧道，配置在ipv6ip模式下。

如例8-11所示，从Tulip到Lily应用命令traceroute，可以看出IPv6包穿越隧道的情况。

例8-11：显示IPv6包穿越从Tulip到Lily的隧道的情况。

第1个地址是Daisy的IPv6以太网地址，第2个地址是Rose的隧道接口地址，第3个地址是Lily的以太网地址。

配置隧道可以提供一种直观的通过IPv4网络连接两个IPv6网络的实现方式。

2. 自动隧道

配置了自动隧道的封装主机可以从目的地的与IPv4兼容的IPv6地址中提取出IPv4地址，而封装主机必须拥有去往该IPv4地址的IPv4连接。源主机将数据包封装到IPv4头部中，将提取出来的IPv4地址作为目的地址，并将从自身IPv4兼容地址中提取出来的IPv4地址作为源地址，而主机间的路由器则根本不知道IPv6净荷的存在。

8.5.4　NAT-PT

另一种允许IPv6与IPv4网络及主机共存的方法是使用NAT-PT（Network Address Translation-Protocol Translation，网络地址转换一协议转换）。IPv6/IPv4路由器为纯IPv6和纯IPv4主机进行地址和协议转换，当这些主机进行通信时，都不需要知道它们正在运行的是不同版本的IP协议，完全由NAT-PT路由器来完成所有的转换工作，包括源地址和目的地址的IPv6与IPv4转换。

IPv4 NAT中存在的问题也依然存在于IPv6-to- IPv4 NAT-PAT中，被转换的入站流量和出站流量都必须穿越同一台地址转换器，地址转换器维护了被转换会话的状态信息。请注意，端到端的安全性是不可能的，这是因为IPSec无法穿越NAT设备。除非在转换路由器上运行应用转换网关，否则在IP头部之外任何位置携带IP地址的应用程序都将无法正常工作。穿越协议域的DNS查询消息中必须要在被转换的DNS包（在IPv4与IPv6之间进行转换）中包含请求和响应信息。

除了地址之外，IPv4与IPv6之间的转换存在的另一个特殊问题就是头部信息。通过本章的学习已经知道，IPv6头部与IPv4头部字段是不同的，在选项的处理上也完全不同，因而除非迫不得已，不要使用这种共存方式。

8.6　附注

1IEEE，“EUI-64（64bit全局标识符）注册机构指南”。

http://standards.ieee.org/regauth/oui/tutorials/EUI64.html（1997年3月）

2R. Hinden和S. Deering, “RFC 2375：IPv6多播地址分配”（仍在发展中）。

3T. Narten、E. Nordmark和 W. Simpson，“RFC 2461：IPv6的邻居发现”（仍在发展中）。

4C. Partridge、T. Mendez和 W. Milliken, “RFC 1546：主机任播服务”（仍在发展中）。

8.7　展 望

IPv6不但极大地扩展了Internet的规模，而且简化了主机的配置管理。许多主机配置工作都可以通过路由器配置来完成，因而路由器管理（将在第9章中进行讨论）比以往任何时候都重要，这样才能保证配置的安全性，并让路由器的运行保持可靠性和最优性。

8.8　推荐读物

Huitema C.所著的《新因特网协议IPv6》，由清华大学出版社于2000年12月出版。虽然该书有些过时（许多RFC已成为草案标准，又出现了许多新的RFC，而且部分RFC也被修改），但其仍然提供了很好的技术论述和设计决策方面的视角。

8.9　复习题

附录D中提供了以下复习题的答案。

（1）下面哪一项正确表示了带有60bit前缀的地址200A 0000 0000 0C00 0000 0000 0000 0000？

A. 200A:0000:0000:0C/60

B. 200A::0C00:0:0:0:0/60

C. 200A:0000:0000:0C00::/60

D. 200A::0C00::/60

E. 200A:0:0:C00::/60

F. 200A::0C/60

（2）地址0:0:0:0:0:0:0:0的使用场合是什么？

（3）假设某用户配置其站点边界路由器（该路由器连接在某个IPv6公共网络上），让该路由器宣告其所有内部网络地址（包括FEC0:0020:0:0100::/56），但却被来自该IPv6公共网络管理员告知有问题，为什么？

（4）哪些扩展头要求自源至目的地路径上的每个IPv6节点都必须予以处理？

（5）哪些扩展头被用于指定在到达目的地之前需要访问的路由器列表并让其中的每台路由器都处理该头部？

（6）假设某路由器接收到一个比其出站链路MTU大的数据包，请问该路由器是否分段该数据包并将这些分段数据包转发到目的地？

（7）请问置位RA消息中的Mbit会产生什么效果？

（8）如果路由器在其RA消息中宣告前缀信息，请问如何使用这些信息？

（9）主机的IP地址可以存在哪两种状态？每种状态的角色是什么？

（10）路由器在其RA消息中宣告何种信息，让主机在发起IP会话时停止使用某特定前缀？

（11）如果某节点的邻居状态为DELAY，那么该节点是否可以向该邻居发送数据包？

（12）某主机没有运行任何路由协议，利用一台默认路由器向远程节点发送数据，如果该默认路由器出现了故障，那么请问该主机是否会继续向该失效路由器发送数据，直至TCP连接失效？

（13）多播包的作用域值有哪些？其作用是什么？

（14）在Cisco路由器启用IPv6路由的命令是什么？

（15）在接口上启用IPv6的接口子命令是什么？

（16）启用RIPng进程的命令是什么？

（17）如何在邻居之间启用BGP-for-IPv6进程？

8.10　参考文献

Atkinson, R.和 S. Kent, “IP认证头”，RFC 2402, 1998年11月。

Atkinson, R和 S. Kent, “IP封装安全净荷头”，RFC 2403, 1998年11月。

Atkinson, R.和 S. Kent, “Internet协议的安全体系架构”，RFC 2401, 1998年11月。

Bates, T., R. Chandra, D. Katz和 Y. Rekhter, “BGP-4的多协议扩展”，RFC 2283, 1998年2月。

Coltun, R., D. Ferguson和 J. Moy, “用于IPv6的OSPF”,RFC 2740, 1999年12月。

Conta, A.和S. Deering, “IPv6规范中的通用分组隧道”,RFC 2473, 1998年12月。

Conta, A.和 S. Deering, “用于IPv6规范的ICMPv6”，RFC 1885, 1995年12月。

Deering, S.和 R. Hinden, “IPv6规范”，RFC 1883, 1995年12月。

Deering, S., W. Fenner和B. Haberman, “用于IPv6的MLD”，RFC 2710, 1999年 10月。

Gilligan, R.和E. Nordmark, “用于IPv6主机和路由器的转换机制”，RFC 1993, 1996年4月。

Haberman, B., H. Sandick和 G. Kump, “IPv6中的PIM路由”，draft-ietf-pim-ipv6-03.txt, 2000年3月。

Hinden, R., M. O’Dell和S. Deering, “可聚合全局单播地址格式”，RFC 2374, 1998年7月。

Hinden, R.和 S. Deering, “IPv6地址体系架构，” RFC 2373,1998年7月。

Hinden, R.和 S. Deering, “IPv6多播地址分配”，RFC 2375, 1998年7月。

Hinden, R.，S. Deering, R. Fink和T. Hain, “初始的IPv6 Sub-TLA ID分配”，<draft-ietf-ipngwg-iana-tla-03.txt>, 2000年1月13日。

Hubbard, K., M. Kosters, D. Conrad, D. Karrenberg和J. Postel, “Internet注册机构IP地址分配指南”，BCP12，RFC 1466, 1996年11月。

IAB和IESG, “IPv6地址分配管理”，RFC 1881, 1995年12月。

IEEE, “EUI-64注册机构指南”，http://standards.ieee.org/db/oui/tutorials/EUI64.html, 1997年3月。

Johnson, D.和S. Deering，“保留的IPv6子网任播地址”，RFC2526, 1999年3月。

McCann, J., S. Deering和J. Mogul, “用于IPv6的路径MTU发现”，RFC 1981, 1996年8月。

Malkin, G和R. Minnear, “用于IPv6的PIPng”，RFC 2080, 1997年1月。

Marques, P.和F. Dupont, “使用BGP-4多协议扩展进行IPv6域间路由”，RFC 2545, 1999年3月。

Narten, T., Nordmark, E. and W. Simpson, “IPv6的邻居发现”，RFC 2461, 1998年12月。

Partridge, C., T. Mendez和W. Milliken, “主机任播服务”，RFC 1546, 1993年11月。

Reynolds, J.和J. Postel, “已分配号码”，STD2，RFC 1700, 1994年10月（也可参见 www.iana.org/iana/assignments.html）。

Thomson, S.和 C. Huitema，“支持IPv6的DNS扩展”，RFC 1886, 1995年12月。

Thompson, S和T. Narten, “IPv6无状态地址自动分配”，RFC 1971, 1996年8月。

Thomson, S.和T. Narten, “IPv6无状态地址自动分配”，RFC 2462, 1998年12月。

Tsirtsis, G和 P. Srisuresh, “NAT-PT”，RFC 2766, 2000年2月。

本章将主要讨论以下主题。

•　策略及规程定义——清晰的策略及规程定义是维护任何运行良好的网络的基本需求，包括服务等级协定、更改管理策略以及逐级上报规程等内容。

•　SNMP—SNMP（Simple Network Management Protocol，简单网络管理协议）是网络管理应用的基础，理解其工作方式是使用任何网络管理应用程序的必要条件。

•　RMON——RMON提供了额外的网络管理能力，理解其工作方式是使用任何基于RMON的网络管理应用程序的必要条件。

•　日志记录——在研究可能与路由器相关的网络问题时，记录下Cisco路由器上发生的事件可以提供非常有价值的资源信息。

•　Syslog——将信息记录到syslog（系统日志）服务器上，实现路由器事件信息的集中式存储，可以用来解决多个网络设备引起的网络事件。

•　NTP——NTP（Network Time Protocol，网络时间协议）可以同步所有网络设备的时钟，从而简化对过去事件的处理。

•　记账——在网络设备上执行的记账功能可以实现相关数据的收集，一方面用来理解流量流，另一方面可以根据这些流量流对网络用户进行计费。

•　配置管理——配置管理是一组用来维护网络运行、验证配置文件的工具及进程。

•　故障管理——故障管理系统的作用是向网络管理员通告网络中的故障事件，这里所说的故障可能是导致某些网络服务不可用的事件，也可能是网络性能受到影响的迹象。

•　性能管理——性能管理系统负责收集相关数据用于趋势和容量规划。

•　安全管理——路由器安全管理可以确保路由器的完整性，有多种工具和配置参数来确保路由器的安全性。

•　支撑管理进程的服务器设计——支撑管理进程的服务器是观察网络的关键，因而需要确保其安全性、健壮性，并提供到其所管理网络设备的冗余接入能力。

•　网络健壮性——网络健壮性需求应包括LAN本身以及将端节点路由到其余网络（离开LAN），仅配置了单个默认网关的端节点可以利用HSRP提供的默认路由器冗余性来实现健壮性。

•　实验室——网络实验室用于测试网络规划、设计、新硬件、新操作系统以及新协议和新规程等，实验室应尽可能地反映实际的生产网络，从而保证测试验证的有效性。

第　9　章
路由器管理

到目前为止，读者已经了解了如何通过网络和路由器转发IP包，为了成功转发IP包，要求网络和路由器都必须保持健康，处于良好运行状态并始终可用。为了保证网络和路由器的健康，必须保证能够管理它们（包括主动式管理和被动式管理）。此外，利用实验室来测试和监控转发机制（包括路由协议、网络地址转换、多播和服务质量等）的效果，以确保网络和路由器能持续平滑地运行。

本章描述了明确操作策略和规程的必要性、在路由器上配置SNMP和RMON以监控网络和路由器的基础以及性能、故障和安全管理的成功要素，此外还讨论了保持路由器可用性的方法以及实验室的构建与应用。

9.1　策略及规程定义

如果没有清晰的策略及规程，几乎不可能成功地管理路由器，必须用文档确定操作策略，明确不同管理级别的负责人以及他们的责任的时间，当路由器的配置发生变更后一定要用文档记录下来。规程记录的则是如何实施变更，包括发生了哪些变更以及恢复和测试规程。当更熟练的工程师开始处理网络问题以及涉及网络管理时，规程则规定了需要遵循的步骤。当然，还需要有明确的计划来宣传这些策略及规程，以便让所有的相关人员都了解它们以及它们所发生的变化。

在规定用户期望从网络中获得相应QoS（Quality of Service，服务质量）（如往返时延时间、最小吞吐量或网络可用性）的策略时应包含相应服务不能满足时所要采取的动作，这些就被称为SLA（Service Level Agreements，服务等级协定）。本节将详细描述SLA及变更管理策略、逐级上报规程以及保持策略和规程更新的必要性。

9.1.1　SLA

SLA明确定义了服务的质量和数量，以及何时、由谁来提供这些服务。SLA中规定的服务数量可以是向用户保证的响应时间和吞吐量以及最大抖动，一般以网络可用性的百分比来表示。SLA标示了网络何时可用、单次故障的最大时间、计划故障时间以及服务提供方，标示服务提供方非常重要，这样可以避免在责任范围上产生误解或分歧。通过定义每个组织机构所要负责的网络组件以及服务等级，可以避免任意指定带来的随意性。只有定义了清晰的SLA，提供SLA的组织机构和接收SLA的组织机构才能理解合同的约定并达成一致。SLA既可以由向本企业提供服务的外部组织机构（如ISP或为本企业提供网络外包服务的公司）提供，也可以由本企业内部向其他商业部门提供网络服务的IT部门提供。

最有效的SLA应该明确写出商业目的，例如，考虑以下SLA声明条款。

•　站点A与站点B之间1小时的平均往返时延小于50ms；

•　链路可用性不小于95%。

如果商业目标需要99.999%的可用性但往返时延达到400ms即可时，上述SLA声明就不是很有用。任何为特定应用、端站或站点提供特殊QoS的提供商都需要在SLA中包含所要保证的QoS等级。

如果不监控所提供服务，那么SLA就不能提供任何好处。在SLA中保证QoS的提供商需要验证用户或应用是否真地得到了SLA中规定的QoS，因而提供端到端保证的SLA必须得到端到端的监控。例如，以下两条SLA声明的测量方式就不一样。

•　站点A的用户与站点B的服务器之间1小时的平均往返时延小于200ms；

•　站点A的站点边界路由器与站点B的站点边界路由器之间1小时的平均往返时延小于100ms。

这两条SLA声明可能包含在同一个SLA中，需要分别进行监控。收集到的数据需要同时报告给服务提供商和服务用户，双方都需要阅读该报告以验证SLA是否得到满足。

9.1.2　变更管理

无变更管理策略的网络就像一个处于混沌状态的网络。变更管理策略是说明何时可以实施变更、由谁实施变更、如何记录和发布即将实施的变更以及如何和在何处记录整个变更情况。

变更管理策略规定了对网络或系统实施变更时所要遵循的规程，包括路由器配置变更、新设计方案实施、IOS升级甚至是新网络应用的实施等内容，应填写至少包括以下内容的电子表格。

•　谁请求变更；

•　为何要实施变更；

•　变更带来的影响是什么（不会造成破坏、可能会造成破坏、造成破坏）；

•　何时实施变更；

•　实施变更需要多长时间；

•　变更的有效时间是多长；

•　对即将实施的变更来说，做了哪些测试规程；

•　谁进行的测试；

•　谁将负责实施变更；

•　实施变更将遵循什么样的规程；

•　为验证变更是否成功，需要执行什么样的变更后测试规程；

•　恢复规程是什么。

利用CCB（Change Control Board，变更控制委员会）可以监控任何指定星期内所有即将实施的变更，并批准或否决变更。CCB除了要包括网络设计、运行、维护和管理等各部门有经验的代表之外，还应包括使用网络的各部门（如组织机构内不同的商业单位）的代表。如果该网络是一个ISP，那么网络用户代表就可能是客户服务代表（负责一组客户的服务）。由 CCB负责审阅变更过程，以确保所有的网络架构师、运维人员、管理员、经理和客户支持人员以及网络用户都知晓变更计划和潜在的影响，并有机会在实施变更前考虑其他应对措施。

在实施变更之前，需要经全体CCB成员同意并经所有相关方签字确认，表示大家都已经知道了即将实施的变更情况及潜在的风险。

有时可能需要实施紧急变更（如为了解决某个故障），因而变更管理策略还需要规定紧急情况下的处理措施，包括谁可以实施紧急变更、在什么情况下可以实施紧急变更以及如何记录紧急变更。非常重要的一点是，必须记录所有的变更情况。为了能够在以后了解变更情况，便于处理将来网络中出现的路由器问题，可以利用表格来记录变更时间、变更内容、变更实施者，并引用变更描述文档（如表9-1所示）。

假设位于站点Denver的某人向网络运行中心报告其去往远程站点的连接问题，称该问题首次出现在5/29/00、星期一早晨，变更日志清楚地显示影响Denver连接的变更发生于星期六晚上，这就为该故障的检测与排除提供了清楚的起始点。

并不是只有企业网需要严格的变更控制策略，ISP也可以从这些策略中获得极大的益处。对企业网来说，如果变更行为在不经意间影响了大量人员，将会给商业活动造成破坏，并招致最终用户的大量抱怨，而ISP网络上的破坏性变更则可能会潜在地影响大量企业，导致更严重的商业活动中断事故。这样一来，不仅会招致更多的抱怨人群，而且这些人还极有可能因不满现有的网络运行状况而更换到该ISP的竞争对手。

9.1.3　上报规程

明确定义的上报规程将规定各种能力级别的工程师在将故障问题提交到上一级工程师之前所应处理的时间，规定由谁以及如何向上一级转交故障问题，还规定了如何、何时以及以多大的频度向管理层通报这些故障问题，包括将仍未解决的问题提请管理层注意之前所经历的时间。

9.1.4　更新策略

制定得再好的策略都会随着新技术的出现或组织机构的变动而逐渐过时，因而必须保持更新以反应变动情况。需要通知实施这些策略和规程的相关人员并对他们做必要的培训，并且要向那些可能会受策略变动影响的相关人员通知所有的变动情况。

9.2　SNMP

CiscoWorks等网络管理软件使用SNMP（Simple Network Management Protocol，简单网络管理协议）来管理网络设备。SNMP是所有漂亮的网络框图、报表及图形背后的基础，由其查询网络设备、收集相应的数据来构建这些网络框图、报表及图形。所有的Cisco路由器都支持SNMPvl, IOS 11.3及以后版本的Cisco路由器都支持SNMPv2。SNMPv2C支持批量数据传送，并且能提供比SNMPv3更详细的差错报告。

注意：　SNMPv2C包括SNMPv2（定义在RFC 1902～1907之中）和SNMPv2C（定义在RFC 1901^2之中）。

9.2.1　SNMP 概述

SNMP包括管理器（manager）和代理（agent），管理器负责收集数据，代理负责提供数据。

管理器可以是CiscoWorks等NMS（Network Management Systems，网络管理系统）的一部分，代理则驻留在被管设备（如路由器）上。

管理器和代理之间会建立一定的关系，使得管理器能够从代理取得信息或者在代理上设置相应的信息。管理器向代理发送SNMP消息以请求数据或者请求代理按照管理器规定的数据设置参数，相应的消息则分别被称为get（获取）和set（设置）。管理器团体（可以从代理获取数据或请求代理设置参数）通过服务控制列表和密码来进行定义，该密码被称为团体字符串（community string）。管理器在所有的get和set消息中都包含该团体字符串，预配置了该团体字符串的代理则验证是否允许该请求管理器执行get或set操作，以及团体字符串是否正确。管理器可以请求运行了代理的平台所支持的MIB（Management Information Base，管理信息库）中定义的任意参数，图9-1举例说明了管理器从路由器请求链路状态信息。

图9-1　管理站发起get请求以查看路由器串口0的操作状态，路由器则响应以get reply（获取回复）消息

管理站希望查明路由器串行接口0的运行状态，为此发起了一条SNMP get请求，请求 MIB变量ifEntry.ifOperStatus.1。其中，“ifEntry”是代理上所有接口可以被轮询的变量列表，“ifOperStatus”是其中的一个变量，“1”则是索引值（在本例中标识串行接口0），get请求消息中包含了团体字符串“resticted”。路由器响应了该消息，响应消息指示被请求的变量值等于1，MIB定义ifOperStatus值为1时表示状态为up（运行），值为2时表示状态为down（中断），值为3时表示状态为testing（测试）。图中所示的链路串口0的状态为up。

注意：　所有具备SNMP能力的路由器都支持MIB II，MIB II中定义了接口变量，有关MIB II的定义请参见RFC 1213^3。

SNMP运行在UDP之上，而且在路由器上的优先级低于其他进程，如果路由器忙于处理高优先级任务，那么将丢弃SNMP消息。大多数管理器的配置都规定在显示任何状态变更之前必须出现一次以上轮询丢失情况。

SNMP可以收集大量信息，通过SNMP可以收集每个网络设备（以及网络设备中的组件）的每种协议（协议栈中的所有层）的统计信息，有时被收集的统计信息的变化非常快，此时管理器将收集变化数据的相关信息，如异常接口上每分钟出现的错误次数。有时可能非常希望广泛地频繁应用SNMP来获取各种各样的数据，但是过多的SNMP流量会给网络性能带来一定的影响，为此需要仔细管理SNMP数据流量。在启用任何管理应用之前，需要全面理解所要产生的SNMP流量（当然还要包含其他流量）。

有时代理会向管理站发送trap（陷阱）消息，trap消息是主动产生的，是某些事件的结果，包括链路中断、BGP链路故障、认证失败或其他事件。事件发生后，路由器会向管理站发送一条SNMP trap消息，以向管理站告知该事件，管理站上的配置会指示如何处理这些trap消息，可能会引起某些网络框图颜色的变化，或者在屏幕上显示一条消息，或者向网络管理员发送一封电子邮件或一条短信。

SNMP是CiscoWorks等网络管理平台的工作基础。

9.2.2　CiscoWorks

利用CiscoWorks可以管理Cisco网络。CiscoWorks运行于HP OpenView、IBM NetView或Sun NetManager等网络管理平台之上，这些网络管理平台提供了通用的网络框图、报表和图形功能，而CiscoWorks则在此基础上增加了一些Cisco专有功能实体，如机架视图和设备配置管理等。

CiscoView是CiscoWorks的一个应用程序，CiscoView提供了Cisco网络设备的实时视图，这些视图展示了被持续更新的有关设备配置和性能状况的物理情况，机架视图则显示了Cisco设备的前后面板视图，包括LED状态指示灯。单击机架视图中的某个端口之后，可以弹出一张与该端口相关的统计表，包含诸如利用率、输入和输出错误、队列丢包、冲突以及被忽略的数据包等信息。CiscoView还可以提供显示Cisco设备系统性能的仪表盘式视图，如内存使用情况、缓存使用情况以及CPU利用率等。CiscoView集中运行在某个网络管理站点，通过单一GUI（显示动态状态报告、性能统计和网络查询等信息）可以检视、重新配置和监控基本的设备数据，而无需物理上前往不同的站点或远程站点检查每台设备、每个模块或每个端口的连接情况。

通过CiscoWorks与所选择的网络管理平台，就可以执行故障管理、性能管理和配置管理，而网络框图、报表和图形则主要依赖于SNMP提供的最新数据。

必须对被CiscoWorks管理的代理进行必要的配置，让其接受CiscoWorks工作站的轮询并向CiscoWorks工作站发送trap消息。

9.2.3　路由器的SNMP配置

可以利用多种全局SNMP命令在路由器上启用CiscoWorks管理功能，所有的全局snmp命令都以snmp-server为开头，而不是使用哪个特殊命令来启用SNMP。在路由器上输入的第一条snmp-server命令将启用两个版本的SNMP。

路由器必须被配置为使用与管理站一致的SNMP版本。

创建管理团体的配置命令如下。

[no] snmp-server community string [view view-name] [ro | rw][access-list number]

团体字符串充当管理器和代理之间的密码，管理站可以以RO（read-only，只读）或RW（read/write，读取/写入）SNMP方式访问路由器。CiscoWorks管理站需要以RW方式访问路由器，以获得完全的管理能力，特别是设置参数、重装路由器已经更新配置的能力。SNMP是一种非常强大的管理工具，通过SNMP MIB几乎可以获取路由器所有的配置和状态信息。通过SNMP读取访问方式获得的信息可以用来了解路由表和ARP表，从而便于某些管理人员了解特定设备以及特定攻击区域的路由情况。SNMP写入访问方式可以更改设备配置、重置链路和路由器。为了限制可以读取或写入路由器的设备，可以利用access-list选项，该列表是一种简单的访问列表，用于指定被允许管理站的地址或地址范围。

启用SNMP所需要的惟一命令就是snmp-server community，其他命令都属于可选命令，用于精细化调整可收集或可设置的信息。

命令snmp-server community中的选项view用法如下。

snmp-server view view-name oid-tree{included | excluded}

该命令的作用是限制SNMP管理器可以访问的MIB对象。oid-tree（Object Identifier tree，对象标识符树）用于标识被包含或被排除的MIB子树，要想标识一个子树，就需要利用数字（如1.3.6.2.4）或单词（如“System”）组成的文本串来指定所期望子树的顶部。指定系统就意味着系统子树中的所有MIB值都被包含或都被排除，1.3.6.2.1.2是iso.org.dod.mgmt.mib2．接口的数字化表达形式。

注意：　参考定义各个MIB的RFC以及RFC 1902 “SNMPv2管理信息的结构”，可以进一步了解所有对象标识符的数字化表达形式。

SNMP管理器可以向虚拟终端和控制台用户发送消息，发送消息的SNMP请求也同时指定消息发出后所要采取的操作，如关闭系统。这是一个非常强大的工具，为了启用该功能，必须配置命令snmp-server system-shutdown，如果没有配置该命令，那么将无法启用该机制。

另一个强大的工具就是让TFTP服务器通过SNMP保存和加载配置文件，可以利用命令snmp-server tftp-server-list number来限制允许使用该能力的服务器，其中的number表示访问列表号。

指定将trap消息发送给哪台主机以及发送什么类型的trap消息的命令如下。

snmp-server host host [version {1 | 2c}] community-string [udp-port port] [trap-type]

如果没有指定trap-type，那么该路由器将可以向主机发送所有类型的trap消息。版本定义的是管理站的SNMP版本，udp-port选项则用于更改默认的端口号。

在向指定主机发送trap消息之前，必须在全局范围内启用trap。某些trap在默认情况下就被启用，而其他trap则需要利用以下命令进行启用。

snmp-server enable traps trap-type trap-option

命令snmp-server enable traps的作用是在路由器上针对某些指定trap消息启用trap机制，而不指定trap消息所要发送的主机，利用该命令可以启用或禁用某些类型的trap。一旦禁用了trap，那么将忽略在每台主机上指定的trap消息。

还有一个在接口层面上控制trap消息的命令，用于在所配置接口上启用或禁用链路状态 trap的接口子命令是[no] snmp trap link-status，默认情况下，所有接口上都启用了trap机制。

对一个接收trap消息的主机来说，需要使用命令来指定该主机的地址，并在全局范围内启用trap机制，可以利用命令snmp-server enable traps，也可以利用其他命令（如snmp trap link-status）或者默认启用。下面将给出一些具体的配置示例。

例9-1所示配置利用团体字符串“access”来表示允许以只读访问方式访问SNMP管理器，启用了BGP trap，并将BGP trap发送给主机172.16.1.200和172.16.1.201。

例9-1：允许以只读访问方式访问SNMP管理器并启用BGP trap。

路由器10.1.2.1和10.1.2.25之间建立了一条BGP外部连接，该连接被拆除后将会生成trap消息，如例9-2所示。

例9-2：拆除BGP外部连接将会生成trap消息。

SNMPvl的trap消息被同时发送给两台trap主机。正在发送trap消息的路由器的地址是10.1.2.25，该地址是向trap主机发送数据包时所使用的出站接口的地址。MIB OID bgpPeerEntry.14.10.1.2.1（表示被该对等体看见的在去往对等体10.1.2.1的连接上的最后BGP差错）的值为00 00，表示没有差错发生。OID bgpPeerEntry.2.10.1.2.1表示BGP对等体的状态（表示该对等体看见的去往对等体10.1.2.1的连接的状态），其值为1，表示处于空闲状态。

注意：　有关Cisco所支持的MIB列表情况请参见www.cisco.com/public/mibs/vl。

在例9-3所示配置中，主机172.16.1.201被升级到SNMPv2C，且该主机仅接收BGP trap消息，172.16.1.200仅接收TTY trap。此外，所有SNMP trap消息的源IP地址都被配置为环回接口的IP地址172.16.2.25。

例9-3：启用SNMPv2C trap并指定SNMP trap消息的源IP地址。

当用户退出路由器时，该路由器将发送TTY连接trap（如例9-4所示）。

例9-4：用户退出路由器时该路由器将发送TTY连接trap。

上例中所示trap类型为enterprises.9，当重新加载路由器或关闭TCP连接时将生成该trap。

ltsLineSessionEntry.1代表线路会话类型，值为5表示该trap是由Telnet会话生成的。

tcpConnEntry.1代表TCP连接的状态，值为5表示该连接已被关闭。接下来的数字分别是Boxer的IP地址以及通过Telnet进入Boxer的设备的IP地址。

ltcpConnEntry.5代表TCP连接已建立的时长，以百分之一秒为单位，因而可知该连接已建立9.58秒。接下来的两个OID代表该TCP连接的输入字节数和该连接的输出字节数，即输入45字节，输出87字节。ItsLineEntry.18显示的是TACACS用户名（如果启用了TACACS的话）。例9-5显示了发送给172.16.1.201的SNMPv2C BGP trap。

例9-5：SNMPv2C BGP trap消息比SNMPvl BGP trap中包含了更多的信息。

SNMPv2C中的trap消息中包含了比SNMPv1 trap消息更多的信息，系统运行时间表示的是该系统网络管理部分最后重新初始化之后的时间，以百分之一秒为单位。OIDinternet.6.3.1.1.4.1.0（值为bgp.7.2）代表专用trap——bgpBackwardTransition，该trap是在连接状态从高编号状态迁移到低编号状态（如从已建立状态到空闲状态）时生成的。例9-6显示的BGP状态为ESTABLISHED状态。

例9-6：BGP状态进入ESTABLISHED。

internet.6.3.1.1.4.1.0 OID的值为bgp.7.1代表bgpEstablished trap，而对等体表项值6表示对等体10.1.2.1的连接为ESTABLISHED。

例9-7配置中的团体字符串“restricted”表示仅允许以只读访问方式访问access-list 1所指定的IP地址，而且限制该主机只能查看部分MIB，特别是接口表项。

例9-7：允许以只读方式访问访问列表所指定的IP地址。

其他SNMP管理器将无法访问携带团体字符串“restricted”的设备上的SNMP代理。如果在该路由器上仅配置了该团体字符串，那么172.16.1.200是惟一可能读取SNMP MIB变量的设备，但其无法设置变量。命令view配置了一个名为interface_entries的视图，该视图仅局限于变量ifEntry。命令community将已定义的视图与团体字符串“restricted”和access-list 1关联在一起。

例9-8显示了对变量ifEntry和MIB树的IP树枝执行SNMP walk操作后的输出结果。

例9-8：为路由器设置视图限制之前对ifEntry和MIB树的IP树枝执行walk操作。

注意：　与命令snmpget仅读取单条表项不同，命令snmpwalk读取的是MIB树的整个树枝。

例9-9显示的是实施了视图限制之后的命令snmpwalk的输出结果。

例9-9：为路由器设置视图限制之后对ifEntry和MIB树的IP树枝执行walk操作。

请注意，SNMP管理站将无法读取未被显式包含在视图定义中的任何MIB。

9.3　RMON

RMON（Remote Monitoring，远程监控）可以大大增强SNMP的提供能力，让管理站能查看更多关于节点以及节点间交互的信息。

9.3.1　RMON 概述

与SNMP类似，RMON的功能也被用于管理站，即RMON控制台和被管代理，RMON数据被存储在路由器的表格中并被发送（被请求时或因某些事件而被触发发送trap）给RMON控制台。由于RMON在最大程度上减少了常规SNMP包中被轮询的数据量，因而减少了网络流量。路由器上的RMON引擎会在本地轮询SNMP MIB变量。RMON中有两个阈值，分别是上升阈值（rising threshold）和下降阈值（falling threshold），当MIB变量的值超过某个阈值时，RMON就会创建一条日志表项并发送一条SNMP trap消息，不过在MIB变量值超过另一个阈值之前，RMON都不会为该阈值生成更多的事件。即，变量值增大到超过上升阈值时会触发一个事件，但是在该变量值低于下降阈值之前都不会触发其他事件。

如果订购的路由器没有包含RMON选项，那么将拥有告警和事件能力。在RMON选项（仅2500和AS5200系列路由器提供）中增加了统计（statistics）、历史（history）、主机（host）、前N名主机（hostTopN）、矩阵（matrix）、过滤器（filter）和捕捉（capture）等7个组。

只有2500和AS5200系列路由器的以太网接口上支持数据包捕捉机制，并且仅能捕捉包头。数据包捕捉方式有如下两种。

•　Natively（本地模式）：目的地是该路由器以太网接口的数据包。

•　Promiscuously（杂乱模式）：以太网网段上的所有数据包。

由于数据包捕捉机制是数据敏感型和处理器敏感型机制，因而如果启用了该机制，那么就应该严密监控路由器的性能和网络流量。

通过告警和事件能力（结合现有的MIB变量），可以定义主动监控区域，还可以在任意MIB对象上设置告警，这些MIB对象的值可以是整数（integer）型、计数器（counter）型、容器（gauge）型或时间戳（timetick）型。

注意：　RFC 2819中定义了全部RMON组以及这些组之间的相互作用。

9.3.2　路由器的RMON配置

定义一个告警表表项以及告警所要设置的变量的命令如下。

rmon alarm number variable interval {delta | absolute} rising-threshold value [event- number] falling-threshold value [event-number] [owner string]

其中，number惟一地标识了告警表中的表项，variable是一个MIB OID，interval是MIB对象相邻两次监控的间隔时间。关键字delta或absolute规定告警是否要测试指定间隔内MIB值的变化或实际的MIB值。rising-threshold是一个阈值，达到该阈值后就会生成一个事件，当本取样值大于或等于该阈值，且上一个取样值小于该阈值时，将生成一个事件。如果命令中指定了event-number，那么该值就是取样值超过上升阈值后所触发的事件数。仅当取样值低于falling-threshold时，才会生成另一个事件，这里的falling-threshold也是一个阈值，达到该阈值后也会生成一个事件；当本取样值小于或等于falling-threshold值，且上一个取样值大于该阈值时，将会生成一个事件；仅当取样值大于rising-threshold时，才会生成另一个事件。

在RMON事件表中增加或删除事件的命令如下。

rmon event number [log] [trap community] [description string] [owner string]

当满足或超过上述告警命令中所指定的event-number和rising-threshold或falling-threshold时，将触发该命令所定义的事件，事件发生后将会生成一条日志表项或一条SNMP trap（或两者）。在发送SNMP trap之前，需要为命令rmon event中指定的团体配置命令snmp-server community和snmp-server host。

例9-10对接口上的大量输出错误和路由器的高CPU使用率启用了相应的事件和告警机制。可以采用完整方式来录入MIB OID，如1.3.6.1.2.1.2.2.1.20.4（表示ifOutErrors的MIB值）或1.3.6.1.4.1.9.2.1.58.0（表示Cisco CPU MIB值，以CPU忙时利用率的5分钟移动平均值来表示），路由器会自动将该OID转换成例9-10所示结果。

例9-10：对接口上的大量输出错误和路由器的高CPU使用率启用事件和告警机制。

RMON事件1记录了一个被描述为“High ifOutErrors”（与所有者jsmith相关联）的事件，该事件还将同时触发一条有关团体eventtrap的SNMP trap，出现相关告警后将创建该事件。例9-10中为MIB变量ifEntry.20.4（代表4号接口上的输出差错）配置了编号为10的RMON告警，本例中的4号接口为串行接口1。告警机制以20秒为周期监控MIB变量，当变量值上升到15或更大时，就会触发告警，从而触发事件1。如果随后的MIB OID取样显示该接口上已经没有了输出错误，那么该告警将被重置并被再次触发。

RMON事件2被描述为“High 5-minute CPU”，当MIB OIDlsystem.58.0（AvgBusy5）的取样值等于或大于50时，相关联的告警（即编号为11的告警）将会生成该事件。当CPU忙时利用率的5分钟移动平均值小于25时，该告警将被重置并被再次触发。

例9-11显示了由事件1所生成的SNMP trap。

例9-11：由例9-10中定义的事件1所生成的SNMP trap。

RFC 2819定义了详细的告警表项^4。告警表项1表示告警编号，如例9-11所示，本SNMP trap是由10号告警生成的。告警表项3定义了正被采样的对象标识符，本条SNMP trap中的 OID是ifEntry.20.4（即串行接口1上的输出错误数）。告警表项4是采样类型，值为1表示该取样类型为绝对值，值为2表示该取样类型为增量。告警表项5是最后一个采样周期内的告警值。告警表项7是已定义的上升阈值，在例9-11的SNMP trap中，告警值20超过了上升阈值15，因而产生告警事件。

利用命令show rmon alarms和show rmon events可以查看RMON的告警和事件。

例9-12显示了这两个命令的输出结果。

例9-12：利用命令show rmon alarms和show rmon events显示RMON的告警和事件表。

事件和告警表中显示的时间是该事件生成时的sysUPTime值，sysUPTime表示路由器最后一次重启后到现在所经过的时间，例9-12中显示的时间值为1天0小时。

9.4　日志记录

在路由器上启用日志记录功能之后，就会根据路由器上发生的某些事件创建和存储一定的消息，日志可以驻留在路由器上，也可以采取外部日志方式（即驻留在网络中的某台服务器上）。

路由器将命令debug的输出结果和系统差错消息发送给日志记录进程，由日志记录进程将这些消息分发到不同的日志记录设备和文件（根据路由器的具体配置而定），消息会被发送给日志缓存、终端命令行以及/或UNIX syslog（系统日志）服务器。其中，在路由器上维护的日志缓存是一种循环缓存，最旧的消息将被最新的消息所取代，在查看日志时，首先显示的则是最旧的表项。

注意：　syslog的格式与4.3 BSD UNIX相兼容。

以下命令的作用分别是启用日志缓存、显示日志内容和清除日志。

•　logging buffered [size]

•　show logging

•　clear logging

所有发送给syslog服务的消息都被存储在服务器的文件之中。这些消息被直接发送给服务器上运行的syslog进程，由该进程将这些消息存储在相应的文件中。

命令logging host的作用是将日志记录到syslog服务器并指定syslog服务器的IP地址。

以Telnet方式登录到路由器之后，正常情况下是看不见任何日志消息的。为了让路由器将日志消息发送给Telnet会话，需要输入EXEC命令terminal monitor。如果通过控制台端口连接到路由器，那么就不需要输入此命令，因为默认配置是将日志消息发送给控制台端口。

之后，路由器将向Telnet会话发送所有日志消息（包括从调试级别的消息到紧急消息的全部消息），这对故障检测与排除工作来说非常有用。记录下通过Telnet所发送和接收的全部信息，可以记录下用户连接到该路由器之后的所有调试操作及事件。

注意：　可以通过Telnet应用程序的日志记录功能或捕捉功能来记录这些信息。

要让日志变得有意义，就必须启用时间戳机制并设置时钟。

例9-13显示了未启用时间戳时命令show logging的输出结果。

例9-13：命令show logging的输出结果。

请注意，上例中发生的事件都没有时间参考点。

命令service timestamps log uptime可以显示自系统最后一次重启之后到现在为止所经过的时间。例9-14显示了应用命令service timestamps log uptime之后同一日志的不同输出结果。

例9-14：启用了命令service timestamps log uptime之后的show logging输出结果。

可以看到，所有事件都被打上了时间戳。上例中的前3个事件都发生在同一时刻，都发生在路由器启动后的第39秒，而第4个事件则发生于路由器启动后的1天7小时。

要想显示实际的日期和时间（路由器所知道的），可以输入以下命令。

service timestamps log datetime [msec] [localtime] [show-timezone]

上述时间可以精确到毫秒，并能显示该路由器的本地时间，此外还可以显示时区。由于某些路由器并不维护其日历，因而每次重启之后，它们的时钟都将被重置。如果没有使用网络时间协议，那么就需要利用以下EXEC命令来手工设置路由器的时钟。

clock set hh:mm:ss day month year

从多台路由器记录日志信息时，一致的时间戳信息可以使得看出事件之间的相关性更容易。在检测与排除故障或查找因某特定事件而在多台路由器上产生的消息时，让所有路由器都使用同一个时区（即不指定localtime）为它们的消息打上时间戳将非常有用。如果每台路由器都使用其localtime为消息打时间戳，那么为清楚起见，应指定show-timezone。Syslog守护进程将基于其自身的时钟在消息到达时将日期和时间记录在文件中。为了限制所要记录的日志数量，可以通过指定消息的严重（severity）等级来选择性地记录日志。表9-2列出了消息的日志记录等级。

在查看日志时，如果指定了某种等级的消息，那么将得到该等级及其以上等级的所有消息。例如，如果指定的等级是调试，那么将得到所有等级的消息，如果指定的等级是警告，那么将得到警告、差错、严重、警报和紧急消息。

使用以下命令来指定消息等级。

•　logging console level——限定将消息记录到控制台。

•　logging monitor level——限定将消息记录到终端命令行。

•　logging trap level——限定将消息记录到syslog服务器。

硬件和软件故障的显示等级为警告至紧急之间，接口启用/停用转换以及系统重启消息的显示等级为通告，重载请求和低进程栈消息的显示等级为告知，debug的输出结果显示等级为调试。

例9-15给出了位于西雅图（处于太平洋时区）的路由器的配置情况。

例9-15：为位于西雅图（处于太平洋时区）的路由器配置日志记录功能。

该路由器的系统时钟基于UTC（Coordinated Universal Time，协调世界时，也称世界标准时间），UTC与格林威治标准时间一样，而太平洋标准时间比UTC早8个小时。

例9-16给出了例9-15配置实施后的路由器日志情况。

例9-16：例9-15配置实施后的路由器日志缓存。

在没有syslog服务器的情况下，虽然日志缓存非常有用，但是日志缓存也存在一些缺陷，例如，在搜索某个事件请求时，要么对整个日志文件进行分页，要么将日志文件存储到其他系统以便使用其他系统的搜索工具。如果希望查找最近发生的事件，由于最早的事件最新显示，因而必须对整个日志文件进行分页（或者再次存储到其他系统）。将日志记录到syslog会自动在UNIX服务器上创建一个文件，这样可以提供更简便的事件搜索和文件维护功能。

9.5　Syslog

Syslog是一个运行于UNIX服务器上的守护进程，该进程收集信息并存储在日志文件中，由服务器上的文件管理系统来维护这些日志文件。

9.5.1　Syslog 概述

UNIX服务器（或其他网络节点）上运行的各种服务都会发送消息，发送这些消息的服务表示了其应用服务（facility）类型，syslog守护进程在确定如何记录这些消息时将使用这些应用服务类型。

通过更新syslog服务器上/etc目录下的文件syslog.conf，就可以配置syslog守护进程。syslog守护进程启动后就会立即读取该文件以确定如何处理即将到来的消息，该文件包含了多行与下面内容相似的信息。

local7.debugging /user/adm/logs/cisco.log

该行信息表示local7应用服务的消息将被记录到cisco.log文件（位于目录/user/adm/logs下）中，相应的消息严重等级为调试及以上等级，该文件中的表项内容是大小写敏感型的。

配置文件发生变更后，要求UNIX管理员强制syslog守护进程重新读取该文件。

9.5.2　路由器的Syslog配置

Cisco路由器默认使用local7应用服务向syslog服务器发送消息。如果该应用服务被其他向syslog服务器发送消息的进程所使用，那么就需要使用以下配置命令在Cisco路由器上更改应用服务类型。

logging facility facility-type

例9-17所示的路由器配置将syslog记录到指定主机，记录的消息严重等级包括通告及以上等级的消息。

例9-17：将syslog记录到指定主机。

配置完成后，UNIX服务器的/etc/syslog.conf文件中将包含一行下列信息：
local7.notice /usr/adm/logs/cisco.log

注意：　请参考相应的用户手册，以了解特定服务器、syslog配置文件及syslog守护进程的具体信息。

其中，local7指定日志记录的应用服务类型，notifiaction表示日志记录等级，所有的信息都被存储在/usr/adm/logs目录下的cisco.log文件中。需要注意的是，该文件必须已经存在，而且syslog守护进程有该文件的写入权限，需要验证syslog守护进程正在运行，而且在配置发生变更后syslog守护进程重新读取了该配置文件。

注意：　UNIX命令kill（与特定信号一起）会强制进程重新读取配置文件，有关命令kill的详细情况请参考UNIX系统的用户手册页。

某些路由器支持通过SNMP向SNMP网络管理器发送syslog消息的能力，通过路由器命令snmp-server enable traps syslog并利用logging history level指定所要发送的日志等级，即可启用该能力。

例9-18显示了由路由器发出的SNMP包中的syslog消息。

例9-18：通过SNMP发送因配置变更而生成的syslog消息。

路由器的配置发生变更后生成了一条syslog消息，每个HistoryEntry行末尾的65是标识特定事件的索引号，syslog历史表项的取值范围为1~6，2表示OID值是生成该消息的应用服务，例9-18中的应用服务是SYS,3是消息的严重等级，6表示通告。历史表项4是该消息类型的文本化标识，历史表项5是该消息的实际文本内容，历史表项6是该消息生成时的 sysUpTime值。

注意：　www.cisco.com/public/mibs/v1/CISCO-SYSLOG-MIB-V1SMI.my给出了完整的 syslog MIB定义情况。

将syslog消息发送给SNMP管理站，通过将数据收集到一台服务器上，可以大大简化数据的管理工作。

9.6　NTP

NTP（Network Time Protocol，网络时间协议）利用一个集中的时间源实现系统时钟的同步。由于在检测与排除网络故障时很少只包含单个系统，因而在搜索日志文件（查找某天某时因特定事件而记录下的差错消息）时，如果包含在故障事件中的潜在系统都使用相同的时钟时间对差错消息进行时间标记，那么将大大简化该操作。

9.6.1　NTP 概述

NTP可以在分布式设备之间同步时间。每台设备都与时间源建立对等关系，时间源的可靠性由层级（stratum level）来定义。第1层（stratum 1）服务器直接连接到一个可靠的时间源，如无线电时钟、GPS卫星定时接收器或原子时钟。第2层（stratum 2）服务器从第1层时间源获取时间，第2层服务器可以通过Internet连接到公共可用的第1层服务器。在www.eecis.udel.edu/~ntp/（来自特拉华大学）上可以找到公共NTP服务器列表以及它们的使用方法。

将组织机构内配置的一对可靠的NTP服务器关联到第2层公共NTP服务器上，就可以为该组织机构网络内的所有路由器提供时间服务。路由器本身也可以充当NTP服务器，事实上，如果没有可用Internet连接，或者NTP协议不能通过防火墙连接到Internet，那么就可以将路由器配置为授权NTP服务器，该路由器将使用其自身的系统时钟作为时间参考基准。只有一台复位后仍能保持其时间的路由器（带有日历系统的路由器）才能被用作授权时间源，其他路由器将没有有效的参考时钟。如果带有日历系统的路由器运行了NTP协议，且该路由器通过NTP获取时间，那么可以通过NTP来更新其日历，以补偿日历时间内在的时间漂移。虽然这可能不如原子时钟那么精确，但至少可以让网络中的路由器都能实现时间同步，从而简化了网络故障的检测与排除。

NTP非常有效，每分钟发送一个数据包即可将两台设备的时间同步到10ms之内。

9.6.2　路由器的NTP配置

在配置NTP时，首先要与时间服务器创建关联关系，利用下面的命令就可以创建该关联关系。

ntp server ip_address [version number] [key keyid] [source interface] [prefer]

ntp peer ip_address [version number] [key keyid] [source interface] [prefer]

如果路由器希望与其他NTP时钟源同步其时钟，那么就需要创建一个服务器关联；如果路由器愿意同步到其他设备或允许其他设备与自己同步，那么就需要建立一个对等体关联。

默认的NTP版本是3，在默认情况下，不会配置keyid，且源IP地址是出站接口的地址。关键字prefer让IOS优选该对等体进行时间同步。

利用以下命令可以控制对NTP服务的访问。

ntp access-group {query-only | serve-only | serve | peer} access-list-number

选项query-only仅允许从所列的IP地址进行NTP控制查询，NTP控制查询被用于代替SNMP管理站进行NTP进程的监控。

选项serve-only仅允许访问列表中所列的IP地址进行时间请求，该路由器不会将自己的时钟同步到远程系统。

选项serve允许进行时间请求和控制查询，但该系统不会将自己的时钟同步到远程系统。

选项peer允许进行时间请求和控制查询，并且允许该路由器将自己的时钟同步到远程系统。

如例9-19所示，该配置允许路由器Seattle将其时间同步到次级公共时间源，另一台路由器Tacoma（与Seattle位于同一个网络中）则被允许将时间同步到Seattle。

例9-19：让路由器Seattle将其时间同步到次级公共时间源，让路由器Tacoma将其时间同步到Seattle。

Seattle仅被允许与128.105.39.11同步其时钟，而地址位于区间172.16.0.0/16之内的节点都可以与Seattle的时钟进行同步。

如果没有可用时间源，就可以一台路由器配置为主时间源，该路由器必须有一个内部日历系统，可以通过重启或开关机周期（power cycle）来维护日期和时间。为了将该日历作为该路由器的授权时间源，需要配置clock calendar-valid命令。

为了将Cisco IOS软件配置为让对等体实现时间同步的NTP主时钟，就需要配置命令ntp master [stratum]，配置一个高层级号的时间源可以确保该路由器不会覆盖带有低层级号（因而是个更可靠的时钟）的其他系统上的时钟。默认的层级号是8，被配置为NTP主时钟的路由器仍然会尝试寻找一个具有更低层级号的服务器，如果没有找到，该路由器将同步到已配置的层级时间源。在其同步完成之后，其他系统就可以与其实现同步。

NTP时间是UTC，如果希望路由器维护一个不同的时区，那么仍然可以利用以下命令来维持本地时间。

clock timezone PST -8
clock summer-time PDT recurring

为了将路由器的日历与通过NTP获得的时间进行同步，需要使用命令ntp update-calendar。

NTP协议支持验证机制，通过以下命令即可启用NTP的验证机制。

ntp authenticate
ntp authentication-key number md5 key
ntp trusted-key number
ntp server ip-address key number

需要在NTP服务器和请求进行时间同步的路由器上同时配置命令ntp authenticate，该命令的作用是启用全局验证。此外，还需要在这两台路由器上同时配置命令ntp authentication-key，该命令定义了一个验证字符串并为其分配了编号。

请求进行时间同步的路由器被配置了命令ntp trusted-key，该命令列出了已在命令ntp authentication-key中定义了的密钥号。在该路由器与NTP服务器实现时间同步之前，该NTP服务器必须包含在其NTP包中，因而只需要在客户服务器上配置命令ntp trusted-key。

在客户路由器上配置命令ntp trusted-key时必须包含选项key number，该选项的作用是将密钥增加到从客户路由器发送给NTP服务器的NTP包中。如果该服务器上已定义了该密钥，那么该NTP服务器接收到该密钥之后，就将该密钥包含在发送给客户路由器的NTP包中。

如例9-20所示，在Seattle与Tacoma之间启用了验证机制。

例9-20：在Seattle与Tacoma之间启用验证机制。

在Tacoma与Seattle的时钟进行同步之前，Tacoma所配置的命令ntp server seattle key 10要求服务器（即Seattle）必须在其NTP包中提供编号为10的密钥。Seattle可以在来自Tacoma的NTP包中看到要求提供10号密钥，之后利用命令authentication-key 10 md5 ntpkey就可以让Seattle在其回应Tacoma的NTP包中包含10号验证密钥。为了解释验证过程，在路由器的配置中省略了命令authentication-key。例9-21显示了命令debug ntp packet的输出结果，时间服务器Seattle没有被配置验证机制，而要求客户路由器Tacoma在与时间服务器进行同步之前必须进行验证。

例9-21：相互交换的NTP包中没有出现NTP服务器上配置的验证密钥。

从Tacoma发送给Seattle的调试包显示了10号验证密钥，Tacoma希望在接收自Seattle的NTP包中包含该密钥，但事实上并没有包含该密钥，因而NTP仍然处于非同步状态（如例9-22所示）。

例9-22：在未通过验证的情况下，命令show ntp status和show ntp association detail的显示结果。

上例仅显示了命令show ntp association detail的第一行输出结果，反映出该对等体被手工配置且没有通过基本的身份检查（验证失败），因而时间无效，该对等体没有实现同步，时间源层级仍为默认值16。

现在，在Seattle的配置中增加命令ntp authentication-key 10 md5 ntpkey和ntp authenticate,例9-23和例9-24分别显示了debug ntp packet和show ntp status及show ntp association detail的输出结果。

例9-23：相互交换的NTP包中有NTP服务器和客户路由器上配置的验证密钥。

由于Seattle在发送给Tacoma的NTP包中包含了验证密钥，因而在NTP中对等体就可达了，对等体的状态也就从未同步状态变为同步状态，并且时间源层级也不再是默认值了（如例9-24所示）。

例9-24：验证成功后，debug ntp packet和show ntp status及show ntp association detail的输出结果。

（待续）

从输出结果可以看出，现在已经实现了时间同步，时间层级也从默认值16变成了4，且对等体已通过验证，其时间也变为有效了。

9.7　记　账

有时收集流量流的统计信息以计算网络使用率非常有用，特别是在实施流量工程或基于使用量对网络用户进行计费时。

可以在路由器接口上启用基本的IP记账（accounting）功能，之后就可以获得数据包的源和目的地列表，以及任两个节点之间传递的字节数和数据包数量。NetFlow可以提供更为详尽的记账功能，除了源、目的地、数据包数量和字节数之外，还可以提供协议和AS信息。可以采取不同的形式来聚合NetFlow数据，包括按自治系统聚合、按子网前缀聚合或按照协议类型聚合等，有关NetFlow的详细论述请见9.7.2小节。

9.7.1　IP记账

IP记账功能可以提供基本的记账服务，可以根据源/目的地统计并维护穿越路由器的数据包数量，而源自该路由器的数据包或目的地是该路由器的数据包则不在统计之内。记账功能是在出站接口上进行的，IP记账功能将禁用接口上的自主交换（autonomous switching）和SSE交换，可以统计所有通过访问列表的数据包以及被该路由器所路由的数据包。作为可选项，也可以对未通过访问列表的数据包启用记账功能，因为如果出现了大量违反访问列表规则的数据包，则表明存在网络攻击行为或该路由器的配置有问题。

利用命令ip accounting即可在路由器的出站接口上启用记账功能。

为了显示在出站接口上启用记账功能之后的效果，可以使用命令show ip accounting [checkpoint] [access-violations].

例9-25显示了在以太网接口上收集到的IP记账数据。

例9-25：在以太网接口上启用IP记账功能，命令show ip accounting显示该接口正向外发送多播包。

上例在路由器Bowler的以太网接口0上启用了IP记账功能，所有通过该以太网端口被路由出去的数据包都将在统计之列，随后给出的记账表显示源地址为10.1.1.88的多播包被发送给224.2.127.254和228.13.20.216。

利用命令clear ip accounting可以清除记账表。

IP记账功能可以提供非常有价值的关于现有接口流量的信息，但是需要注意，启用IP记账功能之后可能会引起性能劣化，这是因为IP记账禁用了接口上的自主交换和SSE交换机制，因而需要使用效率较低的交换机制将接口上的数据包交换到网络中。此外，维护记账数据库还要消耗路由器的内存资源，在路由器的内存资源较低时不建议启用IP记账功能。

命令的作用是定义记账数据库中可以存储的表项数，默认数值是512对源/目的地，因而每个数据库的内存消耗最大为12 928字节。如果将阈值修改或设置得过大，那么所有的可用内存将被消耗掉。

在接口上启用IP记账功能可以根据源地址和目的地址快速查看出站流量，但路由器本身并没有内嵌机制将这些数据传送给可以解析这些数据的服务器，并形成有用信息。而NetFlow不但可以提供更多的流量流信息，还可以提供这方面的功能。

9.7.2　NetFlow

NetFlow交换模式可以标识流量流并在路由器上执行交换和访问列表进程，此外由于NetFlow标识了流量流，因而可以将流量流的统计信息导出到记账服务器。在数据流处于活动状态时，该数据流的数据都被保持在NetFlow的缓存中，当流量流到期时，可以将该流量流增加到聚合缓存并导出至管理站。NetFlow的默认缓存可以包含64K个流缓存表项。

注意：　与其他交换模式相比，NetFlow交换会消耗更多的内存和CPU资源，因而在路由器上启用NetFlow之前必须理解NetFlow对资源的需求。

要想启用NetFlow交换，可以使用接口子命令ip route-cache flow。

要想定义用来接收数据的流采集器的IP地址和UDP端口号，可以使用以下全局命令。

ip flow-export destination ip-address udp-port
ip flow-export [version 1 | version 5 [origin-as | peer-as]]

命令中的版本号必须与流采集器所期望的版本号一致，默认为version 1。

选项origin-as用来指定所导出的数据中应包含源和目的地的BGP发信AS。

选项peer-as用来指定所导出的数据中应包含用于采集数据的路由器的BGP对等体AS，而不是与该源和目的地相关的流量所属的实际AS。

图9-2给出了一个简单的运行BGP并在路由器Hummer上采集NetFlow数据的网络。

图9-2　　运行NetFlow进行流量流记账的BGP网络

路由器Hummer上启用了NetFlow功能，用于采集两个接口上的流信息。例9-26显示了 Hummer的配置情况。

例9-26：让图9-2中的路由器Hummer采集两个以太网接口上的流信息。

如例9-26所示，采集数据中包含的是对等体AS，而不是发信AS。

命令show ip flow export显示了数据导出参数，而命令show ip cache flow则显示了流缓存情况。

例9-27显示了流导出参数以及路由器Hummer的流缓存情况。

例9-27：命令show ip flow export和show ip cache flow所显示的NetFlow流信息。

（待续）

从上例可以看出，NetFlow所提供的信息要远远多于IP记账机制——包大小分布情况以及汇总信息，所有信息都以协议类型和各个流为基础进行显示。

可以采取不同的方式来聚合和组合流信息：基于自治系统号、源前缀、目的前缀或协议端口。聚合缓存可以让路由器在将采集到的NetFlow数据导出给流采集器之前进行一定的聚合，主NetFlow缓存中的流数据到期时将进入各聚合缓存。

流聚合仅使用NetFlow版本8聚合缓存，该版本允许导出聚合缓存，而版本5缓存需要在选项origin-as或peer-as中进行指定配置。

在配置流聚合之前必须在路由器上启用CEF（Cisco Express Forwarding, Cisco快速转发）和NetFlow交换，启用了CEF之后，就可以按照数据包的源地址和目的地址来聚合转发缓存（被用于聚合数据中）。

注意：　如果希望进一步了解CEF，请参考IOS 12.1配置指南中的CEF概述以及CCO上的交换服务配置指南。

利用命令ip cef即可在全局启用CEF，该命令将在所有支持CEF的接口上都启用CEF路由缓存（route-cache）。以下全局命令的作用是定义一个聚合缓存。

ip flow-aggregation cache {autonomous_system | destination-prefix | prefix | protocol-port | source-prefix}

表9-4列举了可用于聚合缓存的部分命令，所有这些命令都必须在聚合缓存配置模式下输入。

AS聚合（AS aggregation）可以聚合拥有相同源BGP AS、目的BGP AS、输入接口以及输出接口的流，导出数据中包含了被聚合记录所汇总的流数、包数、字节数。

例9-28给出了带有AS聚合的Hummer配置情况。

例9-28：图9-2中的路由器Hummer被配置了AS聚合。

利用命令show ip cache flow aggregation as即可显示AS聚合缓存的内容，如例9-29所示。

例9-29：利用命令show ip cache flow aggregation as查看AS聚合缓存的内容。

从上例可以看出，与源接口以太网1/3、源AS 400、目的接口以太网1/2和目的AS 100相关的流一共有357个。

可以进一步启用前缀聚合（prefix aggregation），前缀聚合除了基于与AS聚合相同的数据（包括源和目的BGP AS、输入接口及输出接口），还能进一步按照源和目的前缀以及源和目的前缀掩码对流进行聚合。

目的前缀聚合（destination-prefix aggregation）的作用是聚合拥有相同目的前缀、目的前缀掩码、目的BGP AS和输出接口的数据流，利用该机制可以按照目的地信息来检查穿越 NetFlow路由器的流量。

如例9-30所示对路由器Hummer进行配置。

例9-30：为图9-2中的路由器Hummer配置目的前缀聚合。

例9-31显示了目的前缀聚合缓存的内容。

例9-31：利用命令show ip cache flow aggregation destination-prefix查看目的前缀聚合缓存的内容。

从上例可以看出，与目的接口以太网1/2、目的前缀1.1.3.0、掩码/24、目的AS 100相关的流一共有324个。

同样，也可以利用源前缀聚合（source-prefix aggregation）机制，根据源信息来检查数据流，该方案根据源前缀、源前缀掩码、源BGP AS和输入接口来聚合数据流。

如例9-32所示对路由器Hummer进行源前缀聚合配置。

例9-32：为图9-2中的路由器Hummer配置源前缀聚合。

例9-33显示了源前缀聚合缓存的内容。

例9-33：利用命令show ip cache flow aggregation source-prefix查看源前缀聚合缓存的内容。

从上例可以看出，与源接口以太网1/3、源前缀1.1.2.0、掩码/24、源AS 400相关的流一共有181个。

如果希望按照流量类型来检查数据流，那么就可以启用协议端口聚合（protocol-port aggregation），这样就可以将具有相同IP协议、源端口号和目的端口号的流进行聚合。

如例9-34所示对路由器Hummer进行协议端口聚合配置。

例9-34：为图9-2中的路由器Hummer配置协议端口聚合。

例9-35显示了协议端口聚合缓存的内容。

例9-35：利用命令show ip cache flow aggregation protocol-port查看协议端口聚合缓存的内容。

从上例可以看出，有14种协议端口流被按照IP协议、源端口和目的端口进行聚合。

不同的聚合缓存机制为流量流的聚合方式提供了更多的灵活性，这些信息完全可以被用来进行流量分析，甚至用作计费依据。

表9-5列出了每个UDP数据包所记录的最大流数以及每种聚合机制的最大UDP包尺寸。

Cisco NetFlow FlowCollector是一个收集和报告NetFlow数据的应用程序，FlowCollector负责聚合来自多台Cisco路由器（和交换机）所导出的NetFlow数据，可以对这些数据进行过滤或组合，以满足网络管理者的不同要求。

注意：　有关Cisco NetFlow FlowCollector的详细信息请参考CCO站点www.cisco.com/univercd/cc/td/doc/product/rtrmgmt/nfc/nfc_3_0/nfc_ug/index.htm。

9.8　配置管理

为了确保能将最近的配置恢复到路由器中，需要在数据库中维护配置文件，并周期性（每晚、每周）下载所有网络设备的配置文件。在需要替换现有路由器或者路由器的配置丢失或配置错误时，都需要重新恢复路由器的配置文件。

CiscoWorks可以利用TFTP来下载路由器的配置文件，事实上，可以将路由器的配置文件下载到任意TFTP服务器上。许多组织机构都使用UNIX TFTP服务器和Perl脚本来实现周期性的配置管理工作，某些组织机构的策略可能需要将配置文件存储7天的时间，文件名可能依次是routername.current、routername.1、routername.2、 routername.3等，分别代表7天的配置文件。利用一个简单的脚本即可在每晚将文件routername.N复制到routername.N+1（N在1~6之间），并将routername.current复制到routername.1，同时连接到路由器上，利用TFTP将当前配置文件下载到routername.current，之后再退出路由器。该脚本可以在整个网络中的路由器上依次运行。

注意：　有关Perl的详细信息可以参考以下两本参考书。

《Perl语言入门（第二版）》，作者Randal L. Schwartz、Tom Christiansen和Steve Talbot（编辑）（O’Reilly & Associates, Inc., 1997年7月）；

《Perl语言编程》，作者Larry Wall、Jon Orwant和Tom Christiansen（O’Reilly & Associates,Inc.,2000年7月）。

建议将旧的配置文件存储一段时间，一般至少一周，最好一个月，以便能够将路由器的配置恢复到已知的工作配置，或者在最后一次更改配置而产生问题时，能够进行故障的检查与排除。有了每日的配置文件以及变更管理日志，就可以轻松地为路由器恢复工作配置。

9.9　故障管理

可信赖的网络需要良好的故障管理机制，需要尽可能快地发现潜在和现有故障，以便快速采取措施来解决问题，希望在用户感知网络故障之前，故障管理系统就能检测到设备和链路的故障。

配置了SNMP的路由器在检测到故障后会向管理站发送trap消息，但是由于SNMP利用UDP来发送trap，因而无法保证描述故障信息的消息能到达管理站。因而，故障管理系统不能仅依赖trap，还需要轮询路由器以了解线路、接口和路由器部件的状态情况，除了轮询路由器的部件信息之外，有时管理站还要轮询路由器本身（利用ICMP ping），以确定路由器是否可达。为了确保能够通过任意活动接口到达路由器的IP地址，建议最好使用环回地址作为路由器的标识IP地址，这是因为如果管理站轮询或ping的是路由器的环回地址，那么就可以使用任意可用被路由路径来访问该路由器。而如果管理站轮询或ping的是路由器的非环回接口地址，那么如果该接口失效，即便能够通过其他可用路径到达该路由器，管理站也会宣告该路由器不可达。因而应该配置trap消息使用环回地址作为数据包的源地址，并配置管理站通过环回地址来轮询路由器。

与许多协议一样，需要在管理站快速检测到网络故障与所产生的流量之间做一个平衡。如果管理站没收到trap，那么就需要依赖其轮询或ping机制来检测故障，这样就有可能在一段时间之后才检测到故障。如果故障设备是一台路由器，而管理站被配置为每隔5分钟ping一次路由器，如果管理站没收到trap消息，那么管理站将至多可能需要15分钟才能检测到该故障并宣告路由器失效。至于链路故障及其他组件故障，检测速度则要快一些，因为此时管理站不再依赖于未收到这些组件的回应消息来检测故障，而是直接询问路由器有关这些组件的状态，由路由器向管理站回应这些状态信息。

例如，图9-3所示的管理站正在轮询路由器的接口状态。

图9-3　管理站正在轮询路由器的接口状态

管理站利用MIB中的ifEntry.ifOperStatus object ID来轮询路由器的接口状态，路由器将给予回应，可以看出，3个接口处于有效状态，1个接口处于无效状态。

故障管理系统的作用就是检测故障，检测到故障之后就通过可视化或可听见的告警/发送电子邮件/发送短信等方式报告给网络操作员。发送告警的方式可以根据需要进行定制，如果用户需要7×24小时坐在管理控制台前，那么可听见和可视化告警就足够了；如果控制台不是全天有人监控，那么就可以在无人值守时发送电子邮件或短信告警。故障可以指示链路、路由器或路由器部件失效情况，在故障发生后即形成告警。此外，在故障出现之前，故障管理站也会试图向操作员发出告警。

很多时候，某些特定事件会导致组件故障，例如，串行线路在完全失效之前可能会报告高差错数或载波变换，路由器在失效之前也可能会报告内存问题。故障管理站负责维护阈值信息，超过设定的阈值之后，就会向网络操作员发送告警信息。可以为任意数量的变量设置阈值，在配置阈值之前，需要首先确定网络基准，网络基准需要在网络正常运行的一段时间（如一周）里进行测量，这样就可以得到各个变量的标准值，从而可以按照比正常值高一定比例（如20%）的方式来配置变量阈值。

下面提供了有用信息的一些MIB变量。

•　空闲内存量

•　平均CPU使用率

•　缓冲区故障

•　接口输入和输出速率

•　接口输入和输出错误

•　接口输入和输出队列丢包

•　接口包忽略

•　接口重启

•　串行接口CRC、终止和帧差错

•　帧中继FECN/BECN

•　串行接口载波转换

•　以太网冲突

•　以太网短帧、巨帧和帧差错

•　令牌环线路和突发差错

•　令牌环内部错误

•　令牌环令牌和软故障

•　令牌环信号丢失

上面列出的某些变量可能出现在正常网络中，但是超过某个阈值之后，性能将开始劣化，并可能出现较为严重的问题。管理站会周期性地轮询路由器以获得这些变量的值，如果轮询周期之间的变量值变化情况超过了阈值，则生成告警。

也可以使用RMON来设置阈值，有了RMON，管理站就无需轮询这些变量，由路由器上的RMON代理在本地轮询这些变量，并在超出阈值时向管理站发送trap，管理站接收到trap之后就生成告警。这里存在一个网络使用率与路由器处理能力的平衡，虽然RMON能够减少网络流量，但也增大了路由器的处理需求。

9.10　性能管理

性能管理用于趋势和容量规划，需要收集并分析数据，网络工程师和管理者会审阅这些数据并寻找相关趋势，以了解是否需要增加或减小网络容量。链路利用率、帧中继FECN和BECN以及路由器CPU等参数是指示容量需求变化的主要参数。在网络边缘（尽可能地靠近终端用户）的路由器上周期性测量的响应时间能够直接反应网络组件的过度使用或未充分使用情况，并且可以显示网络容量发生变化后的改进情况。

性能管理站会持续采集数据，它主要通过SNMP来采集数据，并以一个较短的周期（如5分钟）来轮询变量组。为了历史研究的需要，所有数据都以原始格式进行存储，而且每小时都会对这些数据进行处理，并形成最小值、最大值和平均值报告。性能管理站可以在白天处理前几个小时的数据，提供几乎是最近一分钟的报告和图形；也可以在夜间处理这些数据，以提供前一天的详细数据。

性能管理系统还应报告网络性能值落入某区间的持续时间。

以链路利用率为例，非常有必要了解一天之中链路利用率落入以下区间的时长：0～20%、 20～40%、40～60%、60～80%、80～90%和90～100%。

在收集和处理多天的性能数据之后，性能管理系统可以对这些数据做进一步处理，报告每天的最小值、最大值和平均值，以及某个时间周期内的数值区间。如果时间周期为一周，那么除了报告每天的最小值、最大值和平均值之外，还要报告这一周之内落入每个区间的时长。

要求性能管理系统始终保持运行状态并能不间断地收集数据，只有收集到很长一段时间内的数据之后，做出的趋势分析才有意义，将这些趋势应用到网络的未来发展，可以确定可能出现的转折点。

灵活性让性能管理系统更具价值，包括可配置的时间周期（查看数据）以及可以提供几乎为实时的报告在内的特性，使得性能管理系统成为一种能够快速识别容量变更需求的非常有价值的工具。

9.11　安全管理

如果希望网络是安全的，那么就要求路由器必须是安全的。密码是一种控制对路由器进行访问的方法，可以在路由器上配置密码，也可以使用TACACS+或RADIUS服务器。除了密码保护之外，还要将对路由器的交互式访问局限到必需的协议和用户，即仅启用让路由器正常工作和管理的必要协议，并且仅允许那些被确认安全的IP子网访问路由器。即便部署了访问控制机制，仍会有一些恶作剧的网络用户试图阻止路由器正常工作。接下来的几个小节将详细讨论为路由器提供安全和正常工作所需的路由器配置参数。

9.11.1　密码类型和加密

应通过某种认证机制来控制对路由器的访问行为，如果无法使用TACACS+或RADIUS，那么也应该利用enable secret来保护拥有特权的EXEC路由器访问模式。需要注意的是，不要使用早期的enable password，因为该命令的加密算法比较弱，而命令enable secret password通过使用一直不可逆的加密函数来存储启用秘密密码（enable secret password），因而可以提供更好的安全性。当配置文件（因而也包含密码）需要穿越网络或被存储在TFTP服务器上时，这种由安全加密所提供的额外保护层是非常有用的。利用命令service password-encryption来加密各种密码（包括用户名密码、认证密钥密码、特权命令密码、控制台和虚拟终端行访问密码及BGP邻居密码），可以避免在显示路由器配置时被旁观者看见密码的内容。

9.11.2　控制交互式访问

需要控制对路由器的交互式访问行为，可以利用下述命令来限制访问特定的网络号。

access-class access-list_1-199_or_1300-2699 {in | out}

其中，变量access-list的作用是指定被允许连接到线路上的源网络号（带有关键字in），或者指定允许有连接的网络号（带有关键字out）。

为了确保不存在访问漏洞，可以仅允许所期望的远程接入协议，命令如下。

transport input telnet ssh

可以列出所有被允许的远程接入协议，其他任何协议都将被拒绝。

此外，除了需要在控制台端口和辅助端口上使用密码保护之外，还应该使用密码来保护所有连接到路由器上的调制解调器。

如果调制解调器仅被用于拨号接入（这样一来，网络管理员就可以在家中访问路由器），那么就应该禁用反向Telnet功能，以免从网络连接到调制解调器并拨出到其他网络位置。利用反向Telnet，通过指定一个端口号和IP地址，就可以连接到远程设备（该设备连接在路由器的异步端口上）上。通过在调制解调器所连接的线路上使用命令transport input none，即可在任何连接了异步终端或调制解调器（这些设备不应该被用作拨出设备）的接口上禁用反向Telnet。

例9-36的路由器配置中演示了上面讨论的所有访问控制方法。

例9-36：控制路由器上的交互式访问。

从上例可以看出，仅允许Telnet和Secure Shell（安全外壳）这两种远程访问协议，并且仅允许源地址位于172.16.0.0/16范围之内的用户使用这些协议来访问路由器。

9.11.3　最小化DoS攻击的风险

DoS（Denial-of-service，拒绝服务）攻击会导致对某些网络资源的拒绝访问，虽然攻击者可以以多种方式来实施DoS攻击，但仍可以采取一定的措施来最小化针对路由器的DoS攻击所造成的风险。

路由器上的vty端口都有一定的数量限制，一旦这些端口都被占用，那么该路由器就无法建立其他远程会话，从而导致了DoS攻击的潜在威胁，攻击者可以阻塞所有的vty端口，从而拒绝网络管理员的访问要求。为此，可以在最后一个vty端口上配置一个约束性极强的命令access-class，仅允许指定的管理站访问该端口，这样至少可以保证有一个vty端口可用。此外，还要配置 exec-timeout以防止空闲会话无限制地消耗vty端口。为了防止恶意攻击和因远程系统崩溃而产生的“孤立”会话，可以利用命令service tcp-keepalives-in在入站连接上配置TCP保持激活消息。

某些DoS攻击使用定向广播机制，利用伪造的源地址向定向广播地址发送ICMP包，LAN上的所有主机都要做出回应，并向伪造的源地址发送大量的流量流，从而使得真正拥有该源地址的实际节点收到大量数据。只要在所有的LAN接口上都配置命令no ip directed-broadcast即可阻止该类攻击，IOS 12.0及以后版本都默认启用该命令。

携带选项source-route的IP包可以指定该数据包在源和目的地之间必须穿越的路由器，返回包也必须穿越这些指定的路由器。但是，由于源路由包中伪造的源地址会让某个节点旁路路由表，并将数据发送到伪造地址，因而几乎无法有效使用源路由包，这样就可以利用全局命令no ip source-route让路由器丢弃携带选项source-route的数据包。

快速数据包泛洪会导致路由器花费大量时间响应来自接口的中断（interrupt）要求，从而无暇处理其他工作。命令scheduler interval milliseconds的作用是让路由器停止处理这些中断要求，并按照常规间隔处理其他商业事务。更新的平台则可以使用命令scheduler allocate interrupt-time process-time。

其中，变量interrupt-time是路由器在任一个网络中断上下文（network-interrupt context）中进行快速交换所花费的最大毫秒数。变量process-time是禁用网络中断时，路由器在进程级（process level）所花费的最小毫秒数。

路由器可以运行各种小型服务程序进行故障诊断，不过在现实环境中很少使用。TCP服务有Echo、Chargen、Discard和Daytime,UDP服务有Echo、Chargen和Discard。攻击者可以向这些服务泛洪流量，从而影响路由器的路由能力。下述命令可以禁用这些服务。

no service tcp-small-servers
no service udp-small-servers

Cisco IOS Software Release 12.0及以后版本在默认情况下都禁用这些服务。

在不被使用的情况下，应该被禁用的服务还有Finger和Async Line BOOTP Server（异步线路引导服务器），命令如下。

no service finger
no ip bootp server

Finger服务允许Finger协议向路由器发送请求，Finger协议请求等同于发起一个远程show user命令，可以显示路由器上的活动线路信息。

路由器可以向连接到异步线路上的主机提供BOOTP服务，使用命令no ip bootp server可以禁用这些BOOTP服务。

例9-37演示了利用前面所讨论的命令来最小化DoS攻击风险的配置方式。

例9-37：最小化DoS攻击。

为了进一步保证路由器的安全性，可以配置一台远程认证和授权服务器（如TACACS+）。

9.11.4　TACACS+

TACACS+（Terminal Access Controller Access Control System Plus，终端访问控制器访问控制系统+）可以对试图访问路由器或网络接入服务器的用户进行集中验证。TACACS+应用程序驻留在服务器上，以守护进程的方式运行，并将接入权限信息存储在数据库中。当用户登录到配置了TACACS+的路由器时，路由器上的TACACS+客户和TACACS+守护进程将进行通信，向用户发送登录和密码提示符，并交换认证和授权信息。路由器也会向TACACS+守护进程发送记账信息，需要注意的是，用户与路由器之间的通信内容可能不会被加密，但路由器与TACACS+守护进程之间的所有通信内容都会被加密。

TACACS+可以提供认证、授权和记账信息，如下所示。

•　TACACS+认证需要用户输入登录ID和密码，认证服务还可以向已登录用户发送各种消息，如要求用户更改密码等。

•　TACACS+授权可以精细化地控制已登录用户的访问权限，授权在用户登录之后可立即自动执行，以提供访问控制或限制会话持续时间等功能。此外，授权机制还能限制用户在登录到路由器之后可以执行哪些命令。

•　TACACS+记账机制负责收集相关信息以用于计费、审计、报告并发送给TACACS+服务器，记账记录包括用户身份、起始和停止时间、所执行的命令、数据包数和字节数等信息，这些信息对安全审计和计费来说非常有用。当利用TACACS+来控制用户对网络接入服务器（允许用户使用网络上的服务）的访问时，可能会非常希望获得计费信息。

1．TACACS+认证配置

路由器使用AAA来启用TACACS+，命令aaa new-model的作用是启用AAA。

定义认证方法列表的命令如下。

aaa authentication login {default | list_name} group auth_type [auth_type…]

常见的认证方法有tacacs+、radius、kerberos、local、line password、enable password和none。

定义了认证列表之后，就可以应用到线路上，关键字default会自动将这些认证列表应用到所有线路上。首次配置认证时，建议指定一个列表名称并采用手工方式将列表应用到线路上，这样就可以在可控方式下检测自己的配置文件，而不至于将自己锁定于路由器之外。

要想将认证列表应用到线路上，需要使用以下命令。

line type number
login authentication list_name

此外，还需要指定TACACS+服务器的位置，此时就需要使用命令tacacs-server host ip_address来指定TACACS+服务器的IP地址。

例9-38示范了某路由器的TACACS+认证配置情况。

例9-38：为某路由器配置TACACS+认证。

认证列表tac首先使用地址为172.16.1.2的TACACS+服务器进行认证。如果该服务器不可达，则使用第二种认证方法——enable password认证，该认证方法允许在TACACS+服务器不可用时访问路由器。认证列表中的某种认证方法不可用时才会使用其后一种方法，而如果该认证方法返回认证失败信息则不会再使用其后一种方法。例如，TACACS+服务器失效后就使用enable password；如果TACACS+服务器有效，但用户输入的ID有误，那么将会返回一个认证失败信息，并且不允许再尝试其他认证方法。

请注意，例9-38所示的认证列表仅应用于线路vty 0和vty 1，原因是用来进行测试。这样一来，即便TACACS+配置有误，仍然可以通过其他vty线路和控制台端口访问路由器。在将认证列表应用于所有线路之前，必须确认配置文件无误且满足自己的意图。

利用命令tacacs-server key key可以定义TACACS+共享加密密钥，必须在服务器的 TACACS+配置文件中定义相同的密钥。

在进入路由器的启用模式之后也可以使用TACACS+，命令为aaa authentication enable default group auth_type [auth_type]。

如例9-39所示，将配置命令增加到路由器Seattle上，以指定启用级认证（enable-level authentication）和TACACS+共享密钥。

例9-39：在路由器Seattle上指定启用级认证和TACACS+共享密钥。

例9-40显示了与例9-39中的路由器配置一致的TACACS+服务器的配置文件。

例9-40：与例9-39中的路由器Seattle配置一致的TACACS+服务器的配置文件。

上述配置文件中配置了两个常规用户agens和admin，用户$enab15$被用于启用级认证（优先等级为默认值15），但启用级认证的一个副作用就是创建了一个名为$enab15$的用户，如果有人知道该密码，就可以利用该用户ID登录到路由器中。

由例9-39可以知道，需要输入用户名和密码才能访问路由器，仅当TACACS+服务器不可达时才使用普通的路由器登录ID。某些日志消息中会包含用户名，下列日志消息就显示了用户名、用户的IP地址以及配置变更的日期和时间。

Jun 20 16:42:32 UTC: %$YS-5-CONFIG_I: Configured from console by agnes on vtyO（10.1.2.25）

上述配置是一个非常基本的配置，TACACS+还可以提供更多的功能，如定义组且根据组成员关系指定权限（利用DES加密密码或UNIX密码文件）。

注意：　参考TACACS+用户指南可以全面了解实施规范，UNIX密码文件所支持的密码文件类型是passwd（5）。

2．TACACS+授权配置

TACACS+可以控制用户在路由器上进行哪些操作，可以应用访问列表、限制命令、允许PPP和SLIP访问等。TACACS+服务器会为每个用户都建立一个简档（profile），由该简档指定用户被授权做哪些操作。用户登录到路由器之后进行的所有操作都必须符合该用户简档的授权内容。

下述命令的作用是定义授权方法列表并将该列表应用到路由器的线路上。

aaa authorization {network | exec | commands level | reverse-access} {default | list-name} [method1 [method2…]]

line type number
authorization {arap | exec | commands level | reverse-access} {default | list-name}

必须在TACACS+服务器上配置用户简档，前面对TACACS+认证的注意事项也同样适用于TACACS+授权，一定要测试授权配置文件，并且在使用默认授权列表（将被应用于所有的线路和接口）或将某个已命名列表应用于所有线路之前配置一个无访问权限限制的用户。输入了上述命令之后，就可以将授权应用于路由器，授权会影响到现有的连接。此外，TACACS+的配置文件在默认情况下是无任何授权的，如果在路由器上配置了TACACS+授权且应用于所有的线路，但是没有在配置文件中允许任何操作，那么将无法执行任何命令。

例9-41中的TACACS+服务器配置文件中限制了Agnes的可用命令，但未对用户Admin做任何限制。

Agnes仅被允许执行命令show，其余操作均被禁止。

为了使用例9-41中的TACACS+配置，必须对路由器做一定的配置（详见例9-42）。

例9-41：TACACS+配置文件为不同用户提供不同的限制措施。

例9-42：与例9-41中TACACS+服务器配置相关的路由器授权配置。

请注意，在完全测试之前，不要将授权列表应用于所有vty端口。

与TACACS+认证类似，TACACS+授权也能提供更多的功能，本小节仅解释了TACACS+授权机制的一些简单应用，其他功能还有应用访问列表、增强自动命令、应用Telnet约束。

TACACS+记账机制则可以显示连接到路由器上的用户正在做什么。

3．TACACS+记账配置

TACACS+记账机制被用于记录用户的连接信息，包括连接时长、所输入的命令、目的地以及出站连接的时长等，这些信息对计费和安全审计来说十分有用。只要在路由器上使用AAA记账命令并在服务器上的TACACS+配置文件中指定记账文件名，即可启用TACACS+记账功能。

下述命令定义了与己命名列表相关的记账类型。

aaa accounting {system |network | exec | connection | commands level} {default | list-name} {start-stop | wait-start | stop-only | none} [method1 [method2…]]

line type number
accounting {arap | exec | connection | commands level} {default | list-name}

系统记账（system accounting）可以提供系统级事件（如系统重启或配置了记账功能）信息。网络记账（network accounting）可以提供PPP、SLIP或ARAP会话信息（包括数据包数和字节数）。EXEC记账（exec accounting）可以提供路由器上的EXEC终端会话信息，这些信息包括用户名数据以及会话的起止时间。连接记账（connection accounting）可以提供由该路由器发起的连接信息，这里所说的连接是telnet、LAT、tn3270、PAD或rlogin，数据包括目的地址、协议、起止时间、用户名以及所传送的数据包数和字节数。命令记账（command accounting）可以提供所输入命令的信息，这些命令通常都是level 1～level 15的命令（level 1命令是可以在任何登录等级输入的命令，而level 15命令只能用于启用等级）。命令记账会记录实际输入的所有命令（包括配置命令在内）。

要想将记账列表应用于线路，就需要使用子命令accounting [type] list-name。

要想在TACACS+服务器上配置记账功能，需要使用命令accounting file = filename（如例9-43所示）。

例9-43：在TACACS+服务器上配置记账功能。

例9-44显示了在路由器上启用命令记账和EXEC记账功能的配置情况。

例9-44：启用命令记账和EXEC记账。

由于使用的是默认记账列表，因而不需要在该配置中使用线路vty子命令，默认列表会被自动应用于所有线路和所有接口。

例9-45显示了某记账日志中的内容。

例9-45：记账日志显示了命令和EXEC记录。

从上述记账日志中可以看到已输入的命令以及EXEC会话，路由器Agnes在6月20日、星期二的10:34:24关闭了串行接口1，并在同一天的10:34:42终结了其EXEC会话，即会话持续了73秒钟。

可以利用记账信息进行安全审计，这在需要查看哪些人在路由器进行了操作时非常有用。此外，也可以利用记账信息进行用户计费，假设这些信息来自于NAS（Network Access Server，网络接入服务器），并且用户正在通过NASCAR访问网络资源，那么这些记账数据将显示Agnes连接时长为73秒，这样就可以对这73秒钟的网络使用行为进行计费。

9.11.5　RADIUS

RADIUS（Remote Access Dial-In User Service，远程访问拨号接入用户服务）可以提供与 TACACS+类似的功能（也有一些小的差异），RADIUS被设计用作对拨号接入访问某网络进行认证、授权和记账。RADIUS客户端驻留在路由器或NAS上，并与网络中的RADIUS服务器进行通信，主要的功能区别在于RADIUS无法像TACACS+那样控制用户可以在路由器上执行哪些命令。因而，在网络管理员希望严格控制不同用户所能使用的命令时，TACACS+是一种更好的路由器访问控制选择。

RADIUS由Livingston公司开发，其源代码完全公开且没有任何使用限制，目前有多种服务器实现，并且很多厂商的设备也都支持RADIUS客户端。

RADIUS在Cisco路由器上的配置方式与TACACS+一样，也是通过AAA命令。RADIUS服务器和TACACS+服务器可以共存于同一个网络中，为同一台路由器或NAS提供认证、授权和记账功能。

例如，某个设计目标可能希望使用RADIUS服务器来认证用户，在RADIUS服务器不可用时，则使用TACACS+服务器进行用户认证。例9-46显示了将RADIUS服务器设置为主用认证服务器，而将TACACS+服务器作为RADIUS服务器不可用时的备用认证服务器。

例9-46：在同一台路由器上同时启用RADIUS和TACACS+。

启用RADIUS的方式与启用TACACS+的方式完全一样。

9.11.6　SSH

SSH（Secure Shell，安全外壳）可以在用户与路由器之间建立一条安全的加密连接，该连接的功能类似于入站Telnet会话。与Telnet不同的是，SSH连接属于加密连接，因而与Telnet采用明文方式在客户端与服务器（此处指的是路由器）之间传递数据（任何收集流量路径上的数据的网络分析仪都可以读取该数据）相比，SSH要远优于Telnet。如果使用Telnet访问路由器，那么就意味着，有意在路由器上加密的密码将以明文方式在网络上进行传送，而SSH可以加密该网络连接，因而不会以明文方式在客户端和路由器之间交换数据。虽然某些客户端支持RSA认证，但路由器上不支持用于SSH连接的RSA认证，SSH使用的认证方式只是用户ID和密码。

目前仅有7200、7500和12000系列路由器支持SSH，并且仅在DES和3-DES数据加密软件映像上支持SSH。此外，IOS目前仅支持SSH版本1。

要想在路由器上启用SSH，必须执行以下步骤。

•　第1步：在路由器上配置一个主机名和域名。

•　第2步：生成一个RSA密钥对。

•　第3步：启用本地或AAA认证。

•　第4步：如果使用AAA认证，那么就在控制台端口上禁用AAA认证。

•　第5步：配置可选的SSH参数。

利用以下命令即可配置主机名和域名。

hostname hostname
ip domain-name domainname

如果没有配置这些命令，那么在生成RSA密钥对的时候将会报告错误信息。

生成了RSA密钥对之后，SSH就被自动启用；当RSA密钥对被删除后，SSH也就被禁用。

命令crypto key generate rsa的作用是生成RSA密钥对并启用SSH,SSH可以使用本地认证（利用命令username），也可以使用AAA。请注意，一定要在控制台端口上禁用AAA。

SSH的参数可以修改默认的连接行为，可以修改应用于SSH协商阶段的超时值或指定认证重试次数。其中，超时值必须大于120秒，默认为120秒；认证重试次数不能大于5，默认为5。利用以下命令即可修改SSH参数。

ip ssh {[timeout seconds] | [authentication-retries integer]}

例9-47给出了一个基本的SSH配置情况。

例9-47：SSH配置。

请注意，应用于控制台端口的AAA认证列表aaanone没有定义任何认证方法，而认证列表tacauth则被应用于所有的vty端口和辅助端口。

9.12　支撑管理进程的服务器设计

支撑管理进程的服务器应该足够健壮和安全，应在网络中正确放置这些服务器以收集和处理维护网络完整性所需的各种数据，应该将这些服务器放置在有物理安全保证的位置，以保证其运行不会受到干扰。操作系统必须是安全可靠的，而且还要严格限制对这些服务器的远程访问。请记住，由于管理站可以访问网络中的所有路由器，因而必须确保管理站具有很高的安全性。

服务器的规模与厂商的建议相关，部署相对保守的服务器数量时，应确保有足够的、能满足将来扩展需要的处理能力、内存和磁盘空间，以满足采集数据流不断增加的需要。

要求为这些服务器提供到网络设备的冗余连接，以确保这些服务器在其中一台路由器或链路失效的时仍能正常采集数据。如果对网络的运行条件一无所知，那将是非常糟糕的。

9.13　网络健壮性

一个强壮的网络可以抵御一定程度上的网络故障并保持网络应用的平滑运行。

为了保证路由器出现故障时仍能进行正常通信，要求LAN网段配置冗余路由器，但是IPv4 LAN上的主机却在很大程度上依赖于单台默认路由器与远程网段中的主机进行通信。如果该默认路由器出现故障，而主机却并不知情，那么该主机会将流量发送到黑洞路由。VRRP（Virtual Router Redundancy Protocol，虚拟路由器冗余协议）和Cisco HSRP（Hot Standby Routing Protocol，热备份路由协议）等路由器冗余协议都可以解决这个问题，这两种协议都可以让多台路由器共享单个IP地址，因而主机在配置默认网关的IP地址时就可以使用该共享地址。使用该共享地址的路由器中只有一台处于活动状态，如果这台活动路由器出现故障，备用路由器将接管数据流量的发送和接收工作，对主机来说根本感受不到路由器故障，多台路由器仍然将其流量向LAN网段外进行转发。VRRP是一种基于Cisco HSRP的开放式标准，不过Cisco IOS软件并不支持VRRP，因而本书不再讨论VRRP，将在下一小节对HSRP做进一步分析和讨论。

注意：　有关VRRP的定义请参见RFC 2338。

HSRP

HSRP允许单个LAN中或ISL封装的VLAN中的多台路由器共享同一个IP地址和MAC地址。将一组路由器配置为HSRP组，组中的每台路由器都被配置一个组IP地址和一个优先级，其中只有一台路由器处于活动状态并负责接受所有转发到组IP/MAC地址的数据包，该活动路由器失效后，组中的其他路由器将成为活动路由器并开始接受数据包。

HSRP组中优先级最高的路由器将成为活动路由器，默认优先级为100，如果多台路由器的优先级均相同，那么HSRP接口上IP地址最大的路由器将成为活动路由器，优先级第二的路由器将成为备用路由器；在活动路由器出现故障后，该备用路由器将成为活动路由器，并宣告其存在，或者开始宣告一个较低的优先级。图9-4解释了HSRP的基本原理。

路由器Monet被配置了一个接口IP地址172.16.1.100和一个HSRP组1的IP地址 172.16.1.201。由于路由器Monet对外宣告的HSRP优先级（对HSRP组1而言）为120，大于Picasso的默认优先级，因而Monet为HSRP组1的活动路由器。当Wks1准备向其默认网关发送数据包时，其ARP的是HSRP组1的IP地址，Monet响应以HSRP组1的MAC地址，之后Wks1即可向HSRP组1的MAC地址发送数据包，此时将由Monet接收该数据包。

HSRP组中的路由器会互相交换宣告优先级的多播Hello包。Hello包在配置了HSRP组的链路上进行交换，路由器在默认情况下每隔3秒钟发送一条Hello消息。如果活动路由器在一个可配置的时间周期（即保持时间，默认的保持时间为10秒钟）内都未能发送Hello消息，那么优先级最高的备用路由器将成为活动路由器，并开始接受目的地是HSRP组MAC地址的数据包。

图9-4　HSRP

1．MHSRP

MHSRP（Multigroup HSRP，多组HSRP）可以为一个接口配置多个HSRP组。如果希望在同

一个LAN中的多台路由器上分发活动路由器的功能，那么就需要使用MHSRP技术，将某些终端节点的默认路由配置为某个HSRP组的IP地址，而将其他终端节点的默认路由配置为另一个HSRP组的IP地址；如果这两台默认路由器都失效，那么将由其他路由器来接管数据包的转发操作。如果以太网接口不允许关联到多个MAC地址，那么将无法实现MHSRP（那些使用Lance以太网硬件的路由器（1000、2500、3000和4000）在单个以太网上不支持多个组），以太网和FDDI最多支持255个MHSRP组，令牌环最多支持3个MHSRP组（组号分别为0、1、2）。此外，ISL（Inter-Switch Link，交换机间链路）封装链路上也支持MHSRP。图9-5解释了MHSRP的应用情况。

图9-5　可以在路由器接口上配置MHSRP组以实现负载均衡

如图9-5所示，Monet是组1的活动路由器，Picasso是组2的活动路由器，Wks1默认去往172.16.1.201（组1），Wks2默认去往172.16.1.202（组2）。如果Monet接收不到组2的 HSRP Hello消息，那么将成为组1和组2的活动路由器。

2.配置HSRP

要想启用HSRP，可以输入以下接口子命令。

至少要为HSRP组中的一台路由器指定IP地址，如果没有在路由器上指定IP地址，那么就需要通过HSRP Hello消息学习IP地址。

下述命令将影响路由器在HSRP中的行为。

命令times的作用是修改Hello包的间隔时间以及备用路由器认为活动路由器已失效之前所逝去的时间，默认的Hello时间为3秒钟，默认的保持时间为10秒钟。

命令priority和preempt的作用是修改HSRP路由器的优先级，命令preempt让优先级最高的路由器接管活动路由器的角色（即使目前的活动路由器没有任何问题），选项delay的作用是让路由器在成为活动路由器之前延迟指定时长之后再抢占活动路由器的角色，该时长范围为0~3600秒，默认为0。

虽然路由器的LAN接口可能仍处于活动状态，路由器本身也运行良好，但该路由器用来将数据包向外转发的接口可能会失效。此时，转发到该路由器的数据包必须被重定向到其他路由器（如图9-6所示）。

图9-6　无接口跟踪的HSRP

工作站向其默认网关（活动路由器Monet）发送数据包，但Monet的出站接口都失效，因而Monet查询其路由表并将该数据包转发回以太网并由Picasso做进一步转发。

命令track可以启用HSRP跟踪出站接口的状态，让路由器降低其优先级并在接口出现故障时可以从活动状态迁移出去。当被跟踪接口出现故障时，该路由器会更改其宣告的优先级，如果新的优先级低于备用路由器的优先级，且备用路由器被配置为以低优先级来抢占活动路由器，那么该备用路由器将成为该HSRP组的活动路由器。该HSRP组的路由器按照interface-prioroty字段中指定的数值（默认为10）来递减其优先级。可以同时跟踪多个接口，如果跟踪了多个接口，且每个接口都被配置了一个interface-prioroty值，在一个以上接口都出现故障时，所要递减的优先级值将是累积递减值。如果接口上没有设置interface-prioroty值，在多个接口出现故障时，被递减的优先级值将为默认值10，且不累积。

命令authentication的作用是让路由器在其HSRP消息中包含一个认证字符串，必须为组中的所有路由器配置相同的认证字符串，或者根本不配置字符串。第一台启用了HSRP的路由器将成为活动路由器，如果随后被激活的路由器上的认证字符串不匹配，那么新的被激活的路由器将处于学习状态，此时将无任何路由器成为备用路由器。

例9-48显示了图9-7（单组HSRP）中的路由器Monet和Picasso的HSRP配置情况。

例9-48：图9-7中路由器Monet和Picasso的HSRP配置情况。

图9-7　单组HSRP示意图

Picasso通过HSRP功能学习到IP地址和定时器。

对路由器Picasso使用命令show standby后的输出结果如例9-49所示，显示了Picasso所学习到的信息。

请注意，Picasso的状态为备用状态，优先级为100，活动路由器是Monet，其IP地址为 172.16.1.100，HSRP地址为172.16.1.201，相关联的HSRP MAC地址为0000.0c07.ac01。

例9-49：命令show standby的输出结果显示了Picasso从HSRP功能中学习到的IP地址和定时器信息。

例9-50从工作站向HSRP地址发起ping操作，演示了活动路由器出现故障后由备用路由器负责恢复的整个过程。

例9-50：向HSRP地址发起ping操作显示了活动路由器出现故障和备用路由器恢复的过程。

工作站每秒钟都向HSRP地址发送ping包，包1～6成功，包7～16失败。可以看出，备用路由器开始接受发往HSRP MAC地址的ping包大约花费了10～11秒钟的时间。当活动路由器的LAN接口失效后，备用路由器就无法从活动路由器接收到Hello消息，此后备用路由器会等待10秒钟的保持时间，然后再开始接受数据包。

例9-51中的配置在Monet上启用了HSRP接口跟踪机制，图9-8解释了HSRP接口跟踪的好处。Monet的串行接口1和以太网接口0去往远端网络资源，这些远端网络资源也能经Picasso到达，设计目标是只要Monet有一个或多个出站接口（串行接口1和以太网接口0）处于工作状态，那么LAN上的工作站就应该使用去往Monet的默认路由；如果Monet的这两个出站接口均失效，则工作站将选择Picasso作为默认路由。

例9-51：在路由器Monet上启用HSRP接口跟踪机制。

请注意，Monet同时跟踪串行接口1和以太网接口0，如果仅有其中的一个被跟踪接口出现故障，此时Monet的优先级仍为105，仍大于Picasso的优先级，因而Monet仍然为活动路由器。但如果Monet的这两个接口均出现了故障，那么Monet将会宣告其优先级为90（不再是120），这样一来，在等待了一个抢占延时时间之后，Picasso开始接管活动路由器的角色，并侦听其他HSRP消息以确定其是否需要成为备用路由器。因而，需要在Picasso的HSRP配置中增加语句preempt，以启用其接管机制。当Monet的某个接口恢复正常之后，其优先级将更改为105，由于Monet也配置了preempt和delay，因而Monet在等待10秒钟之后将再次成为组1的活动路由器。

图9-8　解释HSRP接口跟踪机制的网络示意图

3．配置MHSRP

图9-9给出了一个MHSRP示意图。

图9-9　MHSRP示意图

例9-52给出了路由器Monet和Picasso的MHSRP配置情况。

例9-52：在路由器Monet和Picasso上配置MHSRP。

从上例可以看出，Monet是组1的活动路由器，其HSRP IP地址为172.16.1.201，Picasso是组2的活动路由器，其HSRP地址为172.16.1.202。为了实现负载均衡功能，将LAN中的一般工作站的默认网关配置为172.16.1.201，而将另一半工作站的默认网关配置为172.16.1.202。

9.14　实　验　室

网络实验室可以为新配置、新IOS版本及功能特性提供相应的测试平台。

由于实验室的目的是在现实网络中进行相关部署之前进行全面测试，因而实验室的环境应完全反应现实的网络环境。虽然一个有效的网络实验室并不完全是现实网络的完全复制，但应包含完全相同的路由器、接口和Cisco IOS软件，要求运行完全相同的路由协议和路由特性。这样一来，任何希望在现实网络中部署的内容都可以在实验室中再现。

实验室要与生产网络相隔离，但要保证使用实验室的人可以轻松访问实验室。一种既能保证实验室与生产网络相隔离，又能通过网络访问实验室的方法就是使用终端服务器，将终端服务器的LAN接口连接到生产网络上，并将其异步端口连接到实验室路由器的控制台端口上。大多数终端服务器都允许通过反向Telnet方式连接到其异步接口所连接的设备上，每个异步端口都与一个协议端口号相关联。只要Telnet到终端服务器的IP地址上并指定相应异步端口的协议端口号，就可以连接到该异步端口所连接的异步设备上。图9-10给出了利用终端服务器互连生产网络和实验室网络的情况。

图9-10　利用终端服务器可以从生产网络连接到相隔离的实验室网络

如图9-10所示，用户从生产网络Telnet到172.16.1.254、端口2001，终端服务器将用户连接到其异步端口1所连接的设备——路由器R1。

需要在终端服务器上做一定的配置，将主机R1关联到上述IP地址和端口号172.16.1.254 2001，从终端服务器向R1发起的Telnet会话通过异步端口1将用户连接到路由器R1上。

应该在实验室中测试所有的网络设计和变更计划，包括变更配置、增加路由器、升级IOS、增加新特性等。实验室测试是良好的变更策略不可缺少的一部分，实验室测试成功可以确保网络变更的成功，从而避免实际网络中的负面结果。实验室测试可以让网络工程师通过其勤奋工作来确保网络的最优运行。

在实际应用中，对新设计方案、新加入的功能特性以及升级Cisco IOS做彻底测试是十分重要的，这些变更对所有网络来说都是非常重要的升级内容。

如果没有好的测试计划，实验室测试结果可能不尽如人意，或者测试结果无效。测试计划描述被测项目并定义测试方法，在开始测试之前指定清晰的测试计划能够节省大量的时间，必须明确要测试的内容并定义详细的测试步骤。事实上，一个好的测试计划可以让任何人遵照执行，并且，任何两个人按照该测试计划得到的测试结果都应该完全一致。

实验室还可以为相关用户提供命令测试的网络环境，可以根据需要测试错误配置所带来的影响，并进行故障检测与排除的锻炼，还可以被用于网络培训以及CCIE备考训练。只有拥有了实验室，才能完全理解网络配置，了解配置结果，并确定哪些特征标识了配置错误。CCIE实验室考试对相关知识深度的要求需要准CCIE们拥有Cisco IOS软件的配置经验。

9.15　命令汇总

表9-6汇总了本章用到的所有命令。

表9-6　　　命令汇总

续表

续表

9.16　附　注

1J.Case等，“RFC 1157：SNMP（简单网络管理协议）”（仍在发展中）。

2J. Case等，“RFC 1901：基于团体的SNMPv2简介”（仍在发展中）。

3K. McCloghrie和M. Rose, “RFC 1213：基于TCP/IP的Internet网络管理的管理信息库：MIB-II”（仍在发展中）。

4S. Waldbusser, “RFC 2819：远程网络监控管理信息库”（仍在发展中）。

9.17　展　望

本章全面总结了外部路由协议以及其他用于域间路由的TCP/IP路由技术，在进行CCIE考试之前应全面了解这些内容。不过，CCIE的考试内容并不仅仅局限于TCP/IP路由技术，读者还需要学习SNA、IPX和AppleTalk等其他路由协议，如果暂时还没有掌握这些内容，那么还需要进一步学习LAN和WAN交换技术。

9.18　推荐读物

Marshal T. Rose所著的The Simple Book:An Introduction to Networking Management:Revised Second Edition，由纽约的Simon & Schuster Trade公司于1995年出版，本书全面阐述了SNMP的相关知识。

Randal L. Schwartz、Tom Christiansen和Steve Talbot（编辑）所著的《Perl语言入门（第二版）》，由中国电力出版社于1997年11月出版。

Larry Wall、Jon Orwant和Tom Christiansen所著的《Perl语言编程》，由中国电力出版社于2001年12月出版。

9.19　复　习　题

附录D中提供了以下复习题的答案。

（1）请解释SNMP轮询与trap之间的差异。

（2）如果已指定记录严重等级为差错（Errors）的消息，那么还将会记录哪些其他等级的消息？

（3）如果查看路由器的接口时发现存在不同寻常的流量模型，通常情况下，所有的流量都是入站流量，但现在却存在出站流量，请问如何快速确定该流量的源和目的地？

9.20　配置练习题

（1）请配置一台路由器，让其仅接受来自管理站172.16.1.2和172.16.1.3的轮询要求，不允许该路由器以写入方式访问管理站，仅允许管理站读取SNMP MIB II接口表项的信息，允许管理站172.16.1.4读取所有MIB变量并通过SNMP加载和保存配置文件。此外，通过 SNMP向管理站172.16.1.4发送通告（Notifications）等级的日志信息。

（2）让路由器在5分钟平均CPU利用率超过90%时向管理站172.16.1.4发送SNMP trap，并且只要CPU利用率在60秒间隔内从低于85%到高于90%，都要发送trap。

（3）让某路由器使用NTP方式基于来自路由器172.16.100.100的时钟信息来更新其时间和日期，但不允许其他路由器根据该路由器的时钟信息来更新时钟。

（4）配置一个NetFlow聚合缓存，基于源前缀和目的前缀来组合数据，在数据中使用对等体AS，并将数据导出到172.16.1.4。

（5）让以太网网段上的两台路由器实现互相备份机制。路由器A是主用路由器，在路由器A出现故障时由路由器B接管其角色，当路由器A恢复之后，其将再次成为主用路由器。路由器A通过两条串行链路（serial 0和serial 1）将流量转发到不同的目的地，在其中的某条链路出现故障后，路由器B将成为主用路由器。

9.21　参考文献

[1]路由器和网络监控。Cisco Systems文档。1998年6月。

www.cisco.com/univercd/cc/td/doc/product/software/ios113ed/113ed_cr/fun_c/fcprt4/fcmonitr.htm（2000年10月24访问）。

[2]路由器的故障检测与排除。Cisco Systems文档。2000年10月。

www.cisco.com/univercd/cc/td/doc/product/software/ios113ed/113ed_cr/fun_c/fcprt4/fctroubl.htm（2000年10月24访问）。

[3]与NTP服务实现时钟同步。Cisco Systems文档。1997年12月。

www.cisco.com/univercd/cc/td/doc/product/iaabu/cddm/cddm111/adguide/ntp.htm。

[4]执行基本的系统管理。Cisco Systems文档。2000年8月。

www.cisco.com/univercd/cc/td/doc/product/software/ios121/121cgcr/fun_c/fcprt3/fcd303.htm #34418（2000年10月24访问）。

[5]配置NetFlow交换机制。Cisco Systems文档。2000年7月。

www.cisco.com/univercd/cc/td/doc/product/software/ios121/121cgcr/switch_c/xcprt3/xcdnfc.htm#4727（2000年10月24访问）。

[6]故障管理。Cisco Systems文档。1997年12月。

www.cisco.com/univercd/cc/td/doc/product/rtrmgmt/cwparent/cw32/cw32ug/faultmgt.htm（2000年10月24访问）。

[7]性能管理。Cisco Systems文档。1997年12月。

www.cisco.com/univercd/cc/td/doc/product/rtrmgmt/cwparent/cw32/cw32ug/perfmgmt.htm（2000年10月24访问）。

[8]提高Cisco路由器的安全性。Cisco Systems文档。2000年8月。

www.cisco.com/warp/public/707/21.html（2000年10月24访问）。

[9]支持SSH版本1。Cisco Systems文档。

www.cisco.com/univercd/cc/td/doc/product/software/ios121/121newft/121t/121tl/sshvl.htm（2000年10月24访问）。

[10]配置TACACS+。Cisco Systems文档。2000年7月。

www.cisco.com/univercd/cc/td/doc/product/software/ios121/121cgcr/secur_c/scprt2/scdtplus.htm#4586（2000年10月24访问）。

[11]TACACS+和RADIUS对比。Cisco Systems文档。1999年3月。

www.cisco.com/warp/public/480/10.html（2000年10月24访问）。

[12]配置认证机制。Cisco Systems文档。2000年10月。

www.cisco.com/univercd/cc/td/doc/product/software/ios120/12cgcr/secur_c/scprtl/scathen.htm（2000年10月24访问）。

[13] IP服务命令。Cisco Systems文档。2000年9月。

www.cisco.com/univercd/cc/td/doc/product/software/ios121/121cgcr/ip_r/iprprtl/1rdip.htm（2000年10月24访问）。

[14]为容错型IP路由使用HSRP。Cisco Systems文档。2000年2月。

www.cisco.com/univercd/cc/td/doc/cisintwk/ics/cs009.htm（2000年10月24访问）。

[15]配置IP服务。Cisco Systems文档。2000年9月。

（2000年10月24访问）

[16] NetFlow聚合。Cisco Systems文档。1999年8月。

（2000年10月24访问）

[17] Cisco网络监控和事件相关性指南。Cisco Systems文档。2000年7月。

[18]轮询MIB变量指南。Cisco Systems文档。2000年9月。

第3部分
附录

附录A　命令show ip bgp neighbors的显示内容

附录B　正则表达式教程

附录C　保留的多播地址

附录D　复习题答案

附录E　配置练习题答案

附录F　故障检测与排除练习题答案

附录A
命令show ip bgp
neighbors的显示内容

本附录将详细解释命令show ip bgp neighbors所显示的大量信息，有些信息不言自明，还有很多信息在本书的不同章节中也做了介绍。

例A-1给出了一个典型的邻居显示结果，为了引用说明方便，在每行输出结果前都添加了编号。表A-1逐行解释了本例中的输出内容。

例A-1：命令show ip bgp neighbors的典型输出结果。

（待续）

续表

续表

附录B
正则表达式教程

本教程完全参考Jeffrey E. F. Friedl在其《精通正则表达式》一书中的精彩内容。虽然本书的第1章就已经描述了几乎全部与Cisco IOS软件工作相关的正则表达式（regular expressions，简写为regex）内容，但仍在本附录的末尾将该书作为推荐读物，这是因为在数据通信和数据处理行业中的大量应用都会用到正则表达式。Friedl不但透彻地说清楚了这些内容，而且行文也非常轻松幽默。

B.1　直接量和元字符

一个典型的AS_PATH过滤器可能如下所示。

关键字permit之后的字符串就是一个正则表达式。正则表达式由直接量（literals）和元字符（metacharacters）组成，其中，直接量就是文本字符，用来描述正则表达式所要匹配的内容。对本例来说，1、701、5646和1240就是描述自治系统号的直接量。

元字符是充当运算符的特殊正则表达式字符，其作用是告诉正则表达式如何处理。表B-1列出了Cisco IOS的可用元字符，接下来将详细描述如何使用这些元字符。

B.2　描述：匹配行起始和行结束

考虑以下AS_PATH过滤器。

该过滤器匹配所有包含字符串850的AS_PATH，这样的AS_PATH匹配项如（850）、（23,5,850,150）和（3568,5850,310）。也就是说，无论该字符串是单独的字符串，还是属性中多个AS号中的一个，或者是属性中某个AS号的一部分，都与该过滤器匹配。

但是，如果希望仅匹配只包含单个AS号850的AS_PATH，那么就必须清楚地描述行起始和行结束。正则表达式以符号插入符（^）来匹配行起始，而以美元符号（$）来匹配行结束，因而语句

的含义就是让正则表达式匹配行起始标志，紧接着是字符串850，然后就是行结束标志的 AS_PATH。

也可以使用两个元字符来匹配一个空AS_PATH，如下所示。

此时，该正则表达式的含义就是匹配那些行起始标志之后立即就是行结束标志的 AS_PATH，如果行起始和行结束标志之间有任何字符，则将都不匹配。

B.3　括入括号：匹配一组字符

中括号可以指定一组单个字符，例如：

该过滤器的含义是匹配单个AS号为850、851、852、853、854、855或859的AS_PATH。

如果这些单个字符的范围是连续的，那么就可以在括号中指定起始和结束字符，如下所示。

除了859之外，该过滤器与前一个过滤器的匹配内容完全相同。

B.4　求反：匹配除某组字符之外的所有内容

当在中括号内使用插入符（^）时，就是对中括号内指定到区间求反，因而该正则表达式与除该区间之外的所有内容相匹配。例如：

该过滤器看起来与前一个过滤器类似，只是在中括号内增加了插入符（^）——意味着“非0～5”。因而该过滤器的含义是匹配AS号在856～859之间的AS_PATH。

B.5　通配符：匹配任意单个字符

点号（.）可以匹配任意单个字符，有意思的是，这里所说的单个字符也包括空格。考虑以下过滤器。

该过滤器的含义是匹配所有以AS号850～859为起始的AS_PATH，由于点号（.）也匹配空格，因而AS号85也属于匹配范围。

B.6　求或：匹配一组字符中的某个字符

竖线（|）用来表示运算符OR，也就是说，匹配竖线（|）两侧的任一侧直接量。例如：

该过滤器的含义就是匹配拥有单个AS号（851或852）的AS_PATH。此外，还可以利用OR函数来实现多种匹配可能，如下所示。

B.7　可选字符：匹配一个可能在也可能不在的字符

问号（？）的作用是匹配0个或1个直接量。例如：

该过滤器的含义是匹配拥有单个AS号850或不包含任何AS号的AS_PATH。请注意这里圆括号的使用，其作用是表示元字符应用于整个AS号。如果使用的是表达式850？，则表示元字符仅应用于最后一个字符，也就是说，将匹配85或850。

B.8　重复：匹配许多重复字符

可以利用两个元字符来匹配重复直接量：星号（*）的作用是匹配0个或多个直接量实例，加号（+）的作用是匹配1个或多个直接量实例。例如：

该过滤器的含义是匹配不包含任何AS号或拥有一个或多个AS号850的AS_PATH，也就是说，AS路径可以是（850）、（850,850）、（850,850,850）等。

下面的过滤器类似，只是要求AS_PATH中至少有一个AS号850。

B.9　边界：描述直接量

在需要指定一串直接量并且要分隔每个直接量时就需要用到下划线（_）。例如，假设希望匹配指定AS_PATH（5610,148,284,13），则相应的过滤器如下。

下划线匹配一个行起始、一个行结束、一个逗号或一个空格。请注意前面的过滤器与下面这个过滤器之间的区别。

由于第一个过滤器指定了行起始和行结束，因而仅匹配AS_PATH（5610,148,284,13）；而对第二个过滤器来说，虽然指定的AS号序列必须包含在AS_PATH之内，但并没有要求该属性中仅包含这些AS号，因而AS_PATH（5610,148,284,13）、（23,15,5610,148,284,13）和（5610,148,284,13,3005）都是匹配项。

B.10　组成在一起：一个复杂的案例

只有组合使用各种元字符来匹配某些复杂的直接量字符串时，正则表达式的强大能力才能真正得以体现。考虑以下过滤器。

该过滤器寻找的AS_PATH要求在接收到该路由之前的最后一个AS号为550，550之前的插入符（^）指定550是AS号列表中的第一个数值，550之后的加号（+）的意思是至少要有一个550实例，可以有多个实例。考虑到一个以上的550实例，该过滤器已经考虑到AS 550正在进行路径附加的可能性（如第3章中所讨论的那样）。

在一个或多个550实例之后，可以有也可以没有880或2304的单个实例，接下来必须有一个1805实例。该正则表达式的最后一部分指定在AS号1805之后，AS_PATH中可以包含任何AS号，也可以无其他AS号。

B.11　推荐读物

Friedl, Jeffrey E. F.《精通正则表达式》Sebastopol, California: O’Reilly & Associates; 1997年

附录C
保留的多播地址

本附录列出了本书写作之时最新的保留多播地址情况，该列表直接取自ftp://ftp.isi.edu/in-notes/iana/assignments/multicast-addresses。要想获得最新的保留多播地址情况，请查询该网站。

C.1　Internet多播地址

IP多播的主机扩展（RFC 1112）中指定了为支持多播机制而对主机的IP实现所作的扩展要求，多播地址位于224.0.0.0～239.255.255.255范围之内，下面列出了当前的地址情况。

224.0.0.0～224.0.0.255范围内（含这两个地址）的地址被保留给路由协议以及其他低等级拓扑结构发现协议或维护协议（如网关发现和组成员关系报告）。无论多播报的TTL是什么，多播路由器不应该转发目的地址位于该范围之内的任何多播报。

在这里有一个相对地址的概念，被用于限定范围内的多播地址，下面的表格列出了这些相对地址。

这些地址被列在MCAST.NET和224.IN-ADDR.ARPA下的域名服务中。

请注意，在以太网或IEEE 802网络中使用时，IP多播地址的低23位将被放置在以太网或IEEE 802网络多播地址1.0.94.0.0.0的低23位，请参见“IANA以太网地址块”。

C.2　引　用

[RFC1045] Cheriton, D., “VMTP：通用消息事务处理协议规范”，RFC 1045, Stanford University,1988年2月。

[RFC1075] Waitzman, D., C. Partridge和Deering，“距离矢量多播路由协议”，RFC-1075, BBN STC, Stanford University, 1988年11月。

[RFC1112] Deering, S.,“针对IP多播的主机扩展”，STD 5，RFC 1112, Stanford University, 1989年8月。

[RFC1119] Mills, D.,“网络时间协议（版本1）规范及实现”，STD 12, RFC 1119, University of Delaware, 1988年7月。

[RFC1190] Topolcic, C., Editor, “实验性Internet流协议，版本2（ST-II）”, RFC 1190, CIP Working Group, 1990年10月。

[RFC2328] Moy, J., “OSPF版本2”，STD 54, RFC 2328, Ascend Communications, 1998年4月。

[RFC1723] Malkin, G, “RIP版本2：携带额外信息”，RFC 1723, Xylogics, 1994年11月。

[RFC1884] Hinden, R.和S. Deering, “IPv6编址体系架构”, RFC 1884, Ipsilon Networks, Xerox PARC, 1995年12月。

[RFC2114] Chiang, S. J. Lee和 H. Yasuda, “数据链路交换客户接入协议”，RFC 2114, Cisco, Mitsubishi, 1997年2月。

[RFC2365] Meyer, D., “IP多播的管理性定界”, RFC 2365, University of Oregon, 1998年7月。

[RFC2730] Hanna, S.,B. Patel和M. Shah, “多播地址动态客户分配协议（MADCAP）”，1999年12月。

C.3　人　员

[Adams] Chris Adams, <jc.adams@reuters.com>, July 2000.

[Albin] Jerome Albin, <albin@taec.enet.dec.com>, June 1997.

[Albright] Shivaun Albright, <shivaun_albright@hp.com>, July 1997.

[Armitage] Ian Armitage, <ian@coactive.com>, August 1999.

[Aronson] Peter Aronson, <paronson@esri.com>, August 1998.<arnoldm@microsoft.com>

[AXC] Andrew Cherenson, <arc@SGI.COM>

[Baker] Fred Baker, <fred@cisco.com>, June 1997.

[Ballardie] Tony Ballardie, <A.Ballardie@cs.ucl.ac.uk>, February 1997.

[Ballister] Tom Ballister, <tballister@starguidedigital.com>, July 1997.

[Banthia] Prakash Banthia,<prakash_banthia@3com.com>,September 1998.

[Barber] Tony Barber, <tonyb@pipex.com>, January 1997.

[Bhatti] Zia Bhatti, <zia@netright.com>, September 1998.

[Blackketter] Dean Blackketter, <dean@corp.webtv.net>, November 1998.

[Blank] Tom Blank, <tomblank@microsoft.com>, November 1996.

[Braden] Bob Braden, <braden@isi.edu>, April 1996.

[Bob Brenner]

[Brockbank] Darcy Brockbank, <darcy@hasc.com>, December 1997.

<bloomer@birch.crd.ge.com>

[BXE1] Brendan Eic, <brendan@illyria.wpd.sgi.com>

[BXF] Bruce Factor, <ahi!bigapple!bruce@uunet.UU.NET>

[BXS2] Bill Schilit,<schilit@parc.xerox.com>

[Carr] Wayne Carr, <Wayne_Carr@ccm.intel.com>, December 1997.

[Casner] Steve Casner, <casner@isi.edu>, January 1995.

[Caughie] Colin Caughie, <cfc@indigo-avs.com>, May 2000.

[Caves] Evan Caves, <evan@acc.com>, June 1998.

[Cheshire] Stuart Cheshire, <cheshire@apple.com>, April 2000.

[Chiang] Steve Chiang, <schiang@cisco.com>, January 1997

[Cho] Joan Cho/SIAC, <jcho@siac.com>, October 1998.

[Cipiere] Patrick Cipiere, <Patrick.Cipiere@sophia.inria.fr>, February 1999.

[Tim Clark]

[Costales] Bryan Costales, <bcx@infobeat.com>, September 1997.

[Crawford] James Crawford, <jcrawford@metropol.net>, May 1998.

[Crowcroft] Jon Crowcroft, <jon@hocus.cs.ucl.ac.uk>, November 1998.

[CXM3] Chuck McManis, <cmcmanis@sun.com>

[Daga] Anthony Daga, <anthony@mksrc.com>, June 1999.

[Deering] Steve Deering, <deering@cisco.com>, October 1999.

[DeMoney] Michael DeMoney, <demoney@eng.sun.com>, April 1997.

[Dillonn] Doug Dillon, <dillon@hns.com>, August 1998.

[Dissett] Daniel Dissett, <ddissett@peerlogic.com>, December 1998.

[DLM1] David Mills, <Mills@HUEY.UDEL.EDU>

[DRC3] Dave Cheriton, <cheriton@DSG.STANFORD.EDU>

[Dunne] Stephen Dunne, <sdun@isma.co.uk>, January 1997.

[DXS3] Daniel Steinber, <Daniel.Steinberg@Eng.Sun.COM>

[Eidson] John Eidson, <eidson@hpl.hp.com>, April 1999.

[Fenner] Bill Fenner, <fenner@parc.xerox.com>, December 1997.

[Farinacci] Dino Farinacci, <dino@cisco.com>, February, March 1996.

[Felix] Ken Felix, <kfelix@pcquote.com>, August 1999.

[Flynn] Edward Flynn, <flynne@nasdaq.com>, September 1998.

[Gabriel] Jon Gabriel, <grabriel@tivoli.com>, December 1998.

[Gaddie] Bob Gaddie, <bobg@dtn.com>, August 1998.

[Gal] Yossi Gal, <yossi@gilat.com>, February 1998.

[Gibson] Terry Gibson, <terry.gibson@sun.com>, August 1997.

[Gilani] Asad Gilani, <agilani@nymex.com>, July 1997.

[Glanzer] Dave Glanzer, <dglanzer@fieldbus.org>, June 2000.

[GSM11] Gary S. Malkin, <GMALKIN@XYLOGICS.COM>

[Goland] Yaron Goland, <yarong@microsoft.com>, August 1999.

[Gordon] Howard Gordon, <hgordon@xingtech.com>

[Green] Cliff Green, <cgreen@xypoint.com>, February 1998.

[Guttman] Erik Guttman, <Erik.Guttman@eng.sun.com>, March 1998.

[Hall] Eric Hall, <ehall@ntrg.com>, August 1999, October 1999.

[Hamilton] Mark Hamilton, <mah@spectralink.com>, November 1998.

[Handley] Mark Handley, <mjh@ISI.EDU>, December 1998.

[Hanna] Stephen Hanna, <steve.hanna@sun.com>, July 2000.

[Hinden] Bob Hinden, <hinden@Ipsilon.com>, November 1997.

[Hodges] Richard Hodges, <rh@source.net>, March 1999.

[Holfelder] Wieland Holdfelder, <whd@pi4.informatik.uni-mannheim.de>, January 1997.

[Honton] Chas Honton, <chas@secant.com>, December 1997.

[IANA] IANA, <iana@iana.org>

[Iyer] Ram Iyer <ram@aaccorp.com>, March 1998.

[Jackson] Dan Jackson, <jdan@us.ibm.com>, September 1997.

[Janssen] Rob Janssen, <rob@pelchl.ampr.org>, January 1995.

[JBP] Jon Postel, <postel@isi.edu>

[JXM1] Jim Miner, <miner@star.com>

[Kammerlander] Ralph Kammerlander, <ralph.kammerlander@khe.siemens.de>, June 2000.

[Kean] Brian Kean, <bkean@dca.com>, August 1995.

[Kerkan] Brian Kerkan, <brian@satcomsystems.com>, May 2000.

[Kittivatcharapong] Sakon Kittivatcharapong, <sakonk@cscoms.net>, May 2000.

[Koopman] Dirk Koopman, <djk@tobit.co.uk>, July 2000.

[Kreutzjans] Michael Kreutzjans, <mike@pcquote.com>, December 1998.

[KS14] Karen Seo, <kseo@bbn.com>

[Lamberg] Mike Lamberg, <mlamberg@siac.com>, February 1997.

[Lee] Choon Lee, <cwl@nsd.3com.com>, April 1996.

[Lewis] Mark Lewis, <Mark_Lewis@ccm.jf.intel.com>, October 1995.

[Lindeman] Morten Lindeman, <Morten.Lindeman@os.telia.no>, March 1999.

[Lyda] Stephen T. Lyda, <slyda@emsg.com>, February 2000.

[Lynch] Joel Lynch, <joel.lynch@cnn.com>, April 1999.

[Andrew Maffei]

[Malamud] Carl Malamud, <carl@invisible.net>, April 1998.

[Malkin] Gary Scott Malkin, <gmalkin@baynetworks.com>, February 1998.

[Mamakos] Louis Mamakos, <louie@uu.net>, March 1997.

[Manning] Bill Manning, <bmanning@isi.edu>, August 1999.

[Marocho] Jose Luis Marocho, <73374.313@compuserve.com>, July 1996.

[Marquardt] Douglas Marquardt, <dmarquar@woz.org>, February 1997.

[Marsh] Gene Marsh, <MarshM@diebold.com>, November 1998.

[Martinicky] Brian Martinicky,<Brian_Martinicky@automationintelligence.com>, March 2000.

[Meier] Bob Meier, <meierb@norand.com>, December 1997.

[Mendal] Geoff Mendal, <mendal@talarian.com>, January 1999.

[Meyer] David Meyer, <meyer@ns.uoregon.edu>, January 1997.

[Meyer2] David Meyer, <dmm@cisco.com>, June 1999-MALLOC assignment
for temp use: renew 06/2000

[Moelard] Henri Moelard, <HMOELARD@wcnd.nl.lucent.com>, March 1998.

[Moran] Ed Moran, <admin@cruzjazz.com>, October 1997.

[John Moy] John Moy, <jmoy@casc.com>

[MXF2] Martin Forssen, <maf@dtek.chalmers.se>

[Nelson] Gunnar Nelson, <nelsong@nasd.com>, March 1999.

[Nevell] Julian Nevell, <JNEVELL@vbs.bt.co.uk>, August 1999.

[Novick] Alan Novick, <anovick@tdc.com>, August 1998.

[O’Rourke] Stacey O’Rourke, <stacey@network-alchemy.com>< August 1999.

[Parnes] Peter Parnes, <peppar@marratech.com> February 2000.

[Peng] Wenjie Peng, <wpeng@tts.telerate.com>, January 1997.

[Polishinski] Steve Polishinski, <spolishinski@etcconnect.com>, March 2000.

[Poole] David Poole, <davep@extendsys.com>, April 1997.

[Przygienda] Tony Przygienda, <prz@siara.com>, October 1999.

[Purkiss] Ed Purkiss, <epurkiss@wdmacodi.com>, September 1998.

[Querubin] Antonio Querubin, <tony@lava.net>, August 1999.

[Revzen] Shai Revzen, <shrevz@nmcfast.com>, April 1999.

[Rodbell] Mike Rodbell, <mrodbell@ciena.com>, January 1997.

[Roper] Mike Roper, <mroper@8x8.com>, September 1999.

[Guido van Rossum]

[Rowatt] Shane Rowatt, <shane.rowatt@star.com.au>, March 1997.

[Roy] George Roy, <c/o Bill Owens owens@appliedtheory.com>, October 1997.

[Rubin] David Rubin, <drubin@ncc.net>, August 1996.

[Rueskamp] Bodo Rueskamp, <br@itchigo.com>, March 2000.

[Rupp] Heiko Rupp, <hwr@xlink.net>, January 1997.

[Sautter] Robert Sautter, <rsautter@acdnj.itt.com>, August 1999.

[SC3] Steve Casner, <casner@precept.com>

[Scannell] Piers Scannell, <piers@globecastne.com>, March 2000.

[Scheifler] Bob Scheifler, <Bob.Scheifler@sun.com>, August 1998.

[Schwartz] Beverly Schwartz, <bschwart@BBN.COM>, June 1998.

[Shindoh] Masato Shindoh, <j111456@yamato.ibm.co.jp>, August 1997.

[Shum] Raymond Shum, <rshum@ms.com>, April 1998.

[Simpson] Bill Simpson, <bill.simpson@um.cc.umich.edu> November 1994.

[Sledge] Bob Sledge, <bob@pqsystems.com>, December 1998.

[Sliwinski] Robert Sliwinski, <sliwinre@maillst.com>, February 2000.

[Joel Snyder]

[Stanev] Nedelcho Stanev, <nstanev@csoft.bg>, May 1999.

[Stewart] Ian Stewart, <iandbige@yahoo.com>, June 1999.

[Strazzera] Paolo Strazzera, <p.strazzera@telematica.it>, June 1999.

[Sveistrup] Darrell Sveistrup, <darrells@truesolutions.net>, June 1999.

[SXA] Susie Armstrong, <Armstrong.wbst128@XEROX.COM>

[SXD] Steve Deering, <deering@PARC.XEROX.COM>

[Thaler] Dave Thaler, <dthaler@microsoft.com>, March 1999, June 2000.

[Thompson] Nigel Thompson, <nigelt@tribal.com>, January 1999.

[Timm] Mary Timm, <mary@xenoscience.com>, July 1998.

[Toga] Jim Toga, <jtoga@ibeam.jf.intel.com>, May 1996.

[Tse] Geordie Tse, <gtse@siac.com>, April 1996.

[tynan] Dermot Tynan, <dtynan@claddagh.ie>, August 1995.

[Uang] Yea Uang, <uang@force.decnet.lockheed.com> November 1994.

[Uusitalo] Mika Uusitalo, <msu@xingtech.com>, April 1997.

[van der Muelen] Ron van der Muelen, <ronv@lsid.hp.com> February 1997.

[Veizades] John Veizades, <veizades@tgv.com>, May 1995.

[Velten] Mike Velten, <mike_velten@liebert.com>, January 1999.

[Vogels] Werner Vogels, <vogels@rnets.com>, August 1998.

[Volpe] Victor Volpe, <vvolpe@smtp.microcom.com>, October 1997.

[Wacey] Ian Wacey, <iain.wacey@gefalbany.ge.com>, May 2000.

[Wallach] Walter Wallach, <walt@sumatech.com>, July 1999.

[Wang]Michael Wang, <Michael.Wang@usa.xerox.com>, March 1999.

[Wasserroth] Stephan Wasserroth, <wasserroth@fokus.gmd.de>, July 2000.

[Watson] Scott Watson, <scott@disney.com>, August 1997.

[Wei] Liming Wei, <lwei@cisco.com>, October 1998.

[Wessels] Duane Wessels, <wessels@nlanr.net>, February 1997.

[White] Peter White, <peter_white@3com.com>, April 1999.

[Wissenbach] Paul Wissenbach, <paulwi@vnd.tek.com>, June 1997.

[Wong] Tony Wong, <wongt@ms.com>, July 1998.

[Woodcock] Bill Woodcock, <woody@zocalo.net>, November 1998.

[Wu] Ishan Wu, <iwu@cisco.com>, March 2000.

[Zulch] Richard Zulch, <richard_zulch@dantz.com>, February 1996.

[Zwemmer] Arnoud Zwemmer, <arnoud@nwn.nl>, November 1996.

附录D
复习题答案

第1章

（1）当前的EGP版本是什么？

答案：当前的EGP版本是2。

（2）什么是EGP内部邻居？什么是EGP外部邻居？

答案：如果EGP网关与邻居位于同一个AS中，则是内部邻居；如果位于不同AS之中，则是外部邻居。

（3）EGP末梢网关与EGP核心网关的主要区别是什么？

答案：末梢网关只能宣告其AS内的网络，而核心网关可以宣告内部和外部网络。

（4）EGP为何使用核心或主干AS的概念？

答案：EGP无环路检测机制，因而为了在工程上设计无环路拓扑结构，就必须让AS间流量穿越主干AS。

（5）主动EGP邻居与被动EGP邻居之间有何区别？

答案：主动邻居可以发起对等关系并向对等体发送Hello消息以维护该关系，而被动邻居则以I-Heard-You消息响应Hello消息。

（6）EGP轮询消息的作用是什么？

答案：轮询消息的作用是向邻居请求Update（更新）消息。

（7）什么是间接邻居或第三方邻居？

答案：间接邻居是一个与其他网关共用相同数据链路，且通过该网关能到达某特定网络，但又不与该网关直接对等的网关。

（8）EGP如何利用度量值计算去往目的地的最佳路径？

答案：虽然EGP有度量值，但无相关机制来确定最佳路径，因而仅用度量值来表示不可达网络。

第2章

（1）BGP-4与早期版本的主要不同之处是什么？

答案：BGP-4是无类别协议，而早期的版本则是有类别的。

（2）CIDR解决了哪两个问题？

答案：CIDR解决了Internet路由表爆炸问题，并减缓了B类网络地址的耗尽速度。

（3）有类别与无类别IP路由器之间的区别是什么？

答案：有类别IP路由器执行路由表查询时，首先找到主类网络地址，然后再匹配子网。而无类别IP路由器则忽略目的地址的类别，并对地址前缀进行最长匹配查找。

（4）有类别与无类别IP路由协议之间的区别是什么？

答案：有类别IP路由协议仅宣告网络或子网地址，而不宣告任何前缀长度信息，因而接收到该宣告的路由器都必须对地址前缀的长度做出一定的假设。而无类别IP路由协议则包含了地址前缀长度信息，从而接收路由器可以解析出地址长度，因而无类别协议可以执行VLSM和地址汇总。

（5）给定地址172.17.208.0/23、172.17.210.0/23、172.17.212.0/23和172.17.214.0/23，请使用最长可能的地址掩码，以单个聚合地址来汇总这些地址。

答案：172.17.208.0/21

（6）什么是地址前缀？

答案：IP地址前缀是IP地址的一部分，是路由器进行路由决策时所考虑的对象。在有类别环境中，地址前缀是主类网络地址或某个子网，而在无类别环境中，地址前缀可以是32bit地址中任意数量的前导bit。

（7）例2-16中的路由表取自某无类别路由器，路由器向以下目的地址转发数据包时的下一跳地址是什么？

172.20.3.5

172.20.1.67

172.21.255.254

172.16.50.50

172.16.0.224

172.16.51.50

172.17.40.1

172.17.41.1

172.30.1.1

例2-16：配置练习题（7）的路由表。

（待续）

答案：

（8）请解释汇总是如何隐藏网络的不稳定性的。

答案：被聚合地址所汇总的成员地址或目的地址是不会被汇总点向外宣告的，因而即便某个成员地址的状态发生了变化，该变化也不会被汇总点宣告出去。

（9）请解释汇总是如何产生不对称流量模型的。

答案：由于汇总隐藏了汇总点之后的互联网络细节，如果多台路由器都宣告了某汇总地址，那么汇总点之外的路由器将选择最近的汇总路由器。

（10）不对称流量是不被期望的吗？

答案：该观点属于主观判断。一方面，不对称流量会让互联网络的网络基准、故障检测及排除变得困难，而且如果互联网络的地域较广，那么将会影响时延敏感型流量；但另一方面，汇总所带来的好处可能会超越这些问题。

（11）什么是NAP？

答案：NAP是一个LAN或交换机，服务提供商可以通过NAP进行互联。从Internet流量的角度来看，NAP是Internet分层拓扑结构中的最高点。

（12）什么是路由服务器？

答案：路由服务器是一台服务器，有了路由服务器，路由器就可以通过某种路由协议建立对等关系，每台路由器都向路由服务器发送更新，而不是向对等体发送更新。路由服务器可以应用一定的路由策略，然后将更新发送给其他对等体。当多台路由器必须通过某公共数据链路（如NAP）建立对等关系时，路由服务器就非常有用，可以大大减少每台路由器所必须建立的对等会话数，特别是当路由器使用BGP等单播路由协议时，它就更为重要（因为此时需要向每个对等体发送独立的数据包）。由于路由服务器并不执行包转发操作，因而不是一台路由器。

（13）什么是与提供商相独立的地址空间？拥有此地址的好处是什么？

答案：与提供商相独立的地址空间是由区域性IP地址注册管理机构负责分配的，而不是某个服务提供商的CIDR地址块的一部分。当AS多归属到多个服务提供商时，这将非常有用。而且由于该地址是可携带的，也就是说，该地址空间的所有者可以在不用重新编址的情况下更换ISP，因而从这方面来说也是非常有用的。

（14）拥有一个与提供商相独立的/21地址为何会有问题？

答案：某些国家的服务提供商不接受长于/19的IP前缀，因而/21可能不会被宣告到整个Internet范围。

（15）什么是路由策略？

答案：路由策略是一组预定义的处理出站和入站路由的规则，典型的用于设置路由策略的工具有路由重分发、路由过滤器和路由映射。

（16）BGP用以可靠连接其邻居的底层协议是什么？

答案：BGP使用TCP端口号179。

（17）BGP的4种消息类型分别是哪些？每种消息类型又是如何使用的？

答案：BGP使用4种消息类型，包括Open（打开）消息、Keepalive（保持激活）消息、Update（更新）消息和Notification（通告）消息。Open消息用于向邻居初次标识一个BGP发言者并开始一个对等会话，Keepalive消息用于维护对等体连接，Update消息用于宣告路由，Notification消息则用于向对等体通告差错情况。

（18）在什么状态（或哪些状态）下，BGP对等体之间可以交换Update消息？

答案：仅当BGP对等体均处于Established（建立）状态时才可以交换Update消息。

（19）什么是NLRI？

答案：NLRI就是在BGP Update消息中宣告的IP地址前缀。

（20）什么是路径属性？

答案：路径属性是BGP路由的特性。

（21）BGP的4种路径属性分别是什么？

答案：BGP的4种路径属性分别是周知强制属性、周知自选属性、可选传递性属性和可选非传递性属性。

（22）AS_PATH属性的作用是什么？

答案：AS_PATH属性描述的是所接收到的Update消息在离开发信路由器之后所经过的AS号，该信息可以被用来确定AS间最短路径，并且可用于检测路由环路。

（23）AS_PATH包括哪些不同类型的属性？

答案：AS_PATH包括AS_SEQUENCE、AS_CONFED_SEQUENCE、AS_SET及AS_CONFED_SET属性。其中，AS_SEQUENCE是一个有序的AS号列表，AS_SET是一个无序的AS号列表，AS_CONFED_SEQUENCE和AS_CONFED_SET与AS_SEQUENCE和AS-SET相同，

但仅用于BGP联盟内部。

（24）NEXT_HOP属性的作用是什么？

答案：NEXT_HOP属性描述了到达目的地（在BGP Update消息中被宣告为NLRI）所应被转发到的下一跳路由器。

（25）LOCAL_PREF属性的作用是什么？

答案：如果多个IBGP发言者在同一个AS内宣告相同的路由，那么就可以利用LOCAL_PREF属性来标识路由的优先级，LOCAL_PREF值越大，路由的优先级就越高。

（26）MULTI_EXIT_DISC属性的作用是什么？

答案：两个自治系统之间存在多条链路时，EBGP发言者就可以通过MED向邻居AS通告入站流量的优先链路。

（27）BGP发言者发起一条聚合路由时哪种或哪些属性会有用？

答案：通过ATOMIC_AGGREGATE属性向下游路由器告知聚合时丢失了路由信息，而AGGREGATOR属性则用于标识发起路由聚合的路由器。

（28）什么是BGP管理性权值？

答案：BGP管理性权值是Cisco专有参数，可以分配给单台路由器中的路由，权值越高，表明该路由越优。管理性权值仅在本地路由器有效，不会被宣告给其他对等体。

（29）假设去往同一目的地有两条路由，一条是EBGP路由，另一条是IBGP路由，请问BGP路由器会优选哪条路由？

答案：如果权值、LOCAL_PREF、AS_PATH长度、ORIGIN代码以及MED都相等，那么EBGP路由将优于IBGP路由。

（30）假设某路由器有两条去往同一目的地的路由，路径A的LOCAL_PREF为300，且AS_PATH中有3个AS号，路径B的LOCAL_PREF为200，且AS_PATH中有2个AS号。假定其他情况完全一致，请问路由器会优选哪条路径？

答案：在BGP决策进程中，LOCAL_PREF比AS_PATH的优先权更高，因而将优选路径A。

（31）什么是路由阻尼？

答案：路由阻尼是一种对BGP路由状态变化而给予的惩罚机制。路由状态的变化越频繁（路由翻动），累加的惩罚值就越大，当惩罚值超过一定阈值时，该路由就会被抑制一段时间，从而大大降低不稳定路由对BGP互联网络的不利影响。

（32）请给出路由阻尼中的惩罚值、抑制门限、重用门限以及半衰期的定义。

答案：惩罚值是路由阻尼机制在路由状态发生变化后给该路由赋予的一种特征值。

抑制门限是一个阈值，如果某路由累加的惩罚值超过了该阈值，那么就不再宣告该路由。

重用门限也是一个阈值，如果被抑制路由的惩罚值降低到该阈值之下时，表示可以重新宣告该路由。

半衰期是路由的累加惩罚值减小的速率，在半衰期结束时，惩罚值也降低到原先的一半。

（33）什么是IGP同步？为什么同步很重要？

答案：IGP同步是一种路由规则，即除非某特定转接路由位于IGP路由表中，否则BGP路由器不能向EBGP对等体宣告该转接路由。如果BGP路由器通过IGP路由器来转发某转接数据包，但该IGP路由器不知道该路由，那么将丢弃该数据包。

（34）在什么情况下可以安全地关闭IGP同步机制？

答案：如果AS内的IBGP对等体为全网状连接或某AS不是一个转接AS时，就可以关闭IGP同步机制。

（35）什么是BGP对等体组？

答案：BGP对等体组就是在一组共享相同路由策略的BGP对等体，由于对等体组可以将路由策略应用于一组路由器（而无需为单台路由器单独配置路由策略），因而可以简化配置工作。

（36）什么是BGP团体？

答案：BGP团体是一组共享相同路由策略的路由器，只要设置路由的COMMUNITY属性即可启用该机制，接收到这些路由的对等体可以识别COMMUNITY属性并应用相应的路由策略。

（37）什么是路由反射器？什么是路由反射客户？什么是路由反射簇？

答案：路由反射器类似于路由服务器，可以让IBGP路由器在无需建立全互连关系的情况下实现对等连接，来自某个对等体的路由会被路由反射器宣告（或反射）给其他对等体，因而与IBGP全互连相比，可以大大减少所需的对等会话数量。路由反射器与路由服务器的区别在于，路由反射器本身也是一台路由器。路由反射客户是与路由反射器建立对等连接的IBGP路由器。路由反射簇就是路由反射器及其客户的集合，一个簇可以拥有多个路由反射器，但簇中的客户必须与本簇中的所有路由反射器建立对等连接。

（38）路径属性ORIGINATOR_ID和CLUSTER_LIST的作用是什么？

答案：在使用路由反射器的时候，ORIGINATOR_ID和CLUSTER_LIST属性可以防止出现路由环路。

（39）什么是BGP联盟？

答案：BGP联盟就是一个大的AS，为便于管理，将该大AS划分为一组小型自治系统。

（40）路由反射器能否用于联盟内？

答案：能。

（41）next-hop-self功能的作用什么？是否有其他实现该功能的替代方案？

答案：next-hop-self的作用是让路由器将接收自外部对等体的路由的NEXT_HOP属性更改为自己的IP地址，当IGP不知道外部下一跳地址时就使用该功能。一种可选的方案就是在外部链路上运行被动模式下的IGP，这样就可以知道外部下一跳地址所位于的子网。

第5章

（1）请说明为什么重复性单播无法代替大规模网络中的多播？

答案：重复性单播会给源带来极大的处理负担，会在源接口、数据链路和所连接的路由器上产生很严重的瓶颈。而且，源必须维护相应的状态以记住向哪些地址发送这些重复的数据包，从而潜在地必须有复杂的成员告知源其将要加入和离开的机制。最后，重复性单播还会带来排队问题，而且数据包之间会产生无法接受的时延问题。

（2）IP多播保留的地址范围是什么？

答案：D类地址被保留给多播使用，即地址的前4个bit为1110，地址范围为224.0.0.0〜239.255.255.255。

（3）单个D类地址前缀能够创建多少个子网？

答案：单个D类地址前缀无法创建子网，IP多播使用的只是单个地址，而不是子网。

（4）对目的地址在224.0.0.1〜224.0.0.255范围内的数据包来说，路由器会采取哪些与其他多播地址不一样的处理方式？

答案：路由器不转发目的地址位于224.0.0.1〜224.0.0.255范围内的数据包。

（5）请写出与下列IP地址相关的MAC地址。

（a）239.187.3.201

（b）224.18.50.1

（c）224.0.1.87

答案：（a）0100.5E3B.03C9

（b）0100.5E12.3201

（c）0100.5E00.0157

（6）MAC地址0100.5E06.2D54代表的多播地址是什么？

答案：MAC地址0100.5E06.2D54可以表示以下32个IP地址中的任一个：第1个8位组是224〜239之间的任一个数，第2个8位组是134或6，第3个8位组是45，最后一个8位组是87。

（7）为什么令牌环介质不适宜分发多播包？

答案：令牌环介质不适宜分发多播包的原因是令牌环帧采用little-endian格式，从而难以简单地将多播IP地址编码为MAC地址。相反，必须使用保留的功能性MAC地址或广播MAC地址，但这两种地址会极大地降低数据链路的效率。

（8）什么是加入等待时间？

答案：加入等待时间是从主机发送加入请求到主机能真正接收到组流量之间的时间周期。

（9）什么是离开等待时间？

答案：离开等待时间是从子网中的最后一个组成员离开多播组到路由器停止向该子网转发多播流量之间的时间间隔。

（10）什么是多播DR（或查询路由器）？

答案：多播查询路由器就是子网中负责向所连主机查询组成员的路由器。

（11）由什么设备发送IGMP Query（查询）消息？

答案：由路由器负责发送IGMP Query（查询）消息，如果某子网连接了多台路由器，那么IP地址最小的路由器将成为查询路由器。

（12）由什么设备发送IGMP Membership Report（成员关系报告）消息？

答案：由主机负责发送IGMP Membership Report（成员关系报告）消息。

（13）IGMP Membership Report（成员关系报告）消息的作用是什么？

答案：由主机发送的IGMP Membership Report（成员关系报告）消息的作用是告知本地路由器其希望加入该多播组。

（14）IGMP General Query（常规查询）与Group-Specific Query（特定组查询）消息之间有何功能性区别？

答案：路由器发送General Query（常规查询）的目的是发现任意及所有多播组的成员，而Group-Specific Query（特定组查询）消息的目的是发现某特定多播组的成员，通常是在接收到Leave Group（离开组）消息之后再发送该消息。

（15）IGMPv2与IGMPv1是否兼容？

答案：IGMPv2的大部分内容与IGMPv1保持兼容，但是如果子网中存在IGMPv1路由器，那么子网中的所有路由器都必须被设置为IGMPv1。

（16）IGMP的IP协议号是什么？

答案：IGMP的IP协议号是2。

（17）Cisco CGMP协议的作用是什么？

答案：通过该协议，以太网交换机可以发现哪些接口上连接了组成员，因而可以只将多播会话分发到那些连接了组成员的交换端口上。

（18）与CGMP相比，IP Snooping的优点是什么？可能的缺点是什么？

答案：与CGMP不同，IP Snooping不是专有协议，因而适用于多厂商混合应用环境。其潜在的缺点是，如果交换机仅以软件方式支持该协议，那么将会影响其性能。

（19）由什么设备发送CGMP消息：路由器、以太网交换机或两者？

答案：只有路由器才能发送CGMP消息，交换机则负责侦听CGMP消息。

（20）什么是反向路径转发机制？

答案：RPF是IP多播路由的基本转发机制，由于路由器发现的最短路径是去往多播源的最短路径，而不是去往目的地的最短路径，当将多播包向目的地进行转发时（更准确的说法是将多播包从多播源向外转发），是沿着最短路径的反方向进行转发的。

（21）多少台主机可以构成一个密集拓扑结构？多少台主机可以构成一个稀疏拓扑结构？

答案：密集拓扑结构与稀疏拓扑结构之间没有具体的主机数量界限。

（22）与隐式加入相比，显示加入的主要优点是什么？

答案：与隐式加入相比，显示加入的主要优点是路由器无需维护那些不是任何组成员上行接口的状态。

（23）有源多播树与共享多播树之间的主要结构性差异是什么？

答案：有源树以源子网或源路由器为根，而共享树则以某些聚合点（RP）或核心路由器为根，而且共享树可以被多个源所共享。

（24）什么是多播定界？

答案：多播定界就是将多播包限制在一个确定的拓扑区域中。

（25）IP多播定界的两种方法是什么？

答案：IP多播定界的两种方法分别是TTL定界和管理性定界。

（26）从多播路由器的观点来看，上游和下游的含义是什么？

答案：上游就是朝向多播源的方向，下游就是离开多播源的方向。

（27）什么是RPF检查？

答案：RPF检查就是验证来自特定多播源的多播包到达的是朝向多播源的上行接口，而不是其他接口。

（28）什么是剪枝？什么是嫁接？

答案：剪枝就是从多播树中删除路由器的操作，嫁接就是向多播树增加路由器的操作。

（29）什么是剪除生存期？剪除生存期到期时会发生什么？

答案：用于隐式加入协议的剪除生存期是路由器维护处于剪除状态的接口的时间。当剪除生存期到期时，路由器将重新在该接口上转发多播包，直至下游邻居重新发出剪除请求。

（30）什么是路由相关性？DVMRP如何通告路由相关性？

答案：路由相关性指的是路由器依赖其上游邻居来转发某特定多播组的多播包。DVMRP路由器通过毒性反转路由（其度量值是所宣告的跳数加上32）来通告路由相关性。

（31）DVMRP是密集模式协议还是稀疏模式协议？

答案：DVMRP是密集模式协议。

（32）MOSPF是密集模式协议还是稀疏模式协议？

答案：MOSPF是密集模式协议。

（33）MOSPF专用LSA的名称及类型是什么？

答案：MOSPF专用LSA的名称是Group Membership LSA（组成员关系LSA），类型为6。

（34）MOSPF路由器是否能与不支持MOSPF的OSPF路由器建立邻接关系？

答案:能。尽管只有数据库描述包中的MC bit被置位的邻居才交换Group MembershipLSA（组成员关系LSA）。

（35）请定义如下MOSPF路由器类型。

（a）域间多播转发路由器

（b）AS间多播转发路由器

（c）万能多播接收路由器

答案：域间多播转发路由器负责转发区域之间的IP多播包，类似于单播OSPF ABR；AS间多播转发路由器负责转发MOSPF域外的IP多播包，类似于单播OSPF ASBR;万能多播接收路由器是一个向其转发所有多播包的路由器。

（36）CBT是密集模式协议还是稀疏模式协议？

答案：CBT是稀疏模式协议。

（37）什么是CBT父路由器？什么是CBT子路由器？

答案：CBT父路由器是上游路由器，而CBT子路由器则是下游路由器。

（38）请描述两种CBT DR从多播源向核心路由器分发多播包的方法以及各自的应用场合。

答案：如果直连的多播源是一个成员源，那么其多播包将通过多播树进行转发；如果多播源是非成员源，那么将创建一条至核心路由器的隧道，并通过该隧道转发多播包。

（39）什么是PIM剪除覆盖？

答案：剪除覆盖就是通过向多路接入网络中的上游路由器发送Join（加入）消息来取消同一网络中其他路由器发出的剪除请求。

（40）什么是PIM转发路由器？如何选择PIM转发路由器？

答案：当多台上游路由器连接到同一个多路接入网络并正在接收同一个多播组的多播包时，PIM转发路由器就是将多播包转发到该网络的路由器。通过Assert（声明）消息中宣告的管理性距离来选举PIM转发路由器，管理性距离最小的即为PIM转发路由器；如果管理性距离相等，那么路由度量值最小的将成为PIM转发路由器•　如果路由度量值也相等，那么IP地址最小的路由器将成为PIM转发路由器。

（41）PIM选择DR的规则是什么？

答案：IP地址（根据PIM Hello消息）最大的PIM路由器就是DR。

（42）什么是PIM SPT？什么是PIM RPT？

答案：最短路径树就是有源树，聚合点树是以聚合点（RP）为根的共享树。

（43）Cisco路由器自动发现PIM-SM RP的两种可用机制是什么？

答案：可以利用Auto-RP或Bootstrap（引导）协议来自动发现PIM-SM RP。

（44）对问题（43）中的两种发现机制来说，哪种机制用于多厂商路由器拓扑结构？

答案：除Cisco外的其他厂商一般不支持Auto-RP，因而Bootstrap（引导）协议适用于多厂商路由器拓扑结构。

（45）什么是C-RP？

答案：C-RP即候选RP，是有资格成为全部多播组或指定的一组多播组的RP的路由器。

（46）什么是BSR？

答案：使用Bootstrap（引导）协议之后，BSR（Bootstrap路由器）负责在整个PIM-SM域中宣告RP-Set中的C-RP信息。

（47）什么是RP映射代理？

答案：使用Auto-RP之后，由RP映射代理负责宣告group-to-RP映射关系。

（48）（S，G）多播路由表项与（*.G）多播路由表项之间有何区别？

答案：（S,G）表项引用的是SPT，而（*，G）表项引用的是RPT。

（49）与自RP至多播源的PIM-SM单向多播树相比，多播源与核心路由器之间的双向CBT树有何重要缺陷？

答案：由于双向树没有明确的上游和下游概念，因而难以保证无环路路径。

（50）什么是PIM-SM源注册？

答案：源注册是路由器将封装在PIM Register（注册）消息中的多播包从多播源转发到RP的一种机制，如果多播源发出的流量较大，那么RP将构建一个SPT并发出一条Register Stop（注册终止）消息。

（51）Cisco路由器何时从PIM-SM RPT切换到SPT？

答案：Cisco路由器在接收到RPT上某特定（S，G）的第一个多播包之后，或者（S，G）的多播包到达速率超过命令ip pim spt-threshold中指定的阈值之后，就会从PIM-SM RPT切换到SPT。

第7章

（1）在7.1节中给出了一个管理性定界的示例，接口E0上的边界阻塞了组织机构本地多播包（目的地址前缀与239.192.0.0/14相匹配的多播包），但允许全局范围的多播包，那么请问组地址224.0.0.50能够穿越该边界吗？

答案：如果目的地址为224.0.0.50的多播包由本地路由器发起，那么该多播包将穿越该边界。虽然access-list 10允许224.0.0.50，但由于该地址位于链路本地范围之内，因而下一跳路由器不会继续转发该多播包。

（2）Cisco IOS软件如何处理运行了PIM协议的点到点接口以及多路接入接口上的DVMRP Prune（剪除）消息？

答案：会忽略多路接入接口上的DVMRP Prune消息，而正常处理点到点接口上的DVMRP Prune消息。

（3）为什么Cisco IOS软件可以接受DVMRP Probe（探测）消息，但却不能发送该消息？

答案：接收DVMRP Probe消息是检测DVMRP邻居的需要。不发送Probe消息的原因是防止多路接入网络上的其他Cisco PIM路由器将该消息的发起者误认为是DVMRP路由器。

（4）什么是PIM（*,*,RP）表项？

答案：PIM（*，*,RP）表项是去往PIM多播边界路由器的树枝，Cisco IOS不支持MBR。

（5）MBGP与普通的BGP之间有何区别？

答案：MBGP有两个扩展属性，即MP_REACH_NLRI和MP_UNREACH_NLRI。

（6）什么是MBGP AFI？

答案：AFI是地址族标识符，当MBGP被用于多播路由时，AFI总是被设置为1（对IPv4），而sub-AFI则用于表示相关的NLRI的是否被用于多播、单播或者同时用于多播和单播。

（7）MSDP携带了不同PIM域中RP之间的多播源和多播组成员信息。这种说法是否正确？

答案：错误。MSDP仅传递多播源信息，而不携带组成员信息。

（8）MSDP的传送协议是什么？

答案：MSDP使用TCP端口号639。

（9）什么是MSDP SA消息？

答案：SA是源有效消息，当多播源的DR注册到RP上时，如果该RP正在运行MSDP，那么将在SA消息中将（S，G）对宣告给其对等体。

（10）MSDP RP如何确定某SA消息是在RPF接口上接收到的？

答案：MSDPRP通过检查BGP下一跳数据库（首先是MBGP，然后是单播BGP）来确定正确的上行接口。

（11）什么是SA缓存？

答案：SA缓存就是存储学习自SA消息的（S，G）状态信息，SA缓存机制是以消耗路由器内存为代价来降低加入等待时间，Cisco IOS软件在默认情况下禁用SA缓存机制。

（12）在不启用SA缓存功能的情况下，有没有办法降低加入等待时间？

答案：有。如果某MSDP对等体正在缓存SA，那么就可以让RP在接收到加入消息后立即使用SA Request（请求）消息向其对等体请求（S，G）信息。

第8章

（1）下面哪一项正确表示了带有60bit前缀的地址200A 0000 0000

0C00 0000 0000 0000 0000？

A. 200A:0000:0000:0C/60

B. 200A::0C00:0:0:0:0/60

C. 200A:0000:0000:0C00::/60

D. 200A::0C00::/60

E. 200A:0:0:C00::/60

F. 200A::0C/60

答案：B、C、E。

（2）地址0:0:0:0:0:0:0:0的使用场合是什么？

答案：这是一个未指定地址，表示缺少一个地址。如果是数据包的源地址，那么表明没有为接口分配地址，正试图发现其不确定地址是否被其他节点所使用。

（3）假设某用户配置其站点边界路由器（该路由器连接在某个IPv6公共网络上），让该路由器宣告其所有内部网络地址（包括FEC0:0020:0:0100::/56），但却被来自该IPv6公共网络管理员告知有问题，为什么？

答案：因为FEC0:0020:0:0100::/56是一个站点本地地址，不能将其宣告到站点边界之外。

（4）哪些扩展头要求自源至目的地路径上的每个IPv6节点都必须予以处理？

答案：逐跳选项头。

（5）哪些扩展头被用于指定在到达目的地之前需要访问的路由器列表并让其中的每台路由器都处理该头部？

答案：紧靠在路由头之前的目的选项头。

（6）假设某路由器接收到一个比其出站链路MTU大的数据包，请问该路由器是否分段该数据包并将这些分段数据包转发到目的地？

答案：不会。该路由器会丢弃该数据包，并向源节点发送一条ICMP Packet Too Big消息，源节点利用这些ICMP包来执行路径MTU发现机制，对数据包进行分段完全是源节点的职责。

（7）请问置位RA消息中的Mbit会产生什么效果？

答案：路由器向链路上的所有主机发送RA消息，如果Mbit被置位，那么主机将从状态化配置服务器获取IP地址。

（8）如果路由器在其RA消息中宣告前缀信息，请问如何使用这些信息？

答案：包含在RA消息中的前缀信息的作用是告诉主机哪些前缀是在链前缀以及/或在自动配置地址时应使用哪些前缀。

（9）主机的IP地址可以存在哪两种状态？每种状态的角色是什么？

答案：优选地址和贬抑地址。可以使用优选地址来发起任何IP会话，而贬抑地址仅被用于维护现有连接，而不能用来发起新连接（如果存在优选地址）。

（10）路由器在其RA消息中宣告何种信息，让主机在发起IP会话时停止使用某特定前缀？

答案：要么是有效生存期值为0，要么是优选生存期值为0。有效生存期为0表示该前缀不再有效，而优选成存期为0则表示贬抑该前缀。

（11）如果某节点的邻居状态为DELAY，那么该节点是否可以向该邻居发送数据包？

答案：可以。虽然状态为DELAY的邻居的可达性没有得到验证，但该节点可以将数据包发送给已缓存的该邻居的链路层地址。

（12）某主机没有运行任何路由协议，利用一台默认路由器向远程节点发送数据，如果该默认路由器出现了故障，那么请问该主机是否会继续向该失效路由器发送数据，直至TCP连接失效？

答案：不会。因为邻居不可达进程、默认路由器列表以及地址解析进程会协助该主机发现失效路由器并寻找一台新的默认路由器。

（13）多播包的作用域值有哪些？其作用是什么？

答案：节点本地作用域、链路本地作用域、站点本地作用域、组织结构本地作用域、全局作用域。利用作用域值可以限制多播的作用范围并限制多播包所能传递的范围。

（14）在Cisco路由器启用IPv6路由的命令是什么？

答案：ipv6 unicast-routing。

（15）在接口上启用IPv6的接口子命令是什么？

答案：ipv6 enable和ipv6 address address prefix[eui-64]。

（16）启用RlPng进程的命令是什么？

答案：ipv6 ripprocess-nameenable。

（17）如何在邻居之间启用BGP-for-IPv6进程？

答案：router bgp local -AS
neighbor neighbor-ipv6-address remote-as remote-as-number
!
address-family ipv6
neighbor neighbor-ipv6-address activate

第9章

（1）请解释SNMP轮询与trap之间的差异。

答案：管理站通过轮询方式从路由器请求相关信息，而trap是由路由器主动发送的有关某事件的信息。

（2）如果指定记录严重等级为差错（Errors）的消息，那么还将会记录哪些其他等级的消息？

答案：紧急（Emergencies）、警报（Alerts）、严重（Critical）。

（3）如果查看路由器的接口时发现存在不同寻常的流量模型，通常情况下，所有的流量都是入站流量，但现在却存在出站流量，请问如何快速确定该流量的源和目的地？

答案：在接口上启用IP记账功能，重复使用命令show ip accounting来查看哪个源/目的地对正在发送流量。

附录E
配置练习题答案

第1章

1.图1-14中的自治系统65531是一个核心AS，请在RTA和RTB上配置EGP，要求如下。

• 不要将AS内的数据链路宣告给任何外部邻居。

• RTA将连接在其S1接口上的网络宣告给RTB。另外，要求RTA和RTB之间不能宣告其他AS间链路。

• RTA和RTB向其外部邻居（除了从其他自治系统学习到的网络）宣告默认路由，而且这两个网关都不得将默认路由宣告给其内部邻居。

图1-14配置练习题（1）的互联网络

答案：RTA和RTB的配置如下。

（2）例1-26给出了图1-15中RTC的路由表。

例1-26：图1-15中RTC的路由表。

图1-15配置练习题（2）的互联网络

利用重分发机制，配置RTC将所有通过EGP学习到的网络都宣告到AS 65510，将192.168.105.0之外的所有内部网络都宣告到核心AS。通过确保不将AS 65510的内部网络经EGP宣告回去来防止路由环路。配置中的进程ID与本地AS号相同。

答案：RTC的相关配置如下。

请注意，上述配置没有为重分发到EGP中的路由指定度量值，EGP增加了默认度量值3。在这个例子中，虽然路由映射也可以实现路由过滤功能，但本例使用了命令distribute-list来进行路由过滤。需要特别关注的是过滤器的配置，当内部网络地址包含在入站EGP更新消息中时将阻塞这些内部网络地址。虽然没有将192.168.105.0宣告到AS之外，但该地址包含在了access-list 20之内。这样做的目的是为了防止该网络通过其他途径找到进入EGP域的路径，进而被路由回AS 65510，而且能防止重复的网络地址进入该AS。

（3）例1-27显示了图1-15中RTD的路由表。

例1-27：图1-15中RTD的路由表。

请根据以下参数配置RTD。

• 仅将192.168.220.0和192.168.230.0宣告到AS 65531；

• 无路由协议被重分发到EGP中；

• 将EGP重分发到AS 65515的IGP中；

• 以度量值1将192.168.3.0从RTC宣告到AS 65515中；

• 以度量值1将192.168.100.0从RTC宣告到AS 65515中；

• 以度量值5将其他路由器宣告到AS 65515中。

答案：RTD的相关配置如下。

（4）例1-28给出了图1-15中RTE的路由表。

请根据以下参数配置RTE.

例1-28：图1-15中RTE的路由表。

• 无IGP被重分发到EGP中；

• EGP不被重分发到任何IGP中；

• AS 65520的所有内部网络都被宣告到AS 65531中；

• AS 65520的内部路由器可以将数据包转发到经RTA宣告的所有网络；

• 所有的进程ID均与AS号相同；

• 所有的OSPF接口都位于Area 0。

答案：RTE的相关配置如下。

（5）如图1-16所示，在前面的练习题中增加了AS 65525,RTF的以太网接口的IP地址为192.168.1.3/24。

图1-16配置练习题（5）的互联网络

请配置路由器RTF，使得其仅与RTB建立对等关系，并且支持第三方邻居。

答案：RTF和RTB的相关配置如下。

第3章

（1）表3-4中的AS 1是一个转接AS，其IGP是OSPF,aera 0跨越整个AS。要求不将AS内部的网络宣告到AS之外，而且运行了EBGP的子网都不允许被宣告到AS 1之内。请写出AS 1中的路由器配置，将所有内部邻居都归入对等体LOCAL。对R3来说，仅允许在环回接口间建立EBGP对等关系。最后，要使用密码ExeRcisel来验证所有的IBGP连接。

答案：

（待续）

（2）表3-4中的AS 2是一个末梢（非转接）AS，其IGP是EIGRP。请配置AS 2中的路由器，让它们与外部对等体建立EBGP对等关系，并将EIGRP路由重分发到BGP中。此外，要求将学习自BGP的路由重分发到EIGRP中。最后，请部署必需的路由过滤器，以防止不正确路由被重分发。

答案：

（3）网络192.168.1.0、192.168.2.0、192.168.3.0、192.168.4.0和192.168.5.0均位于AS 2之中，AS 2的管理员希望邻居AS在发送去往192.168.1.0和192.168.3.0的流量时优选R5，并希望邻居AS在发送去往192.168.2.0和192.168.4.0的流量时优选R6，此时次优链路均作为更有链路的备份链路。192.168.5.0是一个私有网络，不允许将其宣告给EBGP对等体。请修改配置练习题（2）的配置文件，以实现上述路由策略。

答案：请注意，这些配置文件中仍然保留了练习题（2）的AS_PATH过滤器，虽然并不完全需要（因为访问列表可以过滤指定前缀），但是在实际网络中，这样做的好处是可以进一步防止向外宣告错误路由。

（4）配置R5和R6的EBGP邻居，以便将默认路由宣告给AS 2。注意，不允许宣告其他路由。

答案：

（5）AS 2的邻居AS的管理员不同意配置练习题（2）中的某些路由策略，希望其AS中的所有路由器在发送去往192.168.3.0的流量时优选R6，将R5作为备份，在发送去往192.168.4.0的流量时优选R5，将R6作为备份。配置练习题（2）中的其他策略均接受。请给出实现上述路由策略的配置文件。

答案：请注意，在BGP决策进程中，首先考虑的是LOCAL_PREF，其次才是MED。因而在AS 2中的相关路由器上更改相应路由的默认LOCAL_PREF属性会覆盖该路由器的MED。

（6）表3-4中的AS 3是一个末梢（stub）AS,AS 4是一个转接AS，这两个自治系统的IGP均为OSPF,R7和R8的内部接口均位于aera 0。请给出R7和R8的BGP及OSPF配置文件，将表3-4所列出的内部地址均宣告给所有的EBGP对等体，并确保OSPF域中的路由器能够到达外部目的地。不要在BGP和OSPF之间进行路由的重分发，而且要确保R7的BGP路由器ID为192.168.3.254。

答案：R7上的route-map STUB可以防止将接收自EBGP对等体的路由宣告给其他EBGP对等体，从而让该AS成为非转接AS,R8未配置这样的路由过滤器，因而AS 4是一个转接AS。

（待续）

表3-5 AS 3和AS 4的内部目的地

（7）请修改配置练习题（6）的配置文件，让R7和R8在直连两者的链路上运行OSPF，并将BGP从该链路上删除。子网172.16.3.0/24与172.16.4.0/24之间的流量应优选该直连链路，而将其他EBGP链路均作为备用链路。AS 3内的其他地址与AS 4间的流量应优选EBGP链路，而将直连链路作为备用链路。此外，来自其他自治系统的流量可以将直连链路作为备用路由，例如，在去往AS 4的EBGP链路出现故障时，邻居AS可以将去往AS 4的流量发给AS 3，再通过该直连链路转发给AS 4。

答案：

（待续）

（8）表3-4中的AS 5是一个转接AS，其IGP是IS-IS,level 2区域47.0001跨越整个AS,192.168.9.0、192.168.10.0、192.168.11.0和192.168.12.0均是AS 5的内部网络。请给出R9、R10和R11的IS-IS及BGP配置文件，要求确保IS-IS域中的路由器都知道所有的外部路由，并将所有的内部网络都宣告给全部EBGP对等体。不要将IS-IS路由重分发到BGP中。

答案：虽然也可以在外部接口上运行被动模式下的IS-IS，但这些配置使用的都是next-hop-self。

（9）请修改配置练习题（8）的配置文件，仅让AS 4知道网络192.168.12.0，其他自治系统都不知道。

答案：从R9和R11的配置文件中删除了192.168.12.0的network语句，这样就不再宣告该网络。在R10的配置中，将NO_EXPORT的COMMUNITY属性加入到去往192.168.12.0的路由中，因而该路由不会被宣告到AS 4之外。

（10）请修改配置练习题（9）的配置文件，让AS3和AS4优选经AS1的路径去往网络192.168.11.0。

答案：

（待续）

（11）表3-4中的AS 6拥有192.168.16.0、192.168.17.0、192.168.18.0和192.168.19.0等几个内部网络。请给出R12的BGP配置，要求向其邻居AS宣告这些网络以及这些网络的汇总路由，而邻居AS仅向其他自治系统宣告汇总路由。

答案：

（12）请修改R12的EBGP邻居的最后配置，让邻居不接受不属于R12宣告的聚合路由的所有前缀，不接受长于24bit的前缀，而且要求所接受的前缀数量不得超过5条。

答案：

（13）例3-164给出了表3-4中R7的BGP配置情况，表3-4中所列出的前缀均通过OSPF进行宣告。

例3-164：路由器R7的配置。

请解释路由映射EX 13的作用。

答案：路由映射的条项10匹配前缀172.16.1.0并将2预附加到AS_PATH，因而AS 2中的路由器将拒绝该前缀；条项20匹配前缀172.16.2.0并将1预附加到AS_PATH，因而AS 1中的路由器将拒绝该前缀；条项30匹配与拥有AS_PATH为（1,2）的路由相匹配，也就是说与源自AS 2且被AS 1宣告的路由相匹配，该条项将4、5预附加到这些路由的AS_PATH中，因而AS 4和AS 5中的路由器将拒绝该前缀；条项40则抑制其他路由的宣告。

（14）图3-36中的路由器R1是路由器R2、R3和R4的路由反射器，并通过帧中继PVC与这些邻居进行互连。请给出R1的配置文件，要求为连接在这4台路由器上的网络提供完全的网络连接性，簇ID为6500。

图3-36 配置练习题（14）的路由反射簇

答案：

第4章

请根据图4-28来完成配置练习题（1）〜（5）。

图4-28 配置练习题（1）〜（5）所要使用的互联网络

（1）图4-28中的ISP1为AS 3分配了地址块201.50.13.0/24,ISP2为AS 3分配了地址块200.100.30.0/24，RTR1和RTR2从ISP路由器处接收全部BGP路由，但不向ISP传送任何路由，它们之间运行IBGP，并在所有以太网接口上运行OSPF,BGP与OSPF之间不进行路由重分发，路由器接口的地址如下。

RTR1,E0:172.16.3.1/24

RTR1,E1:172.16.2.1/24

RTR1,S0:201.50.26.13/30

RTR2,E0:172.16.3.2/24

RTR2,E1:172.16.1.1/24

RTR2,S0:200.100.29.241/30

SVR1是AS 3的权威DNS服务器，其地址为172.16.3.3,DNS1以地址201.50.13.1到达SVR1，而DNS2以地址200.100.30.254到达SVR1。请据此写出RTR1和RTR2的路由及NAT配置文件，正确使用ISP分配的地址块转换内部地址，任一台内部设备都能到达两个ISP，但在任何情况下，源地址为私有地址的数据包都不能离开AS 3。

答案：

（待续）

（2）图4-28中SVR2的地址是172.16.2.2，SVR3的地址是172.16.2.3，请修改配置练习题（1）中的配置文件，使得ISP1所在AS中的设备能够以轮询方式连接到DNS服务器（地址为201.50.13.3）上。

答案：除了新命令之外，还对ISPlPool进行了修改，使其不再包含地址201.50.13.3。

（3）从ISP2发往200.100.30.50的HTTP数据包被发送到图4-28中的SVR2，从ISP2发往200.100.30.50的SMTP数据包被发送到图4-28中的SVR3，请修改前面的配置文件，以实现本练习题的地址转换要求。

答案：由于IG地址位于ISP2Pool区间之内，因而除了静态NAT映射之外，必须重新配置ISP2Pool。

（4）要使图4-28中的5台外部设备（201.50.12.67〜201.50.12.71）被AS 3中的设备分别视为192.168.1.1〜192.168.1.5，请在前面的配置文件中增加相应的NAT配置语句。

答案：

（5）当AS 3中地址位于子网172.16.100.0/24中的设备向ISP2发送数据包时，要求IG地址均为200.100.30.75，请按此要求修改前面配置练习题中的配置文件。

答案：解决方案是配置PAT，但是与本章所示PAT案例不同，这里所用的地址不是出站接口的地址，因而在RTR2上配置的地址池只包含单个地址。还需要注意的是，本配置中修改了access-list 1，因而用于PAT的IL地址没有被转换到ISP2Pool区间之内。

（6）如图4-29所示，在拓扑结构中增加了冗余链路，使得RTR1和RTR2都有去往两个ISP的连接，并且两台路由器均从两个ISP处接收全部BGP路由，RTR1的S1接口地址为200.100.29.137/30，RTR2的S1接口地址为201.50.26.93/30。请写出这两台路由器的配置文件，要求保证前面练习题中的各种功能特性仍能正常工作。

图4-29配置练习题（6）所要使用的互联网络

答案：

（待续）

第6章

（1）启用IP多播路由的全局Cisco IOS软件命令是什么？

答案：ip multicast-routing

（2）请给出在接口上启用PIM密集模式、稀疏模式以及稀疏—密集模式的命令。

答案：

（3）请给出将RP地址静态指定为172.18.20.4的命令。

答案：ip pim rp-address 172.18.20.4

（4）请按以下要求给出所需的配置语句：将多播组239.1.2.3和228.1.8.0〜228.1.8.255静态映射到RP 192.168.15.5，将多播组239.6.7.8映射到RP 192.168.20.10，将其他多播组映射到RP 192.168.25.1。

答案：

（5）图6-11中所示路由器的接口运行的均是稀疏—密集模式，请按以下要求给出所需的配置语句：让R1成为起始地址为226.13.0.0/24的多播组的RP,R2成为起始地址为239.0.0.0/8的多播组的RP。R3是映射代理，要确保映射代理仅承认R1和R2为指定多播组的RP。此外，所有Auto-RP消息的TTL均为20。

图6-11 配置练习题（5）〜（8）的拓扑结构

答案：

（6）在给定配置练习题（5）所示的配置情况下，假如某多播源发起多播组228.23.14.135的多播流量，并且有一个组成员希望加入该多播组，那么将会发生什么事件？

答案：R1和R2都没有被配置为该多播组的RP，由于所有接口都运行在稀疏—密集模式下，因而为该多播组调用密集模式，并在源和成员之间构建了SPT。

（7）如图6-11所示，请按如下要求写出相应的配置文件：启用Bootstrap协议，让R1和R2同时成为配置练习题（5）所述多播组地址的C-RP，让R3成为BSR，R4成为备用BSR。

答案：

（8）如图6-11所示，请按如下要求写出相应的配置文件：在多播源172.16.1.75与组成员172.16.2.100之间实现多播流量均衡。隧道接口使用无编号IP地址，参考接口为E0，假设IGP正在宣告这些地址。

答案：

（9）查看6.1.3小节中Homburg和Porkpie的配置可以知道，这两台路由器都在隧道接口上运行OSPF的被动模式，为什么？

答案：让单播路由协议（本例中为OSPF）运行于被动模式下，不仅可以知道接口的地址（这对多播RPF功能来说是必需的），而且可以防止单播流量使用该隧道。

（10）命令ip pim spt-threshold 100 group-list 25的作用是什么？

答案：当数据包到达该多播组地址或access-list 25中指定地址的速率超过100kbit/s时，PIM-SM路由器就会从共享树切换到最短路径树。

第9章

（1）请配置一台路由器，让其仅接受来自管理站172.16.1.2和172.16.1.3的轮询要求，不允许该路由器以写入方式访问管理站，仅允许管理站读取SNMP MIB II接口表项的信息，允许管理站172.16.1.4读取所有MIB变量并通过SNMP加载和保存配置文件。此外，通过SNMP向管理站172.16.1.4发送通告（Notifications）等级的日志信息。

答案：

（2）让路由器在5分钟平均CPU利用率超过90%时向管理站172.16.1.4发送SNMP trap，并且只要CPU利用率在60秒间隔内从低于85%到高于90%，都要发送trap。

答案：

（3）让某路由器使用NTP方式基于来自路由器172.16.100.100的时钟信息来更新其时间和日期，但不允许其他路由器根据该路由器的时钟信息来更新时钟。

答案：

（4）配置一个NetFlow聚合缓存，基于源前缀和目的前缀来组合数据，在数据中使用对等体AS，并将数据导出到172.16.1.4。

答案：

（5）让以太网网段上的两台路由器实现互相备份机制。路由器A是主用路由器，在路由器A出现故障时由路由器B接管其角色，当路由器A恢复之后，其将再次成为主用路由器。路由器A通过两条串行链路（serial 0和serial 1）将流量转发到不同的目的地，在其中的某条链路出现故障后，路由器B将成为主用路由器。

答案：

附录F
故障检测与排除
练习题答案

第1章

（1）如图1-17所示，在互联网络中增加了路由器RTG。

图1-17　故障检测及排除练习题（1）的互联网络

虽然RTG与RTB处于对等关系并相互交换可达性信息，但是却存在一个配置错误。请根据例1-29所提供的信息，找出错误之所在。

答案：RTG的EGP配置应该是router egp 65505，而不是router egp 65531。

例1-29：图1-17中的RTB和RTG的EGP表。

第3章

图3-37给出了故障检测及排除练习题（1）〜（6）的互联网络拓扑结构。

图3-37　故障检测及排除练习题（1）〜（6）的互联网络

（1）例3-165给出了图3-37中路由器R2的BGP配置情况。

例3-165：路由器R2的配置。

例3-166给出了R2的BGP表和路由表情况，虽然表中有去往图3-37中各自治系统目的地的路由，但ping这些目的地均失败，为什么？

例3-166：图3-37中R2的BGP表和路由表。

答案：因为R2没有去往BGP表中所引用的下一跳地址的路由，R1和R3必须宣告去往这些地址的路由或使用命令neighbor next-hopself。

（2）例3-167给出了图3-37中路由器R1和R5的debug输出结果，通过这些信息可以看出哪些问题？

例3-167：图3-37中路由器R1和R5的debug输出结果。

（待续）

答案：R5的BGP配置中包含了语句neighbor 172.16.255.6 remote-as 30，而该语句应该为neighbor 172.16.255.6 remote-as 10。

（3）例3-168给出了图3-37中路由器R1和R3的BGP表情况，第一个表显示通过R6（172.16.255.25）或R3（172.16.254.9）均可到达172.17.0.0/24，那么R1将选择哪条路径？为什么？

例3-168：图3-37中路由器R1和R3的BGP表。

答案：由于EBGP路径要优于IBGP路径，因而R1将使用经R6的路径。

（4）例3-169给出了图3-37中路由器R1、R3、R6和R7的BGP及IGP配置情况。

例3-169：路由器R1、R3、R6和R7的BGP及IGP配置。

例3-168显示了R1和R3的BGP表。对下面的每个目的地来说，R6将使用哪个下一跳地址？请解释使用这些地址的原因。

目的地：

172.20.7.102

172.18.58.35

10.53.12.6

答案：172.20.7.102的下一跳地址172.17.1.1，

172.18.58.35的下一跳地址172.16.255.26，

10.53.12.6的数据包被丢弃。

由于R1和R3都没有关闭同步机制，因而它们仅宣告其学习自EBGP邻居的路由，R6从R1学习了172.18.0.0/24，但R1不会向外宣告172.20.0.0/24（因为该路由学习自IBGP对等体），R3将该路由器宣告给R7，而R7又将该路由通过EIGRP宣告给R6。由于R1和R3都是从IBGP邻居R2学习到的默认路由，因而这两台路由器都不会向外宣告该默认路由。

（5）例3-170给出了图3-37中路由器R1和R3的BGP配置情况。

要求抑制所有精确路由，仅宣告聚合路由。但R8的BGP表（如例3-171所示）却仍然显示存在精确路由，问题出在什么地方？

例3-170：路由器R1和R3的BGP配置。

例3-171：图3-37中路由器R8的BGP表。

答案：命令aggregate-address中指定的掩码应该是255.248.0.0，由于所指定的聚合路由与R1和R3路由表中的路由都不匹配，因而没有宣告该聚合路由。

（6）来自AS 60、去往图3-37中其他自治系统的数据包应通过R6和R1之间的链路进行转发，而将R7和R3之间的链路作为备用链路（虽然去往Internet的流量仍然使用该链路）。为了实施该路由策略，R3应仅宣告默认路由和聚合路由172.16.0.0/13，R1应宣告精确路由。例3-172显示了R1、R3、R6和R7的配置情况。

例3-172：R1、R3、R6和R7的配置。

例3-173显示了R7的路由表，从表中可以看出是否实现了上述目标？如果没有，为什么？

例3-173：故障检测及排除练习题（6）中R7的路由表。

答案：没有完全实现上述目标。虽然去往172.18.0.0/24和172.19.0.0/24的路由是正确的，但去往172.20.0.0/24和172.21.0.0/24的路由没在路由表中。这是因为在路由器R3上配置的命令aggregate-address不但抑制了向R3的对等体宣告精确路由，而且还抑制了向其IBGP对等体宣告精确路由，因而R1不知道去往172.20.0.0/24和172.21.0.0/24的路由。

（7）再次回顾例3-19和例3-98，Meribel将其本地路由172.17.0.0宣告给EBGP对等体（ORIGIN属性为Incomplete），而Lillehammer又将该路由宣告回Meribel（ORIGIN属性为IGP）。请问这是否会让Meribel优选来自Lillehammer的路由，从而形成路由环路？

答案：不会。虽然对BGP决策进程来说，IGP的ORIGN属性优先级高于Incomplete的ORIGIN属性，但管理性权值的优先级要高于ORIGIN属性。在默认情况下，Meribel给本地发起的路由分配的权值是32768，而给学习自外部的路由分配的权值是0，因而本地路由的优先级较高。

（8）例3-174给出了图3-24中路由器Colorado的配置情况。

例3-174：图3-24中路由器Colorado的配置。

图3-24中显示的所有路由器ID都配置在环回接口上，除BGP之外，这些路由器上未运行任何路由协议。假设图中所示的全部链路都正常，请问其他5台路由器是否都是Colorado的EBGP对等体？如果不是，为什么？

答案：不是。由于Colorado没有关于10.1.255.6/32的静态路由，因而路由器NewHampshire不是Colorado的EBGP对等体。

（9）参考故障检测及排除练习题（8）中路由器Colorado（如图3-24所示）的配置文件，请问从配置中删除语句no auto-summary的后果是什么？

答案：删除该语句对图中的拓扑结构不会产生任何影响，这是因为所有的路由器ID以及所有自治系统的地址都是10.0.0.0的子网。

（10）参考故障检测及排除练习题（8）中的配置文件，请问入站路由过滤器允许哪些路由？

答案：入站路由过滤器引用了AS_PATH列表2，该列表允许AS_PATH满足以下条件的所有路由。

•　路由的AS_PATH由单个AS号组成；

•　AS号的十进制表示值必须是3位数；

•　AS号的第一个数字必须是2〜6（含2和6）；

•　AS号的第二个和第三个数字必须是0。

（11）参考故障检测及排除练习题（8）中路由器Colorado（如图3-24所示）的配置文件，请问子网10.1.3.0/24中的主机可以ping哪些子网（除了自身AS内部的子网或AS间链路之外）？

答案：仅能ping子网10.1.11.0/24、10.1.12.0/24和10.1.255.1/32，这是因为Colorado上

的出站路由过滤器阻止其EBGP对等体学习本地路由之外的任何路由。

第4章

（1）请指出例4-33配置中的错误。

例4-33：故障检测与排除练习题（1）的配置文件。

答案：静态映射中的IG地址覆盖了地址池EX1。

（2）图4-30中的RTR1连接了两个地址空间重叠的互联网络。

图4-30　故障检测与排除练习题（2）所要使用的互联网络

在图中的路由器上部署了NAT机制（具体配置详见例4-34），但是网络设备无法通过该路由器进行通信，请问错在何处？

例4-34：故障检测与排除练习题（2）的配置文件。

答案：问题并不在于NAT，而在于路由。这是因为所有的地址转换都是动态的，通信双方的主机都无法确定初始地址，因而也就没有办法将数据包发送给对方。

（3）参考图4-21中Cozumel和Guaymas的配置，如果删除这两个配置中的access-list 1的第一行，将会产生什么结果？Cozumel和Guaymas是否仍能ping通对方？

答案：当其中的一台路由器向另一台路由器发送源自其E1接口的数据包时，该数据包的源地址将被转换为IG地址池中的地址。即便换转了源地址，这两台路由器仍能ping通对方。例如，假设Cozumel向Guaymas发出ping包，其源地址10.255.13.254可能会被转换为206.100.176.50，虽然Guaymas并不知道该地址属于其直连子网的一部分，但是它有一条去往206.100.176.0/20（指向Cozumel）的路由，因而Guaymas在发送ping的响应包时，该响应包会被转发到Cozumel，其目的地址又被转换回10.255.13.254。

第6章

（1）请说明例6-63输出结果的含义。

例6-63：故障检测与排除练习题（1）的输出结果。

答案：由于没在路由器上启用多播路由，因而这些多播包将被丢弃。

（2）请说明例6-64输出结果的含义。

例6-64：故障检测与排除练习题（2）的输出结果。

答案：上述输出结果表示在接口E0上接收到（192.168.13.5，227.134.14.26）的多播包，显然该接口不是去往多播源的上行接口，因而该接口不是RPF接口，这些多播包也就无法通过RPF检查，从而被丢弃。

（3）请说明例6-65输出结果的含义。

例6-65：故障检测与排除练习题（3）的输出结果。

答案：在地址172.16.3.50处的路由器既是一个C-RP（224.0.1.39），也是一个映射代理。接口S0.405正在接收Auto-RP消息，并从接口S0.407向外转发这些消息，此外，接口E0上也接收到这些消息，但没有通过RPF检查，因而接口S0.405是去往172.16.3.50的上行接口。

（4）图6-12所示4台路由器中哪台路由器是PIM指派路由器？

答案：IP地址最大的路由器是PIM DR，因而RT4是PIM DR。

（5）图6-12中的哪台路由器正向组成员发送IGMPv2查询消息？

答案：IP地址最小的路由器是IGMPv2查询路由器，因而RT2是查询路由器。

（6）表6-5列出了去往图6-12中多播源172.16.12.18的所有单播路由，请问哪台路由器是PIM转发路由器？

图6-12　故障检测与排除练习题（4）、（5）、（6）的拓扑结构

表6-5　去往图6-12中多播源172.16.12.18的所有单播路由

答案：管理性距离最小的路由器是PIM转发路由器；在管理性距离相等的情况下，度量值最小的路由器是PIM转发路由器。EIGRP的管理性距离是90，而OSPF的管理性距离为110，因而EIGRP的管理性距离较小。对这两台EIGRP路由器来说，R2的路由拥有较小的度量值，因而R2是PIM转发路由器。

（7）例6-66显示了图6-10所示PIM域的RPF跟踪情况，该路由器运行的单播IGP是RIP-2。请问该跟踪信息是否指示了什么问题？

例6-66：故障检测与排除练习题（7）的mtrace输出结果。

答案：是的。Beret和Boater之间存在等价路径（或者经过Turban，或者经过Fez）。由于Beret可以只有一个RPF邻居，因而其选择IP地址最大的邻居。在本练习题中，Turban的IP地址最大，但跟踪结果显示其使用的路径是经过Fez的路径，因而可以知道Beret与Turban之间存在问题。

TCP/IP路由技术　（第二卷）

■　掌握BGP-4（事实上的域间路由协议标准）的操作、配置及故障检测与排除；

■　理解NAT的操作、配置及故障检测与排除；

■　通过一系列案例研究及练习题来理解IP多播路由的部署、配置及故障检测与排除；

■　熟悉IPv6（下一代IP协议）的设计目标以及当前的发展状态；

■　通过大量经专家验证的方法来管理路由器；

■　通过大量实用且全面的复习题、配置练习题及故障检测与排除练习题来测试和验证各种所学知识；

■　在掌握高级TCP/IP路由技术的同时，还可以进一步加强CCIE的认证准备工作。

为了管理日益增大的互连网络，需要全面理解路由器的操作行为，理解外部网关协议的各种复杂运行机制，包括TCP连接、消息状态、路径属性、内部路由协议互操作，以及建立邻居连接等内容。本书为读者全面理解BGP-4（边界网关协议版本4）、多播路由、NAT（网络地址转换）、IPv6，以及有效管理路由器等提供了各种翔实的专业知识。Jeff Doyle丰富的实践经验，易于阅读的写作风格及内容全面的论述，使得本书成为所有网络专家的案头宝典。

本书大大扩展了第一卷的主题内容：网络增长所带来的可扩展性和管理性要求。第二卷从第一卷的内部网关协议扩展到了自治系统间的路由协议，以及包括多播和IPv6在内的许多特殊路由问题，并且沿用了在第一卷中所采取的有效的信息组织结构，即在讨论完主题基础知识之后，辅之以一系列能充分展现现实网络世界中各种概念的配置案例，并通过各种经过验证的故障检测与排除方法来解决网络中可能出现的各种问题。本书不但可以帮助广大读者在自己的名字之后获得极具价值的CCIE,®号，而且还能帮助大家掌握现实网络中所需的大量专家级网络知识和技巧。无论您是在准备CCIE认证考试，还是在准备CCIE再认证考试，或是在寻求有关高级路由问题的专家建议，本书都将帮助您理解各种基本概念，并应用各种最佳实践技巧来应对网络的日益增长和有效管理等问题。

Table of Contents

书名页
版权页
内容提要
关于作者
关于技术审校人
献　词
致　谢
译者的话
目录
前　言
第1部分　外部网关协议

第1章　外部网关协议

- 1.1　EGP 的起源

- 1.2　EGP 的操作

- 1.2.1　EGP 的拓扑结构问题
- 1.2.2　EGP 功能
- 1.2.3　EGP 消息格式

- 1.3　EGP 的不足

- 1.4　配置 EGP

- 1.4.1　案例研究：EGP 末梢网关
- 1.4.2　案例研究：EGP 核心网关
- 1.4.3　案例研究：间接邻居
- 1.4.4　案例研究：默认路由

- 1.5　检测与排除 EGP 故障

- 1.5.1　邻居表释义

- 1.5.2　以糖浆般的速度进行收敛

- 1.6　附注
- 1.7　展望
- 1.8　复习题
- 1.9　配置练习题
- 1.10　故障检测与排除练习题

第2章　BGP-4 简介

- 2.1　无类别域间路由

- 2.1.1　汇总概述
- 2.1.2　无类别路由
- 2.1.3　汇总：好处、坏处及不对称流量
- 2.1.4　Internet：迄今为止依然是分层结构
- 2.1.5　CIDR：降低路由表爆炸的危险
- 2.1.6　CIDR：降低B类地址空间被耗尽的危险
- 2.1.7　CIDR 面临的难题

- 2.2　谁需要 BGP

- 2.2.1　单归属自治系统
- 2.2.2　多归属到单自治系统
- 2.2.3　多归属到多自治系统
- 2.2.4　关于“负载均衡”
- 2.2.5　BGP 的危害

- 2.3　BGP 基础

- 2.3.1　BGP 消息类型
- 2.3.2　BGP 有限状态机
- 2.3.3　路径属性
- 2.3.4　管理性权值
- 2.3.5　AS_SET
- 2.3.6　BGP 决策进程
- 2.3.7　路由阻尼

- 2.4　I BGP 与 IGP 同步

- 2.5　管理大规模 BGP 对等应用

- 2.5.1　对等体组
- 2.5.2　团体
- 2.5.3　路由反射器
- 2.5.4　联盟

- 2.6　BGP 消息格式

- 2.6.1　Open（打开）消息
- 2.6.2　Update（更新）消息
- 2.6.3　Keepalive（保持激活）消息
- 2.6.4　Notification（通告）消息

- 2.7　附注
- 2.8　展望
- 2.9　推荐读物
- 2.10　复习题

第3章　BGP-4 的配置及故障检测与排除

- 3.1　基本的 BGP 配置

- 3.1.1　案例研究：在 BGP 路由器之间建立对等关系

- 3.1.2　案例研究：将 IBGP路由注入 BGP
- 3.1.3　案例研究：将 BGP路由注入 IGP
- 3.1.4　案例研究：无 IGP时的 IBGP
- 3.1.5　案例研究：IBGP 作用于 IGP 之上
- 3.1.6　案例研究：EBGP 多跳
- 3.1.7　案例研究：聚合路由

- 3.2　管理 BGP 连接

- 3.3　路由策略

- 3.3.1　重置 BGP 连接
- 3.3.2　案例研究：通过 NLRI 过滤路由
- 3.3.3　案例研究：通过 AS_PATH 过滤路由
- 3.3.4　案例研究：通过路由映射过滤路由
- 3.3.5　案例研究：管理性权值
- 3.3.6　案例研究：管理性距离和后门路由
- 3.3.7　案例研究：使用 LOCAL_PREF 属性
- 3.3.8　案例研究：使用 MULTI_EXIT_DISC 属性
- 3.3.9　案例研究：预附加 AS_PATH
- 3.3.10　案例研究：路由标记
- 3.3.11　案例研究：路由阻尼

- 3.4　大型 BGP

- 3.4.1　案例研究：BGP 对等体组
- 3.4.2　案例研究：BGP 团体
- 3.4.3　案例研究：私有 AS 号
- 3.4.4　案例研究：BGP 联盟
- 3.4.5　案例研究：路由反射器

- 3.5　推荐读物
- 3.6　展 望
- 3.7　命令汇总
- 3.8　配置练习题
- 3.9　故障检测及排除练习题

第2部分　高级 IP 路由问题

第4章　网络地址转换

- 4.1　NAT 操作

- 4.1.1　NAT 基本概念
- 4.1.2　NAT 与 IP 地址保护
- 4.1.3　NAT 与 ISP 迁移
- 4.1.4　NAT 与多归属自治系统
- 4.1.5　端口地址转换
- 4.1.6　NAT 与 TCP 负载分发
- 4.1.7　NAT 与虚拟服务器

- 4.2　NAT 存在的问题

- 4.2.1　头部检验
- 4.2.2　分段
- 4.2.3　加密
- 4.2.4　安全
- 4.2.5　协议相关问题

- 4.3　NAT 配置

- 4.3.1　案例研究:静态NAT
- 4.3.2　案例研究：动态NAT
- 4.3.3　案例研究：网络融合
- 4.3.4　案例研究：通过 NAT多归属到 ISP
- 4.3.5　端口地址转换
- 4.3.6　案例研究：TCP 负载均衡
- 4.3.7　案例研究：服务分发

- 4.4　NAT 的故障检测与排除
- 4.5　参考文献
- 4.6　展 望
- 4.7　命令汇总
- 4.8　配置练习题
- 4.9　故障检测与排除练习题

第5章　IP 多播路由简介

- 5.1　IP 多播的需求

- 5.1.1　多播IP地址
- 5.1.2　组成员概念
- 5.1.3　IGMP
- 5.1.4　CGMP

- 5.2　多播路由存在的问题

- 5.2.1　多播转发
- 5.2.2　多播路由
- 5.2.3　稀疏与密集拓扑结构
- 5.2.4　隐式加入与显式加入
- 5.2.5　有源树与共享树
- 5.2.6　多播定界

- 5.3　DVMRP 操作

- 5.3.1　邻居发现和维护
- 5.3.2　DVMRP 路由表
- 5.3.3　DVMRP 包转发
- 5.3.4　DVMRP 消息格式

- 5.4　MOSPF 操作

- 5.4.1　MOSPF 基础
- 5.4.2　区域间 MOSPF
- 5.4.3　AS 间 MOSPF
- 5.4.4　MOSPF 扩展格式

- 5.5　CBT 操作

- 5.5.1　CBT 基础
- 5.5.2　发现核心路由器
- 5.5.3　CBT 指派路由器
- 5.5.4　成员源和非成员源
- 5.5.5　CBT 消息格式

- 5.6　PIM 简介

- 5.7　PIM-DM 操作

- 5.7.1　PIM-DM 基础
- 5.7.2　剪除覆盖
- 5.7.3　单播路由变化
- 5.7.4　PIM-DM 指派路由器
- 5.7.5　PIM 转发路由器选举

- 5.8　PIM-SM 操作

- 5.8.1　PIM-SM 基础
- 5.8.2　发现 RP
- 5.8.3　PIM-SM 与共享树
- 5.8.4　源注册
- 5.8.5　PIM-SM 与最短路径树
- 5.8.6　PIMv2 消息格式

- 5.9　附 注
- 5.10　展 望
- 5.11　推荐读物
- 5.12　命令汇总
- 5.13　复习题

第6章　IP 多播路由的配置及故障检测与排除

- 6.1　IP 多播路由的配置

- 6.1.1　案例研究：配置 PIM-DM
- 6.1.2　配置 PIM-SM
- 6.1.3　案例研究：多播负载均衡

- 6.2　IP 多播路由的故障检测与排除

- 6.2.1　使用 mrinfo

- 6.2.2　使用 mtrace和 mstat

- 6.3　展 望
- 6.4　配置练习题
- 6.5　故障检测与排除练习题

第7章　大规模多播路由

- 7.1　多播定界
- 7.2　案例研究：穿越非多播域的多播技术
- 7.3　连接到DVMP网络

- 7.4　域间多播

- 7.4.1　MBGP
- 7.4.2　MSDP 的操作
- 7.4.3　MSDP 消息格式

- 7.5　案例研究：配置M BGP
- 7.6　案例研究：配置MSDP
- 7.7　案例研究：MDSP网状多播组
- 7.8　案例研究：任播RP
- 7.9　案例研究：MSDP默认对等体
- 7.10　命令汇总
- 7.11　附 注
- 7.12　展望
- 7.13　复习题

第8章　IPv6

- 8.1　IPv6 设计目的

- 8.1.1　提高扩展能力
- 8.1.2　简化配置
- 8.1.3　提高安全性

- 8.2　IPv6 当前状态

- 8.2.1　IPv6 规范（RFC）
- 8.2.2　厂商支持情况
- 8.2.3　实现情况

- 8.3　IPv6 包格式

- 8.3.1　IPv6 地址
- 8.3.2　地址结构
- 8.3.3　IPv6 头部

- 8.4　IPv6 功能

- 8.4.1　在 Cisco路由器上启用 IPv6 能力
- 8.4.2　ICMPv6
- 8.4.3　邻居发现
- 8.4.4　自动配置
- 8.4.5　路由
- 8.4.6　任播进程
- 8.4.7　多播
- 8.4.8　QoS

- 8.5　从 IPv4 向 IPv6 的迁移

- 8.5.1　双栈
- 8.5.2　DNS
- 8.5.3　在 IPv4中隧道化 IPv6
- 8.5.4　NAT-PT

- 8.6　附注
- 8.7　展 望
- 8.8　推荐读物
- 8.9　复习题
- 8.10　参考文献

第9章　路由器管理

- 9.1　策略及规程定义

- 9.1.1　SLA
- 9.1.2　变更管理
- 9.1.3　上报规程
- 9.1.4　更新策略

- 9.2　SNMP

- 9.2.1　SNMP 概述
- 9.2.2　CiscoWorks
- 9.2.3　路由器的 SNMP 配置

- 9.3　RMON

- 9.3.1　RMON 概述

- 9.3.2　路由器的 RMON 配置

- 9.4　日志记录

- 9.5　Syslog

- 9.5.1　Syslog 概述

- 9.5.2　路由器的 Syslog 配置

- 9.6　NTP

- 9.6.1　NTP 概述

- 9.6.2　路由器的 NTP 配置

- 9.7　记账

- 9.7.1　IP 记账

- 9.7.2　NetFlow

- 9.8　配置管理
- 9.9　故障管理
- 9.10　性能管理

- 9.11　安全管理

- 9.11.1　密码类型和加密
- 9.11.2　控制交互式访问
- 9.11.3　最小化 DoS 攻击的风险
- 9.11.4　TACACS+
- 9.11.5　RADIUS
- 9.11.6　SSH

- 9.12　支撑管理进程的服务器设计
- 9.13　网络健壮性
- 9.14　实验室
- 9.15　命令汇总
- 9.16　附注
- 9.17　展 望
- 9.18　推荐读物
- 9.19　复习题
- 9.20　配置练习题
- 9.21　参考文献

第3部分　附　录

附录A　命令 show ip bgp neighbors 的显示内容

附录B　正则表达式教程

- B.1　直接量和元字符
- B.2　描述：匹配行起始和行结束
- B.3　括入括号：匹配一组字符
- B.4　求反：匹配除某组字符之外的所有内容
- B.5　通配符：匹配任意单个字符
- B.6　求或：匹配一组字符中的某个字符

- B.7　可选字符：匹配一个可能在也可能不在的字符

- B.8　重复：匹配许多重复字符
- B.9　边界：描述直接量
- B.10　组成在一起：一个复杂的案例
- B.11　推荐读物

附录C　保留的多播地址

- C.1　Internet 多播地址
- C.2　引用
- C.3　人 员

附录D　复习题答案
附录E　配置练习题答案
附录F　故障检测与排除练习题答案