1.2使用OpenDaylight界面下发流表

发布时间 2023-06-08 09:03:16作者: ChuenSan

使用OpenDaylight界面下发流表

任务目的

1、掌握YANG UI下发流表的方式,了解YANG UI的功能特点,以及其在OpenDaylight架构中所起的作用。
2、通过下发流表的过程,梳理出数据包处理的简单流程。并且进一步了解单级流表和多级流表的处理过程。

任务环境
设备名称 软件环境(镜像) 硬件环境
控制器 Ubuntu 14.04桌面版 OpenDaylight Lithium CPU:2核 内存:4G 磁盘:20G
交换机 Ubuntu 14.04命令行版 Open vSwitch 2.3.1 CPU:1核 内存:2G 磁盘:20G
主机 Ubuntu14.04命令行版 CPU:1核 内存:2G 磁盘:20G

注:系统默认的账户为:
管理员权限用户名:root,密码:root@openlab;
普通用户用户名:openlab,密码:user@openlab。
可查看当前实验环境右侧“钥匙”img 按钮获取对应的密码。

任务内容

1、比较使用YANG UI下发流表的方法,与直接在交换机中通过命令下流表的方方法,总结两者的异同点。
2、通过YANG UI下发流表控制主机之间的连通性,并且利用scapy工具进行测试验证。
3、分别基于OpenFlow1.0协议和OpenFlow1.3协议下发流表,经过下流表的过程了解单级流表和多级流表的概念。

实验原理

YANG UI是OpenDaylight中一款基于DLUX的应用,旨在简化、激励应用的开发与测试。YANG UI通过动态封装、调用YANG模型和相关REST APIs,生成并展示一个简单的UI界面。开发人员可以通过API请求获取交换机信息,并且以JSON格式展示。YANG UI主要面向上层应用开发,为应用开发人员提供了很多相关工具,有效的节约了开发人员的时间。

OpenFlow1.0协议处理数据包的流程相对简单,因为1.0版本只支持单流表。交换机接收到数据包后解析数据包,数据包解析后就开始匹配,从table 0 开始匹配,如果匹配成功则对该数据包执行相应的动作,更新相应的计数器。如果没有找到匹配项则将数据包交给控制器。

OpenFlow1.3协议支持多流表匹配,即一个交换机只会有多个流表,因此数据包处理过程相对复杂。首先解析进入设备的报文,然后从table 0开始匹配,按照优先级高低依次匹配该流表中的流表项,一个报文在一个流表中只会匹配上一条流表项。通常根据报文的类型,报文头的字段例如源MAC地址、目的MAC地址、源IP地址、目的IP地址等进行匹配,大部分匹配还支持掩码进行更精确、灵活的匹配。也可以通过报文的入端口或元数据信息来进行报文的匹配,一个流表项中可以同时存在多个匹配项,一个报文需要同时匹配流表项中所有匹配项才能匹配该流表项。报文匹配按照现有的报文字段进行,比如前一个流表通过apply actions改变了该报文的某个字段,则下一个表项按修改后的字段进行匹配。如果匹配成功,则按照指令集里的动作更新动作集,或更新报文/匹配集字段,或更新元数据和计数器。根据指令是否继续前往下一个流表,不继续则终止匹配流程执行动作集,如果指令要求继续前往下一个流表则继续匹配,下一个流表的ID需要比当前流表ID大。当报文匹配失败了,如果存在无匹配流表项(table miss)就按照该表项执行指令,一般是将报文转发给控制器、丢弃或转发给其他流表。如果没有table miss表项则默认丢弃该报文。

在Open vSwitch中,流表项作为ovs-ofctl的参数,采用“字段=值”的格式。如果有多个字段,可以用逗号分开,一些常见字段如下:

字段名称 说明
in_port=port 传递数据包的端口的OpenFlow端口编号
dl_vlan=vlan 数据包的VLAN Tag值,范围是0-4095,0xffff代表不包含VLAN Tag的数据包
dl_src= dl_dst= 匹配源或者目标的MAC地址 01:00:00:00:00:00/01:00:00:00:00:00 代表广播地址 00:00:00:00:00:00/01:00:00:00:00:00 代表单播地址
dl_type=ethertype 匹配以太网协议类型,其中: dl_type=0x0800 代表IPv4协议; dl_type=0x086dd 代表IPv6协议; dl_type=0x0806 代表ARP协议;
nw_src=ip[/netmask] nw_dst=ip[/netmask] 当 dl_typ=0x0800 时,匹配源或者目标的IPv4地址,可以使IP地址或者域名
table=number 指定要使用的流表的编号,范围是0-254。在不指定的情况下,默认值为0。通过使用流表编号,可以创建或者修改多个Table中的Flow。
实验步骤

