searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享

OVS Faucet教程(1)

2024-06-07 09:50:27
24
0

1, 部署ovs

  本节介绍如何设置Open vSwitch,方便后面与faucet联合起来使用,搭建整套流控制器和虚拟交换网络 

 1. 使用Git从open vswitch官网获取源码

 2. 构建ovs

$./boot.sh
$./configure
$make-j4

3. 创建ovs 沙箱。使用沙箱的好处是可以避免跟本机在run的ovs冲突

$make sandbox

2. 部署faucet

  通过docker 的方式部署faucet是最方便的手段

$mkdir -p /var/log/faucet/
$docker pull faucet/faucet:latest
$docker run -d \
    --name faucet \
    --restart=always \
    -v /etc/faucet/:/etc/faucet/ \
    -v /var/log/faucet/:/var/log/faucet/ \
    -p 6653:6653 \
    -p 9302:9302 \
    faucet/faucet

Port 6653 用于OpenFlow下发流表, port 9302 用于Prometheus 

3. 使用faucet和ovs建立虚拟网络

现在Open vSwitch和Faucet已经准备好了,我们将通过本教程受用faucet和ovs建立起一个L2的交换网络

我们将通过每一步详细介绍了解从顶部的Faucet到底部的数据平面层,所讨论的功能是如何工作的。从最高到最低级别,这些层和连接它们的软件组件是:

Faucet

作为系统中的最高级别,这是网络配置的来源。

Faucet可以连接到各种监视和性能工具,本教程我们将通过用于配置的Faucet.yaml和用于观察状态(如MAC学习和ARP解析)的Faucet.log来深入了解系统。

The OpenFlow subsystem in Open vSwitch

OpenFlow是由开放网络基金会(Open Networking Foundation)标准化的协议,像Faucet这样的控制器用它来控制Open vSwitch和其他交换机如何处理网络中的数据包。

我们将使用ovs-ofctl来观察或者修改Open vSwitch的OpenFlow行为。我们还将使用ovs-appctl(一个用于与ovs-vswitchd和其他开放的vSwitch守护进程进行通信的实用程序)来查询和控制运行中的ovs守护进程。

此外,默认情况下,OVS沙箱将OpenFlow的Open vSwitch日志记录级别提高到debug的水平,我们只需通过读取其日志文件就可以了解大量有关OpenFlow行为的信息。

Open vSwitch datapath

这实质上是为加速数据包处理而设计的高速缓存。Open vSwitch包括几个不同的数据路径,例如基于Linux内核的数据路径和仅限用户空间的数据路径(有时称为“ DPDK ”数据路径)。

我们将演示如何使用Open vSwitch功能来调试、排除故障和了解整个系统。

Switching

第2层(L2)交换是现代网络的基础。它也非常简单,是一个很好的起点,所以让我们在Faucet中设置一个带有一些VLAN的交换机,看看它在每一层是如何工作的。首先将以下内容输入inst/faucet.yaml:

dps:
    switch-1:
        dp_id: 0x1
        timeout: 3600
        arp_neighbor_timeout: 3600
        interfaces:
            1:
                native_vlan: 100
            2:
                native_vlan: 100
            3:
                native_vlan: 100
            4:
                native_vlan: 200
            5:
                native_vlan: 200
vlans:
    100:
    200:

此配置文件定义了名为Switch-1的单个交换机(“数据路径”或“ DP ”)。交换机有五个端口,编号为1到5。端口1、2和3位于VLAN 100中,端口4和5位于VLAN 2中。Faucet可以通过其数据路径ID(dp_id: 0x1)来识别交换机。

现在重新启动Faucet,以使配置生效,例如:

$sudo docker restart faucet

假设配置更新成功,您现在应该在inst/faucet.log的末尾看到一个新行:

Sep 10 06:44:10 faucet INFO     Add new datapath DPID 1 (0x1)

Faucet现在正在等待一个dp_id为0x1的交换机通过OpenFlow连接到它,因此我们的下一步是创建通过ovs创建一个虚拟交换机,并使其连接到Faucet。切换到签出ovs的终端,并使用make sandbox启动一个沙箱:

----------------------------------------------------------------------
You are running in a dummy Open vSwitch environment.  You can use
ovs-vsctl, ovs-ofctl, ovs-appctl, and other tools to work with the
dummy switch.

Log files, pidfiles, and the configuration database are in the
"sandbox" subdirectory.

Exit the shell to kill the running daemons.
blp@sigabrt:~/nicira/ovs/tutorial(0)$

