LOADING

Follow me

Floodlight API简介及应用【zoues.com】
六月 14, 2017|ITPaaSSDN

Floodlight API简介及应用【zoues.com】

Floodlight API简介及应用【zoues.com】

作者简介:黄志文,福州大学数计学院2014级计算机科学与技术(实验班)本科生,研究侧重于数据平面可编程化。

一、背景

Floodlight是Apache授权并且基于JAVA开发的企业级OpenFlow控制器,它的稳定性、易用性已经得到SDN专业人士以及爱好者们的一致好评,并因其完全开源,这让SDN网络世界变得更加有活力。控制器作为SDN网络中的重要组成部分,能集中地灵活控制SDN网络,为核心网络及应用创新提供了良好的扩展平台。
Floodlight API简介及应用
Floodlight提供的API接口主要有:ACL、防火墙、静态流表、虚拟网。

二、环境

三、访问控制(ACL)

Floodlight包含以响应方式执行ACL的防火墙应用程序。控制器通过监视Packet-in消息来响应性地执行ACL规则,然后推送流表。然而,通过主动添加ACL规则方式,控制器执行ACL规则而不用监视Packet-in消息,从而避免额外的延迟。 ACL应用程序解析用户的REST更新ACL请求,并以主动的方式通过静态流表强制执行,而无需监视Packet-in消息。删除相关的ACL规则时,还可以及时删除生成的ACL流表。

增加ACL规则:

Java

1
curl X POST d ‘{“src-ip”:”10.0.0.1/32″,”dst-ip”:”10.0.0.2/32″,”action”:”deny”}’ http://controller_ip:8080/wm/acl/rules/json

显示所有ACL规则:

Java

1
curl http://controller_ip:8080/wm/acl/rules/json | python -mjson.tool

删除ACL规则:

Java

1
curl X DELETE d ‘{“ruleid”:”1″ }’ http://controller_ip:8080/wm/acl/rules/json

删除所有ACL规则:

Java

1
curl http://controller_ip:8080/wm/acl/clear/json

ACL规则的属性:

属性 类型 备注
 nw-protp               string TCP或UDP或ICMP
src-ip ipv4地址[/子网掩码] 必填
dst-ip ipv4地址[/子网掩码] 必填
tp-dst number nw-proto ==“TCP”或“UDP”时有效。
action string “DENY” 或者 “ALLOW”,没有指定默认”DENY”

注意点:

  • 较早添加的ACL规则有较高的优先级
  • ACL由静态流表组成
  • Src-ip Dst-ip必填

四、静态流表(Static Entry Pusher)

用户通过REST API公开的Floodlight模块,允许用户手动将流表和组下发到OpenFlow网络。

OpenFlow支持两种流下发方式:主动和被动。当数据包到达没有匹配流的OpenFlow交换机时,就会发生响应流表下发。数据包被发送到控制器,它对其进行分析,添加适当的流表,并让交换机继续转发。或者,在数据包到达之前,可以通过控制器在交换机中主动下发流表。Floodlight支持两种机制。Static Entry Pusher通常用于响应式。

请注意,默认情况下,Floodlight会加载响应流表下发的Forwading模块。可以从floodlight.properties文件中删除转发。

下发流表:

Java

1
curl X POST d ‘{“switch”:”00:00:00:00:00:00:00:01″, “name”:”flow-mod-1″, “cookie”:”0″, “priority”:”32768″, “in_port”:”1″,”active”:”true”, “actions”:”output=2″}’ http://controller_ip:8080/wm/staticentrypusher/json

查看流表:

Java

1
curl http://controller_ip:8080/wm/staticentrypusher/list/00:00:00:00:00:00:00:01/json

查看所有流表:

Java

1
curl http://controller_ip:8080/wm/staticentrypusher/list/all/json

清空某一交换机上的所有流表:

Java

1
curl http://controller_ip:8080/wm/staticentrypusher/clear/00:00:00:00:00:00:00:01/json

清空所有流表:

Java

1
curl http://controller_ip:8080/wm/staticentrypusher/clear/all/json

删除流表:

Java

1
curl X DELETE d ‘{“name”:”flow-mod-1″}’ http://controller_ip:8080/wm/staticentrypusher/json

必须输入的属性:

属性

类型

备注

name

string

唯一,作为流表的主键

switch

switch DPIP

格式:xx:xx:xx:xx:xx:xx:xx:xx

entry_type

string

“flow” 或者 “group”,未填默认flow

保留端口关键字:

保留端口

备注

all

