了解 Ryu OpenFlow 控制器、mininet、WireShark 和 tcpdump [英] Understanding Ryu OpenFlow Controller, mininet, WireShark and tcpdump

查看:53
本文介绍了了解 Ryu OpenFlow 控制器、mininet、WireShark 和 tcpdump的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 OpenFlow 和 SDN 的新手.我需要帮助在 Ubuntu 或 Debian 机器上设置 Ryu OpenFlow 控制器并了解基本的 Ryu 应用程序.

I am a newbie to OpenFlow and SDN. I need help setting up the Ryu OpenFlow controller on a Ubuntu or Debian machine and understand a basic Ryu application.

注意:这个问题已经有了答案.

Note: this question already has an answer.

推荐答案

这可能是我在 Stack Overflow 上写的最长的帖子之一.我一直在学习 OpenFlow、SDN 和 Ryu,并想在这里为初学者记录我的知识.如果需要,请更正/编辑我的帖子.

This is probably one of the longest posts I have written on Stack Overflow. I have been learning about OpenFlow, SDN and Ryu and would like to document my knowledge for a beginner here. Please correct/edit my post if needed.

本简短指南假定您已经了解计算机网络和主要网络协议.本指南将帮助您从系统设置开始使用 OpenFlow.

This short guide assumes you already have knowledge of computer networks and major networking protocols. This guide will help you get started with OpenFlow from system setup.

请阅读SDN/OpenFlow |Flowgrammable.

进一步阅读:网络的未来和协议的过去Scott Shenker 和软件定义网络,IEEE INFOCOM 2009.

开始之前:

基础设施层包括网络核心内的路由器和交换机.

The Infrastructure layer includes the routers and switches inside the network core.

控制层包括运行 OpenFlow 控制器的 PC 以及控制器本身.

The Control layer includes the PC that runs an OpenFlow controller along with the controller itself.

应用层包括在该控制器之上运行的应用程序.在 Ryu 中,这些应用程序是用 Python 编写的.

The Application layer includes the applications that run on top of that controller. In Ryu, these applications are written in Python.

OpenFlow 是一种协议,基础设施和控制层使用该协议进行交互.OpenFlow 本身不提供 API.它是一种开源协议,由开发支持 OpenFlow 的交换机的供应商和编写控制器的开发人员(如 Ryu)使用.API 由控制器提供.

OpenFlow is a protocol using which the Infrastructure and the Control layer interact. OpenFlow does not provide an API of itself. It is an open source protocol that is used by vendors who develop OpenFlow capable switches and by developers who write the controllers, like Ryu. The API is provided by the controller.

先决条件

您需要访问互联网.如果您在虚拟机中运行 Debian,请发出以下命令以通过 NAT 自动配置您的以太网接口:

You need internet access. If you are running Debian inside a Virtual Machine, issue the following command to automatically configure your Ethernet interface via NAT:

su  
dhclient eth0

启用 sudo

Debian 默认不附带 sudo.您稍后将使用的某些 Ryu 应用程序需要 sudo.您可以安装 sudo 并将自己添加到 sudo'ers 列表中,如下所示:

Debian does not come with sudo by default. Some Ryu applications you'll use later on require sudo. You can install sudo and add yourself to the sudo'ers list as follows:

su
apt-get install sudo # you might need to do apt-get update first!
visudo

找到显示 %sudo ALL=(ALL:ALL) ALL 的行并在其正下方添加一个条目:

Find the line that says %sudo ALL=(ALL:ALL) ALL and add an entry immediately below it:

yourusername ALL=(ALL:ALL) ALL

CTRL+X 然后按 Y 将更改保存到 sudoers 文件.现在您可以以 root 身份注销以返回您自己的 shell

Press CTRL+X and then press Y to save the changes to the sudoers file. Now you can logout as root to return to your own shell

exit

启用最佳屏幕分辨率(仅限虚拟机)

如果您在 Virtual Box 中运行 Debian,默认安装不会为 Virtual Box 启用全屏分辨率支持.稍后在第 3 节中您将需要更大的屏幕.现在启用它是个好主意.

If you are running Debian in Virtual Box, the default installation does not enable full screen resolution support for Virtual Box. You'll need a bigger screen later in section 3. It's a good idea to enable it now.

在虚拟机窗口中,单击设备 >插入访客添加 CD 映像 ...

In the Virtual Machine's window, click Devices > Insert Guest Additions CD Image ...

然后 cd 到包含文件的目录

Then cd to the directory containing the files

cd /media/cdrom

由于权限问题,Debian 不会让您运行该脚本.将文件复制到您的主目录,更改权限,然后运行它:

Debian won't let you run the script due to permission issues. Copy the files to your home directory, change the permissions, and then run it:

mkdir ~/VBOXGUEST  
cp * ~/VBOXGUEST  
cd ~/VBOXGUEST  
chmod 755 *  
sudo ./VBoxLinuxAdditions.run

重启

sudo shutdown -r now

安装 Git

sudo apt-get install git

安装迷你网

Mininet 允许您在笔记本电脑/PC 上虚拟模拟各种网络接口.使用 Git 安装它:

Mininet allows you to virtually emulate various network interfaces on your laptop/PC. Install it using Git:

cd ~  # if you are in some other directory
git clone git://github.com/mininet/mininet
cd mininet
git tag  # this will list available versions
git checkout -b 2.2.1 2.2.1  # replace 2.2.1 with the version you wish to install
cd ..
mininet/util/install.sh -a  # default installation, includes all components, recommended

我建议您安装 OpenFlow Wireshark Dissector.您可以稍后安装 Wireshark 来分析数据包.OpenFlow Wireshark Dissector 帮助 Wireshark 从 OpenFlow 数据包中获取尽可能多的信息.

I recommend you install the OpenFlow Wireshark Dissector. You can later install Wireshark to analyze packets. The OpenFlow Wireshark Dissector helps Wireshark fetch as much information from OpenFlow packets as possible.

mininet/util/install.sh -h

运行以下命令检查您的 mininet 安装:

Run the following command to check your mininet installation:

sudo mn --test pingall

安装 Ryu OpenFlow 控制器

OpenFlow 控制器使用 OpenFlow 协议在控制层和基础设施层之间进行通信.此外,它是提供 API 以开发在应用层(在控制层之上)运行的 SDN 应用程序的控制器.有许多 OpenFlow 控制器.Ryu OpenFlow 控制器是一种使用 Python 脚本作为其应用程序的控制器.同样,使用 Git 安装它:

An OpenFlow Controller communicates between the Control Layer and the Infrastructure layer using the OpenFlow protocol. Also, it's the controller that provides an API to develop SDN applications that run in the Application Layer (on top of the Control Layer). There are numerous OpenFlow controllers. Ryu OpenFlow controller is one that uses Python scripts as its applications. Again, install it using Git:

cd ~
git clone git://github.com/osrg/ryu.git

安装 Wireshark

sudo apt-get install wireshark

安装支持的 Python 模块

Debian 8.3 默认安装了 Python 2.7 和 3.4.但是,您需要安装一些 Ryu 应用程序(Python 脚本)使用的 Python 模块.您可以使用 pip 安装 Python 模块:

Debian 8.3 does come with both Python 2.7 and 3.4 installed by default. However, you need to install some Python modules that the Ryu applications (Python scripts) use. You can install Python modules using pip:

cd ~/ryu  
sudo apt-get install python-dev python-pip python-setuptools  
sudo pip install .

上面将自动运行位于此目录中的 setup.py 并从 Python 包索引中获取缺少的 Python 模块.该脚本将自动安装所有相关模块.但是,请运行以下命令以确保您以后不会丢失任何模块:

the above will automatically run setup.py located in this directory and fetch the missing Python modules from the Python Package Index. The script will automatically install all relevant modules. However, do run the following to make sure you aren't missing any module later:

sudo pip install webob  
sudo pip install eventlet  
sudo pip install paramiko  
sudo pip install routes  

启动

使用以下命令启动 mininet 以模拟 3 个主机和一个交换机:

Start mininet to emulate 3 hosts and a switch using the following command:

sudo mn --topo single,3 --mac --switch ovsk --controller remote

您将看到一个 mininet 提示.此提示可用于 ping 主机、在它们之间发送数据包等.

You will see a mininet prompt. This prompt can be used to ping hosts, send packets between them, etc.

打开另一个终端窗口来运行 Ryu.在此示例中,我们将运行一个应用程序 (simple_switch_13.py),该应用程序将模拟一个简单的第 2 层交换机,它将所有接收到的数据包转发到除接收到的端口之外的所有端口.

Open up another terminal window to run Ryu. In this example, we will run an application (simple_switch_13.py) that will emulate a simple layer 2 switch that will forward all received packets to all ports except the one received on.

cd ~/ryu  
PYTHONPATH=. ./bin/ryu-manager ryu/app/simple_switch_13.py

确保您在运行此程序时位于您的主目录中.

Make sure you are in your home directory when you run this.

你已经准备好了.要 ping 主机并分析数据包传输,请移至下一部分.