在sandbox中,创建一个交换机命名为br0,将其datapath-id设置为0x1,向其添加名为P1到P5的模拟端口,并告诉它连接到Faucet控制器:

$ ovs-vsctl add-br br0 \
         -- set bridge br0 other-config:datapath-id=0000000000000001 \
         -- add-port br0 p1 -- set interface p1 ofport_request=1 \
         -- add-port br0 p2 -- set interface p2 ofport_request=2 \
         -- add-port br0 p3 -- set interface p3 ofport_request=3 \
         -- add-port br0 p4 -- set interface p4 ofport_request=4 \
         -- add-port br0 p5 -- set interface p5 ofport_request=5 \
         -- set-controller br0 tcp:127.0.0.1:6653 \
         -- set controller br0 connection-mode=out-of-band

注意:Faucet需要端口处于“打开”状态才能对其进行配置。在低于2.11.0的Open vSwitch版本中,虚拟端口以关闭状态启动。需要强制他们使用以下ovs-appctl命令:

$ ovs-appctl netdev-dummy/set-admin-state up

现在,如果再次查看inst/faucet.log,应该会看到已经识别并配置了新交换机及其端口的Faucet:

Sep 10 06:45:03 faucet.valve INFO     DPID 1 (0x1) switch-1 Cold start configuring DP
Sep 10 06:45:03 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 100 vid:100 ports:Port 1,Port 2,Port 3
Sep 10 06:45:03 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 200 vid:200 ports:Port 4,Port 5
Sep 10 06:45:24 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 1 (1) up
Sep 10 06:45:24 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 2 (2) up
Sep 10 06:45:24 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 3 (3) up
Sep 10 06:45:24 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 4 (4) up
Sep 10 06:45:24 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 5 (5) up

在Open vSwitch端,查看sandbox/ovs-vswitchd.log,可以看到许多相关活动。例如,下面是基本的OpenFlow会话设置和交换机端口和功能的Faucet探针:

rconn|INFO|br0<->tcp:127.0.0.1:6653: connecting...
vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPT_HELLO (OF1.4) (xid=0x1):
 version bitmap: 0x01, 0x02, 0x03, 0x04, 0x05
vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_HELLO (OF1.3) (xid=0xdb9dab08):
 version bitmap: 0x01, 0x02, 0x03, 0x04
vconn|DBG|tcp:127.0.0.1:6653: negotiated OpenFlow version 0x04 (we support version 0x05 and earlier, peer supports version 0x04 and earlier)
rconn|INFO|br0<->tcp:127.0.0.1:6653: connected
vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FEATURES_REQUEST (OF1.3) (xid=0xdb9dab09):
00040|vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPT_FEATURES_REPLY (OF1.3) (xid=0xdb9dab09): dpid:0000000000000001
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS GROUP_STATS QUEUE_STATS
vconn|DBG|tcp:127.0.0.1:6653: received: OFPST_PORT_DESC request (OF1.3) (xid=0xdb9dab0a): port=ANY
vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPST_PORT_DESC reply (OF1.3) (xid=0xdb9dab0a):
 1(p1): addr:aa:55:aa:55:00:14
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 2(p2): addr:aa:55:aa:55:00:15
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 3(p3): addr:aa:55:aa:55:00:16
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 4(p4): addr:aa:55:aa:55:00:17
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 5(p5): addr:aa:55:aa:55:00:18
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br0): addr:42:51:a1:c4:97:45
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max

 

之后,可以看到Faucet删除所有现有流程,然后开始添加新流程:

vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xdb9dab0f): DEL table:255 priority=0 actions=drop
vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xdb9dab10): ADD priority=0 cookie:0x5adc15c0 out_port:0 actions=drop
vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xdb9dab11): ADD table:1 priority=0 cookie:0x5adc15c0 out_port:0 actions=goto_table:2
vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xdb9dab12): ADD table:2 priority=0 cookie:0x5adc15c0 out_port:0 actions=goto_table:

...

OpenFlow

让我们来看看Faucet设置的OpenFlow表。faucet表格布局为:

Table 0
Port-based ACLs

Table 1
Ingress VLAN processing

Table 2
VLAN-based ACLs

Table 3
Ingress L2 processing, MAC learning

Table 4
L3 forwarding for IPv4

Table 5
L3 forwarding for IPv6

Table 6
Virtual IP processing, e.g. for router IP addresses implemented by Faucet

Table 7
Egress L2 processing

Table 8
Flooding

我们dump流表,检查流表情况:

$ ovs-ofctl dump-flows br0

