增加第五单元

tmp/e55771d673c71e872ed5dc71b8109184/head
xphi 4 years ago
parent 4febba7f19
commit 0bd5ecc9b5

1
.gitignore vendored

@ -24,3 +24,4 @@ _minted-*
*.exe
*.obj
*.listing
settings.json

@ -64,7 +64,7 @@ BGP是自治系统间的路由协议是一种外部网关协议
\begin{figure}[!ht]
\centering
\includegraphics[width=8cm]{switch-topo}
\includegraphics[width=12cm]{networking-topo}
\caption{三层路由组网实验拓扑图}
\label{fig:c:router-ob_networking-topo}
\end{figure}

@ -78,7 +78,7 @@
\begin{figure}[!ht]
\centering
\includegraphics[width=8cm]{switch-topo}
\includegraphics[width=8cm]{router-topo}
\caption{三层路由器实验拓扑图}
\label{fig:c:router-ob_router-topo}
\end{figure}

@ -6,23 +6,224 @@
\subsection{实验目的}
\label{subsec:c:sdn-ob:s:ns_object}
本实验的主要目的是让学生掌握网络测试的常用原理及方法,
了解在测试过程中影响测量精度的原因及如何提高测量精度。
了解软硬件结果的测量方法与优势。
\subsection{实验内容}
\label{subsec:c:sdn-ob:s:ns_content}
使用可编程网络平台及用户应用AMS自动测量系统软件源代码
对网络远端的服务器进行RTT延时测量和带宽测量
测量不同长度网线的数据传输时长。主要完成以下内容:
\begin{enumerate}
\item 测量RTT时长使用AMS软件测量一台校园网内服务器的RTT时间
测量报文使用ping协议文本
\item 测量带宽:在测量网络中添加一台可编程网络平台,
配置为带宽响应测量模式,测量这两个节点之间的实时网络流量,
并用不同测量报文大小来验证测量结果;
\item 测量网线时延:测量不同长度网线的数据传输时延,
根据测量结果分析本系统的测量优势与局限;
\item 添加软件计时测量:修改测量报文代码,
在开始发送时取系统时间做为软件发送时间,
在接收到报文后为每个报文设置系统接收时间计算软件的RTT时间。
\end{enumerate}
\subsection{实验原理、方法和手段}
\label{subsec:c:sdn-ob:s:ns_principle}
\subsubsection{测量原理}
网络测量主要是通过时间和数据量相关和相对的关系来反映网络中的各种特性,
如带宽、延时、抖动和丢包等。
网络测量的分类标准有多种。根据测量的方式分为:
主动测量和被动测量;根据测量点的多少分为:单点测量与多点测量;
根据被测量者知情与否分为:协作式测量与非协作式测量;
根据测量所采用的协议分为基于BGP协议的测量、
基于TCP/IP协议的测量以及基于SNMP协议的测量
根据测量的内容分为:拓扑测量与性能测量。
\subsubsection{可编程网络平台的测量特征}
本实验的测量最主要方法是由软件构造测量报文和设定发送报文的时刻表,
由硬件在指定时间进行报文发送,并在接收获得回应报文后标记硬件的接收时刻。
接收数据由软件汇总统计计数,与原发送数据进行时间关联,
计算测量结果。硬件的时间控制精度为8ns
故测量数据的收发时间均控制在8ns误差范围内。
根据时间的精准控制,扩展出硬件背靠背发包测试网络带宽,
精准周期发包测量精准抖动。
\subsubsection{测量流程}
\begin{enumerate}
\item \textbf{软件构造测量报文:}根据测量要求,软件构造测量报文,
报文内容由用户决定。如果测量通用服务器可以使用ping报文
\item \textbf{软件设置测量报文的发送间隔:}软件设备每个测量报文的发送间隔,
间隔时间可以是零,表示硬件背靠背发送报文;
\item \textbf{软件发送测量报文到硬件缓存:}软件将所有测量报文构造好后,
通过分组发送函数发送到硬件缓存。硬件最大缓存32个MTU为1500的分组数据
\item \textbf{软件启动发送:}所有测量分组发送到硬件完成后,
软件可以随时启动发送,通过写硬件状态寄存器的方式通知硬件开始发送测量报文;
\item \textbf{硬件根据时间参数严格输出测量报文:}
硬件从开始接收到发送标记时刻开始发送第一个报文,
然后根据报文携带的间隔时间,循环等待,直到下一个报文发送时刻,
将该报文依次发送出去;
\item \textbf{硬件接收测量响应报文,标记硬件时间戳:}
等待测量响应服文返回,当接收到任何响应报文后,
硬件均会在报文的头部添加本址硬件时间戳信息,然后将该报文发送给软件;
\item \textbf{软件接收报文:}软件根据测量要求,循环接收测量响应报文,
如ping 32个报文后需要接收到32个响应报文
\item \textbf{软件计算测量结果:}测量响应报文接收完成后,
将之前设置的测量配置参数(各报文发送间隔)、
硬件开始发送报文时间戳和接收报文内的时间戳等信息汇总起来进行计算,
得到测量结果后打印输出。
\end{enumerate}
\subsection{实验条件}
\label{subsec:c:sdn-ob:s:ns_requirement}
\begin{itemize}
\item 可编程网络平台两个,被测试服务器一台;
连接拓扑如图\ref{fig:c:sdn-ob_ns-topo}所示;
\item 串口线一根,网线多根;
\item AMS软件源代码
\end{itemize}
\begin{figure}[!ht]
\centering
\includegraphics[width=9cm]{ns-topo}
\caption{高精度网络测量实验拓扑图}
\label{fig:c:sdn-ob_ns-topo}
\end{figure}
\subsection{实验步骤}
\label{subsec:c:sdn-ob:s:ns_procedure}
\begin{enumerate}
\item 测试平台与被测量主机间的连接性,在平台\texttt{ping 192.168.1.111}
\begin{code}[console]
root@HNXS-FAST:/home/hnxs/ams# ping 192.168.1.111
PING 192.168.1.111 (192.168.1.111) 56(84) bytes of data.
64 bytes from 192.168.1.111: icmp_seq=1 ttl=64 time=1.57 ms
64 bytes from 192.168.1.111: icmp_seq=2 ttl=64 time=1.60 ms
64 bytes from 192.168.1.111: icmp_seq=3 ttl=64 time=1.74 ms
^C
--- 192.168.1.111 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 1.576/1.640/1.746/0.088 ms
\end{code}
\item 运行AMS测量命令测量服务RTT的命令如下
\begin{code}[console]
root@HNXS-FAST:/home/hnxs/ams# ams 192.168.1.111 5 70 1000000000
fastU->REG Version:20180827,OpenBox HW Version:2030200722
FAST UA REG->from pid:1068,state:21,mid:131
fastU->Register UA to FAST Kernel! Wait Reply......
fastU->UA->pid:1068,mid:131,Register OK!
fastU->libua version:20180827
fastU->librule version:20181015,Default Action:0x40000080
wait for ams pkts...
fastU->fast_ua_recv......
\end{code}
系统输出如上信息说明AMS运行成功并发送5个70字节大小的ping报文出去默认间隔为1秒。等待ping响应回来。
\item 观察RTT测量结果
\begin{code}[text]
AMS ID PKT_SIZE TS(ns)
0, 70, 1583184
1, 70, 1625224
2, 70, 1707240
3, 70, 1492256
4, 70, 1650272
\end{code}
观察测量结果计算结果在1.5ms左右与之前的ping测试结果相差不大。
\item 测试两个测量平台之间的实时网络带宽
\begin{code}[console]
root@HNXS-FAST:/home/hnxs/ams# ams 192.168.1.111 5 100 0
fastU->REG Version:20180827,OpenBox HW Version:2030200722
FAST UA REG->from pid:1068,state:21,mid:131
fastU->Register UA to FAST Kernel! Wait Reply......
fastU->UA->pid:1068,mid:131,Register OK!
fastU->libua version:20180827
fastU->librule version:20181015,Default Action:0x40000080
wait for ams pkts...
fastU->fast_ua_recv......
\end{code}
测试之前要在此链路中间增加一个背景流使用iperf的UDP流大小为600Mbps
系统给服务器发送5个100字节大小的ping报文出去默认间隔为1秒。
\item 观察带宽测试结果
\begin{code}[text]
AMS ID PKT_SIZE BW(bps)
0, 70, 341467254
\end{code}
Iperf的背景流设置参数为600M时其实际带宽会跑到648Mbps左右。
链路上只有两种数据流,该测量值只是某个测量小时段的带宽反馈,
UDP流也存在不稳定性故其结果相加不可能完全是1000Mbps。
其相加结果与千兆带宽基本相等。
\item 测量网线传输延时
\begin{code}[console]
root@HNXS-FAST:/home/hnxs/ams# ams
fastU->REG Version:20180827,OpenBox HW Version:2030200722
FAST UA REG->from pid:1068,state:21,mid:131
fastU->Register UA to FAST Kernel! Wait Reply......
fastU->UA->pid:1068,mid:131,Register OK!
fastU->libua version:20180827
fastU->librule version:20181015,Default Action:0x40000080
wait for ams pkts...
fastU->fast_ua_recv......
\end{code}
网络测量时需要连接在设备的0和1号端口上默认测量32组数据。
\item 观察网线测量结果
\begin{code}[text]
AMS ID PKT_SIZE TS(ns)
0, 100, 20194
1, 100, 20214
2, 100, 20210
3, 100, 20216
4, 100, 20202
\end{code}
从数据分析每组测量结果有些误差,但基本
\item 分析测量数据的差异
\begin{enumerate}
\item 对相同测试案例进行多组测量,观察数据变化。
\item 分析RTT测量时软件计时测量与硬件计时测量的差异。
\end{enumerate}
\end{enumerate}
\subsection{思考题}
\label{subsec:c:sdn-ob:s:ns_rethink}
\begin{enumerate}
\item 硬件背靠背报文发送是什么意思?其测量的原理是什么?
\item 通过硬件方式测量多组延时数据,为什么仍有较大波动?
\item 如何测量网络的抖动?
\end{enumerate}
\subsection{注意事项及有关说明}
\label{subsec:c:sdn-ob:s:ns_notice}
\begin{enumerate}
\item 测量服务器的PING延时需要修改发包内容为正确的PING报文内容。
\item 测量报文的间隔可以设置为零,但真正发包时的发包时刻计算却不是零,
是因为硬件报文是逐个逐个发送的,且每个报文发送时间长短与其报文长度相关。
\item 时间计算与带宽计算中均用到了除法,引入了误差。
硬件时钟本身是存在误差(时钟飘移)的,也会引入计数的误差。
\end{enumerate}
\subsection{考核方法}
\label{subsec:c:sdn-ob:s:ns_criterion}
完成本次实验,需要提交一份实验报告和一分程序输出日志。
\begin{enumerate}
\item 20分在规定时间内完成实验并提交实验成果
\item 25分实现软件计时测量与硬件测量对比
\item 25分将多线测量结果以图形曲线形式汇总并做分析总结
\item 20分完成网络抖动测量并做图形化汇总统计
\item 10分实验报告与源代码内容完整、格式整洁。
\end{enumerate}