一、实验环境检查

步骤1 登录OpenDaylight控制器,执行命令netstat -an|grep 6633查看端口是否处于监听状态。

img
说明:由于OpenDaylight组件过于庞大,所以服务启动比较慢,需等待一段时间。

步骤2 在保证控制器6633端口处于监听状态后,使用root用户登录交换机,执行set-controller br-sw tcp:30.0.1.3:6633命令连接控制器

注意30.0.1.3是控制器的ip地址

# ovs-vsctl del-controller br-sw
# ovs-vsctl set-controller br-sw tcp:30.0.1.3:6633

img
如上所示,controller下方显示“is_connected:true”,表明连接成功。

步骤3 当交换机与控制器连接成功后,登录主机,执行ifconfig命令,配置主机ip地址

手动配置主机1的IP地址(eth1)如下图所示。
image-20230524153131977
手动配置主机2的IP地址(eth1)如下图所示。
image-20230524153230073
手动配置主机3的IP地址(eth1)如下图所示。
image-20230524153251383
分别执行ifconfig命令查看主机是否配置IP地址成功。

二、基于OpenFlow1.0协议下发流表

步骤1 切换到交换机,执行以下命令设置OpenFlow协议版本为1.0。

ovs-vsctl set bridge br-sw protocols=OpenFlow10

步骤2 选择控制器,单击浏览器图标,打开浏览器。

步骤3 访问OpenDaylight Web页面,url是http://127.0.0.1:8080/index.html,用户名和密码是admin/admin,如下图所示。

image-20230524153325157

步骤4 单击左侧的“Nodes”查看节点信息。其中尤其需要关注Node Id,下发流表的时候会用到Node Id,如下图所示。

image-20230524153352536

步骤5 单击上图中的“Node Connectors”列的数据即“9”,可以查看具体节点连接信息,如下图所示。

img

步骤6 选择左侧的“Yang UI”,单击“Expand all”展开所有目录,查看各种模块,如下图所示。

img

步骤7 展开“opendaylight-inventory rev.2013-08-19”,选择“config ——> nodes ——> node{id} ——> table{id} ——> flow{id}”,如下图所示。

image-20230524153428382

步骤8 补全node id、table id和flow id的值。

其中node id参见之前查询到的Node Id。table id和flow id可以自定义。由于OpenFlow1.0协议只支持单流表,所以这里的table id设置为0,如下图所示。
image-20230524153446913

步骤9 单击flow list后面的“+”,展开流表相关的参数。填写第一个框id,路径中的flow id也会随之同步,如下图所示。

img

步骤10 展开“match ——> ethernet-match ——> ethernet -type”,填写“type”为“0x0800”,如下图所示。

image-20230524153528715
说明:由于使用IP地址进行匹配,所以需要设置以太网协议类型。

步骤11 填写匹配参数,在“layer-3-match”后面的下拉框中选择“ipv4-match”,使用IP匹配。

步骤12 展开“layer-3-match”,填写源IP地址和目的IP地址,如下图所示。

img
其中源地址填写主机1的IP地址,目的地址填写主机2的IP地址。

步骤13 展开“instructions”,并单击“instruction list”后面的“+”,在“instruction”后面下拉框中选择“apply-actions-case”,如下图所示。

image-20230524153551807

步骤14 展开“apply-actions”,单击“action list”后面的“+”,在action后面的下拉框中选择“drop-action-case”,action order和instruction order都设置为0,如下图所示。

image-20230524153616236

步骤15 设置“priority”为27,“idle-timeout”为0,“hard-timeout”为0,“cookie”为100000000,“table_id”为0,如下图所示。

image-20230524153635089
说明:priority设置的比已有流表项的高,而idle-timeout和hardtimeout都设置为0则代表该流表项永远不会过期,除非被删除。

步骤16 向右滚动Actions栏,在路径后面有动作类型GET、PUT、POST、DELETE,下发流表则选择PUT动作,然后单击“Send”,如下图所示。

img

步骤17 如果下发成功会出现下面的提示,如果下发不成功则会弹出相应的错误信息。

img

步骤18 切换到交换机,执行如下命令查看流表,确保刚刚下发的流表已经下发到交换机。如下图所示。

ovs-ofctl dump-flows br-sw

img

步骤19 登录主机1,执行如下命令向主机2、主机3发送数据包,测试主机间的连通性。

# scapy
>>> result,unanswered=sr(IP(dst=”10.0.0.10”,ttl=(3,10))/ICMP())
>>> result,unanswered=sr(IP(dst=”10.0.0.14”,ttl=(3,10))/ICMP())

