前言:
LINC switch是一个由flowforwarding. org主导开发的一款基于Apache2.0协议开源的Openflow交换机软件。本文在安装指南的基础上,介绍了其运行时的配置与使用。
介绍:
LINC switch基于Erlang构建,因而它的配置文件要基于Erlang语法。在编辑配置文件时可以准备一个支持括号补全的编辑器或Erlang IDE。
推荐使用sublime text,当然你也可以用Eclipse与Erlang插件集成或IntelliJ IDEA加Erlang插件的IDE编辑。
准备:安装好sublime text后,更改语法类型为Erlang:
我们可以从xshell中复制默认的sys.config文件的内容至sublime text:
为LINC的运行进行特定配置
1.Erlang语法快速理解:
一个Erlang配置文件中可能会包含多种数据结构,比如元组,列表,字符串,数字和原子(atom),例如:
字符串:"hello"
数字:1234或1.234
原子:this\_is\_atom
元组:{ofs\_port\_no,1}
列表:[1,2,3]
这些数据结构在很多动态语言中都有,如果你熟悉javascript或python的话会很容易运用起来。但实际上,Erlang的数据结构又存在一些不同点:
- 1.字符串实际上是列表,一个由字母的ascii码组成的列表,但字符串在Erlang中的使用不及原子(atom)方便。字符串必须用双引号括起来。
- 2.原子以小写字母组成,准确地说是以小写字母开头。可以在元组的第一个位置标识该元组(用Erlang的用户都应该知道)。基本上可以在很多地方代替字符串。
- 3.在Erlang中,变量以大写字母开头,变量不可变。
- 4.在Erlang中,“%%”为注释。
2.启用LINC的OF config支持:
1 |
{of_config, enabled} |
该元组第二个元素可以为disabled。
3.配置逻辑交换机:
一个交换机实体上可以运行多个逻辑交换机,每个逻辑交换机都可以有一个单独的控制器,端口和队列
1 2 3 4 5 6 7 8 9 10 11 12 |
{logical_switches, [ {switch, 0, [ ….. ]}, {switch, 1, [ ….. ]}, {switch, 2, [ ….. ]} ]} |
配置逻辑交换机,用户可以指定backend,控制器,端口等内容:
1 2 3 4 5 6 7 8 |
{switch, 0, [ {backend, linc_us4}, {controllers, []}, {ports, []}, {queues_status, disabled}, {queues, []} ]} |
配置backend(关于什么是backend,请参考“LINC switch架构分析与源码探索”):
启用Openflow1.2的支持:
1 |
{backend, linc_us3}, |
启用openflow1.3的支持:
1 |
{backend, linc_us4}, |
配置控制器:
1 2 3 4 |
{controllers, [ {"Switch0-DefaultController", "localhost", 6633, tcp} ]}, |
这里需要指定一个ipv4的地址,端口和协议,默认的端口为6633。实际上,这个可以空着,建议由OF-Config客户端自动配置。
配置input和output的端口:
我们通过ports元组配置ingress和egress端口,但是ingress和egress的端口在配置时看上去并没有任何区别。每个端口的定义中包含:端口编号、接口名称、队列定义和端口带宽。
1 2 3 4 5 6 |
{ports, [ %% {port, 1, [{interface, "eth0"}]}, %% {port, 2, [{interface, "tap0"}]}, %% {port, 3, [{interface, "tap1"}, {ip, "10.0.0.1"}]} ]}, |
配置队列:
虽然对于openflow并不是必要的,但可以考虑启用它。默认情况下这个特性是关闭的。
1 |
{queues_status, disabled}, |
同样,元组的第二个元素可以为enabled。如果启用队列,则需要把它们分配给端口并设置合适的速率。比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{queues, [ {port, 1, [{port_rate, {100, kbps}}, {port_queues, [ {1, [{min_rate, 100}, {max_rate, 100}]}, {2, [{min_rate, 100}, {max_rate, 100}]} ]}]}, {port, 2, [{port_rate, {100, kbps}}, {port_queues, [ {1, [{min_rate, 100}, {max_rate, 100}]}, {2, [{min_rate, 100}, {max_rate, 100}]} ]}]} ]} ]} |
4.添加TLS支持:
在设立TLS连接的逻辑交换机和控制器间需要证书和密钥的支持。这里保存着证书和私钥,储存的值为base64编码和DER编码的字符串。
1 2 |
{certificate, ""}, {rsa_private_key, ""} |
5.添加netconf支持:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{enetconf, [ {capabilities, [{base, {1, 1}}, {startup, {1, 0}}, {'writable-running', {1, 0}}]}, {callback_module, linc_ofconfig}, {sshd_ip, any}, {sshd_port, 1830}, {sshd_user_passwords, [ {"linc", "linc"} ]} ]}, |
我们可以用ssh来测试:
1 |
ssh -v -p 1830 -l linc -s 127.0.0.1 netconf |
6.添加错误日志记录:
LINC使用lagger库记录日志。
1 2 3 4 5 6 7 8 9 10 11 12 |
{lager, [ {handlers, [ {lager_console_backend, info}, {lager_file_backend, [ {"log/error.log", error, 10485760, "$D0", 5}, {"log/console.log", info, 10485760, "$D0", 5} ]} ]} ]}, |
几种可以参考的sys.config范例
在这里,将会给出几个config_gen的用例:
1.一个交换机+三个控制器:
1 2 |
scripts/config_gen -s 0 eth1 eth2 eth3 -c tcp:127.0.0.1:6633 tcp:10.48.10.10:6644 tls:192.168.10.10:6655 -o rel/files/sys.config |
用例解释:
-s指定交换机编号,生成的sys.config中交换机以这样的方式命名:Switch0-Controller
-c指定控制器,tcp为基于tcp的连接,tls为基于tls的连接。
生成的文件像这样:
可以看到controllers里有三个同名但控制器设定不同的值。
2.两个交换机+不同的控制器:
1 2 |
scripts/config_gen -s 0 eth1 eth2 eth3 -c tcp:127.0.0.1:6633 -s 1 eth5 eth6 eth7 tcp:10.48.10.10:6644 tls:192.168.10.10:6655 -o rel/files/sys.config |
3.两个交换机+同一个控制器:
1 2 |
scripts/config_gen -s 0 eth1 eth2 eth3 -s1 eth5 eth6 eth7 -c tcp:127.0.0.1:6633 tcp:10.48.10.10:6644 tls:192.168.10.10:6655 -o rel/files/sys.config |
可以看到,官方提供了一个非常方便的工具去进行测试。LINC适合openflow快速的测试和研究工作。
测试控制器:
运行LINC:
1 |
root@workgroup3:~/LINC-Switch/rel/linc/bin# ./linc start |
这里我们只用Ryu:
1 2 3 |
root@workgroup3:~/LINC-Switch# pip install ryu root@workgroup3:~/LINC-Switch# cd scripts/ryu root@workgroup3:~/LINC-Switch# ryu-manager --verbose /usr/local/src/ofswitch/LINC-Switch/scripts/ryu/l2_switch_v1_3.py |
我们在flow learning模式启动了Ryu,openflow的协议版本为1.3。
停止LINC可以这样:
1 |
root@workgroup3:~/LINC-Switch/rel/linc/bin# ./linc stop |
通过REST设置防火墙服务:
LINC可以成为一个基于REST管理的防火墙服务,接下来进行测试:
用config_gen生成一个合适的sys.config(仅测试用):
1 |
root@workgroup3:~/LINC-Switch/scripts# ./config_gen -s 0 eth0 -c tcp:127.0.0.1:6633 -o sys.config |
把文件复制到/LINC-Switch/rel/linc/releases/1.0即可
启动LINC:
1 |
root@workgroup3:~/LINC-Switch/rel/linc/bin# ./linc console |
新开终端,进入Ryu的目录启动Ryu:
1 |
root@workgroup3:/usr/local/lib/python2.7/dist-packages/ryu# ryu-manager --verbose --use-stderr app/rest_firewall.py lib/ofctl_v1_2.py |
当你看到这句话时即算成功:
1 |
[FW][INFO] dpid=0000000c295fa162: Join as firewall. |
同时在Erlang终端可以看到这个:
1 2 |
(linc@workgroup3)1> 16:52:38.087 [info] Created port: {port,1,[{queues_status,disabled},{queues,[]},{config,{port_configuration,undefined,up,false,false,false}},{features,{features,undefined,'100Mb-FD',true,copper,unsupported}},{queues,[]},{interface,"eth0"}]} 16:52:38.094 [info] Connected to controller 127.0.0.1:6633/0 using OFP v4 |
测试防火墙是否开启:
1 |
root@workgroup3:~# curl -i -H "Accept: application/json" -X GET http://localhost:8080/firewall/module/status |
返回:
1 2 3 4 5 6 |
HTTP/1.1 200 OK Content-Type: application/json; charset=UTF-8 Content-Length: 56 Date: Sun, 23 Aug 2015 08:54:53 GMT [{"status": "disable", "switch_id": "0000000c295fa162"}] |
至此,防火墙已经启动。
更多详细用法可以参考:https://github.com/FlowForwarding/LINC-Switch/blob/master/docs/example-REST-firewall.md
总结:
本文从配置文件开始,对LINC的配置与运行都做了介绍。如果想更加深入LINC,利用LINC进行openflow研究,可以参考github代码中的官方文档去构建testbed,运行demo等。
参考:
https://github.com/FlowForwarding/LINC-Switch/blob/master/docs/LINC_Switch_Quick_Start_Guide.pdf
https://github.com/FlowForwarding/LINC-Switch/blob/master/docs/build_linc_switch.md
https://github.com/FlowForwarding/LINC-Switch/blob/master/docs/example-REST-firewall.md
作者简介:何智刚,2015至今,现为广东的一名在校高三学生,在学习之余,主要研究Docker,OpenStack,SDN,对领域都有所涉猎,目标是迈向full stack。