所有的端口

flood

所有的端口,除了入端口和禁止flood的端口

in_port

数据包入端口

local

本地网络栈交换机端口

normal

交换机L2/L3 pipeline

any

任一交换机端口

controller

控制器端口

可选动作:

属性

类型

必要条件

支持OF版本

备注

output

number/保留端口

 

all

没有丢包选项

set_vlan_vid

number

eth_vlan_vid = something 

1.0

十六进制(0x开头)或十进制

set_eth_src

MAC地址

 

1.0-1.1

xx:xx:xx:xx:xx:xx

set_eth_dst

MAC地址

 

1.0-1.1

xx:xx:xx:xx:xx:xx

set_ipv4_src

IPv4 [/mask]

eth_type = 0x0800

1.0-1.1

xx.xx.xx.xx

set_ipv4_dst

IPv4 [/mask]

eth_type = 0x0800

1.0-1.1

xx.xx.xx.xx

group

number

 

1.1+

十六进制(0x开头)或十进制

enqueue

number:number

 

1.0

第一个数字是端口号,第二个则是队列号。十六进制(0x开头)或十进制

set_queue

number

 

1.1_

十六进制(0x开头)或十进制

strip_vlan

 

eth_vlan_vid = something

1.0

 

set_vlan_pcp

number

eth_vlan_vid = something

1.0

 

set_vlan_pcp

number

eth_vlan_vid = something

all

十六进制(0x开头)或十进制

push_vlan

eth-type-number

 

1.1+

十六进制(0x开头)或十进制。必须单独执行来设置VLAN ID

pop_vlan

 

eth_vlan_vid = something

1.1+

 

set_ip_tos

number

eth_type = 0x0800 || 0x86dd

1.0

十六进制(0x开头)或十进制

set_ip_ecn

number

eth_type = 0x0800 || 0x86dd

1.0

十六进制(0x开头)或十进制

set_ip_ttl

number

eth_type = 0x0800 || 0x86dd

1.1+

十六进制(0x开头)或十进制

dec_ip_ttl

 

eth_type = 0x0800 || 0x86dd

1.1+

十六进制(0x开头)或十进制

copy_ip_ttl_in

 

eth_type = 0x0800 || 0x86dd

1.1+

 

copy_ip_ttl_out

 

eth_type = 0x0800 || 0x86dd

1.1+

 

set_mpls_label

number

eth_type = 0x8847 || 0x8848

1.1+

十六进制(0x开头)或十进制

set_mpls_tc

number

eth_type = 0x8847 || 0x8848

1.1+

十六进制(0x开头)或十进制

set_mpls_ttl

number

eth_type = 0x8847 || 0x8848

1.1+

十六进制(0x开头)或十进制

dec_mpls_ttl

 

eth_type = 0x8847 || 0x8848

1.1+

 

push_mpls

number

 

1.1+

十六进制(0x开头)或十进制

pop_mpls

number

eth_type = 0x8847 || 0x8848

1.1+

十六进制(0x开头)或十进制

push_pbb

number

 

1.1+

十六进制(0x开头)或十进制

pop_pbb

 

eth_type = 0x88e7

1.1+

 

set_tp_src

number

ip_proto = 0x06 || 0x11 || 0x84

1.0

十六进制(0x开头)或十进制

set_tp_dst

number

ip_proto = 0x06 || 0x11 || 0x84

1.0

十六进制(0x开头)或十进制

set_field

OXM-value

See match table above.

1.2+

例 "set_field=eth_src-00:11:22:33:44:55"

meter

number

 

1.5+

替换"instruction_goto_meter"
十六进制(0x开头)或十进制

copy_field

copy field

 

1.5+

JSON object.:

{
    "src_field" : "eth_src",
    "dst_field" : "eth_dst",
    "src_offset_bits" : "0",
    "dst_offset_bits" : "0",
    "num_bits" : "48"
}

set_tp_src

number

ip_proto = 0x06 || 0x11 || 0x84

1.0

十六进制(0x开头)或十进制

可选匹配项:

属性

类型

必要条件

支持OF版本

备注

in_port

number/保留端口

 

all

 

eth_type

number

 

all

十六进制(0x开头)或十进制

eth_src

MAC地址

 

all

xx:xx:xx:xx:xx:xx

eth_dst

MAC地址

 

all

xx:xx:xx:xx:xx:xx

ip_proto

number

eth_type = 0x0800 || 0x86dd

all

十六进制(0x开头)或十进制

ipv4_src

IPv4 [/mask]