img
由上图可知,主机1与主机2之间不通,主机1与主机3通,新下发的流表项生效。
说明:如果主机之间通则能够收到answer,如果主机之间不通那么就无法收到answer,当主机之间不通时scapy就会一直发送数据包,如果需要停止可以使用Ctrl+c。

步骤20 切换到交换机,执行以下命令删除刚刚下发的流表项,并查看流表确保成功删除。

# ovs-ofctl del-flows br-sw dl_type=0x0800,nw_src=10.0.0.3,nw_dst=10.0.0.4
# ovs-ofctl dump-flows br-sw

步骤21 切换到主机1执行如下命令,测试主机1和主机2是否连通。

>>> result,unanswered=sr(IP(dst=”10.0.0.10”,ttl=(3,10))/ICMP())

image-20230524153739138
由上图可知,主机1与主机2之间就通了。

三、基于OpenFlow1.3协议下发流表

步骤1 登录交换机,设置OpenFlow协议版本为1.3。执行以下命令:

# ovs-vsctl set bridge br-sw protocols=OpenFlow13

步骤2 与OpenFlow1.0下发流表的过程解基本一致。展开opendaylight-inventory rev.2013-08-19,选择“config ——> nodes ——> node{id} ——> table{id} ——> flow{id}”。

步骤3 补全Actions栏中的路径,其中node id参见之前查询到的Node Id。table id和flow id可以自定义。由于OpenFlow1.3协议支持多级流表,所以这里的table id设置为2。

步骤4 单击flow list后面的“+”,流表相关的参数就会展开。设置id为1,路径中的flow id也会随之同步,如下图所示。

img

步骤5 展开“match ——> ethernet-match ——> ethernet -type”,填写“type”为0x0800,如下图所示。

image-20230524153826327

步骤6 在“layer-3-match”后面的下拉框中选择“ipv4-match”。

步骤7 展开“layer-3-match”,填写源IP地址和目的IP地址。以主机1的IP为源IP,以主机3的IP为目的IP,如下图所示。

image-20230524153844897

步骤8 展开“instructions”,并单击“instruction list”后面的“+”,在“instruction”后面下拉框中选择“apply-actions-case”,如下图所示。

image-20230524153901607

步骤9 展开“apply-actions”,单击“action list”后面的“+”,在“action”后面的下拉框中选择“drop-action-case”,“action order”和“instruction order”都设置为0,如下图所示。

image-20230524153927836

步骤10 设置“priority”为25,“idle-timeout”为0,“hard-timeout”为0,“cookie”为10000000,“table_id”为2,如下图所示。

img

步骤11 向右滚动Actions栏,选择“PUT”动作,然后单击“Send”下发流表。PUT成功就会弹出“Request sent successfully”,否则弹出错误信息。

步骤12 切换到主机1,执行如下命令,向主机3发送数据包,测试主机1和主机3的连通性。

>>> result,unanswered=sr(IP(dst=”10.0.0.14”,ttl=(3,10))/ICMP())

image-20230524154013611
由上图可知,主机1与主机3之间是连通的,新下发的流表没有发挥作用。原因是数据包在table 0中能够匹配到相应流表就不会被转发到table2,想要table2的流表项发挥作用就需要向table0增加一条流表,将源IP为10.0.0.3,目的IP为10.0.0.2的数据包转发到table2中处理。

步骤13 选择“config ——> nodes ——> node{id} ——> table{id} ——> flow{i}”。node id参见之前查询到的Node Id、table id设为0、flow id设为1。

步骤14 展开“match ——> ethernet-match ——> ethernet -type”,填写“type”为0x0800。

步骤15 匹配参数保持不变,以主机1的IP为源IP,以主机3的IP为目的IP。

步骤16 展开“instructions”,并单击“instruction list”后面的“+”,在“instruction”后面下拉框中选择“go-to-table-case”,如下图所示。

img

步骤17 展开“go-to-table”,table_id填写为2,即将符合匹配条件的数据包根据table2中的流表项处理。instruction order依旧设为0,如下图所示。

img

步骤18 设“priority”置为23,“idle-timeout”为0,“hard-timeout”为0,“cookie”为1000000000,“table_id”为0,如下图所示。

img

步骤19 向右滚动Actions栏,选择“PUT”动作,然后单击“Send”下发流表。

步骤20 切换到交换机,执行以下命令查看新下发的流表项。

# ovs-ofctl -O OpenFlow13 dump-flows br-sw

img

步骤21 切换到主机1,执行如下命令发送数据包,测试主机之间的连通性。

>>> result,unanswered=sr(IP(dst=”10.0.0.10”,ttl=(3,10))/ICMP())
>>> result,unanswered=sr(IP(dst=”10.0.0.14”,ttl=(3,10))/ICMP())

img
由上图可知,主机1与主机3之间不通,而主机1与主机2之间通,流表发挥作用。