计算机网络原理
第四章 第6节补充
一、先从普通转发表开始
以前我们讲的 IP 转发表是这样的:
目的网络 | 掩码 | 下一跳 | 接口 130.130.130.0 | 255.255.255.0 | - | Eth1 140.140.140.0 | 255.255.255.0 | - | Eth2 default | - | 某下一跳 | 某接口
路由器收到一个 IP 数据报后,只看一个东西:
目的 IP 地址
然后做:
匹配上哪一项,就从对应接口发出去。
所以传统路由器可以概括成:
也就是:看目的 IP,决定往哪走。
二、那流表比普通转发表强在哪里?
普通转发表只看目的 IP。
但是流表可以看很多字段。
比如一个分组来了,它的首部里有很多信息:
链路层:
输入端口
源 MAC 地址
目的 MAC 地址
以太网类型
VLAN ID
网络层:
源 IP 地址
目的 IP 地址
IP 协议号
ToS / DSCP
运输层:
TCP/UDP 源端口
TCP/UDP 目的端口
流表可以从这些字段里挑一些来匹配。
所以它不是只会:
而是可以:
这个是:通用转发 general forwarding
三、什么叫“流”?
在 OpenFlow 里,流可以理解成:
具有相同特征的一类分组。
比如:
例子 1:所有去 51.6.0.8 的包
这是一类流。
例子 2:所有 TCP 目的端口为 22 的包
这也是一类流。
这通常代表 SSH 流量。
例子 3:所有从 10.0.0.3 发往 10.2.x.x 的包
这也是一类流。
所以“流”本质上就是:
用若干首部字段定义出来的一类数据包。
四、流表是什么?
流表就是很多条规则组成的表。
每条规则一般有三部分:
也就是:
部分 | 含义 Match | 匹配哪些分组 Action | 匹配后怎么处理 Stats | 统计匹配了多少包、多少字节
1. Match:匹配条件
比如:
或者:
或者:
匹配字段可以跨很多层。
2. Action:动作
匹配之后可以做很多动作。
常见动作:
forward(2):从端口 2 转发
drop:丢弃
modify:修改首部字段
send to controller:发给控制器
flood:泛洪
所以流表不只是“转发”,还可以“丢弃、修改、上交控制器”。
3. Stats:统计
统计这条规则匹配了:
多少个 packet
多少 byte
比如防火墙、流量管理、计费都可能用到。
五、最简单的流表示例
假设有一张流表:
Match | Action IP Dst = 51.6.0.8 | forward(6) TCP DstPort = 22 | drop IP Src = 128.119.1.1 | drop otherwise | send to controller
意思是:
如果目的 IP 是 51.6.0.8:
如果 TCP 目的端口是 22:
如果源 IP 是 128.119.1.1:
如果都不匹配:
六、为什么说流表可以统一抽象很多设备?
因为很多网络设备本质都能写成:
1. 路由器
传统路由器:
匹配:
动作:
所以路由器可以写成:
Match | Action IP Dst = 130.130.130.0/24 | forward(Eth1) IP Dst = 140.140.140.0/24 | forward(Eth2)
2. 二层交换机
交换机主要看 MAC 地址。
匹配:
动作:
比如:
Match | Action MAC Dst = AA:BB:CC:DD:EE:FF | forward(3)
所以交换机也可以用流表表示。
3. 防火墙
防火墙主要是允许或阻止流量。
比如禁止 SSH:
匹配:
动作:
也就是:
Match | Action TCP DstPort = 22 | drop
再比如禁止某个 IP:
Match | Action IP Src = 128.119.1.1 | drop
所以防火墙也能写成流表。
4. NAT
NAT 要修改地址和端口。
比如内网主机:
要转换成:
可以抽象成:
Match | Action IP Src = 10.0.0.1, TCP SrcPort = 3345 | rewrite SrcIP = 138.76.29.7, rewrite SrcPort = 5001, forward
所以 NAT 也是:匹配 + 修改 + 转发
七、OpenFlow 是什么?
OpenFlow 不是一个新的普通路由算法。
它更像是:控制器和交换设备之间沟通流表规则的协议。
在 SDN 里,网络分成:控制平面
由控制器负责。
它像“大脑”。
负责决定:
哪些流应该走哪条路径
哪些流应该丢弃
哪些流应该修改
哪些规则应该安装到交换机里
数据平面
由 OpenFlow 交换机负责。
它像“手脚”。
只负责按照流表执行动作:
查表
匹配
转发
丢弃
修改
OpenFlow 的作用
OpenFlow 负责让控制器告诉交换机:
你这里装一条规则:匹配什么,动作是什么。
OpenFlow 是 SDN 控制器给交换机下发流表规则的一种协议。
八、OpenFlow 工作流程
假设一个分组进入 OpenFlow 交换机。
它大概这样处理:
第一步:查流表
交换机拿分组首部字段去匹配流表。
第二步:找到匹配项
如果匹配到一条规则,就执行对应 action。
比如:
就从端口 3 发出去。
第三步:如果没有匹配项
交换机可以把这个分组发给控制器:
控制器看完之后决定:
丢弃
转发
安装一条新规则
修改路径
然后控制器再把规则下发给交换机。
九、为什么要用 OpenFlow?
传统网络里,每台路由器自己运行协议,自己决定怎么转发。
OpenFlow/SDN 的思想是:把决策集中到控制器,让底层设备只执行规则。
这样有几个好处。
1. 网络可编程
以前路由器行为比较固定。
现在控制器可以像写程序一样控制网络。
比如:
某类流量走路径 A
某类流量走路径 B
游戏流量优先
某个源 IP 全部封禁
某个端口全部丢弃
2. 统一管理
控制器掌握全网拓扑,可以统一计算路径。
不用每台设备各自为战。
3. 灵活实现多种设备功能
同一个 OpenFlow 交换机,通过不同流表,可以表现得像:
路由器
交换机
防火墙
NAT
负载均衡器
十、优先级 priority
这点很重要,因为流表可能有多条规则同时匹配。
比如一个分组:
它可能同时匹配:
Match | Action IP Src = 128.119.1.1 | drop TCP DstPort = 22 | drop IP Dst = 51.6.0.8 | forward(6)
那么到底按哪条?
OpenFlow 流表项通常有:
priority,优先级。
如果多条规则匹配,选优先级最高的。
这个和 IP 最长前缀匹配有点像。
传统路由表是:多个 IP 前缀匹配,选最长前缀。
流表是更通用的:多个流表项匹配,选优先级高的。
十一、通配符 wildcard(就是正则表达式)
流表里经常有 *。
* 表示:这个字段不关心,什么值都可以。
比如:
IP Src | IP Dst | TCP DstPort | Action * | 51.6.0.8 | * | forward(6)
表示:不管源 IP 是谁,不管端口是多少,只要目的 IP 是 51.6.0.8,就从端口 6 转发。
再比如:
IP Src | IP Dst | TCP DstPort | Action * | * | 22 | drop
表示:不管谁发的,也不管发给谁,只要 TCP 目的端口是 22,就丢弃。
十二、结合打游戏的例子理解
比如一个校园网/公司网想禁止某些流量。
它可以下发 OpenFlow 规则:
Match | Action UDP DstPort = 某游戏端口 | drop
那游戏数据包就过不去。
如果它想让游戏流量走低延迟链路,可以写:
Match | Action UDP DstPort = 游戏端口 | forward(高速出口)
如果它想让网页流量走普通出口:
Match | Action TCP DstPort = 80 or 443 | forward(普通出口)
所以 OpenFlow 很像:
用规则表控制不同类型流量怎么走。
十三、OpenFlow 和普通路由表的区别
对比 | 普通路由表 | OpenFlow 流表 主要匹配字段 | 目的 IP | 多层首部字段 动作 | 转发到下一跳/接口 | 转发、丢弃、修改、送控制器 控制方式 | 路由协议计算 | 控制器下发 灵活性 | 较低 | 高 表项形式 | 目的网络 → 接口 | Match → Action 典型应用 | 路由器 | SDN、交换机、防火墙、NAT 等
路由表是流表的一种特例。
传统路由表相当于只匹配目的 IP,只执行转发动作的流表。
十四、其实可以把 OpenFlow 想成“网络里的 if 语句”
这特别好理解。
一条流表项就像一条 if 语句:
if 目的IP == 51.6.0.8: 从端口6转发
或者:
if TCP目的端口 == 22: 丢弃
或者:
if 源IP == 10.0.0.1 and 目的IP == 10.2.0.4: 从端口3转发
所以 OpenFlow 设备其实就是在高速执行很多条:
十五、OpenFlow 例子:控制一条路径
假设有三个交换机:
想让:
的数据走这条路径。
控制器可以分别给每个交换机下规则。
在 s1 上
匹配:
动作:
在 s2 上
匹配:
动作:
在 s3 上
匹配:
动作:
这样一来,整条路径就被控制器安排好了。
编排出来的表项可以控制网络范围内的行为。
十六、OpenFlow 和 SDN 的关系
SDN是一种网络架构思想:
控制平面和数据平面分离,控制器集中控制网络。
OpenFlow
是 SDN 中一种具体协议:
控制器通过 OpenFlow 给交换机下发流表。
十七、自问自答
问:什么是流表?
答:
流表是通用转发设备中的规则表,每个表项通常由匹配字段、动作和统计信息组成。设备对到达分组的首部字段进行匹配,并执行对应动作。
问:OpenFlow 表项包括什么?
答:
Match、Action、Stats。
问:OpenFlow 的 Match 可以匹配哪些字段?
答:
可以匹配输入端口、源/目的 MAC、VLAN、源/目的 IP、IP 协议号、TCP/UDP 源端口和目的端口等多个层次的首部字段。
问:OpenFlow 的 Action 有哪些?
答:
可以转发到某个端口、丢弃、修改首部字段,或者封装后发送给控制器。
问:为什么 OpenFlow 是通用转发?
答:
因为它不局限于目的 IP 转发,而是能匹配链路层、网络层、运输层多个字段,并执行转发、丢弃、修改等动作。
问:OpenFlow 如何抽象路由器、交换机、防火墙、NAT?
答:
路由器匹配目的 IP 前缀并转发;交换机匹配目的 MAC 并转发或泛洪;防火墙匹配 IP 地址或端口并允许/丢弃;NAT 匹配地址和端口并改写地址端口。它们都能表示成匹配加行动。
OpenFlow 的核心是流表,流表的核心是 Match + Action + Stats。
传统路由表:
OpenFlow 流表:
所以:路由表是流表的特例,OpenFlow 是把网络设备行为变成可编程规则表。
OpenFlow 让网络设备不再只会按目的 IP 转发,而是可以像执行 if 语句一样,根据多层首部字段灵活处理分组。