@ -6,23 +6,587 @@
\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}
\subsection{SDN交换机工作原理}
SDN即Software Defined Network软件定义网络
是一种新型网络创新架构,用于解决传统网络架构中对于网络虚拟化、
各类自动化部署以及新型网络协议的问题。
SDN将传统的紧耦合网络设备被拆分成了应用、控制、转发三层
其中应用和控制层面能够控制网络中数据的流向以及协议控制,
而底层的网络设备被抽象为了可自定义的转发逻辑实体,
可被上层应用定义为不同类型的转发设备。
在应用层用户可通过通用、简单的API获取网络信息
并可修改转发设备的工作逻辑,达到动态改变网络架构的目的。
\subsection{SDN交换机分组处理流程}
\begin{enumerate}
\item \textbf{启动协议通道:}
SDN交换机运行OpenFlow协议代理程序与上层控制器建立通信连接。
交换机解析处理OpenFlow协议
根据协议要求完成协议功能的相关数据收集和配置功能,
构造相应的OpenFlow协议应答控制器。
\item \textbf{建立连接:}OpenFlow协议代理运行时
交换机首先和控制器建立连接,
并发送OFP\_HELLO消息用以确认双方都支持的OFP协议版本信息
\item \textbf{查询或设置数据:}
控制器通过OpenFlow的具体消息协议查询或设置交换机其他相关功能的数据
如OFPT\_HELLO、OFPT\_ECHO\_REQUEST、OFPT\_PACKET\_IN、OFPT\_PACKET\_OUT、
OFPT\_FLOW\_MOD、OFPT\_PORT\_MOD、OFPMP\_DESC、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一台。
网络配置及连接拓扑如图\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}:《可编程网络平台-操作手册》完成。
\subsubsection{基于SDN交换机源码选择实现自己的协议功能}
\begin{enumerate}
\item 修改源代码
\begin{code}[c]
enum ofperr handle_openflow_callback(struct ofp_buffer *ofpbuf,int len)
{
int oftype = ofpbuf->header.type;
SHOW_FUN(0);
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
fastU->REG Version:20180827,OpenBox HW Version:2030200722
port_name:eth0,port:0
port_name:obx0,port:0
xofp uses obsolete (PF_INET,SOCK_PACKET)
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!
eth0 ADD!
obx0 ADD!
obx1 ADD!
obx2 ADD!
obx0(0x29008) Start...
obx2(0x2e100) Start...
obx3(0x30958) Start...
obx1(0x2b890) Start...
obx3 ADD!
\end{code}
\item 查看控制器界面基本信息,
在浏览器打开控制器WEB网站\url{http://192.168.1.3/ui/index.html}
控制界面如图\ref{fig:c:sdn-ob_sdn-switch}所示:
\begin{figure}[!htp]
\centering
\includegraphics[width=14cm]{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=14cm]{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=14cm]{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=14cm]{sdn-test-topo}
\caption{SDN网络拓扑信息}
\label{fig:c:sdn-ob_sdn-test-topo}
\end{figure}
\end{enumerate}
\subsubsection{在测试主机ping的前后分别观察流表变化}
\begin{enumerate}
\item ping之前的流表信息使用REST API方式获取其json数据
如图\ref{fig:c:sdn-ob_empty-flowtable}所示:
\begin{figure}[!htp]
\centering
\includegraphics[width=14cm]{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=14cm]{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 查询交换机基本信息
\begin{code}[console]
# curl http://192.168.1.3:8080/wm/core/switch/\
00:00:00:0a:00:00:08:01/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/\
00:00:00:0a:00:00:08:01/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"
}, {
"port_number": "1",
"receive_packets": "86",
"transmit_packets": "205",
"receive_bytes": "11427",
"transmit_bytes": "22632",
"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": "573991"
}, {
"port_number": "2",
"receive_packets": "0",
"transmit_packets": "0",
"receive_bytes": "0",
"transmit_bytes": "0",
"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": "573992"
}, {
"port_number": "3",
"receive_packets": "616",
"transmit_packets": "220",
"receive_bytes": "56948",
"transmit_bytes": "24659",
"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": "573994"
}, {
"port_number": "4",
"receive_packets": "0",
"transmit_packets": "0",
"receive_bytes": "0",
"transmit_bytes": "0",
"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": "573995"
}]
}]
}
\end{code}
\item 查询交换机流表信息
\begin{code}[console]
# curl http://192.168.1.3:8080/wm/core/switch/\
00:00:00:0a:00:00:08:01/flow/json
\end{code}
\begin{code}[json]
{
"flows": [{
"version": "OF_13",
"cookie": "9007199254740992",
"table_id": "0x0",
"packet_count": "5",
"byte_count": "571392",
"duration_sec": "0",
"duration_nsec": "0",
"priority": "1",
"idle_timeout_s": "5",
"hard_timeout_s": "0",
"flags": [],
"match": {
"in_port": "1",
"eth_dst": "b8:27:eb:c1:d1:39",
"eth_src": "b8:27:eb:d8:83:20",
"eth_type": "0x806"
},
"instructions": {
"instruction_apply_actions": {
"actions": "output=3"
}
}
}, {
"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"
}
}
}, {
"version": "OF_13",
"cookie": "9007199288295424",
"table_id": "0x0",
"packet_count": "161",
"byte_count": "571408",
"duration_sec": "0",
"duration_nsec": "0",
"priority": "1",
"idle_timeout_s": "5",
"hard_timeout_s": "0",
"flags": [],
"match": {
"in_port": "1",
"eth_dst": "b8:27:eb:c1:d1:39",
"eth_src": "b8:27:eb:d8:83:20",
"eth_type": "0x800",
"ipv4_src": "192.168.2.111",
"ipv4_dst": "192.168.2.119"
},
"instructions": {
"instruction_apply_actions": {
"actions": "output=3"
}
}
}, {
"version": "OF_13",
"cookie": "9007199305072640",
"table_id": "0x0",
"packet_count": "2",
"byte_count": "571416",
"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": "0x806"
},
"instructions": {
"instruction_apply_actions": {
"actions": "output=1"
}
}
}]
}
\end{code}
\end{enumerate}
\subsubsection*{修改Python脚本手动配置流表观察测试主机的通信变化}
\begin{enumerate}
\item 修改流表脚本,使其转发端口错误
\begin{code}[console]
#vim openflow_flow-test.py
\end{code}
\begin{code}[python]
import httplib
import json
class StaticFlowPusher(object):
def __init__(self, server):
self.server = server
def get(self, data):
ret = self.rest_call({}, 'GET')
return json.loads(ret[2])
def set(self, data):
ret = self.rest_call(data, 'POST')
return ret[0] == 200
def remove(self, objtype, data):
ret = self.rest_call(data, 'DELETE')
return ret[0] == 200
def rest_call(self, data, action):
path = '/wm/staticflowpusher/json'
headers = {
'Content-type': 'application/json',
'Accept': 'application/json',
}
body = json.dumps(data)
conn = httplib.HTTPConnection(self.server, 8080)
conn.request(action, path, body, headers)
response = conn.getresponse()
ret = (response.status, response.reason, response.read())
print ret
conn.close()
return ret
pusher = StaticFlowPusher('192.168.1.3')
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
#"ip_proto":"0x11", #proto
"in_port":"1", #inport
"ipv4_src":"192.168.2.111", #sip
"ipv4_dst":"192.168.2.119", #dip
#"tp_src":"50001", #sport
#"tp_dst":"50001", #dport
"actions":"output=2" #正确值应该为3
}
flowbe1 = {
'switch':"00:00:00:0a:00:00:08:01",
"table":"1",
"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
#"ip_proto":"0x11", #proto
"in_port":"3", #inport
"ipv4_src":"192.168.2.119", #sip
"ipv4_dst":"192.168.2.111", #dip
#"tp_src":"50001", #sport
#"tp_dst":"50001", #dport
"actions":"output=2" #正确值应该为1
}
pusher.set(flowbe0)
pusher.set(flowbe1)
\end{code}
脚本执行命令如下:
\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 20分通过脚本设置可以实现两个测试主机ping能和不能ping通
\item 20分通过网上搜索学习
使用其他多个REST~API查询到了交换机更多的数据内容
\item 10分实验报告与源代码内容完整、格式整洁。
\end{enumerate}