You are all set. To ping hosts and analyse the packet transmissions, please move onto the next section.

在本节中,我们将使用 mininet 从一台主机向另一台主机发送数据包,并使用 tcpdump 和 Wireshark 分析生成的传输.

In this section, we will fire packets from one host to another using mininet, and analyze the resulting transmissions using tcpdump and Wireshark.

数据包的传输方式正是我们在软件定义网络中可以控制的.我们通过编写在控制器之上运行的不同应用程序来做到这一点.这些应用构成了SDN控制平面的应用层.

The way the packets get transmitted is exactly what we can control in Software Defined Networking. We do this by writing different applications that run on top of the controller. These applications form the Application layer of the SDN control plane.

设置拓扑并运行控制应用程序

注意:在前面的部分中,您使用 mininet 创建了一个拓扑,并启动了一个 Ryu 应用程序来控制传输.如果您重新启动或退出其中任何一个,我会在此处重复创建拓扑并启动 Ryu 应用程序的命令:

Note: In the earlier section, you created a topology with mininet, and started a Ryu application to control the transmissions. In case you rebooted, or exited any of them, I repeat the commands to create the topology and start the Ryu application here:

cd ~
sudo mn --topo single,3 --mac --switch ovsk --controller remote

在单独的终端窗口中:

cd ~/ryu
PYTHONPATH=. ./bin/ryu-manager ryu/app/simple_switch_13.py

玩数据包

在 mininet 提示符下,发出以下命令为您创建的拓扑中的三个主机打开一个控制台窗口:

In the mininet prompt, issue the following to open a console window for each of the three hosts in the topology you created:

mininet> xterm h1 h2 h3

堆叠这些控制台,以便您可以同时看到它们!然后在 h2 和 h3 的 xterms 中运行 tcpdump,这是一个用于打印主机看到的数据包的实用程序:

Stack these consoles so you can see them all simultaneously! Then in the xterms for h2 and h3, run tcpdump, a utility to print the packets seen by a host:

tcpdump -XX -n -i h2-eth0  
tcpdump -XX -n -i h3-eth0

注意:如果你之前使用过Wireshark,就相当于分别在这两个主机的eth0接口上抓包.

Note: If you have used Wireshark earlier, it's like capturing packets on the eth0 interface of these two hosts respectively.

在创建拓扑时,mininet 为三台主机分配了以下 IP 地址:

When creating topology, mininet assigned the following IP addresses to the three hosts:

h1: 10.0.0.1  
h2: 10.0.0.2  
h3: 10.0.0.3

从主机 1 的 shell,ping 主机 2 和主机 3 并观察每个命令后对其他两个控制台的影响:

From host 1's shell, ping host 2 and host 3 and observe the effect on the other two consoles after each command:

ping 10.0.0.2  
ping 10.0.0.3

尝试 ping 一个无法访问的(不存在的主机),并在控制台上查看效果:

Try pinging an unreachable (non existent host), and see the effect on the consoles:

ping 10.0.0.7

您应该已经观察到本节中的 ICMP (ping) 和 ARP(谁拥有此 IP 地址)协议!您也可以使用 Wireshark 而不是 tcpdump 执行上述操作.这是 tcpdump 的图形替代方案.

You should have observed the ICMP (ping) and ARP (who has this IP address) protocols live in this section! You can also do the above using Wireshark instead of tcpdump. That's a graphical alternative to tcpdump.

注意:数据包的转发方式全部取决于在 Ryu 上运行的应用程序.您可以编写一个应用程序来丢弃所有数据包.在这种情况下,您的 ping 操作不会对其他两个控制台产生任何影响.

Note: The way the packets are forwarded ALL depends on the application running on top of Ryu. You could write an application to drop all packets. In that case, your pings would produce no effect on the other two consoles.

在本节中,我们将分析第 3 节中控制数据包传输的第 2 层交换机应用程序的简化版本的工作原理.

In this section, we analyze the working of a simplified version of a Layer 2 Switch application that controlled the transmissions of packets in section 3.

学习桥(或第 2 层交换机)的工作

我之前提到过,如果您正在阅读本指南,我假设您已经了解基本的网络协议(其中包括第 2 层交换机、学习网桥或以太网交换机的工作原理!)我会不管怎样,用下面几行总结一下.

I mentioned earlier that if you are reading this guide, I assume you already have knowledge of basic networking protocols, (which includes the working of a layer 2 switch, or a learning bridge, or an Ethernet switch!) I'll summarize it in a few lines below regardless.

