前言:
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支持:
代码语言:javascript复制{of_config, enabled}
该元组第二个元素可以为disabled。
3.配置逻辑交换机:
一个交换机实体上可以运行多个逻辑交换机,每个逻辑交换机都可以有一个单独的控制器,端口和队列
代码语言:javascript复制{logical_switches,
[
{switch, 0,
[ …..
]},
{switch, 1,
[ …..
]},
{switch, 2,
[ …..
]}
]}
配置逻辑交换机,用户可以指定backend,控制器,端口等内容:
代码语言:javascript复制{switch, 0,
[
{backend, linc_us4},
{controllers, []},
{ports, []},
{queues_status, disabled},
{queues, []}
]}
配置backend(关于什么是backend,请参考“LINC switch架构分析与源码探索”): 启用Openflow1.2的支持:
代码语言:javascript复制{backend, linc_us3},
启用openflow1.3的支持:
代码语言:javascript复制{backend, linc_us4},
配置控制器:
代码语言:javascript复制 {controllers,
[
{"Switch0-DefaultController", "localhost", 6633, tcp}
]},
这里需要指定一个ipv4的地址,端口和协议,默认的端口为6633。实际上,这个可以空着,建议由OF-Config客户端自动配置。
配置input和output的端口: 我们通过ports元组配置ingress和egress端口,但是ingress和egress的端口在配置时看上去并没有任何区别。每个端口的定义中包含:端口编号、接口名称、队列定义和端口带宽。
代码语言:javascript复制{ports,
[
%% {port, 1, [{interface, "eth0"}]},
%% {port, 2, [{interface, "tap0"}]},
%% {port, 3, [{interface, "tap1"}, {ip, "10.0.0.1"}]}
]},
配置队列: 虽然对于openflow并不是必要的,但可以考虑启用它。默认情况下这个特性是关闭的。
代码语言:javascript复制{queues_status, disabled},
同样,元组的第二个元素可以为enabled。如果启用队列,则需要把它们分配给端口并设置合适的速率。比如:
代码语言:javascript复制{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编码的字符串。
代码语言:javascript复制{certificate, ""},
{rsa_private_key, ""}
5.添加netconf支持:
代码语言:javascript复制{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来测试:
代码语言:javascript复制ssh -v -p 1830 -l linc -s 127.0.0.1 netconf
6.添加错误日志记录:
LINC使用lagger库记录日志。
代码语言:javascript复制{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.一个交换机 三个控制器:
代码语言:javascript复制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.两个交换机 不同的控制器:
代码语言:javascript复制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.两个交换机 同一个控制器:
代码语言:javascript复制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:
代码语言:javascript复制root@workgroup3:~/LINC-Switch/rel/linc/bin# ./linc start
这里我们只用Ryu:
代码语言:javascript复制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可以这样:
代码语言:javascript复制root@workgroup3:~/LINC-Switch/rel/linc/bin# ./linc stop
通过REST设置防火墙服务:
LINC可以成为一个基于REST管理的防火墙服务,接下来进行测试: 用config_gen生成一个合适的sys.config(仅测试用):
代码语言:javascript复制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:
代码语言:javascript复制root@workgroup3:~/LINC-Switch/rel/linc/bin# ./linc console
新开终端,进入Ryu的目录启动Ryu:
代码语言:javascript复制root@workgroup3:/usr/local/lib/python2.7/dist-packages/ryu# ryu-manager --verbose --use-stderr app/rest_firewall.py lib/ofctl_v1_2.py
当你看到这句话时即算成功:
代码语言:javascript复制[FW][INFO] dpid=0000000c295fa162: Join as firewall.
同时在Erlang终端可以看到这个:
代码语言:javascript复制(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
测试防火墙是否开启:
代码语言:javascript复制root@workgroup3:~# curl -i -H "Accept: application/json" -X GET http://localhost:8080/firewall/module/status
返回:
代码语言:javascript复制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等。