传统路由和OVS区别
本文主要描述了一种将三层路由变成二层交换转发(以及二层转发变成三层路由)的实现方式,以应对OVS(OpenFlow)跨网段路由复杂的问题;当然技术本身是客观的,具体应用还要看场景。
随着SDN技术不断“发展”,玩路由器交换机的变成了“传统网工”,搞控制器、转发器的才算是正常工作,当然任何新技术的掌握都离开对“历史”了解或者反刍;也许几年以后当有人听到一条一条的配置ACL、配置路由表是一件很不可思议的事情,因为那时所有的配置都是控制器做好模型生成配置自动下发的,点点鼠标或者写个py脚本就可以了。
一、传统的路由交换机
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地址到自己的路由表中进行查询,找到“最匹配”的路由条目后,将数据包根据路由条目所指示的出接口或者下一跳IP转发出去,这就是IP路由(当然路由器还会做一些额外的工作:将数据包的三层包头的TTL减一,修改数据包的二层源MAC地址为自己出接口的MAC,修改数据包的二层目的MAC地址为下一跳的MAC);而每一台路由器都会在本地维护一个路由表(Routing Table),路由表中装在着路由器获知的路由条目,路由条目由路由前缀(路由所关联的目的地址)、路由信息的来源、出接口或者下一跳IP等元素构成;路由器通过静态配置或者动态的方式获取路由条目并维护自己的路由表。
二、OpenFlow的出现
当OpenFlow出现以后,路由器、交换机统一变成了转发器,转发依据:流表
OK,我们先看一下流表长啥样:
Java
|
1
2
3
4
5
6
|
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平台下并不是一件难事,只需一条命令:
Java
|
1
|
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/32可能跟源主机是跨三层网络的,那现在怎么办呢?OK,可以在源主机上面增加一条明细路由把10.0.0.200/24指向默认网关,在目的主机上面增加一条明细路由把10.0.0.100/32指向默认网关,然后再ping一下,有木有看到自己的嘴角上扬呢!
本质都是一样的,改变ARP的请求方式!
传统路由和OVS区别的更多相关文章
- springboot rabbitmq direct exchange和topic exchange 写法上关于路由键的区别
这是direct exchange写法中消息发送写法,可见下图红色框中路由键是queue队列中定义的路由键 这是topic exchange写法中消息发送写法,可见下图红色框中路由键是exchange ...
- MongoDB与传统数据库的使用区别——批量插入与批量查询
我在百X知道上回答问题时经常遇到类似与这样的问题:MongoDB有没有像MySQL一样的ODBC驱动?MongoDB能不能像MySQL一样获取字段名称或类型. 我的回答是:不行,因为MongoDB不是 ...
- Ajax与传统Web开发的区别
基本概念 1.1,Ajax AJAX:即“Asynchronous Javascript And XML”(异步的JavaScript和XML),是指一种创建交互式网页应用的网页开发技术,尤其是在一种 ...
- 【Ajax 1】Ajax与传统Web开发的区别
导读:从用户体验度的角度来说,利用Ajax进行开发的网站,其体验度高于利用传统Web开发技术,那么,是什么因素导致了这一现象呢?难道说Ajax开发,就一定优于传统Web技术吗?本篇文章,将主要介绍Aj ...
- ThingJS和传统3D开发的区别
物联网3D可视化开发已经辐射到各行各业,无论车间还是消防,城市还是粮仓,亦或是地铁.科技园,物联网可视化是科技的进步,也是行业的进步.而传统的3D可视化开发实施起来并不那么乐观.如果使用ThingJS ...
- Restful API和传统的API的区别
一.功能区别 Restful API是当作资源的唯一标识符,而传统是实现某某功能 如:/api/getList/1 and /api/getList?page=1 二.methods多样性 Restf ...
- 传统IO与NIO区别二
nio是new io的简称,从jdk1.4就被引入了.现在的jdk已经到了1.6了,可以说不是什么新东西了.但其中的一些思想值得我来研究.这两天,我研究了下其中的套接字部分,有一些心得,在此分享. ...
- OE1、OE2、ON1、ON2路由有什么区别?
OSPF的路由类型: 1 .O 域内路由 2 .O/A 域间路由 3 .OE1 域外路由,会累加METRIC值(默认20) 4 .OE2 域外路由,不累加METRIC值(默认20),由外部 ...
- Redis,传统数据库,HBase,Hive区别联系
首先介绍各个数据库: Redis: 传统数据库: HBase: Hive:
随机推荐
- spider-抓取网页内容(Beautiful soup)
http://jingyan.baidu.com/article/afd8f4de6197c834e386e96b.html http://cuiqingcai.com/1319.html Windo ...
- Linux tar命令详解
当你想要压缩一大堆文件时,你得先将这一大堆文件先打成一个包(tar命令),然后再用压缩程序进行压缩(gzip bzip2命令) tar常见命令参数 必要参数有如下: -A 新增压缩文件到已存在的压缩 ...
- python常见释疑(有别于报错)(不定时更新)
文:铁乐与猫 01.在cmd运行py脚本后,直接回到了提示符,没有任何输出,看起来像是并没有运行一样. 答:你的感觉很可能是对的,但脚本很可能己经正常运行,只是你的代码里面很可能没有给出print提示 ...
- JqGrid中文文档之TreeGrid
几年之前写过一个非常简单的jqgrid属性说明. 今天又用到jqgrid这个控件了,捣鼓了许久,第一个treegrid完成了 jQuery("#list1").jqGrid({ u ...
- 解决qpidd服务安装不上的问题
前几天对一个文件夹命名,忘记了qpidd的路径在这个文件夹的下面,导致后来qpidd用不了. 并且有打开计算机-管理-服务时,看到Advanced MessageQueuing Protocol 未启 ...
- 【译文】InnoDB 的不同的SQL如何加锁
http://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html 前置:检索如果用不到索引,会扫描全表,并根据策略加锁.所以,这就是我们合理建立 ...
- 【原创】uWSGI http和http-socket说明
http 和 http-socket的使用上有一些区别: http: 自己会产生一个http进程(可以认为与nginx同一层)负责路由http请求给worker, http进程和worker之间使用的 ...
- 【原创】Apache ab结果参数详解
解释如下: Server Software 服务器软件软件名称. Server Hostname 被测服务器的主机名. Server Port 被测试的Web服务器的监听端口. SSL/TLS Pro ...
- 1864. [ZJOI2006]三色二叉树【树形DP】
Description Input 仅有一行,不超过500000个字符,表示一个二叉树序列. Output 输出文件也只有一行,包含两个数,依次表示最多和最少有多少个点能够被染成绿色. Sample ...
- [USACO09MAR]Cow Frisbee Team
嘟嘟嘟 这个是一个很明显的dp,遇到这种倍数的问题的,就令dp[i][j]表示选到了第 i 只牛(不是选了 i 只牛),sum(Ri) % f == j 的方案数,则, dp[i][j] = dp[i ...