LINC switch系列之架构分析与源码探索

2018-04-03 13:47:35 浏览数 (1)

前言

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的人都能从中得益。

0 人点赞