前言
LINC switch是一个由flowforwarding. org主导开发的一款纯openflow交换机,目的是发展和评估openflow协议1.2,1.3,1.4及OF-config1.1在标准商用硬件上应用,因此它提供了对openflow标准的完整支持。是深入学习,理解openflow协议的优质工具。本文就对该交换机软件做一个简单分析。
关于Erlang
Erlang是一种运行在虚拟机上的函数式语言,和其他运行在虚拟机的语言类似,单纯在性能上无法和C这类语言相比,因为底层的虚拟机就是用C实现的。但是,它利用函数式语言无副作用的特性,提供了一个无锁,基于消息传递的并发机制。为了满足电信产品对高容错,高可用,高并发的需求,Erlang维护了一个OTP库,通过这个库,可以轻易地构建出产品级的应用。
因为Erlang出自电信行业,所以支持各种通讯协议和数据包的解析,因此用于openflow自然比较方便。
Erlang运行时环境可以安装在多个平台上,比如Linux, Windows, FreeBSD…就像JVM一样可以跨平台。
理论上,LINC可以安装在任何Erlang可以运行的平台或系统上,不过目前用的最多的应该是安装在Linux上,注意,内核版本要求在3.1以上,Erlang的版本要在R16或以上。
Erlang有哪些内容值得研究?
1.基于消息传递的并发机制:不像其他并发机制需要锁,它要的只是发送一个消息给其他对象。
2.热代码替换:这个特性能在保证系统不停机的同时,升级系统的代码或是修补Bug,这是目前很多语言都没实现的。
3.OTP库:这个库是整个Erlang中最难掌握的部分,应该说,怎样不依靠OTP开发Erlang应用才是最难的。
4.Mnesia:这是一个由Erlang实现的NoSQL,查询,插入等操作都是基于Erlang语法,这个数据库与语言紧密结合。
深入学习LINC之前的准备?
1.入门Erlang shell,很多对运行中系统的更改都可以通过shell操作实现。
2.理解Erlang中的数据结构,比如元组,列表等。
3.理解rebar,一个Erlang应用打包工具。
LINC架构
LINC由以下组件组成:openflow capable switch,openflow协议模块,OF-config模块。
对应的库分别是:of_config,of_protocol,linc。系统通过Erlang/OTP的监督树实现,保证了容错性。
of_protocol:它包含一些用于encode和decode的工具,用于openflow消息与Erlang消息的转换。这个入口负责接收外部的openflow消息并转换,最后传至linc库处理。
linc:它实现了具体的openflow交换机的功能。它维护着多个逻辑交换机及相应的channel,replaceable back-ends及一些通用的逻辑交换机逻辑。
of_config:这个库处理与OF-Config协议有关的事务。在系统中负责对来自openflow configuration point的OF-Config消息进行分析,批准并翻译成Erlang消息。输出的消息将传至linc,用于对openflow交换机的管理。比如把openflow资源关联到某个指定的逻辑交换机实例上。
什么是channel?
channel是一个openflow逻辑交换机与控制器的交流层,在交换机和控制器间起“翻译”的作用。它负责与多个控制器连接的TCP/TLS链接的管理,依靠of_protocol对openflow消息进行翻译,翻译为Erlang可以操作的消息。
什么是Replaceable back-ends?
它执行实际上的对数据包的转发工作,并管理流表,端口等内容,响应来自控制器的openflow消息。因为使用了一个通用的API——gen_switch,一方面,逻辑交换机对backend没有特别依赖,同时逻辑交换机能使用多种backend。
一个简单的示意图,通过此图可以更好地理解其内部结构。
LINC主要依赖的库:
of_protocol:这个库用于编码和解码openflow消息,代码地址:https://github.com/FlowForwarding/of_protocol
epcap:这个Erlang应用用来从eth接口读取数据包(LINC就是基于pcap处理数据包的),代码地址:https://github.com/esl/epcap
tunctl:这个Erlang应用用来管理TUN/TAP接口,代码地址:https://github.com/msantos/tunctl
procket:这个Erlang库用来创建和操作套接字,代码地址:https://github.com/msantos/procket
pkt:一个Erlang网络协议库,代码地址:https://github.com/esl/pkt
LINC内部工作流程:
OF config1.1接口与openflow configuration point的交互(绿色数字):
1.NETCONF工具发送一个OF CONFIG消息以设定一个控制器(NETCONF工具即支持OF-config的控制器,如Ryu)。
2.of_config解析XML消息并转换为Erlang term。
3.更新LINC的状态并初始化一个指向新控制器的channel。
openflow 1.2与1.3接口与openflow控制器的交互(红色数字):
1.控制器通过channel发送packet_out消息。
2.channel对OF消息进行翻译,再发送到LINC backend。
3.LINC用flows去更新ETS表。
LINC backend的Erlang组件工作的流程(蓝色数字):
1.Erlang进程管理中的OF port收到来自网络接口的数据包。
2.数据被解包并翻译为Erlang term。
3.Erlang term被转发至LINC backend。
4.LINC Erlang backend生成route进程去处理数据。
5.route进程从flow/group table获取流并应用它们。
6.route进程发送packet_in消息至channel进程。
7.packet_in消息被编码为OF消息。
8.OF packet_in消息发送到控制器。
9.OF packet_out消息通过流表路由。
10.作为输出的action包被发送至raw socket。
LINC源码目录探索
我们从GitHub clone一份代码下来,进入目录:
gitclone https://github.com/FlowForwarding/LINC-Switch.git
cd LINC-Switch
app目录:该目录中是数个LINC Erlang应用,LINC与其他大多数的Erlang项目一样均使用rebar打包。
docs目录:里面包含一系列的文档,可供参考。
rel目录:这个目录包含rebar的配置文件。
scripts:该目录包含一些辅助的Erlang程序及shell脚本,还提供了一个测试用的简单控制器。
在app目录下又有数个子目录,每个子目录都是一个Erlang应用,以下是详细介绍:
1.linc:LINC的核心,为每个应用提供root supervisor;在控制器与backend间传输消息;实现了OF-config接口,为backends准备好配置设定等。
2.linc_us3:openflow协议1.2版本的backend,wire protocol为0x03。
3.linc_us4:openflow协议1.3版本的backend,wire protocol为0x04。
4.linc_us4_oe:openflow协议1.3版的包含扩展的backend, wire protocol为0x04。
5.linc_us5:openflow协议的1.4版的backend, wire protocol为0x05。
总结
本文从运作原理到源码组织都做了比较基础的介绍。希望学习LINC switch的人都能从中得益。