You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
p2l5wexnu/data/ch_sdn-openbox/sec_sdn.tex

396 lines
16 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

%# -*- coding: utf-8-unix -*-
\section{基于OpenFlow的SDN交换机}
\label{sec:c:sdn-ob:s:sdn}
\subsection{实验目的}
\label{subsec:c:sdn-ob:s:sdn_object}
本实验的主要目的是让学生了解SDN的概念及架构原理掌握OpenFlow协议格式、内容、工作流程及对应功能作用。掌握SDN控制器北向API使用方法可通过API编程获取和设置交换机数据。
\subsection{实验内容}
\label{subsec:c:sdn-ob:s:sdn_content}
使用可编程网络平台及SDN交换机示例框架代码完成OpenFlow协议的部分功能逻辑。验证并分析SDN交换机的工作原理与处理流程。主要完成以下内容
\begin{enumerate}
\item \textbf{阅读协议:}阅读OpenFlow 1.3版本协议白皮书,
掌握其协议内容及对应功能;
\item \textbf{设计实现协议功能:}基于SDN交换机示例框架代码
选择开发OpenFlow协议的部分功能完成逻辑设计与实现
\item \textbf{验证交换机功能:}运行自己的SDN交换机与控制器建立连接
在控制器查询其工作状态与相关协议功能展示。
如交换机基本信息描述、交换机流表状态、
交换机端口状态及计数统计、网络拓扑展示效果;
\item \textbf{检验流表:}验证SDN交换机连接主机间的通信功能
并观察流表内容及变化情况;
\item \textbf{REST API应用}使用实验提供的北向REST API接口查询控制器
获取或设置交换机的不同功能数据;
\item \textbf{定义流表:}使用REST API接口修改流表内容
观察主机的通信情况是否受到影响。
\end{enumerate}
\subsection{实验原理、方法和手段}
\label{subsec:c:sdn-ob:s:sdn_principle}
\subsubsection{SDN交换机工作原理}
SDN是一种新型网络创新架构用于解决传统网络架构中对于网络虚拟化、各类自动化部署以及新型网络协议的问题。
SDN将传统的紧耦合网络设备拆分成了应用、控制和转发三层其中应用和控制层面能够控制网络中数据的流向以及协议控制而底层的网络设备被抽象为了可自定义的转发逻辑实体可被上层应用定义为不同类型的转发设备。
在应用层用户可通过通用、简单的API获取网络信息并可修改转发设备的工作逻辑达到动态改变网络架构与功能的目的。
\subsection{SDN交换机分组处理流程}
\begin{enumerate}
\item \textbf{启动协议通道:}
SDN交换机运行OpenFlow协议代理程序与上层控制器建立通信连接。
交换机解析处理OpenFlow协议
根据协议要求完成协议功能的相关数据收集和配置功能,
构造相应的OpenFlow协议应答控制器
\item \textbf{建立连接:}OpenFlow协议代理运行时
交换机首先和控制器建立连接,
并发送OFP\_HELLO消息用以确认双方都支持的OpenFlow协议版本信息
\item \textbf{查询或设置数据:}
控制器通过OpenFlow的具体消息协议查询或设置交换机其他相关功能的数据
如OFPT\_HELLO、OFPT\_ECHO\_REQUEST、OFPT\_PACKET\_IN、OFPMP\_DESC、
OFPT\_PACKET\_OUT、OFPT\_FLOW\_MOD、OFPT\_PORT\_MOD、OFPMP\_FLOW、OFPMP\_ PORT\_STATS等
\item \textbf{处理转发分组:}当交换机接收到一个数据转发分组时,
提取分组数据中的相关字段组成查表关键字,然后在本地进行流表匹配。
如果匹配成功,则根据流表的动作处理该分组,如从其他端口转发出去;
如果匹配不成功,则会执行默认动作,将分组打包送到控制器;
\item \textbf{PACKET\_IN分组上传}交换机查表不命中或是接收到链路探测报文,
则将该数据封装在OpenFlow的PACKET\_IN消息中上传给控制器
\item \textbf{PACKET\_OUT分组下发}通过PACKET\_IN上传的分组
经过控制器分析处理后会将其封装在OpenFlow协议的PACKET\_OUT消息中
并携带输出端口信息下发到交换机。交换机接收到该消息数据后,
根据输出信息指示,将该分组从指定端口输出。
通过PACKET\_OUT发送的分组数据还包括链路探测协议报文
\item \textbf{FLOW\_MOD消息处理}
控制器通过下发FLOW\_MOD消息给交换机的流表设置转发表项内容
FLOW\_MOD消息中包括分组特征元组信息和动作执行列表。
特征元组通常包括常用的MAC信息、帧类型和五元组信息等
动作通常包括输出端口或丢弃信息等。
\end{enumerate}
\subsection{实验条件}
\label{subsec:c:sdn-ob:s:sdn_requirement}
\begin{itemize}
\item 可编程网络平台一个,测试主机两台,
SDN控制器安装SDN控制器软件Floodlight一台。控制器主机没有两个网口时中间加一个普通交换机
\item 测试主机与控制器主机的网络配置及连接拓扑如图\ref{fig:c:sdn-ob_sdn-topo}所示;
\item 串口线一根,网线三根;
\item SDN交换机框架开发源代码、流表配置Python脚本。
\end{itemize}
\begin{figure}[!ht]
\centering
\includegraphics[width=9cm]{sdn-topo}
\caption{OpenFlow交换机实验拓扑图}
\label{fig:c:sdn-ob_sdn-topo}
\end{figure}
\subsection{实验步骤}
\label{subsec:c:sdn-ob:s:sdn_procedure}
\subsubsection{编译运行SDN交换机验证交换机基本功能}
请参考附录\ref{app:openbox}《FAST平台介绍与操作说明手册》完成。
\subsubsection{基于SDN交换机源码选择实现自己的协议功能}
\begin{enumerate}
\item 修改源代码
\begin{code}[c]
enum ofperr handle_openflow_callback(struct ofp_buffer *ofpbuf,int len)
{
int oftype = ofpbuf->header.type;
LOG_DBG("ofpbuf->header.type=%d\n",ofpbuf->header.type);
switch(oftype)
{
case OFPT_HELLO:
/*用户不实现该类消息处理则直接break函数返回CONTINUE
*由系统库完成后续处理;*/
break;
case OFPT_PACKET_OUT:
/*若用户想实现该消息的处理,则在此处完成对消息的功能逻辑,
*然后直接返回HANDLE表示已经处理库函数直接返回*/
//TO DO 用户在些添加处理逻辑,完成该消息功能
return HANDLE;
//可再增加其他OpenFlow协议的消息类型
}
return CONTINUE;
}
\end{code}
用户可以根据自己的需求选择实现OpenFlow协议的部分消息功能一旦处理了该消息一定要返回消息处理标识HANDLE否则直接break即可。
\item 编译源代码
\begin{code}[console]
root@HNXS-FAST:/home/hnxs/sdn# make
gcc o user_openflow l reg l ua l rule l ofp -lpthread
root@HNXS-FAST:/home/hnxs/sdn# ls
main_openflow.c Makefile user_openflow
root@HNXS-FAST:/home/hnxs/sdn#
\end{code}
\end{enumerate}
\subsubsection{运行修改后的交换机再次验证SDN交换机的功能}
\begin{enumerate}
\item 运行SDN交换机交换机正常工作后输出如下
\begin{code}[console]
root@HNXS-FAST:/home/hnxs/sdn# ./ user_openflow -4 192.168.1.3 -i obx0,obx1,obx2,obx3
\end{code}
\begin{code}[text]
fastU->REG Version:20180827,OpenBox HW Version:2030200722
port_name:eth0,port:0
port_name:obx0,port:0
port_name:obx1,port:1
port_name:obx2,port:2
port_name:obx3,port:3
fastU->librule version:20181015,Default Action:0x40000080
xofp)Connect to SDN Controller [ 192.168.1.3:6653 ] OK!
0_nms_of13)DELETE ALL RULE!
obx0(0x29008) Start...
obx2(0x2e100) Start...
obx3(0x30958) Start...
obx1(0x2b890) Start...
\end{code}
\item 查看控制器界面基本信息在浏览器打开控制器WEB网站http://192.168.1.3/ui/index.html控制界面如图\ref{fig:c:sdn-ob_sdn-main}所示:
\begin{figure}[ht!]
\centering
\includegraphics[width=11cm]{sdn-main}
\caption{SDN主界面信息}
\label{fig:c:sdn-ob_sdn-main}
\end{figure}
\item 查看连接交换机信息,如图\ref{fig:c:sdn-ob_sdn-switch}所示:
\begin{figure}[H]
\centering
\includegraphics[width=11cm]{sdn-switch}
\caption{SDN交换机信息}
\label{fig:c:sdn-ob_sdn-switch}
\end{figure}
\item 查看连接测试主机信息SDN主机及连接信息如图\ref{fig:c:sdn-ob_sdn-host}所示:
\begin{figure}[htp!]
\centering
\includegraphics[width=12cm]{sdn-host}
\caption{SDN主机信息}
\label{fig:c:sdn-ob_sdn-host}
\end{figure}
\item 查看端口状态与计数信息与流表信息,端口与流表信息如图\ref{fig:c:sdn-ob_port-flowtable}所示。交换机流表详细信息查询方法见下一小节描述。
\begin{figure}[htp!]
\centering
\includegraphics[width=12cm]{port-flowtable}
\caption{端口状态与流表计数信息}
\label{fig:c:sdn-ob_port-flowtable}
\end{figure}
\item 查看网络拓扑信息,网络拓扑信息如图\ref{fig:c:sdn-ob_sdn-test-topo}所示:
\begin{figure}[htp!]
\centering
\includegraphics[width=10cm]{sdn-test-topo}
\caption{SDN网络拓扑信息}
\label{fig:c:sdn-ob_sdn-test-topo}
\end{figure}
\end{enumerate}
\subsubsection{在测试主机ping的前后分别观察流表变化}
\begin{enumerate}
\item ping之前的流表信息为空如图\ref{fig:c:sdn-ob_empty-flowtable}所示:
\begin{figure}[htp!]
\centering
\includegraphics[width=10cm]{empty-flowtable}
\caption{空流表信息}
\label{fig:c:sdn-ob_empty-flowtable}
\end{figure}
\item ping之后的流表信息如图\ref{fig:c:sdn-ob_flowtable-ping}所示:
\begin{figure}[htp!]
\centering
\includegraphics[width=10cm]{flowtable-ping}
\caption{ping通后流表信息}
\label{fig:c:sdn-ob_flowtable-ping}
\end{figure}
ping通之后在SDN交换机的流表里多了4条转发流表分别是两个方向的ARP应答报文转发表和两个方向的IP报文转发表具体内容在后面的REST API数据中查验。由此可以说明控制器向SDN交换机注入了四条转发流表允许两边的主机相互ping通。
\end{enumerate}
\subsubsection{使用REST API接口查询交换机的相关功能数据}
\begin{enumerate}
\item 查询交换机基本信息
使用curl命令和对应的REST API地址查询交换机的对应信息。在命令行终端输入如下命令即可查询返回交换机的基本信息数据内容。
\begin{code}[console]
# curl http://192.168.1.3:8080/wm/core/switch/all/desc/json
\end{code}
\begin{code}[json]
{
"desc": {
"version": "OF_13",
"manufacturer_description": "HuNan XinShi NetWork",
"hardware_description": "OpenBox HW 2017",
"software_description": "OpenBox Driver 1.0.0",
"serial_number": "None",
"datapath_description": "None"
}
}
\end{code}
\item 查询端口计数信息
\begin{code}[console]
# curl http://192.168.1.3:8080/wm/core/switch/all/port/json
\end{code}
\begin{code}[json]
{
"port_reply": [{
"version": "OF_13",
"port": [{
"port_number": "local",
"receive_packets": "10957",
"transmit_packets": "1180",
"receive_bytes": "592738",
"transmit_bytes": "143898",
"receive_dropped": "0",
"transmit_dropped": "0",
"receive_errors": "0",
"transmit_errors": "0",
"receive_frame_errors": "0",
"receive_overrun_errors": "0",
"receive_CRC_errors": "0",
"collisions": "0",
"duration_sec": "4294966827",
"duration_nsec": "573987"
},
]
}]
}
\end{code}
端口计数统计信息返回的内容中只摘取显示了一个端口的数据显示,其他端口数据内容已经省略。
\item 查询交换机流表信息
\begin{code}[console]
# curl http://192.168.1.3:8080/wm/core/switch/all/flow/json
\end{code}
\begin{code}[json]
{
"flows": [{
"version": "OF_13",
"cookie": "9007199271518208",
"table_id": "0x0",
"packet_count": "162",
"byte_count": "571400",
"duration_sec": "0",
"duration_nsec": "0",
"priority": "1",
"idle_timeout_s": "5",
"hard_timeout_s": "0",
"flags": [],
"match": {
"in_port": "3",
"eth_dst": "b8:27:eb:d8:83:20",
"eth_src": "b8:27:eb:c1:d1:39",
"eth_type": "0x800",
"ipv4_src": "192.168.2.119",
"ipv4_dst": "192.168.2.111"
},
"instructions": {
"instruction_apply_actions": {
"actions": "output=1"
}
}
},
]
}
\end{code}
交换机流表信息返回的内容中只摘取显示了一条流表的数据显示,其他流表数据内容已经省略。
\end{enumerate}
\subsubsection{修改Python脚本手动配置流表观察测试主机的通信变化}
\begin{enumerate}
\item 修改流表脚本,使其转发端口错误;
修改openflow\_flow-test.py主要修改其流表定义内容其他位置代码无需修改。流表定义内容如下
\begin{code}[python]
flowbe0 = {
'switch':"00:00:00:0a:00:00:08:01",
"table":"0",
"name":"flow-0",
"cookie":"60",
"priority":"1",
"active":"true",
"eth_dst":" b8:27:eb:c1:d1:39", #dmac
"eth_src":" b8:27:eb:d8:83:20", #smac
"eth_type":"0x800", #type
"in_port":"1", #inport
"ipv4_src":"192.168.2.111", #sip
"ipv4_dst":"192.168.2.119", #dip
"actions":"output=2" #执行动作输出端口为2
}
flowbe1 = {
'switch':"00:00:00:0a:00:00:08:01",
"table":"0",
"name":"flow-1",
"cookie":"61",
"priority":"1",
"active":"true",
"eth_dst":"b8:27:eb:d8:83:20", #dmac
"eth_src":"b8:27:eb:c1:d1:39", #smac
"eth_type":"0x800", #type
"in_port":"3", #inport
"ipv4_src":"192.168.2.119", #sip
"ipv4_dst":"192.168.2.111", #dip
"actions":"output=2" #执行动作输出端口为2
}
\end{code}
\item 重启SDN控制器并停止测试主机的ping操作
\item 配置用户流表,脚本执行命令如下:
\begin{code}[console]
# python openflow_flow-test.py
(200, 'OK', '{"status" : "Entry pushed"}')
(200, 'OK', '{"status" : "Entry pushed"}')
\end{code}
脚本执行成功两条流表添加成功在测试主机两边进行ping测试观察是否能够ping通
\item 修改流表脚本,使其转发端口正确,再次验证。
\begin{enumerate}
\item 两种动作分别修改为1进3出和3进1出。添加流表后再重新ping测试观察是否能够ping通
\item 由此说明对于SDN交换机
可以通过用户修改流表的方式来定义某一条具体流的转发行为。
\end{enumerate}
\end{enumerate}
\subsection{思考题}
\label{subsec:c:sdn-ob:s:sdn_rethink}
\begin{enumerate}
\item WEB界面上显示的转发流表是如何生成的分析其生成流程
\item 测试主机第一次ping通的数据处理流程与第二次ping通的数据处理流程有何不同
\item 控制器界面的拓扑图是如何生成的?需要哪些数据?
\end{enumerate}
\subsection{注意事项及有关说明}
\label{subsec:c:sdn-ob:s:sdn_notice}
\begin{enumerate}
\item SDN控制器为JAVA实现有时候WEB存在缓存导致数据显示不及时在流表更新显示两次实验对比先清空历史缓存数据后再显示
\item Python脚本实现了一个http协议的客户端脚本程序通过http协议及REST API的路径请求或设置SDN控制器WEB的对应功能模块获取或设置该模块的返回数据或输入参数传输数据类型为json格式。
\end{enumerate}
\subsection{考核方法}
\label{subsec:c:sdn-ob:s:sdn_criterion}
完成本次实验,需要提交一份实验报告、一份程序源代码和一份程序输出日志。
\begin{enumerate}
\item 20分在规定时间内完成实验并提交实验成果
\item 40分根据实现OpenFlow消息类型的多少计分简单类型5分复杂类型10分
\item 10分通过脚本设置可以实现两个测试主机ping通和不能ping通
\item 20分通过网上搜索学习
使用其他多个REST API查询到了交换机更多的数据内容
\item 10分实验报告与源代码内容完整、格式规范。
\end{enumerate}