@ -6,23 +6,168 @@
\subsection{实验目的}
\label{subsec:c:sdn-ob:s:topo_object}
本实验的主要目的是让学生了解OpenFlow协议中PACKET\_IN和链路探测协议
LLDP的工作原理和网络拓扑构建方法。
\subsection{实验内容}
\label{subsec:c:sdn-ob:s:topo_content}
使用可编程网络平台及SDN交换机源码分析LLDP的工作原理。
通过PACKET\_IN消息收集网络设备节点信息。
掌握网络拓扑的构建方法。主要完成以下内容:
\begin{enumerate}
\item \textbf{打印连接主机信息:}基于SDN交换机源码
在端口分组接收回调函数中添加相关逻辑,
解析输入分组数据提取设备MAC与IP信息打印显示其内容
\item \textbf{打印接收LLDP消息}基于SDN交换机源码
在端口分组接收回调函数中添加相关逻辑,
解析输入分组数据打印LLDP分组的相关协议字段
\item \textbf{打印发送LLDP消息}基于SDN交换机源码
在OpenFlow协议回调函数中添加相关逻辑
提取SDN控制器下发的PACKET\_OUT消息且消息封装的分组协议为LLDP格式
打印输出LLDP分组中的相关协议字段
\item \textbf{提取控制器链路与设备信息:}
使用REST~API接口获取SDN控制器的网络链路信息和设备连接信息
\item \textbf{构建拓扑图:}以WEB形式展示网络拓扑结构图
\item \textbf{修改网络验证:}改变物理网络拓扑结构后,
重新展示学习到的网络拓扑结构图。
\end{enumerate}
\subsection{实验原理、方法和手段}
\label{subsec:c:sdn-ob:s:topo_principle}
\subsubsection{LLDP工作原理}
LLDP是一个用于信息通告和获取的协议但是需要注意的一点是
LLDP发送的信息通告不需要确认不能发送一个请求来请求获取某些信息
也就是说LLDP是一个单向的协议只有主动通告一种工作方式
无需确认,不能查询、请求。
LLDP协议主要完成的功能有初始化并维护本地MIB 库中的信息;
从本地MIB 库中提取信息并将信息封装到LLDP帧中。
LLDP帧的发送有两种触发方式一是定时器到期触发一是设备状态发生了变化触发
识别并处理接收到的LLDPDU帧维护远端设备LLDP MIB 信息库;
当本地或远端设备MIB信息库中有信息发生变化时发出通告事件。
网络拓扑的测量是通过一些链路探测协议在各交换节点中相互收发来完成的链路的拓扑测量功能。
SDN交换机使用LLDP链路探测协议主要是通过PACKET\_OUT消息发送LLDP分组
通过PACKET\_IN接收LLDP分组通过计算获取交换机之间的连通关系和端口连接关系。
\subsubsection{SDN交换机中LLDP的分组处理流程}
\begin{enumerate}
\item 主动发送LLDP
SDN控制器主动构造特定的LLDP报文含交换机标记与输出端口信息
封装在OpenFlow的PACKET\_OUT方法中从指定的交换机各端口发送出去
\item 接收处理LLDP如果端口连接的是主机则主机会丢弃该报文
若同样是OpenFlow交换机则会通过PACKET\_IN的方式将该LLDP报文转发给控制器
\item LLDP学习控制器收到LLDP报文后
则会学习到这两个交换机之间存在一条连接链路;
\item 网络设备信息学习:主机连接到交换机后,
主机端会主动构造一些广播报文发送到网络上,
这些报文会携带上本机的MAC地址和IP地址等信息
交换机接收到主机发送报文后,在其交换流表中找不到转发表项,
则会将该报文完整内容和其所输入的端口信息封装在OpenFlow协议的PACKET\_IN方法中
将报文送到SDN控制器控制器接收到该消息后
通过学习对比发现是一台新主机入网则会将该报文中的源MAC地址、
IP地址和接收交换机信息及输入端口信息等均记录在一张网络设备信息数据表中
\item 构建设备连接关系:
交换机之间的链路信息加上交换机与主机之间的链路信息就完整的构成了全网的拓扑连接关系。
\end{enumerate}
\subsection{实验条件}
\label{subsec:c:sdn-ob:s:topo_requirement}
\begin{itemize}
\item 网络创新实验平台两个交换测试主机两台SDN控制器一台。
连接拓扑如图\ref{fig:c:sdn-ob_openflow-topo}所示;
\item 串口线一根,网线五根;
\item 网络创新实验平台使用手册、开发环境;
\item OpenFlow拓扑实验环境配置手册
\end{itemize}
\begin{figure}[!ht]
\centering
\includegraphics[width=10cm]{openflow-topo}
\caption{OpenFlow拓扑测量实验拓扑图}
\label{fig:c:sdn-ob_openflow-topo}
\end{figure}
\subsection{实验步骤}
\label{subsec:c:sdn-ob:s:topo_procedure}
\begin{enumerate}
\item 运行SDN交换机
请参考附件《可编程网络平台-操作手册》完成。
\item 基于SDN交换机开源代码在端口分组接收回调函数中添加相应逻辑
\begin{code}[c]
int port_recv_callback(int inport,struct fast_packet *pkt,int pkt_len)
{
//解析分组字段提取LLDP分组并打印输出其相关协议字段
//解析分组字段判断帧类型为0x0800源IP为单播地址的分组打印其源MAC地址与IP地址
}
\end{code}
\begin{enumerate}
\item 解析接收数据,判断以太网帧类型,
如果帧类型为0x88CC则说明是LLDP协议分组根据LLDP协议打印相关协议字段内容
\item 解析分组提取输入帧类型为0x0800的分组
打印输出其源MAC地址与源IP地址仅输出IP地址为单播类型的条目
\end{enumerate}
\item 编译SDN交换机验证添加逻辑功能观察是否正确打印需要的消息内容
\item 分析端口接收回调函数中打印的消息内容;
\begin{enumerate}
\item 从LLDP分组中可解析得知对端交换机的某个端口发送到本交换机的某个端口
\item 从普通IPv4报文中可以获得连接到该交换机上的主机节点信息
MAC地址和IPv4地址
\end{enumerate}
\item 验证并观察SDN控制器自带的拓扑展示界面
\begin{enumerate}
\item 在控制器主机打开WEB界面输入地址
\texttt{127.0.0.1/ui/index.html}。查看浏览器界面数据;
\item 切换浏览器的拓扑显示版块,
查看网络拓扑展示效果可以看到两台交换机中间用线连接;
\item 连接上一台测试主机,刷新拓扑界面,
查看到界面新增了一台主机并显示其IP地址信息
\item 再连接上另一台主机,刷新拓扑界面,
查看到界面又新增了一台主机并显示其IP地址信息
\item 断开两台交换机之间的网线,新拓扑界面,
查看两个交换机之间的连线消失了;
\item 断开一台测试主机,新拓扑界面,查看其对应的主机从界面消失;
\end{enumerate}
\item 使用控制器的北向REST API接口查询网络的所有链路连接关系数据
API接口为\texttt{/wm/topology/links/json}
\item 使用控制器的北向REST API接口查询全网所有设备节点信息
API接口为\texttt{/wm/device/}
\item 自己开发网络拓扑展示效果图;
\item 修改网络拓扑后验证自己开发程序的效果。
\end{enumerate}
\subsection{思考题}
\label{subsec:c:sdn-ob:s:topo_rethink}
\begin{enumerate}
\item 网络拓扑中的设备节点信息学习,使用广播报文中的信息会带来哪些影响?
\item OpenFlow交换机之间用一台普通交换机连接能学习到全网的拓扑结构信息吗
分析原因。
\end{enumerate}
\subsection{注意事项及有关说明}
\label{subsec:c:sdn-ob:s:topo_notice}
\begin{enumerate}
\item JAVA的WEB程序显示的缓存每新刷新操作前请清理浏览器历史缓存数据。
\end{enumerate}
\subsection{考核方法}
\label{subsec:c:sdn-ob:s:topo_criterion}
完成本次实验,需要提交一份实验报告和一分程序输出日志。
\begin{enumerate}
\item 20分在规定时间内完成实验并提交实验成果
\item 20分正确打印输入与输出LLDP消息内容和连接主机信息
\item 20分通过REST API编程获取链路状态信息与设备信息并能生成拓扑关系图
\item 20分以图形界面形式展示拓扑图
\item 10分动态修改物理拓扑后程序可以及时刷新出正确拓扑图状态
\item 10分实验报告与源代码内容完整、格式整洁。
\end{enumerate}

@ -24,8 +24,8 @@
\item 第一单元:谢怡、陈建发、洪劼超、雷蕴奇,厦门大学
\item 第二单元:吴荻、周丽涛,国防科技大学
\item 第三单元:张晓丽,昆明理工大学
\item 第四单元:胡罡、徐东来、徐明、夏竟,国防科技大学
\item 第五单元:胡罡、徐东来、蔡志平、徐明、夏竟,国防科技大学
\item 第四单元:胡罡、孙志刚,国防科技大学
\item 第五单元:夏竟、蔡志平、徐明,国防科技大学
\item 统筹规划:徐明、夏竟,国防科技大学
\end{itemize}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.
Loading…
Cancel
Save