eth_type = 0x0800

all

 

xx.xx.xx.xx[/xx]

ipv4_dst

IPv4 [/mask]

eth_type = 0x0800

all

 

xx.xx.xx.xx[/xx]

tp_src

number

ip_proto = 0x06 || 0x11 || 0x84

 

UDP,TCP,SCTP

tp_dst

number

ip_proto = 0x06 || 0x11 || 0x84

 

UDP,TCP,SCTP

eth_vlan_vid

number

 

all

必须在匹配值中包含当前位(bit 12),例:要匹配标记0x0064,请使用0x1064
十六进制(0X开头)或十进制.

eth_vlan_pcp

number

eth_vlan_vid = something

all

十六进制(0X开头)或十进制.

ipv6_src

IPv6 [/mask]

eth_type = 0x86dd

1.2+

xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx[/xx]

ipv6_dst

IPv6 [/mask]

eth_type = 0x86dd

1.2+

xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx[/xx]

ipv6_label

number

eth_type = 0x86dd

1.2+

十六进制(0X开头)或十进制.

ip_tos

number

eth_type = 0x0800 || 0x86dd

all

十六进制(0X开头)或十进制.

ip_ecn

number

eth_type = 0x0800 || 0x86dd

all

十六进制(0X开头)或十进制.

ip_dscp

number

eth_type = 0x0800 || 0x86dd

all

十六进制(0X开头)或十进制. 

udp_src

number

ip_proto = 0x11

all

UDP

udp_dst

number

ip_proto = 0x11

all

UDP

tcp_src

number

ip_proto = 0x06

all

TCP

tcp_dst

number

ip_proto = 0x06

all

TCP

sctp_src

number

ip_proto = 0x84

all

SCTP

sctp_dst

number

ip_proto = 0x84

all

SCTP

icmpv4_type

number

ip_proto = 0x01

1.2+

十六进制(0X开头)或十进制.

icmpv4_code

number

ip_proto = 0x01

1.2+

十六进制(0X开头)或十进制.

icmpv6_type

number

ip_proto = 0x3a

1.2+

十六进制(0X开头)或十进制.

icmpv6_code

number

ip_proto = 0x3a

1.2+

十六进制(0X开头)或十进制.

ipv6_nd_sll

MAC

icmpv6_type = 0x87

1.2+

xx:xx:xx:xx:xx:xx

ipv6_nd_tll

MAC

icmpv6_type = 0x88

1.2+

xx:xx:xx:xx:xx:xx

ipv6_nd_target

IPv6

icmpv6_type = 0x87 || 0x88

1.2+

xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx

ipv6_exthdr

number

eth_type = 0x86dd

1.3+

十六进制(0X开头)或十进制.

arp_opcode

number

eth_type = 0x0806

1.2+

十六进制(0X开头)或十进制.

arp_sha

MAC

eth_type = 0x0806

1.2+

xx:xx:xx:xx:xx:xx

arp_tha

MAC

eth_type = 0x0806

1.2+

xx:xx:xx:xx:xx:xx

arp_spa

IPv4

eth_type = 0x0806

1.2+

xx.xx.xx.xx

arp_tpa

IPv4

eth_type = 0x0806

1.2+

xx.xx.xx.xx

mpls_label

number

eth_type = 0x8847 || 0x8848

1.2+

十六进制(0X开头)或十进制.

mpls_tc

number

eth_type = 0x8847 || 0x8848

1.2+

十六进制(0X开头)或十进制.

mpls_bos

boolean

eth_type = 0x8847 || 0x8848

1.3+

"true" or "false"

pbb_uca

boolean

 

1.3+

"true" or "false"

tunnel_id

number

 

1.3+

十六进制(0X开头)或十进制.

tunnel_ipv4_src

IPv4

 

1.3+

xx.xx.xx.xx
OVS使用的NXM

tunnel_ipv4_dst

IPv4

 

1.3+

xx.xx.xx.xx
OVS使用的NXM

metadata

number

 

1.2+

十六进制(0X开头)或十进制.

tcp_flags

number

ip_proto = 0x06

 1.5+

十六进制(0X开头)或十进制.

actset_output

number
reserved_port

 

 1.5+

十六进制(0X开头)或十进制.

packet_type

number/number

 

 1.5+

Must take form ns/ns_type, where both ns and ns_type are numbers.
十六进制(0X开头)或十进制.

sctp_dst

number

ip_proto = 0x84

all

SCTP only.

icmpv4_type

number

ip_proto = 0x01

 1.2+