运行这个命令,它会产生许多额外的垃圾,使输出更难阅读。比如统计数据和“ cookie ”值都是相同的。此外,由于历史原因,ovs-ofctl默认使用OpenFlow 1.0.  Faucet和大多数现代控制器使用OpenFlow 1.3,所以最好强制使用OpenFlow 1.3。方便起见,我们自己定义一个shell函数:

$dump-flows(){
  ovs-ofctl-o openflow13--names--no-stat dump-flows “$@”\
    |sed ' S/cookie=0x5ADC15C0,//'
}

我们还可以定义save-flows和diff-flows函数以供以后使用:

$save-flows(){
  ovs-ofctl-oopenflow13--no-names--sort dump-flows “$@”
}
$diff-flows(){
  ovs-ofctl-oopenflow13 diff-flows “$@”|sed ' s/cookie=0x5adc15c0//'
}

现在,让我们来看看我们得到的流以及它们的含义,如下所示:

$dump-flows br0

为了减少硬件交换机上的资源利用率,Faucet将尝试安装最小的OpenFlow表集,以匹配在Faucet.yaml中启用的功能。由于我们只启用了switching,因此最终将只有4个表。如果我们检查inst/faucet.log的内容,Faucet会告诉我们每个表的功能:

Sep 10 06:44:10 faucet.valve INFO     DPID 1 (0x1) switch-1 table ID 0 table config dec_ttl: None exact_match: None match_types: (('eth_dst', True), ('eth_type', False), ('in_port', False), ('vlan_vid', False)) meter: None miss_goto: None name: vlan next_tables: ['eth_src'] output: True set_fields: ('vlan_vid',) size: 32 table_id: 0 vlan_port_scale: 1.5
Sep 10 06:44:10 faucet.valve INFO     DPID 1 (0x1) switch-1 table ID 1 table config dec_ttl: None exact_match: None match_types: (('eth_dst', True), ('eth_src', False), ('eth_type', False), ('in_port', False), ('vlan_vid', False)) meter: None miss_goto: eth_dst name: eth_src next_tables: ['eth_dst', 'flood'] output: True set_fields: ('vlan_vid', 'eth_dst') size: 32 table_id: 1 vlan_port_scale: 4.1
Sep 10 06:44:10 faucet.valve INFO     DPID 1 (0x1) switch-1 table ID 2 table config dec_ttl: None exact_match: True match_types: (('eth_dst', False), ('vlan_vid', False)) meter: None miss_goto: flood name: eth_dst next_tables: [] output: True set_fields: None size: 41 table_id: 2 vlan_port_scale: 4.1
Sep 10 06:44:10 faucet.valve INFO     DPID 1 (0x1) switch-1 table ID 3 table config dec_ttl: None exact_match: None match_types: (('eth_dst', True), ('in_port', False), ('vlan_vid', False)) meter: None miss_goto: None name: flood next_tables: [] output: True set_fields: None size: 32 table_id: 3 vlan_port_scale: 2.1

 

目前,我们有:

Table 0 (vlan)
    Ingress VLAN processing

Table 1 (eth_src)
    Ingress L2 processing, MAC learning

Table 2 (eth_dst)
   Egress L2 processing

Table 3 (flood)
   Flooding

在表0中,我们看到流在每个端口(VLAN_TCI=0x0000/0x1FFF)上识别没有VLAN报头的数据包,push为端口配置的VLAN,并继续流向表3。还有一个回程流以丢弃其他数据包,这实际上意味着如果任何接收的数据包已经具有VLAN报头,则它将被丢弃:

priority=9000,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
priority=9000,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
priority=9000,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
priority=9000,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
priority=9000,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
priority=0 actions=drop

 

注意

语法设置_字段:4196->VLAN_VID很奇怪,而且有些误导。OpenFlow 1.3将VLAN_VID字段定义为13位字段,其中,如果存在VLAN报头,则将第12位设置为1。因此,由于4196是0x1064,该动作设置VLAN值0x64,其十进制是100。

表1从丢弃一些不适当的信息包的流开始,在这种情况下,EtherType 0x9000(Ethernet Configuration Testing Protocol)不应由交换机转发:

table=1, priority=9099,dl_type=0x9000 actions=drop

表1主要用于MAC学习,但控制器尚未学习任何MAC地址。表1也会丢弃一些更不合适的数据包,例如那些来自广播源地址的数据包:

table=1, priority=9099,dl_src=ff:ff:ff:ff:ff:ff actions=drop
table=1, priority=9001,dl_src=0e:00:00:00:00:01 actions=drop
table=1, priority=9000,dl_vlan=100 actions=CONTROLLER:96,goto_table:2
table=1, priority=9000,dl_vlan=200 actions=CONTROLLER:96,goto_table:2
table=1, priority=0 actions=goto_table:2

