当前位置: 首页 > Web前端 > HTML

OpenFlow(OVS)下的《路由技术》

时间:2023-04-02 21:05:15 HTML

前言熟悉这个设备的同学应该都是四十多岁吧!这应该是思科最老的路由器了。80年代以来,路由交换技术不断发展,但在这波澜壮阔的变革中,总有一些东西在喧闹的机房里闪闪发光,就像工程师的头顶,充满智慧!Cisco“古董”路由器本文主要介绍一种将三层路由改为二层交换转发(二层转发改为三层路由)的实现方法,以应对OVS(OpenFlow)跨网段路由的复杂问题;当然,技术本身是客观的,具体应用还是要看场景。随着SDN技术的不断“发展”,玩路由器、交换机的已经成为“传统网络工作者”,而玩控制器、转发器的还算正常工作。当然,掌握任何新技术都离不开对“历史”的理解或反思;可能几年后,当有人听到一个一个的配置ACL和路由表的时候,会是一件不可思议的事情,因为那个时候所有的配置都是在模型生成配置完成后由控制器自动下发的,鼠标点一下或者写apy脚本就够了。传统的路由交换机就OK了。言归正传,我们先了解一下传统路由和交换的区别:交换:一般指报文在同一网段内转发。转发依据:MAC地址PC视角:当两台主机在同一网段时。当PC1需要访问PC2时,PC1会先发送arp请求报文,请求PC2的MAC地址;PC1收到响应后,将PC2的MAC地址封装在报文位置的目的MAC地址中,然后将报文丢给交换机;PC2也会做类似的动作。交换机视角:交换机会收到网段上的所有数据帧;使用接收到的数据帧中的源MAC地址构建MAC地址表(源地址自学习),并使用地址老化机制维护地址表。在MAC地址表中查找数据帧中的目的MAC地址,找到则将数据帧发送到对应的端口,如果找不到则发送到除入端口外的所有端口;转发广播帧和组播帧。路由:一般指数据包在不同网段的转发。转发依据:IP路由PC视角:当两台主机在不同网段,PC1需要访问PC2时,PC1会先在自己的路由表中查询PC2的IP地址对应的下一跳地址(一般为默认网关)地址,然后发送ARP报文请求下一跳对应的MAC地址;PC1收到响应后,会将MAC地址封装在数据包的目的MAC地址中(注意此时的目的IP仍然是PC2的IP地址,不是下一跳IP),然后将数据抛出数据包到路由器;PC2也会做类似的动作。路由器视角:当路由器收到一个IP数据包时,路由器会在数据包的三层包头中找出目的IP地址,然后将目的IP地址拿到自己的路由表中查询,找到“最佳match”路由项后,根据路由项指示的出接口或下一跳IP转发数据包。修改数据包的二层源MAC地址为自己出接口的MAC,修改数据包的二层目的MAC地址为下一跳的MAC);而每个路由器都会在本地维护一张路由表(RoutingTable),路由表中包含了路由器学习到的路由条目。路由表项由路由前缀(与路由关联的目的地址)、路由信息源、出接口或下一跳IP组成;路由器是静态或动态配置的。获取路由条目并维护自己的路由表。OpenFlow的出现当OpenFlow出现的时候,路由器和交换机就成了转发器。转发依据:流表OK。先看看流表长什么样:root@ubuntu:~#ovs-ofctldump-flowsbr2NXST_FLOWreply(xid=0x4):cookie=0x0,duration=16080.313s,table=0,n_packets=1,n_bytes=42、idle_age=15691、priority=200、arp、arp_tpa=2.2.2.0/24actions=output:100cookie=0x0、duration=15964.186s、table=0、n_packets=1、n_bytes=42、idle_age=15691、priority=100,arp,arp_tpa=1.1.1.0/24actions=output:1cookie=0x0,duration=15985.113s,table=0,n_packets=5,n_bytes=490,idle_age=15692,priority=200,icmp,nw_dst=2.2。2.0/24actions=output:100cookie=0x0,duration=15802.910s,table=0,n_packets=5,n_bytes=490,idle_age=15692,priority=100,icmp,nw_dst=1.1.1.0/24actions=output:1当然,有人把流表称为ACL,这也是可以理解的。它们都有强大的匹配域和Actions,流表的Pipeline可以看作是它的特点(性能暂时忽略);到目前为止,MAC表和路由表在转发器上都是不可见的,只能看到上面的流表。对于OVS来说,如果Bridge配置为Secure模式,默认是没有流表的;如果我们现在把OVS配置成一个普通的传统二层交换机,只需要添加几个关于ARP和ICMP的流表,就可以ping通了(可以参考上面的例子),比较简单。当然,有人可能会说还有更简单的方法:将Bridge配置成Standalone模式或者增加一个流表,默认action=NORMAL。但是如果是这样的话,所有的流量都会回到传统的二层三层转发。作为新时代的OVS,这很符合我的性格。如果是这样的话,这个工作应该交给LinuxBridge。但问题来了。如果OVS配置为带路由功能的转发器,难度会更大;因为通过上面的分析,路由转发过程比较复杂,需要做的工作如下:需要一个类似网关的设备(Device)来响应ARP请求:当然网关地址可以是添加OVS时自动生成的设备配置,或者可以添加单独的设备作为网关。需要修改数据包的二层源和目的MAC地址以及三层包头的TTL:因为路由是逐跳转发的,所以每一跳都需要做这个工作,即使是通过转发现在的流表,中间转发器直接转发数据包到倒数第二跳时,仍然需要修改数据包的目的MAC地址为接收端的MAC地址。一个万物交换的世界在OpenFlow的世界里,所有的网络设备都是转发器或者交换机,做简单的转发转发动作;OK,那我们能不能把跨网段访问的路由转发改成普通的二层转发呢?答案是肯定的!下面我们用一个例子来实现这个想法:首先,我们要解决的第一个问题就是网关的问题:如何取消对网关的ARP请求?这在linux平台下不是什么难事,只需要一个命令:root@ubuntu:~#iprouteadd0.0.0.0/0deveth0scopelink(注意arp_ignore需要为0或1)链接路由直接arp即可目标地址,而不是arp下一跳地址。也就是说,目标地址属于直连本地的二层链路,不跨越三层。由于是不跨三层的链路,arp可以畅通无阻,但是标准并没有规定arp协议包的请求源和请求目的地必须是同一网段的地址(甚至没有amaskconstraint),so,下面其中一个arp请求是有效的:Verificationgotaresponse:细心的童鞋可以发现上面的命令其实解决了我们两个问题,网关的问题就解决了,而且因为源主机直接请求的是目的主机的MAC地址,所以在封装的时候也直接封装了目的主机的MAC,这样就省去了我们在倒数第二跳修改到目的主机的数据包的目的MAC的工作。最后剩下的问题就是防环路的TTL,处理起来比较简单。我们可以在流表中添加actions=dec_ttl(1),output:100来自动减少每一跳的TTL。然后在接收端的PC上做类似的操作,中间的OVS添加相关的ARP和业务流的流表,实现跨网段的“交换”。小Tips通过上面的描述,已经实现了从路由到跨网段交换的转换。另外,也可以实现所谓的二层交换到路由的转换。比如10.0.0.100/24访问10.0.0.200/24。按照我们的假设,应该是通过二层转发,即直接请求目的主机的MAC地址,然后封装发送;但是由于种种原因,目的主机10.0.0.200/24可能会和源主机跨越三层网络,那么我们现在该怎么办呢??OK,可以在源主机上添加详细路由指向10.0.0.200/24到默认网关,在目的主机上添加详细路由指向10.0.0.100/24到默认网关,以及然后再次ping它,你看到自己了吗?嘴角上扬!交换机应该是做二层转发的,剩下的交给分布式吧!