边界网关协议

边界网关协议（，缩写：BGP）是互联网上一个核心的去中心化自治路由协议。它通过维护IP路由表或“前缀”表来实现自治系统（AS）之间的可达性，属于矢量路由协议。BGP不使用传统的内部网关协议（IGP）的指标，而使用基于路径、网络策略或规则集来决定路由。因此，它更适合被称为矢量性协议，而不是路由协议。
大多数ISP必须使用BGP来与其他ISP建立路由连接（尤其是当它们采取多宿主连接时）。因此，即使大多数互联网用户不直接使用它，但是与7号信令系统——即通过PSTN的跨供应商核心响应设置协议相比，BGP仍然是互联网最重要的协议之一。特大型的私有IP网络也可以使用BGP。例如，当需要将若干个大型的OSPF（开放最短路径优先）网络进行合并，而OSPF本身又无法提供这种可扩展性时。使用BGP的另一个原因是其能为多宿主的单个或多个ISP（RFC 1998）网络提供更好的冗余。
历史.
BGP是为了取代外部网关协议（EGP）协议而创建的，其允许运行一个完全分散的路由系统，从ARPANET模型的核心路由系统过渡到包括NSFNET骨干网及其相关区域网络的分散系统。这使得互联网成为一个真正的分权制度。自1994年以来，第四版的BGP在互联网上使用，所有以前的版本现在都已过时且不可用。第4版中主要的增强功能是通过支持无类别域间路由和路由聚合来减少路由表的大小。第4版（BGP-4）是在早期的 RFC 1771 第4版的基础上编纂，通过20多个草案修改，最终在2006年1月通过，形成 RFC 4271。RFC 4271 版本纠正了一些错误，澄清模糊之处，带来了更接近工业级应用标准的RFC行业惯例。
IPv6 BGP在1995年被 RFC 1883 定义，在1998年的 RFC 2283 中有所改进。它使得BGP-4能够支持诸如IPv4、IPv6等一系列的地址类型，也被称为多协议BGP（Multiprotocol BGP，MP-BGP）。
BGP运行.
BGP的邻居关系（或称通信对端/对等实体，peer）是通过人工配置实现的，对等实体之间通过TCP端口179建立会话交换数据。BGP路由器会周期地发送19字节的保持存活（keep-alive）消息来维护连接（默认周期为60秒）。在各种路由协议中，只有BGP使用TCP作为传输层协议。
同一个AS自治系统中的两个或多个对等实体之间运行的BGP被称为iBGP（Internal/Interior BGP）。归属不同的AS的对等实体之间运行的BGP称为eBGP（External/Exterior BGP）。在AS边界上与其他AS交换信息的路由器被称作边界路由器（border/edge router），边界路由器之间互为eBGP对端。在Cisco IOS中，iBGP通告的路由距离为200，优先级比eBGP和任何内部网关协议（IGP）通告的路由都低。其他的路由器实现中，优先级顺序也是eBGP高于IGP，而IGP又高于iBGP。
iBGP和eBGP的区别主要在于转发路由信息的行为。例如，从eBGP peer获得的路由信息会分发给所有iBGP peer和eBGP peer，但从iBGP peer获得的路由信息仅会分发给所有eBGP peer。所有的iBGP peer之间需要全互联。
BGP也可以运行于VPN之上，使得位置上相隔较远的站点也能安全地交换路由信息。
协议扩展协商.
在peer的握手过程中，通过OPEN消息来协商所支持的协议扩展，例如多协议扩展、各种故障恢复模式等。
BGP路由联通性和路由学习.
同一AS内如果有多个路由器参与BGP路由，则它们之间必须配置成全连通的网状网格结构：任意两个路由器之间都必须配置成对等实体。这样做会带来扩展方面的问题，因为所需要的（TCP）连接数是（BGP）路由器数量的平方。为缓减这个问题，BGP支持两种选项：route reflectors （RFC 4456）和confederations（RFC 5065）。下面讨论了在全连通的IBGP网格中的基本更新处理（UPDATE）。
基本更新过程.
NLRI（Network Layer Reachability Information网络层可达信息）。
一个BGP路由器可以从多个邻居接收NLRI更新信息，并且将（自己拥有的）NLRI信息通告给自己的邻居们（与收到NLRI更新消息的邻居可以不一致）。BGP维护自己的主路由表，称为Loc-RIB（本地路由信息库），注意与路由器的主路由表的区别。针对每一个邻居，当前BGP的进程（可以理解成本地BGP实体）维护一个Adj-RIB-In（邻接路由信息库，入站），记录从该邻居收到的NLRI消息；还要维护一个Adj-RIB-Out（出站），记录从本地BGP实体发送给该邻居的NLRI信息。
在上一段中提到的Loc-RIB, Adj-RIB-In和Adj-RIB-Out的具体实现（这些RIB的物理存储和结构）都由不同的厂商在实现BGP时自行决定。虽然本地路由器上往往通过管理指令查询这些RIB，但BGP路由器并不关心其他BGP路由器是如何实现这些RIB的。具体实现方法可以不同，大家往往把两个Adj-RIBs和loc-RIB存在同一个数据结构中，依靠每个RIB表项后附加的额外信息来区分。BGP进程可以从附加信息中得知很多信息，例如哪些表项是属于为某个特定邻居准备的Adj-RIBs，Loc-RIB表项是否有资格被递交给本地路由器的路由表管理进程，逐邻接路由选择进程收到的Loc-RIB是否符合策略。
如果Loc-RIB表项有资格被提交给本地路由器的路由表管理进程，BGP会把自认为最优的多条路由递交给主路由表进程。所递交的BGP路由是否被选用，则是完全由上述进程的具体实现决定的。例如，如果从路由器的本地端口获知某一前缀与本路由器直接相连，则通常会选择直接转发的路由。只要直连的端口还在正常工作，去向该目的前缀的BGP路由就不会被真正纳入路由表（主路由表）。如果直连端口无法正常工作，并且不存在优先级较高的路由，则Loc-RIB路由表项就会被载入主路由表。之前有一个常见的误解，认为BGP传送各种策略。实际上BGP只传送信息，基于这些信息，BGP进程可以做决策。有些信息显然是用于决策的，例如communities和multi-exit discriminators （MED）。
路由选择.
在选择合适的NLRI加入loc-RIB时，BGP标准规定了很多决策准则。评价NLRI的第一个准则就是判断它的下一跳属性必须是可达（reachable或resolvable）。下一跳可达还可以做如下解释：在本路由器的主路由表中，有一条活动可用的路由，指向下一跳地址所在的前缀。换句话说，必须有一条活动可用的路由去向下一跳。
其次，针对每个邻居，本地BGP进程可以采用不同的标准和厂商自定的原则决定哪些路由可以加入该邻居对应的Adj-RIB-in。邻居可以把去向某个目的地的多条路由发给你，but the first level of preference is at the neighbor level。对于某个目的地，只有一条路由会被加入所谓的Adj-RIB-In（注：在本地，针对每个邻居都有一个Adj-RIB-In）。如果邻居撤销了任何路由，该BGP进程还要负责从Adj-RIB-In中删除对应的条目（如果有）。
如果某个Adj-RIB-In发生变化，本地的主BGP进程将判断对应的邻居通告的新路由是否比Loc-RIB中现有路由更好。如是，将进行替换。如果某个路由被邻居撤销，而且没有别的路由指向相应的目的地，则需要从Loc-RIB中删除相应的路由表项，并且BGP不再将该表项递交给主路由表管理器。如果OSPF或其他非BGP协议也没能为本路由器找到一条指向该目的地的路由，则相应的路由表项将从主路由表中删除。
逐邻居选择.
如果某条路由信息（NLRI）来自一个本域内的对等实体（IBGP），BGP标准规定的第一条准则就是检查LOCAL_PREFERENCE（以下简称LOCAL_PREF）属性。如果来自邻居（同一AS域）的多条IBGP路由指向同一目的前缀，则选择具有最高LOCAL_PREF的那条路由。如果恰巧有多条路由都具有相同的最高LOCAL_PREF，则执行下一条准则。标准中规定LOCAL_PREF为第一准则，一旦确定了下一跳（NEXT_HOP）可达，Cisco和其他几个厂商首先考虑了本地路由器定义的WEIGHT值（该属性仅在本地路由器有效，不会通过BGP扩散），即选择具有最大WEIGHT的路由。
可以通过本地配置或控制软件能够操纵LOCAL_PREF、WEIGHT以及其他的准则。标准中并未定义这样的操纵，但在实际产品中广泛存在。例如，BGP选择进程（selection process）并不直接使用COMMUNITY属性（见下面）。但BGP邻居进程（neighbor process）可以根据手动配置的规则来设置LOCAL_PREF或别的factor的属性值。例如，当COMMUNITY属性值满足某种模式匹配准则（或者说具有某种模式）时，BGP邻居进程就可以修改LOCAL_PREF的值。如果某条路由是从相邻AS的某个对等实体（BGP）获知的，per-neighbor BGP process会根据本地的策略规则计算该路由的LOCAL_PREF，并且与来自同一邻居的其他路由的LOCAL_PREF比较大小。
如果不考虑厂商自己对规则的修改，在BGP协议中，per-neighbor level上依次执行下面的准则，直至选出唯一的一条路由：
BGP配置错误事件.
BGP配置对于互联网流量路由至关重要，配置错误，经过BGP的自动扩散，会导致互联网流量紊乱甚至中断。