最近关于重构我现有的解决方案以用Python绘制LSDBs的工作促使我和我的好朋友Mark(“Solar”)讨论如何使解决方案供应商不可知论和动态化。
由于我最近与XTC[8]和WAE(通过dCloud)[1]进行的实验室工作以及Mark与Northstar[3]的专业互动,我们一致认为,以供应商不可知的方式收集LSDB的明显解决方案是利用BGP-LS地址族,该地址族用于RSVP-TE LSP(即Northstar)。
BGP-LS公司
BGP-LS目前的形式起源于(我们相信)RFC7752[7]——一种将LSDB项(LSA或lsp)从链路状态协议转换成MP-BGP-NLRI的拟议方法,用于通过新的AFI/SAFI对进行传输。也就是说,通过BGP与LSDB通信。
最明显的用例是奥斯本的书基于MPLS的流量工程[4] 描述为“离线路径计算”——一种通过维护链路状态拓扑、链路/路径利用率和MPLS LSP状态的带外oracle来解决打包问题的机制。这样可以减少整个网络的状态,将其委派给转发路径之外的中心实体,并允许在RSVP-TE LSP在现场运行时鸟瞰视图。用于集中控制。
构建和维护这样一个工具所需的拓扑信息,在任何lsp可以被发送信号或者可以整理转发状态之前,属于正在使用的链路状态协议。回想一下,链路状态协议维护网络拓扑的完整视图,以周期性的泛洪作为更新机制。这个被称为链路状态数据库(LSDB)的“完整视图”是任何离线路径计算元素的眼睛。
如果LSDB是眼睛,BGP-LS就是连接它们和大脑的神经和突触:SDN-WAN控制器。
任务
首先,我们设定了以下目标
- 托管一个BGP语言工具,它可以/能够对等BGP-LS,并允许通过网络与python进行交互
- 建立一个运行ISIS的实验室,边缘节点与BGP-LS连接到我们的BGP语音工具。
- 将讲Python的BGP连接到写入工具BGP。
- 绘制拓扑图
对于我们的BGP语言工具,我们选择了GoBGP
GoBGP是一个开源的BGP实现,从零开始为现代环境设计,并用现代编程语言实现,Golang语言 .
可交付成果
可以找到指向托管解决方案的Github的链接在这里 .
bgp ls-vis是执行以下操作的脚本和模块的PoC集合:
- 通过gRPC连接到正在运行的GoBGP实例,并提交BGP-LS表内容的查询
- 或者,从文件加载缓存的BGP-LS表
- 只过滤返回的结构化数据中有用和必需的值
- 生成表示提取的NLRI的NetworkX图形对象
- 将所述NetworkX图形对象的可视化表示绘制到屏幕或文件
除上述主要任务外,可交付成果还允许加载从GoBGP提取的BGP-LS表的YAML转储。这允许使用缓存的BGP-LS表的NLRI绘制拓扑图,而不必使用到GoBGP实例的gRPC连接。这也将允许我们创建单元测试,其中gRPC连接将不可行。
因为设计是模块化的,所以绘图解决方案是分开的,与BGP-LS和LSDB收集工作不同。在绘制拓扑之前,我们在NetworkX中准备一个拓扑,可以使用几个图形库。例如,我们介绍了使用Pyplot、Graphviz和Dash(一种web框架)的绘图方法。
18路由器IS-IS拓扑结构如下所示。注意以下几点:
- 对于P13、14和18之间的广播段,支持伪节点段,如下面的蓝色节点所示。
- tlv137(主机名)信息在存在的地方被提取,并用于按主机名命名节点。如果不存在,则使用IGP RID。
- 注意链接的双向性。我们用有向图来实现这一点。
第1部分-初始设计和测试拓扑
设计需要3个组件:
- 网络本身–链路状态路由协议,包括边缘节点对等BGP-LS
- GoBGP的一个实例运行BGP-LS,窥视网络
- 我们编写的脚本,它通过gRPC连接到GoBGP实例以收集BGP-LS NLRI
我们从GNS3中的实验室拓扑开始,它包括以下内容:
- 18台Cisco设备:17x IOS经典镜像(7200),1台CSR1000v
- 一个ubuntu虚拟机,有两个端口:南到拓扑,北到真实世界。
- 一个云节点,将虚拟机从实验室连接到现实世界,gRPC连接最终将在这个节点上移动。
关于上述拓扑的一些注意事项
- 我们最初尝试使用OSPF来解决这个问题,但是很快就遇到了一个问题:GoBGP无法解析从CSR1000v节点(R2)发送的BGP-LS NLRI。有效载荷中的IGP RID位格式出现问题。因此,我们转向了IS-IS。
- 在与GoBGP建立BGP-LS会话后,我们尝试验证它,其中GoBGP抛出了一个空引用错误。对GoBGP bug跟踪器的研究表明,BGP-LS AFI的实现仅用于API,因此我们无法从bashshell查看表中的NLRI。然而,我们能够成功地关联在CSR1000v的NLRI发射计数,并在GoBGP扬声器处接收到的计数-这些值是相同的,告诉我们所有NLRI都在成功移动。
- https//github.com/osrg/gobgp/issues/2263
- Fujita commented on 22 APR 2020只有API支持bgp ls系列。pull request是最受欢迎的。 Holmium
- 除了路由器13、14和18之间的段是广播型网络外,每条链路都是点对点的网络类型。这是为了能够处理伪节点(在OSPF nomencapture中读为“DR/BDR”)。
最后,由于Marks的经验和对Junos的偏好,他使用vMX设备为自己的GoBGP服务器提供了类似的拓扑,并将BGP-LS NLRI用于真正的厂商无关测试。
配置代码段
gobgpp配置文件由以下YAML定义,调用代码如下:
sudo -E ./gobgpd -f gobgpd.conf -t yaml
global: config: as: 65001 router-id: 10.2.9.9 neighbors: config: neighbor-address: 10.2.9.2 peer-as: 65001 transport: config: local-address: 10.2.9.9 afi-safis: config: afi-safi-name: ls
CSR1000v上的IOS-XE允许通过Cisco文档中详细说明的步骤将链路状态路由信息分发(而不是重新分发)到BGP-LS。[6]
Configuring IS-IS With Border Gateway Protocol Link-State Perform the following steps to configure IS-IS with BGP-LS: Enable the IS-IS routing protocol and enter router configuration mode. Device(config-router)# router isis Distribute BGP link-state. Device(config-router)# distribute link-state Configuring BGP Perform the following steps to configure BGP with BGP-LS: Enable the BGP routing protocol and enter router configuration mode. Device(config-if)# router bgp 100 Configure the address-family link-state. Device(config-router)# address-family link-state link-state
两个平台都确认CSR1000v和GoBGP之间的BGP会话已启动,我们观察到发送的NLRI计数与接收到的NLRI计数。
{"level":"info","msg":"gobgpd started","time":"2021-01-09T11:51:04-05:00"} {"Topic":"Config","level":"info","msg":"Finished reading the config file","time":"2021-01-09T11:51:04-05:00"} {"level":"info","msg":"Peer 10.2.9.2 is added","time":"2021-01-09T11:51:04-05:00"} {"Topic":"Peer","level":"info","msg":"Add a peer configuration for:10.2.9.2","time":"2021-01-09T11:51:04-05:00"} {"Key":"10.2.9.2","State":"BGP_FSM_OPENCONFIRM","Topic":"Peer","level":"info","msg":"Peer Up","time":"2021-01-09T11:51:06-05:00"}
osboxes@osboxes:~$ ./gobgp nei Peer AS Up/Down State |#Received Accepted 10.2.9.2 65001 00:00:25 Establ | 41 41 P2#show bgp link-state link-state summary | i bestpath 41/41 BGP path/bestpath attribute entries using 12384 bytes of memory
第2部分–gRPC连接到GoBGP实例,并拉入BGP-LS NLRI
gRPC与python的不幸特性要求您在建立连接之前准备好接口脚本。程序就是关于GoBGP自述的详细信息谢天谢地,只有一个命令:
Generating Interface You need to generate the server and client interface from GoBGP proto files at first. $ python -m grpc_tools.protoc -I./ --python_out=. --grpc_python_out=. *.proto $ ls *.py attribute_pb2.py attribute_pb2_grpc.py capability_pb2.py capability_pb2_grpc.py gobgp_pb2.py gobgp_pb2_grpc.py
由此生成上述6个文件。我们把它和测试脚本放在同一个目录中,__init__
并使用所需的gRPC调用来建立连接。
from google.protobuf.json_format import MessageToDict RPC & GoBGP imports import grpc import gobgp_pb2 as gobgp import gobgp_pb2_grpc import attribute_pb2 channel = grpc.insecure_channel(f"172.20.10.2:50051") stub = gobgp_pb2_grpc.GobgpApiStub(channel) request = gobgp.ListPathRequest( table_type=gobgp.LOCAL, name="", family=gobgp.Family(afi=gobgp.Family.AFI_LS, safi=gobgp.Family.SAFI_LS), prefixes=None, sort_type=True, ) response = self.stub.ListPath(request) table = [MessageToDict(nlri) for nlri in response]
上面的代码应该有助于建立到GoBGP实例的gRPC连接,并提取完整的BGP-LS表,最后将其格式化为一个列表和dict字典;这是我们在别处进行RESTful查询的常见格式。
可以看到拓扑结构为BGP-18的一个例子在这里 . (tests/bgp-ls_table_dumps/18-node-isis-w-bcast-segment.yaml
)
获得BGP-LS表后,最后一步是将其解析为一种更简洁且与我们的用例相关的格式。从YAML所描述的结构中,您可以快速识别单个项目列表、专用“类型”键中的对象类型,以及我们根本不需要的tlv和空字段的层次结构。
因此,我们定义了一个方法get_lsdb
它将原始的BGP-LS表解析为一个更易于导航的数据结构。这是我们的LSDB,其中有3种类型的LSA:节点、链路和前缀-与BGP-LS RFC中定义的NLRI类型相关。
linkDescriptor: interfaceAddrIpv4: 10.3.4.3 neighborAddrIpv4: 10.3.4.4 localNode: asn: 65001 igpRouterId: 0020.9000.0003 lsattribute: link: bandwidth: 125000000.0 igpMetric: 10 localRouterId: 2.90.0.3 remoteRouterId: 2.90.0.4 reservableBandwidth: 12500.0 unreservedBandwidth: 12500.0 12500.0 12500.0 12500.0 12500.0 12500.0 12500.0 12500.0 node: localRouterId: 2.90.0.3 prefix: {} remoteNode: asn: 65001 igpRouterId: 0020.9000.0004 type: Link localNode: asn: 65001 igpRouterId: 0020.9000.0008 lsattribute: link: localRouterId: 2.90.0.8 node: isisArea: SRI0 localRouterId: 2.90.0.8 name: P8 prefix: {} type: Node localNode: asn: 65001 igpRouterId: 0020.9000.0001 prefixDescriptor: ipReachability: 2.90.0.1/32 ospfRouteType: LsOspfRouteType(0) type: Prefix
第3部分-使用绘图工具绘制LSDB(NetworkX)
我们工作的最后一步是采用上面描述的LSDB格式,在内存中构造一个代表BGP-LS NLRI的拓扑结构。
我们用NetworkX实现了这一点。
NetworkX是一个Python包,用于创建、操作和研究复杂网络的结构、动态和功能。https://networkx.org/
graphing.build_nx_from_lsdb(lsdb: list) -> nx.MultiDiGraph
–一种将LSDB转换为NetworkX图形对象的方法。它建立在链接状态可视化器中展示的先前工作的基础上,这些工作启发了我们的工作,以及在此之前的工作:https://github.com/theclam/ospfcli2dot
NetworkX图形对象由NetworkX节点和边对象组成。图对象可以是许多类型的图中的一种,最适合于链路状态拓扑的加权有向多图
- 多重图,允许相同两个顶点之间有多条边
- 定向的,允许边具有单向性
- 加权,允许链路状态代价表示遍历给定边的度量
另外,NetworkX node和edge对象允许包含任意数据,这允许我们将BGP-LS NLRI中包含的第三级属性作为所述图形对象的属性进行整理。我们用它来表示以下不完整的属性列表
- 节点/边连接一个伪节点
- 为边缘定义的TED带宽约束
- TLV137–节点主机名
- 用于绘制NetworkX图形的任意已知键,如颜色和线宽
我们找到的最快、最简单的绘图库是Pyplot。它是快速和最小的,虽然不是特别漂亮。
未来
“OpenStar”是一个有趣的潜在标题,它可能描述了我们对这个项目的长期目标或者它可能激励的任何其他工作。只提供OpenEnd-BGE-1和OPEND-WAP-1的支持。
如果我们可以为ODL实例提供一个前端,以实现与Northstar解决方案类似的解决方案,或者我们可以为现有解决方案编写自己的IPFIX和PCEP工具来实现离线路径计算呢?建立我们自己的开源北极星将是一个多么好的学习练习。
然而,在实现这些崇高目标之前,还需要更为紧迫的工作。
- 马克的工作在一个基于网络的前端使用Dash正在取得巨大的进展,我们继续合作,以获得一些将是工程师面对面和漂亮。
- 我们必须使解决方案具有动态性和智能性,以便它能够提取最新的BGP-LS信息,并与基线拓扑的缓存或可信副本进行比较,以检测和指示故障(即链路或节点丢失)。
- 我们可以从一个讲BGP的客户机上提取任何其他东西,以允许我们在拓扑结构上绘制各种东西,例如绘制一个有信号的LSP的路径。
这些都是我们正在考虑的想法,但这项工作还没有完成。在它的当前状态下,这是一个概念验证解决方案来绘制BGP-LS表,仅此而已。
如果您想更多地讨论我们已经准备好的解决方案,我邀请您通过LinkedIn与我联系,或者加入在https://discord.me/networking
参考文献和附录
- 思科dCloud。2021Cisco WAN Automation Engine 7.1.3,带NSO、SR、SR-PCE、XTC和Crosswork情境管理器V2. [online] Available at: <https://dcloud2-lon.cisco.com/content/demo/402876?returnPathTitleKey=content-view>;[访问日期:2021年1月13日]。
- 藤田,T.,2021年。Gobgp. [在线]Osrg.github.io. Available at: <https://osrg.github.io/gobgp/>;[访问日期:2021年1月13日]。
- Juniper网络公司。2021Northstar WAN SDN网络控制器-Juniper Networks. [online] Available at: <https://www.juniper.net/uk/en/products-services/sdn/northstar-network-controller/>;[访问日期:2021年1月13日]。
- Osborne,E.和Simha,A.,2003年。基于MPLS的流量工程. 印第安纳波利斯,印第安纳波利斯:思科,第426-431页 .
- 辛格,D.,2021年。又一个新的BGP-NLRI:BGP-LS-包推送器. [在线]Packetpushers.net. Available at: <https://packetpushers.net/yet-another-new-bgp-nlri-bgp-ls/>;[访问日期:2021年1月13日]。
- Support,P.,Routers,C.和Guides,C.,2021年。IP路由:BGP配置指南-边界网关协议链路状态[Cisco ASR 1000系列聚合服务路由器]. [online] Cisco. Available at: <https://www.cisco.com/c/en/us/td/docs/ios-xml/ios/iproute_bgp/configuration/xe-16/irg-xe-16-book/bgp ls.html\concept dad231d4288ae9db0a3b6b45731>;[访问日期:2021年1月13日]。
- 工具.ietf.org . 2021.RFC 7752–使用BGP的链路状态和流量工程(TE)信息的北向分布. [online] Available at: <https//tools.ietf.org/html/rfc7752;[访问日期:2021年1月13日]。
- Trate, F., 2021.在你的网络基础设施中添加一点XTC——思科博客. [online] Cisco Blogs. Available at: <https://blogs.cisco.com/sp/add-a-dollop-of-xtc-to-your-network-infrastructure>;[访问日期:2021年1月13日]。