表2用于将数据包定向到已学习的MAC,但Faucet尚未学习任何MAC,因此它只是将所有数据包发送到表3:

table=2, priority=0 actions=goto_table:3

表3丢弃了更多我们不想转发的数据包,在本例中为STP报文:

table=3, priority=9099,dl_dst=01:00:0c:cc:cc:cd actions=drop
table=3, priority=9099,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=drop

表3实现了泛洪、广播和多播。广播和泛洪的流程很容易理解:如果数据包来自给定端口,并且需要泛洪或广播,则将其输出到同一VLAN中的所有其他端口:

table=3, priority=9004,dl_vlan=100,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p1,output:p2,output:p3
table=3, priority=9004,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5
table=3, priority=9000,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3
table=3, priority=9000,dl_vlan=200 actions=pop_vlan,output:p4,output:p5

还有一些用于处理一些标准形式的多播的流,以及回退丢弃流:

table=3, priority=9003,dl_vlan=100,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3
table=3, priority=9003,dl_vlan=200,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p4,output:p5
table=3, priority=9001,dl_vlan=100,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3
table=3, priority=9002,dl_vlan=100,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3
table=3, priority=9001,dl_vlan=200,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5
table=3, priority=9002,dl_vlan=200,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5
table=3, priority=0 actions=drop

Tracing

OVS允许我们可以查看更具体的内容:跟踪特定数据包通过Open vSwitch所采用的路径。我们可以使用ofproto/trace命令来跟踪数据流。此命令是我们使用ovs-appctl直接发送到ovs-vswitchd demon程序的命令。

注意

ovs-appctl实际上是一个非常简单的JSON-RPC客户端,还可以使用其他一些调用JSON-RPC的实用程序,或者从程序中将其作为API访问。

ovs-vswitchd(8)手册页有很多关于如何使用ofproto/trace的详细信息,但让我们从一个简单的示例开始。

让我们来看看这个小例子的完整输出:

$ovs-appctl ofproto/trace br0 in_port=p1
Flow: in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000

bridge("br0")
-------------
 0. in_port=1,vlan_tci=0x0000/0x1fff, priority 9000, cookie 0x5adc15c0
    push_vlan:0x8100
    set_field:4196->vlan_vid
    goto_table:1
 1. dl_vlan=100, priority 9000, cookie 0x5adc15c0
    CONTROLLER:96
    goto_table:2
 2. priority 0, cookie 0x5adc15c0
    goto_table:3
 3. dl_vlan=100, priority 9000, cookie 0x5adc15c0
    pop_vlan
    output:1
     >> skipping output to input port
    output:2
    output:3

Final flow: unchanged
Megaflow: recirc_id=0,eth,in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000
Datapath actions: push_vlan(vid=100,pcp=0),userspace(pid=0,controller(reason=1,dont_send=1,continuation=0,recirc_id=1,rule_cookie=0x5adc15c0,controller_id=0,max_len=96)),pop_vlan,2,3

输出的第一行,以flow:开头,只是以更详细的形式重复我们的请求,包括被置零的L2字段。

Bridge(“br0”)下的每个编号项目都显示了数据流在表中的流向和操作。例如,我们在表0中看到,数据包与push_vlan报头的流相匹配,将VLAN ID设置为100,并在表1中继续进行进一步处理。在表1中,数据包被发送到控制器以允许进行MAC学习,然后表3将数据包泛洪到同一VLAN中的其他端口。

接下来是摘要信息。显示报文从进入br0以后到出br0整个过程,数据包没有发生变化(总体而言,开始报文打上VLAN tag,然后出去时有去掉了VLAN tag),因此最终报文未发生变化。

0条评论
0 / 1000
h****n
4文章数
1粉丝数
h****n
4 文章 | 1 粉丝

OVS Faucet教程(1)

2024-06-07 09:50:27
24
0

1, 部署ovs

  本节介绍如何设置Open vSwitch,方便后面与faucet联合起来使用,搭建整套流控制器和虚拟交换网络 

 1. 使用Git从open vswitch官网获取源码

 2. 构建ovs

$./boot.sh
$./configure
$make-j4

3. 创建ovs 沙箱。使用沙箱的好处是可以避免跟本机在run的ovs冲突

$make sandbox

2. 部署faucet

  通过docker 的方式部署faucet是最方便的手段

