本文主要描述了一种将三层路由变成二层交换转发(以及二层转发变成三层路由)的实现方式,以应对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区别的更多相关文章

  1. springboot rabbitmq direct exchange和topic exchange 写法上关于路由键的区别

    这是direct exchange写法中消息发送写法,可见下图红色框中路由键是queue队列中定义的路由键 这是topic exchange写法中消息发送写法,可见下图红色框中路由键是exchange ...

  2. MongoDB与传统数据库的使用区别——批量插入与批量查询

    我在百X知道上回答问题时经常遇到类似与这样的问题:MongoDB有没有像MySQL一样的ODBC驱动?MongoDB能不能像MySQL一样获取字段名称或类型. 我的回答是:不行,因为MongoDB不是 ...

  3. Ajax与传统Web开发的区别

    基本概念 1.1,Ajax AJAX:即“Asynchronous Javascript And XML”(异步的JavaScript和XML),是指一种创建交互式网页应用的网页开发技术,尤其是在一种 ...

  4. 【Ajax 1】Ajax与传统Web开发的区别

    导读:从用户体验度的角度来说,利用Ajax进行开发的网站,其体验度高于利用传统Web开发技术,那么,是什么因素导致了这一现象呢?难道说Ajax开发,就一定优于传统Web技术吗?本篇文章,将主要介绍Aj ...

  5. ThingJS和传统3D开发的区别

    物联网3D可视化开发已经辐射到各行各业,无论车间还是消防,城市还是粮仓,亦或是地铁.科技园,物联网可视化是科技的进步,也是行业的进步.而传统的3D可视化开发实施起来并不那么乐观.如果使用ThingJS ...

  6. Restful API和传统的API的区别

    一.功能区别 Restful API是当作资源的唯一标识符,而传统是实现某某功能 如:/api/getList/1 and /api/getList?page=1 二.methods多样性 Restf ...

  7. 传统IO与NIO区别二

    nio是new io的简称,从jdk1.4就被引入了.现在的jdk已经到了1.6了,可以说不是什么新东西了.但其中的一些思想值得我来研究.这两天,我研究了下其中的套接字部分,有一些心得,在此分享.  ...

  8. OE1、OE2、ON1、ON2路由有什么区别?

    OSPF的路由类型: 1 .O    域内路由 2 .O/A  域间路由 3 .OE1  域外路由,会累加METRIC值(默认20) 4 .OE2  域外路由,不累加METRIC值(默认20),由外部 ...

  9. Redis,传统数据库,HBase,Hive区别联系

    首先介绍各个数据库: Redis: 传统数据库: HBase: Hive:

随机推荐

  1. PFC电源设计与电感设计计算学习笔记

    PFC电源设计与电感设计计算 更新于2018-11-30 课程概览 常见PFC电路和特点1 常见PFC电路和特点1 CRM PFC电路设计计算 CCM PFC电路设计计算 CCM Interleave ...

  2. ZT Shell 排序

    Shell 排序 分类: 算法 C 2008-09-17 11:02 1898人阅读 评论(4) 收藏 举报 shell语言c 刚才在CSDN的C语言板块看到了有人说Shell排序的问题,所以一起学习 ...

  3. ZT 类模板Stack的实现 by vector

    *//*第3章 类模板 与函数相似,类也可以被一种或多种类型参数化.容器类就是一个具有这种特性的典型例子,它通常被用于管理某种特定类型的元素.只要使用类模板,你就可以实现容器类,而不需要确定容器中元素 ...

  4. caioj 1172 poj 2823 单调队列过渡题

    给定一个n个数的数列,从左至右输出每个长度为m的数列段内的最大数. 输入:第一行两个整数n和m( 1<= n <= 20 0000,m<=n).下来给出n个整数. 输出:一行一个整数 ...

  5. TCP socket和web socket的区别

    小编先习惯性的看了下某中文百科网站对Web Socket的介绍,觉得很囧.如果大家按照这个答案去参加BAT等互联网公司的前端开发面试,估计会被鄙视. 还是让我们阅读一些英文材料吧. 让我们直接看sta ...

  6. 一篇文章搞懂DOM

    学习JavaScript肯定是会遇到DOM操作,那么什么是DOM?它又是干嘛用的?这篇文章为你揭晓答案. DOM是document object model的缩写,简称文档对象模型. 简单的说DOM是 ...

  7. Mac OS X 10.9 Mavericks 无法启动 WebStorm(PhpStorm)

    手滑把Mac的系统升到了10.9,结果机子上的PhpStorm6.0启动不了. 十分天真的重装了一次PhpStorm,问题依然没有修复. 开始怨念苹果的这次升级,毕竟以往的升级都是无缝的,升级OS就应 ...

  8. 25个增强iOS应用程序性能的提示和技巧 — 中级篇

    本文由破船译自:raywenderlich 转载请注明出处:BeyondVincent的博客 _____________ 在开发iOS应用程序时.让程序具有良好的性能是非常关键的.这也是用户所期望的. ...

  9. [BJWC2008]雷涛的小猫

    嘟嘟嘟 dp. 刚开始我想的是dp[i][j]表示在第 i 棵树上,高度为h能吃到的最多的果子,如此能得到转移方程: dp[i][j] = max(dp[i][j + 1], dp[k][j + de ...

  10. chrome的uget扩展程序红色 Unable to connect with uget-integrator问题

    我们根据网上的教程在ubuntu16.04中安装下载工具uget+aria2并配置chrome时,最后重新打开chrome浏览器,发现uget扩展程序是红色的,点开看到”Unable to conne ...