学习"网桥根据它的端口存储它所连接的主机的数据库.主机由其网卡的 MAC 地址标识,如下所示:ab:cd:ef:12:34:56(十六进制).端口仅通过其编号来标识.例如,一个有 4 个端口的交换机有端口 1、2、3 和 4.

A "learning" bridge stores a database of the hosts its connected to, against it's ports. The hosts are identified by the MAC address of their network card, which looks like this: ab:cd:ef:12:34:56 (it's in hexadecimal). The ports are identified simply by their number. For example, a switch with 4 ports has port 1, 2, 3 and 4.

如果交换机在其端口 2 上接收到数据包,它将查看该数据包的目标 MAC 地址(它的目标主机).然后它会查看它的数据库,看看它是否知道该主机连接到哪个端口.如果它发现它,它只会将该数据包转发到该特定端口.但是,如果它的数据库中还没有条目,它会将该数据包泛洪到所有端口,并且主机可以自行检查数据包是否发往它们.

If a switch receives a packet on its port 2, it will look at the destination MAC address (which host it's destined to) of that packet. It then looks into it's database to see if it knows which port is that host connected to. If it finds it out, it forwards that packet ONLY to that specific port. But if it doesn't have an entry in it's database yet, it floods that packet to ALL ports, and the hosts can check for themselves if the packet was destined for them.

同时,交换机查看该数据包的 MAC 地址,它立即知道主机 X 位于端口 2.它将该条目存储在该数据库中.所以现在你知道了,如果目的主机回复源主机,交换机就不必泛洪回复数据包了!

At the same time, the switch looks at the source MAC address of that packet, and it immediately knows that host X is located at port 2. It stores that entry in that database. So now you know that if the destination host replies to the source host, the switch won't have to flood the reply packet!

Ryu API Python 代码简介

与其直接进入simple_switch_13.py,不如选择一个非常简单,没有学习"的程序.能力.目前,没有转发数据库.下面的程序只是一个简单的第 2 层交换机,它将接收到的数据包传输到所有端口(淹没数据包):

Instead of going directly to simple_switch_13.py, let's choose a very simple program that has no "learning" capability. For now, there is no forwarding database. The below program is just a simple layer 2 switch that transmits a received packet to all ports (floods the packet):

    from ryu.base import app_manager
    from ryu.controller import ofp_event
    from ryu.controller.handler import MAIN_DISPATCHER
    from ryu.controller.handler import set_ev_cls

    class L2Switch(app_manager.RyuApp):
        def __init__(self, *args, **kwargs):
            super(L2Switch, self).__init__(*args, **kwargs)

        @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
        def packet_in_handler(self, ev):
            msg = ev.msg
            dp = msg.datapath
            ofp = dp.ofproto
            ofp_parser = dp.ofproto_parser

            actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]
            out = ofp_parser.OFPPacketOut(
                datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,
                actions=actions)
            dp.send_msg(out)

导入

我不会深入研究导入语句.我们将在分析使用它们的代码时单独讨论导入.

I will not delve into the import statements yet. We will discuss the imports individually as we analyze the code that uses them.

基本应用框架

以下代码是一个完美完整的 Ryu 应用程序.事实上你也可以执行它!但它不会做任何事情:

The following code is a perfectly complete Ryu application. In fact you can execute it too! It won't do anything though:

    from ryu.base import app_manager

    class L2Switch(app_manager.RyuApp):
        def __init__(self, *args, **kwargs):
            super(L2Switch, self).__init__(*args, **kwargs)

作为类的参数,我们传递 ryu.base.app_manager.RyuApp 导入(在第一行导入).在 Ryu API 手册中,app_manager 类是 Ryu 应用程序的中央管理.它加载 Ryu 应用程序,为它们提供上下文并在 Ryu 应用程序之间路由消息.

As an argument to the class, we pass ryu.base.app_manager.RyuApp import (imported in the first line). From the Ryu API handbook, app_manager class is the central management of Ryu applications. It loads Ryu applications, provide contexts to them and routes messages among Ryu applications.

EventOFPPacketIn 事件

一个新方法packet_in_handler被添加到L2Switch类.当 Ryu 收到 OpenFlow packet_in 消息时调用它.当 Ryu 收到 packet_in 消息时,会引发 ofp_event.EventOFPPacketIn 事件.set_ev_cls 装饰器告诉 Ryu 什么时候应该调用关联函数 packet_in_handler.

A new method packet_in_handler is added to L2Switch class. This is called when Ryu receives an OpenFlow packet_in message. When Ryu receives a packet_in message, a ofp_event.EventOFPPacketIn event is raised. The set_ev_cls decorator tells Ryu when the associated function, packet_in_handler should be called.