$mkdir -p /var/log/faucet/
$docker pull faucet/faucet:latest
$docker run -d \
    --name faucet \
    --restart=always \
    -v /etc/faucet/:/etc/faucet/ \
    -v /var/log/faucet/:/var/log/faucet/ \
    -p 6653:6653 \
    -p 9302:9302 \
    faucet/faucet

Port 6653 用于OpenFlow下发流表, port 9302 用于Prometheus 

3. 使用faucet和ovs建立虚拟网络

现在Open vSwitch和Faucet已经准备好了,我们将通过本教程受用faucet和ovs建立起一个L2的交换网络

我们将通过每一步详细介绍了解从顶部的Faucet到底部的数据平面层,所讨论的功能是如何工作的。从最高到最低级别,这些层和连接它们的软件组件是:

Faucet

作为系统中的最高级别,这是网络配置的来源。

Faucet可以连接到各种监视和性能工具,本教程我们将通过用于配置的Faucet.yaml和用于观察状态(如MAC学习和ARP解析)的Faucet.log来深入了解系统。

The OpenFlow subsystem in Open vSwitch

OpenFlow是由开放网络基金会(Open Networking Foundation)标准化的协议,像Faucet这样的控制器用它来控制Open vSwitch和其他交换机如何处理网络中的数据包。

我们将使用ovs-ofctl来观察或者修改Open vSwitch的OpenFlow行为。我们还将使用ovs-appctl(一个用于与ovs-vswitchd和其他开放的vSwitch守护进程进行通信的实用程序)来查询和控制运行中的ovs守护进程。

此外,默认情况下,OVS沙箱将OpenFlow的Open vSwitch日志记录级别提高到debug的水平,我们只需通过读取其日志文件就可以了解大量有关OpenFlow行为的信息。

Open vSwitch datapath

这实质上是为加速数据包处理而设计的高速缓存。Open vSwitch包括几个不同的数据路径,例如基于Linux内核的数据路径和仅限用户空间的数据路径(有时称为“ DPDK ”数据路径)。

我们将演示如何使用Open vSwitch功能来调试、排除故障和了解整个系统。

Switching

第2层(L2)交换是现代网络的基础。它也非常简单,是一个很好的起点,所以让我们在Faucet中设置一个带有一些VLAN的交换机,看看它在每一层是如何工作的。首先将以下内容输入inst/faucet.yaml:

dps:
    switch-1:
        dp_id: 0x1
        timeout: 3600
        arp_neighbor_timeout: 3600
        interfaces:
            1:
                native_vlan: 100
            2:
                native_vlan: 100
            3:
                native_vlan: 100
            4:
                native_vlan: 200
            5:
                native_vlan: 200
vlans:
    100:
    200:

此配置文件定义了名为Switch-1的单个交换机(“数据路径”或“ DP ”)。交换机有五个端口,编号为1到5。端口1、2和3位于VLAN 100中,端口4和5位于VLAN 2中。Faucet可以通过其数据路径ID(dp_id: 0x1)来识别交换机。

现在重新启动Faucet,以使配置生效,例如:

$sudo docker restart faucet

假设配置更新成功,您现在应该在inst/faucet.log的末尾看到一个新行:

Sep 10 06:44:10 faucet INFO     Add new datapath DPID 1 (0x1)

Faucet现在正在等待一个dp_id为0x1的交换机通过OpenFlow连接到它,因此我们的下一步是创建通过ovs创建一个虚拟交换机,并使其连接到Faucet。切换到签出ovs的终端,并使用make sandbox启动一个沙箱:

----------------------------------------------------------------------
You are running in a dummy Open vSwitch environment.  You can use
ovs-vsctl, ovs-ofctl, ovs-appctl, and other tools to work with the
dummy switch.

Log files, pidfiles, and the configuration database are in the
"sandbox" subdirectory.

Exit the shell to kill the running daemons.
blp@sigabrt:~/nicira/ovs/tutorial(0)$

在sandbox中,创建一个交换机命名为br0,将其datapath-id设置为0x1,向其添加名为P1到P5的模拟端口,并告诉它连接到Faucet控制器:

$ ovs-vsctl add-br br0 \
         -- set bridge br0 other-config:datapath-id=0000000000000001 \
         -- add-port br0 p1 -- set interface p1 ofport_request=1 \
         -- add-port br0 p2 -- set interface p2 ofport_request=2 \
         -- add-port br0 p3 -- set interface p3 ofport_request=3 \
         -- add-port br0 p4 -- set interface p4 ofport_request=4 \
         -- add-port br0 p5 -- set interface p5 ofport_request=5 \
         -- set-controller br0 tcp:127.0.0.1:6653 \
         -- set controller br0 connection-mode=out-of-band