十六进制(0X开头)或十进制.

icmpv4_code

number

ip_proto = 0x01

 1.2+

十六进制(0X开头)或十进制.

icmpv6_type

number

ip_proto = 0x3a

 1.2+

十六进制(0X开头)或十进制.

icmpv6_code

number

ip_proto = 0x3a

 1.2+

十六进制(0X开头)或十进制.

ipv6_nd_sll

MAC

icmpv6_type = 0x87

 1.2+

xx:xx:xx:xx:xx:xx

ipv6_nd_tll

MAC

icmpv6_type = 0x88

 1.2+

xx:xx:xx:xx:xx:xx

ipv6_nd_target

IPv6

icmpv6_type = 0x87 || 0x88

 1.2+

xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx

ipv6_exthdr

number

eth_type = 0x86dd

 1.3+

十六进制(0X开头)或十进制.

arp_opcode

number

eth_type = 0x0806

 1.2+

十六进制(0X开头)或十进制.

arp_sha

MAC

eth_type = 0x0806

 1.2+

xx:xx:xx:xx:xx:xx

arp_tha

MAC

eth_type = 0x0806

 1.2+

xx:xx:xx:xx:xx:xx

arp_spa

IPv4

eth_type = 0x0806

 1.2+

xx.xx.xx.xx

arp_tpa

IPv4

eth_type = 0x0806

 1.2+

xx.xx.xx.xx

mpls_label

number

eth_type = 0x8847 || 0x8848

 1.2+

十六进制(0X开头)或十进制.

mpls_tc

number

eth_type = 0x8847 || 0x8848

 1.2+

十六进制(0X开头)或十进制.

mpls_bos

boolean

eth_type = 0x8847 || 0x8848

 1.3+

"true" or "false"

pbb_uca

boolean

 

 1.3+

"true" or "false"

tunnel_id

number

 

 1.3+

十六进制(0X开头)或十进制.

tunnel_ipv4_src

IPv4

 

 1.3+

xx.xx.xx.xx
NXM used by OVS.

tunnel_ipv4_dst

IPv4

 

 1.3+

xx.xx.xx.xx
NXM used by OVS.

metadata

number

 

 1.2+

十六进制(0X开头)或十进制.

tcp_flags

number

ip_proto = 0x06

 1.5+

十六进制(0X开头)或十进制.

actset_output

number
reserved_port

 

 1.5+

十六进制(0X开头)或十进制.

packet_type

number/number

 

 1.5+

1
采取ns / ns_type形式,其中nsns_type都是数字。

十六进制(0X开头)或十进制.

arp_spa

IPv4

eth_type = 0x0806

 1.2+

xx.xx.xx.xx

arp_tpa

IPv4

eth_type = 0x0806

 1.2+

xx.xx.xx.xx

mpls_label

number

eth_type = 0x8847 || 0x8848

 1.2+

十六进制(0X开头)或十进制.

mpls_tc

number

eth_type = 0x8847 || 0x8848

 1.2+

十六进制(0X开头)或十进制.

mpls_bos

boolean

eth_type = 0x8847 || 0x8848

 1.3+

"true" or "false"

五、防火墙(Firewall)

显示防火墙是启用还是禁用。

Java

1
curl http:// controller_ip:8080/wm/firewall/module/status/json

开启防火墙,默认拒绝所有的通信除非增加ALLOW规则:

Java

1
curl http:// controller_ip:8080/wm/firewall/module/enable/json -X PUT -d ”

为IP主机10.0.0.3和主机10.0.1.5之间的所有流添加ALLOW规则。不指定操作意味着允许规则:

Java

1
2
curl X POST d ‘{“src-ip”: “10.0.0.3/32”, “dst-ip”: “10.0.0.7/32”}’ http:// controller_ip:8080/wm/firewall/rules/json
curl X POST d ‘{“src-ip”: “10.0.0.7/32”, “dst-ip”: “10.0.0.3/32”}’ http:// controller_ip:8080/wm/firewall/rules/json

六、虚拟网(Virtual Network Filter)

创建名为“VirtualNetwork1”的虚拟网络,ID为“NetworkId1”,网关为“10.0.0.7”,租户为“默认”(目前被忽略):

Java

1
curl X PUT d ‘{ “network”: { “gateway”: “10.0.0.7”, “name”: “virtualNetwork1” } }’ http://localhost:8080/networkService/v1.1/tenants/default/networks/NetworkId1

将主机添加到MAC地址为“00:00:00:00:00:08”的VirtualNetwork1和端口“port1”:

Java

1
curl X PUT d ‘{“attachment”: {“id”: “NetworkId1”, “mac”: “00:00:00:00:00:08”}}’ http://localhost:8080/networkService/v1.1/tenants/default/networks/NetworkId1/ports/port1/attachment

七、应用场景

如图所示的网络拓扑环境:
Floodlight API简介及应用
实现可添加/删除 TCP/UDP 数据报控制项,每一控制项可设定以下 3 个选项:协议类型TCP或 UDP),源 IP,目的端口。实现匹配控制项的网络数据阻断(从 h1 或 h2 发送至 server 服务器的数据报)。(注意:目的 IP 不是 server 服务器 IP 的数据报不受影响)

举例说明:假设 h1 的 IP 为 192.168.10.1, 可在程序界面增加以下控制项:{TCP,192.168.10.1, 22},从而使得所有来自 h1 的、目的 IP 为 server 服务器且目的端口为 22 的 TCP 数据报均被拦截。

解决方案:
编写简单的shell脚本调用floodlight API来实现所需功能。

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
!/bin/sh
 
opr=$1
proto=$3
ip=$4
port=$5
name=$2
if [ “$opr” = “add” ]&&[ “$proto” = “tcp” ]; then
curl X POST d ‘{“switch”:”00:00:00:00:00:00:00:01″, “name”:”‘${name}‘”, “cookie”:”0″, “priority”:”32768″,”eth_type”:”0x0800″,”ip_proto”:”0x06″,”tcp_dst”:”‘${port}‘”,”ipv4_dst”:”10.0.0.3″,”ipv4_src”:”‘${ip}‘”,”active”:”true”, “actions”:”output=4″}’ http://10.0.2.15:8080/wm/staticentrypusher/json
curl http://10.0.2.15:8080/wm/staticentrypusher/list/00:00:00:00:00:00:00:01/json
elif [ “$opr” = “add” ]&&[ “$proto” = “udp” ]; then
curl X POST d ‘{“switch”:”00:00:00:00:00:00:00:01″, “name”:”‘${name}‘”, “cookie”:”0″, “priority”:”32768″,”eth_type”:”0x0800″,”ip_proto”:”0x11″,”udp_dst”:”‘${port}‘”,”ipv4_dst”:”10.0.0.3″,”ipv4_src”:”‘${ip}‘”,”active”:”true”, “actions”:”output=4″}’ http://10.0.2.15:8080/wm/staticentrypusher/json
curl http://10.0.2.15:8080/wm/staticentrypusher/list/00:00:00:00:00:00:00:01/json
else [ “$opr” = “del” ]
curl X DELETE d ‘{“name”:”‘${name}‘”}’ http://10.0.2.15:8080/wm/staticentrypusher/json
curl http://10.0.2.15:8080/wm/staticentrypusher/list/00:00:00:00:00:00:00:01/json
fi

在/mininet/custuom/文件夹下写一个生成自定义网络拓扑的Python脚本3h-1s.py来实现的拓扑。

Java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from mininet.topo import Topo
 
from mininet.cli import CLI
from mininet.log import lg, info
 
class MyTopo( Topo ):
    “Simple topology example.”
    def __init__( self ):
        “Create custom topo.”
        # Initialize topology
        Topo.__init__( self )
        # Add hosts and switches
        h1 = self.addHost( ‘h1’ )
        h2 = self.addHost( ‘h2’ )
        server = self.addHost( ‘server’ )
        s1 = self.addSwitch( ‘s1’ )
        # Add links
        self.addLink( s1, h1 )
        self.addLink( s1, h2 )
        self.addLink( s1, server )
topos = { ‘mytopo’: ( lambda: MyTopo() ) }

打开终端,创建网络拓扑,同时与控制器建立连接,如图所示:
Floodlight API简介及应用
通过xterm命名分别打开server主机和h1主机,在server下发命令。
Floodlight API简介及应用
再用iperf将主机server设为server,将主机h1设为client。
Floodlight API简介及应用
Floodlight API简介及应用
由图可知,在流表下发之后,server和h1无法在端口22建立TCP连接,证明实现了匹配控制项的网络数据的阻断。

通过shell脚本调用Floodlight北向API 删除静态流表。
Floodlight API简介及应用
用iperf验证流表是否删除。
Floodlight API简介及应用
Floodlight API简介及应用
由图可知,在删除流表之后,server和h1在端口22建立TCP连接,证明实现了匹配流表的删除。

no comments
Share

发表评论