set_ev_cls 装饰器的第一个参数表示调用函数的事件.正如您所期望的那样,每次引发 ofp_event.EventOFPPacketIn 事件时,都会调用此函数.

The first argument of the set_ev_cls decorator indicates an event that makes function called. As you expect easily, every time a ofp_event.EventOFPPacketIn event is raised, this function is called.

第二个参数表示当你想要让 Ryu 处理事件时开关的状态.可能,您想在 Ryu 和交换机之间的握手完成之前忽略 OpenFlow packet_in 消息.使用 MAIN_DISPATCHER 作为第二个参数意味着这个函数只有在协商完成后才会被调用.MAIN_DISPATCHER 表示交换机的正常状态.在初始化阶段,交换机处于HANDSHAKE_DISPATCHER状态!

The second argument indicates the state of the switch when you want to allow Ryu to handle an event. Probably, you want to ignore OpenFlow packet_in messages before the handshake between Ryu and the switch finishes. Using MAIN_DISPATCHER as the second argument means this function is called only after the negotiation completes. MAIN_DISPATCHER denotes the normal state of the switch. During the initialization stage, the switch is in HANDSHAKE_DISPATCHER state!

现在让我们看一下函数的主体.我们将把它分成两部分.

Now let's look at the body of the function. We'll break it down into two parts.

    msg = ev.msg  
    dp = msg.datapath  
    ofp = dp.ofproto  
    ofp_parser = dp.ofproto_parser

ev.msg是一个包含接收到的数据包的数据结构.

ev.msg is a data structure that contains the received packet.

msg.dp 是该数据结构中的一个对象,表示数据路径(开关).

msg.dp is an object inside that data structure that represents a datapath (switch).

dp.ofprotodp.ofproto_parser 是代表 Ryu 和交换机协商的 OpenFlow 协议的对象.

dp.ofproto and dp.ofproto_parser are objects that represent the OpenFlow protocol that Ryu and the switch negotiated.

    actions = [ofp_parser.OFPActionOutput(ofp.OFPP_FLOOD)]  
    out = ofp_parser.OFPPacketOut(  
        datapath=dp, buffer_id=msg.buffer_id, in_port=msg.in_port,  
        actions=actions)  
    dp.send_msg(out)

OFPActionOutput 类与 packet_out 消息一起使用,以指定您要从中发送数据包的交换机端口.由于在这个简化的应用程序中没有转发数据库,​​我们将数据包洪泛到所有端口,因此使用常量OFPP_FLOOD.

OFPActionOutput class is used with a packet_out message to specify a switch port that you want to send the packet out of. Since there is no forwarding database in this simplified application, we flood the packet to all ports, so the constant OFPP_FLOOD is used.

OFPPacketOut 类用于构建 packet_out 消息.

OFPPacketOut class is used to build a packet_out message.

通过使用datapath 类的send_msg 方法,您可以将OpenFlow 消息对象发送到actions 变量中定义的端口.我重复一遍,在这种情况下,构建的动作使得目的地包括所有端口.

By using datapath class's send_msg method, you can send an OpenFlow message object to the ports defined in the actions variable. I repeat, in this case, actions is built such that the destination includes ALL ports.

活动

您在上面的代码中反复看到了术语事件.在事件驱动编程中,程序的流程由事件控制,事件由系统接收到的消息引发(例如,EventOFPPacketIn 在收到 packet_in 消息时引发 Ryu 来自(启用OpenFlow的)开关).我们之前讨论过 OpenFlow 是一种协议,控制器(Ryu、PC)和基础设施(或交换机)使用该协议进行通信.类似消息 packet_in 正是两者之间使用OpenFlow协议的通信样子!

You repeatedly saw the term event in the above code. In event driven programming, the flow of the program is controlled by events, which are raised by messages received by the system (e.g. EventOFPPacketIn is raised when the packet_in message is received by Ryu from the (OpenFlow enabled) switch). We earlier discussed that OpenFlow is a protocol using which the controller (Ryu, PC) and the infrastructure (or switch) communicate. Messages like packet_in are exactly what the communication between the two looks like using the OpenFlow protocol!

后续步骤

您可能希望继续构建自己的 Ryu 应用程序.学习 Ryu API(或 Python 语言,如果您还不熟悉的话)可能是一个很好的起点.祝你好运!

You might want to go ahead and build your own Ryu applications. Learning the Ryu API (or the Python language, if you are not already familiar with it) might be a good point to start. Good luck!

这篇关于了解 Ryu OpenFlow 控制器、mininet、WireShark 和 tcpdump的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