注意:Faucet需要端口处于“打开”状态才能对其进行配置。在低于2.11.0的Open vSwitch版本中,虚拟端口以关闭状态启动。需要强制他们使用以下ovs-appctl命令:

$ ovs-appctl netdev-dummy/set-admin-state up

现在,如果再次查看inst/faucet.log,应该会看到已经识别并配置了新交换机及其端口的Faucet:

Sep 10 06:45:03 faucet.valve INFO     DPID 1 (0x1) switch-1 Cold start configuring DP
Sep 10 06:45:03 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 100 vid:100 ports:Port 1,Port 2,Port 3
Sep 10 06:45:03 faucet.valve INFO     DPID 1 (0x1) switch-1 Configuring VLAN 200 vid:200 ports:Port 4,Port 5
Sep 10 06:45:24 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 1 (1) up
Sep 10 06:45:24 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 2 (2) up
Sep 10 06:45:24 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 3 (3) up
Sep 10 06:45:24 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 4 (4) up
Sep 10 06:45:24 faucet.valve INFO     DPID 1 (0x1) switch-1 Port 5 (5) up

在Open vSwitch端,查看sandbox/ovs-vswitchd.log,可以看到许多相关活动。例如,下面是基本的OpenFlow会话设置和交换机端口和功能的Faucet探针:

rconn|INFO|br0<->tcp:127.0.0.1:6653: connecting...
vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPT_HELLO (OF1.4) (xid=0x1):
 version bitmap: 0x01, 0x02, 0x03, 0x04, 0x05
vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_HELLO (OF1.3) (xid=0xdb9dab08):
 version bitmap: 0x01, 0x02, 0x03, 0x04
vconn|DBG|tcp:127.0.0.1:6653: negotiated OpenFlow version 0x04 (we support version 0x05 and earlier, peer supports version 0x04 and earlier)
rconn|INFO|br0<->tcp:127.0.0.1:6653: connected
vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FEATURES_REQUEST (OF1.3) (xid=0xdb9dab09):
00040|vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPT_FEATURES_REPLY (OF1.3) (xid=0xdb9dab09): dpid:0000000000000001
n_tables:254, n_buffers:0
capabilities: FLOW_STATS TABLE_STATS PORT_STATS GROUP_STATS QUEUE_STATS
vconn|DBG|tcp:127.0.0.1:6653: received: OFPST_PORT_DESC request (OF1.3) (xid=0xdb9dab0a): port=ANY
vconn|DBG|tcp:127.0.0.1:6653: sent (Success): OFPST_PORT_DESC reply (OF1.3) (xid=0xdb9dab0a):
 1(p1): addr:aa:55:aa:55:00:14
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 2(p2): addr:aa:55:aa:55:00:15
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 3(p3): addr:aa:55:aa:55:00:16
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 4(p4): addr:aa:55:aa:55:00:17
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 5(p5): addr:aa:55:aa:55:00:18
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max
 LOCAL(br0): addr:42:51:a1:c4:97:45
     config:     0
     state:      LIVE
     speed: 0 Mbps now, 0 Mbps max

 

之后,可以看到Faucet删除所有现有流程,然后开始添加新流程:

vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xdb9dab0f): DEL table:255 priority=0 actions=drop
vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xdb9dab10): ADD priority=0 cookie:0x5adc15c0 out_port:0 actions=drop
vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xdb9dab11): ADD table:1 priority=0 cookie:0x5adc15c0 out_port:0 actions=goto_table:2
vconn|DBG|tcp:127.0.0.1:6653: received: OFPT_FLOW_MOD (OF1.3) (xid=0xdb9dab12): ADD table:2 priority=0 cookie:0x5adc15c0 out_port:0 actions=goto_table:

...

OpenFlow

让我们来看看Faucet设置的OpenFlow表。faucet表格布局为:

Table 0
Port-based ACLs

Table 1
Ingress VLAN processing

Table 2
VLAN-based ACLs

Table 3
Ingress L2 processing, MAC learning

Table 4
L3 forwarding for IPv4

Table 5
L3 forwarding for IPv6

Table 6
Virtual IP processing, e.g. for router IP addresses implemented by Faucet

Table 7
Egress L2 processing

Table 8
Flooding

我们dump流表,检查流表情况:

$ ovs-ofctl dump-flows br0

运行这个命令,它会产生许多额外的垃圾,使输出更难阅读。比如统计数据和“ cookie ”值都是相同的。此外,由于历史原因,ovs-ofctl默认使用OpenFlow 1.0.  Faucet和大多数现代控制器使用OpenFlow 1.3,所以最好强制使用OpenFlow 1.3。方便起见,我们自己定义一个shell函数:

$dump-flows(){
  ovs-ofctl-o openflow13--names--no-stat dump-flows “$@”\
    |sed ' S/cookie=0x5ADC15C0,//'
}

我们还可以定义save-flows和diff-flows函数以供以后使用:

$save-flows(){
  ovs-ofctl-oopenflow13--no-names--sort dump-flows “$@”
}
$diff-flows(){
  ovs-ofctl-oopenflow13 diff-flows “$@”|sed ' s/cookie=0x5adc15c0//'
}

现在,让我们来看看我们得到的流以及它们的含义,如下所示:

$dump-flows br0

为了减少硬件交换机上的资源利用率,Faucet将尝试安装最小的OpenFlow表集,以匹配在Faucet.yaml中启用的功能。由于我们只启用了switching,因此最终将只有4个表。如果我们检查inst/faucet.log的内容,Faucet会告诉我们每个表的功能:

Sep 10 06:44:10 faucet.valve INFO     DPID 1 (0x1) switch-1 table ID 0 table config dec_ttl: None exact_match: None match_types: (('eth_dst', True), ('eth_type', False), ('in_port', False), ('vlan_vid', False)) meter: None miss_goto: None name: vlan next_tables: ['eth_src'] output: True set_fields: ('vlan_vid',) size: 32 table_id: 0 vlan_port_scale: 1.5
Sep 10 06:44:10 faucet.valve INFO     DPID 1 (0x1) switch-1 table ID 1 table config dec_ttl: None exact_match: None match_types: (('eth_dst', True), ('eth_src', False), ('eth_type', False), ('in_port', False), ('vlan_vid', False)) meter: None miss_goto: eth_dst name: eth_src next_tables: ['eth_dst', 'flood'] output: True set_fields: ('vlan_vid', 'eth_dst') size: 32 table_id: 1 vlan_port_scale: 4.1
Sep 10 06:44:10 faucet.valve INFO     DPID 1 (0x1) switch-1 table ID 2 table config dec_ttl: None exact_match: True match_types: (('eth_dst', False), ('vlan_vid', False)) meter: None miss_goto: flood name: eth_dst next_tables: [] output: True set_fields: None size: 41 table_id: 2 vlan_port_scale: 4.1
Sep 10 06:44:10 faucet.valve INFO     DPID 1 (0x1) switch-1 table ID 3 table config dec_ttl: None exact_match: None match_types: (('eth_dst', True), ('in_port', False), ('vlan_vid', False)) meter: None miss_goto: None name: flood next_tables: [] output: True set_fields: None size: 32 table_id: 3 vlan_port_scale: 2.1

 

目前,我们有:

Table 0 (vlan)
    Ingress VLAN processing

Table 1 (eth_src)
    Ingress L2 processing, MAC learning

Table 2 (eth_dst)
   Egress L2 processing

Table 3 (flood)
   Flooding

在表0中,我们看到流在每个端口(VLAN_TCI=0x0000/0x1FFF)上识别没有VLAN报头的数据包,push为端口配置的VLAN,并继续流向表3。还有一个回程流以丢弃其他数据包,这实际上意味着如果任何接收的数据包已经具有VLAN报头,则它将被丢弃:

priority=9000,in_port=p1,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
priority=9000,in_port=p2,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
priority=9000,in_port=p3,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4196->vlan_vid,goto_table:1
priority=9000,in_port=p4,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
priority=9000,in_port=p5,vlan_tci=0x0000/0x1fff actions=push_vlan:0x8100,set_field:4296->vlan_vid,goto_table:1
priority=0 actions=drop

 

注意

语法设置_字段:4196->VLAN_VID很奇怪,而且有些误导。OpenFlow 1.3将VLAN_VID字段定义为13位字段,其中,如果存在VLAN报头,则将第12位设置为1。因此,由于4196是0x1064,该动作设置VLAN值0x64,其十进制是100。

表1从丢弃一些不适当的信息包的流开始,在这种情况下,EtherType 0x9000(Ethernet Configuration Testing Protocol)不应由交换机转发:

table=1, priority=9099,dl_type=0x9000 actions=drop

表1主要用于MAC学习,但控制器尚未学习任何MAC地址。表1也会丢弃一些更不合适的数据包,例如那些来自广播源地址的数据包:

table=1, priority=9099,dl_src=ff:ff:ff:ff:ff:ff actions=drop
table=1, priority=9001,dl_src=0e:00:00:00:00:01 actions=drop
table=1, priority=9000,dl_vlan=100 actions=CONTROLLER:96,goto_table:2
table=1, priority=9000,dl_vlan=200 actions=CONTROLLER:96,goto_table:2
table=1, priority=0 actions=goto_table:2

