前言ubuntu
熟悉这款设备的同窗,应该也快到不惑之年了吧!这应该是Cisco最古老的路由器了。上个世纪80年代至今,路由交换技术不断发展,可是在这波澜壮阔的变化之中,总有一些东西在嘈杂的机房内闪闪发光,像极了工程师的头顶,充满了智慧!cookie
Cisco“古董”路由器网络
本文主要描述了一种将三层路由变成二层交换转发(以及二层转发变成三层路由)的实现方式,以应对OVS(OpenFlow)跨网段路由复杂的问题;固然技术自己是客观的,具体应用还要看场景。分布式
随着SDN技术不断“发展”,玩路由器交换机的变成了“传统网工”,搞控制器、转发器的才算是正常工做,固然任何新技术的掌握都离开对“历史”了解或者反刍;也许几年之后当有人听到一条一条的配置ACL、配置路由表是一件很难以想象的事情,由于那时全部的配置都是控制器作好模型生成配置自动下发的,点点鼠标或者写个py脚本就能够了性能
传统的路由交换机学习
OK,言归正传,咱们先来了解一下传统路由、交换的区别:接口
交换: 通常指的是同网段内分组包的转发,转发依据:MAC地址ip
PC视角:当两台主机在同一个网段,PC1须要访问PC2时,PC1首先会发送arp请求报文,请求PC2的的MAC地址;收到响应后,PC1会把PC2的MAC地址封装在分组包的目的MAC的位置,而后将分组报文扔给交换机;PC2也会作相似的动做。路由
交换机视角:交换机会接收网段上的全部数据帧;利用接收数据帧中的源MAC地址来创建MAC地址表(源地址自学习),使用地址老化机制进行地址表维护。MAC地址表中查找数据帧中的目的MAC地址,若是找到就将该数据帧发送到相应的端口,若是找不到,就向除入端口之外的全部的端口发送;向全部端口转发广播帧和多播帧。it
路由:通常指不一样网段的数据包的转发,转发依据:IP路由
PC视角:当两台主机在不一样的网段,PC1须要访问PC2时,PC1首先会在本身的路由表内查询PC2的IP地址对应的下一跳(通常默认是网关)地址,而后再去发送ARP报文,请求该下一跳对应的MAC地址;收到响应后,PC1会把该MAC地址封装在数据包的目的MAC的位置(注意此时的目的IP还是PC2的IP地址,而不是下一跳IP),而后将数据报文扔给路由器;PC2也会作相似的动做。
路由器视角:当路由器收到一个IP数据包,路由器就会找出数据包的三层包头中的目的IP地址,而后拿着目的IP地址到本身的路由表中进行查询,找到“最匹配”的路由条目后,将数据包根据路由条目所指示的出接口或者下一跳IP转发出去,这就是IP路由(固然路由器还会作一些额外的工做:将数据包的三层包头的TTL减一,修改数据包的二层源MAC地址为本身出接口的MAC,修改数据包的二层目的MAC地址为下一跳的MAC);而每一台路由器都会在本地维护一个路由表(Routing Table),路由表中装在着路由器获知的路由条目,路由条目由路由前缀(路由所关联的目的地址)、路由信息的来源、出接口或者下一跳IP等元素构成;路由器经过静态配置或者动态的方式获取路由条目并维护本身的路由表。
OpenFlow的出现
当OpenFlow出现之后,路由器、交换机统一变成了转发器,转发依据:流表
OK,咱们先看一下流表长啥样:
root@ubuntu:~# ovs-ofctl dump-flows br2
NXST_FLOW reply (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/24 actions=output:100
cookie=0x0, duration=15964.186s, table=0, n_packets=1, n_bytes=42, idle_age=15691, priority=100,arp,arp_tpa=1.1.1.0/24 actions=output:1
cookie=0x0, duration=15985.113s, table=0, n_packets=5, n_bytes=490, idle_age=15692, priority=200,icmp,nw_dst=2.2.2.0/24 actions=output:100
cookie=0x0, duration=15802.910s, table=0, n_packets=5, n_bytes=490, idle_age=15692, priority=100,icmp,nw_dst=1.1.1.0/24 actions=output:1
固然有人称流表为ACL,这也能够理解,都有着强大的匹配域以及Action,流表的Pipeline能够算是其特点(性能暂时先不care);到此为止,MAC表、路由表在转发器上面已经通通看不到了,你能看到只有上面的流表。
就OVS来讲,若是把Bridge配置成Secure模式,默认是没有什么流表的;若是如今咱们把OVS配置成一台普通的传统二层交换机,只须要增长几条关于ARP、ICMP的流表,就能够Ping通了(能够参考以上示例),这仍是比较简单的。
固然可能有些人说还有更简单的:只需把Bridge配置Standalone模式或者增长一条默认action=NORMAL的流表就能够了。可是若是这样的话,全部的流量又回到传统的二层三层转发去了,做为新时代的OVS,这符合个人个性啊,若是这样的话,这活仍是交给Linux Bridge来干吧。
可是问题来了,若是把OVS配置成一台有路由器功能的转发器,这就比较困难了;由于经过上文分析路由转发过程相对来讲仍是比较复杂的,须要作的工做以下:
须要一个相似网关的设备(Device),来响应ARP请求:固然能够在新增OVS时自动生成的设备上配置网关地址,也能够增长单独的设备专门做为网关。
须要修改数据包的二层源目MAC地址以及三层包头的TTL:由于路由是逐跳转发的,每一跳都须要作这些工做,即便是如今经过流表转发,中间的转发器直接转发报文,到达倒数第一跳的时候仍是须要把数据包的目的MAC地址修改成接受端的MAC地址。
一切皆交换的世界
在OpenFlow的世界全部的网络设备都是转发器或者称为交换机,执行简单的转发转发动做; OK,那咱们能不能将跨网段访问的路由转发变换成普通的二层转发呢?答案是YES!
下面咱们经过一个示例来实现这个想法:
首先咱们要解决的第一个问题就是网关的问题:如何取消对网关的ARP请求?这个在Linux平台下并非一件难事,只需一条命令:
root@ubuntu:~# ip route add 0.0.0.0/0 dev eth0 scope link
(同时注意arp_ignore须要是0或1)
Link路由是能够直接arp目标地址的,而不是arp下一跳地址。意思就是说,目标地址是属于跟本地直连的二层链路上,不跨三层。既然是不跨三层的链路,arp就能够畅行无阻,而标准中又没有规定arp协议包的请求源和请求目标必须是同一个网段的地址(甚至都没有掩码约束),因此说,一个如下的arp请求是有效的:
验证获得了响应:
细心的童鞋能够发现上面的命令实际上解决了咱们的两个问题,网关的问题解决了,另外因为源主机直接请求目的主机的MAC地址,因此封装的时候也直接封装了目的主机的MAC,省去了咱们在倒数第一跳修改数据包的目的MAC为目的主机的工做。
最后剩下一个问题就是防环的TTL的问题,这个处理起来也比较简单一些,咱们能够在流表中加入actions=dec_ttl(1), output:100,在每一跳中自动减少TTL。
而后在接收端的PC上面作相似的操做,中间的OVS添加相关ARP以及业务流的流表,就实现了跨网段的“交换”。
Little 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一下,有木有看到本身的嘴角上扬呢!
交换机本就应该作二层转发的事情,其余的分布式出去吧!