表2用于将数据包定向到已学习的MAC,但Faucet尚未学习任何MAC,因此它只是将所有数据包发送到表3:

table=2, priority=0 actions=goto_table:3

表3丢弃了更多我们不想转发的数据包,在本例中为STP报文:

table=3, priority=9099,dl_dst=01:00:0c:cc:cc:cd actions=drop
table=3, priority=9099,dl_dst=01:80:c2:00:00:00/ff:ff:ff:ff:ff:f0 actions=drop

表3实现了泛洪、广播和多播。广播和泛洪的流程很容易理解:如果数据包来自给定端口,并且需要泛洪或广播,则将其输出到同一VLAN中的所有其他端口:

table=3, priority=9004,dl_vlan=100,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p1,output:p2,output:p3
table=3, priority=9004,dl_vlan=200,dl_dst=ff:ff:ff:ff:ff:ff actions=pop_vlan,output:p4,output:p5
table=3, priority=9000,dl_vlan=100 actions=pop_vlan,output:p1,output:p2,output:p3
table=3, priority=9000,dl_vlan=200 actions=pop_vlan,output:p4,output:p5

还有一些用于处理一些标准形式的多播的流,以及回退丢弃流:

table=3, priority=9003,dl_vlan=100,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3
table=3, priority=9003,dl_vlan=200,dl_dst=33:33:00:00:00:00/ff:ff:00:00:00:00 actions=pop_vlan,output:p4,output:p5
table=3, priority=9001,dl_vlan=100,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3
table=3, priority=9002,dl_vlan=100,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p1,output:p2,output:p3
table=3, priority=9001,dl_vlan=200,dl_dst=01:80:c2:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5
table=3, priority=9002,dl_vlan=200,dl_dst=01:00:5e:00:00:00/ff:ff:ff:00:00:00 actions=pop_vlan,output:p4,output:p5
table=3, priority=0 actions=drop

Tracing

OVS允许我们可以查看更具体的内容:跟踪特定数据包通过Open vSwitch所采用的路径。我们可以使用ofproto/trace命令来跟踪数据流。此命令是我们使用ovs-appctl直接发送到ovs-vswitchd demon程序的命令。

注意

ovs-appctl实际上是一个非常简单的JSON-RPC客户端,还可以使用其他一些调用JSON-RPC的实用程序,或者从程序中将其作为API访问。

ovs-vswitchd(8)手册页有很多关于如何使用ofproto/trace的详细信息,但让我们从一个简单的示例开始。

让我们来看看这个小例子的完整输出:

$ovs-appctl ofproto/trace br0 in_port=p1
Flow: in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000

bridge("br0")
-------------
 0. in_port=1,vlan_tci=0x0000/0x1fff, priority 9000, cookie 0x5adc15c0
    push_vlan:0x8100
    set_field:4196->vlan_vid
    goto_table:1
 1. dl_vlan=100, priority 9000, cookie 0x5adc15c0
    CONTROLLER:96
    goto_table:2
 2. priority 0, cookie 0x5adc15c0
    goto_table:3
 3. dl_vlan=100, priority 9000, cookie 0x5adc15c0
    pop_vlan
    output:1
     >> skipping output to input port
    output:2
    output:3

Final flow: unchanged
Megaflow: recirc_id=0,eth,in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=00:00:00:00:00:00,dl_type=0x0000
Datapath actions: push_vlan(vid=100,pcp=0),userspace(pid=0,controller(reason=1,dont_send=1,continuation=0,recirc_id=1,rule_cookie=0x5adc15c0,controller_id=0,max_len=96)),pop_vlan,2,3

输出的第一行,以flow:开头,只是以更详细的形式重复我们的请求,包括被置零的L2字段。

Bridge(“br0”)下的每个编号项目都显示了数据流在表中的流向和操作。例如,我们在表0中看到,数据包与push_vlan报头的流相匹配,将VLAN ID设置为100,并在表1中继续进行进一步处理。在表1中,数据包被发送到控制器以允许进行MAC学习,然后表3将数据包泛洪到同一VLAN中的其他端口。

接下来是摘要信息。显示报文从进入br0以后到出br0整个过程,数据包没有发生变化(总体而言,开始报文打上VLAN tag,然后出去时有去掉了VLAN tag),因此最终报文未发生变化。

文章来自个人专栏
紫金DPU弹性裸金属
2 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
2
1