教辅篇(Tutorial)--POX

POX的话,直接在根目录下进入到POX目录下,执行

mininet@mininet-vm:~/pox$ python pox.py log.level --DEBUG misc.of_tutorial

以上命令是开启DEBUG模式(输出更多信息). 创建一个of_tutorial类型的模型(类似于集线器工作)

创建完成后创建mininet实例,发现输出了一些信息

DEBUG:core:POX 0.2.0 (carp) going up...
DEBUG:core:Running on CPython (2.7.6/Oct 26 2016 20:30:19)
DEBUG:core:Platform is Linux-4.2.0-27-generic-x86_64-with-Ubuntu-14.04-trusty
INFO:core:POX 0.2.0 (carp) is up.
DEBUG:openflow.of_01:Listening on 0.0.0.0:6633
INFO:openflow.of_01:[None 1] closed
INFO:openflow.of_01:[00-00-00-00-00-01 2] connected
DEBUG:misc.of_tutorial:Controlling [00-00-00-00-00-01 2]

我们可以在h1 h2 h3中打开各自的终端xterm h1 h2 h3, 然后使用tcpdump监听,(功能类似于wireshark,可以捕捉到进来的各种数据包), 方法是,在h2的终端中输入tcpdump -XX -i h2-eth0,就开始监听了

tcpdump

在mininet下使用iperf试一下性能:


集线器性能一般,因为所有的数据包都要跑到controller中

如果想使用交换机模式,则要进入到/pox/pox/misc中修改of_tutorial.py,删除act_like_switch中的特定注释,退出保存.


POX的API

当switch和controller连接的时候,就得到了一个connection.

connection.send(...)

就可以向switch发送OF消息

ofp_action_output类

用于switch的端口发送的消息
示例: 创建一个action, 发送数据包泛洪到所有端口

out_action = of.ofp_action_output(port = of.OFPP_FLOOD)

ofp_match类

如其名,用于匹配
比如有一些可以匹配的东西
dl_src - 数据链路层中的源MAC
dl_dst - 数据链路层中的目的MAC
in_port - 进入的端口

示例: 创建一个匹配,匹配来自端口3的数据包

match=of.ofp_match()
match.in_port = 3

ofp_packet_out OF报文

constructed packet -> switch构造的包,赋予ID为buffer_id

类型 含义
buffer_id the buffer_id of a buffer you wish to send. Dont set if sending a constructed packet.
data switch发送的原始数据(如果发送buffered packet则不要填写)
action 做出的动作
in_port 从哪里抵达的端口

示例:

action = of.ofp_action_output(port = out_port)
msg.actions.append(action)

#send message to switch
self.connection.send(msg)

ofp_flow_mod OF报文

这个报文主要用来匹配传入数据包的某些字段

关键字:idle_timeout, hard_timeout, action, priority, buffer_id, in_port, match

示例:

fm = of.ofp_flow_mod()
fm.match.in_port = 3
fm.actions.append(of.ofp_action_output(port = 4))

*如果想看openflow常量,在~/openflow/include/openflow/openflow.h中,如果想看POX的openflow库文件,在pox/openflow/libopenflow_01.py中

POX的包解析器

用来将数据包分析成各个字段然后交给python处理. 分析库在pox/lib/packet/中,每一个协议都有对应的解析文件

POX的工作过程

首先在init方法中,生成了一些重要常量

    # Keep track of the connection to the switch so that we can
    # send it messages!
    self.connection = connection

    # This binds our PacketIn event listener
    connection.addListeners(self)

又生成了一个空变量去追踪MAC和端口的相互绑定

    # Use this table to keep track of which ethernet address is on
    # which switch port (keys are MACs, values are ports).
    self.mac_to_port = {}

act_like_hub方法中
调用了

    self.resend_packet(packet_in, of.OFPP_ALL)

这里的OFPP_ALL就是全部端口,也可以使用OFPP_FLOOD


resend_packet方法(转发)中,新建一个实例化报文,绑定了内容后,,给动作表绑定了目的端口,最终执行这个实例


写了三个小时,终于把of_tutorial.py中的switch部分初步完成了(不会python真的好惨啊). V0.1实现的功能是:

  1. 如果在流表中有转发信息,则直接转发
  2. 如果流表中没有,则广播信息

不知道为什么不能自动学习???这个BUG也太大了吧

# Copyright 2012 James McCauley
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
This component is for use with the OpenFlow tutorial.

It acts as a simple hub, but can be modified to act like an L2
learning switch.

It's roughly similar to the one Brandon Heller did for NOX.
"""

from pox.core import core
import pox.openflow.libopenflow_01 as of

log = core.getLogger()



class Tutorial (object):
  """
  A Tutorial object is created for each switch that connects.
  A Connection object for that switch is passed to the __init__ function.
  """
  def __init__ (self, connection):
    # Keep track of the connection to the switch so that we can
    # send it messages!
    self.connection = connection

    # This binds our PacketIn event listener
    connection.addListeners(self)

    # Use this table to keep track of which ethernet address is on
    # which switch port (keys are MACs, values are ports).
    self.mac_to_port = {}


  def resend_packet (self, packet_in, out_port):
    """
    Instructs the switch to resend a packet that it had sent to us.
    "packet_in" is the ofp_packet_in object the switch had sent to the
    controller due to a table-miss.
    """
    msg = of.ofp_packet_out()
    msg.data = packet_in

    # Add an action to send to the specified port
    action = of.ofp_action_output(port = out_port)
    msg.actions.append(action)

    # Send message to switch
    self.connection.send(msg)


  def act_like_hub (self, packet, packet_in):
    """
    Implement hub-like behavior -- send all packets to all ports besides
    the input port.
    """

    # We want to output to all ports -- we do that using the special
    # OFPP_ALL port as the output port.  (We could have also used
    # OFPP_FLOOD.)
    self.resend_packet(packet_in, of.OFPP_ALL)

    # Note that if we didn't get a valid buffer_id, a slightly better
    # implementation would check that we got the full data before
    # sending it (len(packet_in.data) should be == packet_in.total_len)).


  def act_like_switch (self, packet, packet_in,port):
    """
    Implement switch-like behavior.
    """


    # Here's some psuedocode to start you off implementing a learning
    # switch.  You'll need to rewrite it as real Python code.

    # Learn the port for the source MAC

    self.mac_to_port[str(packet.src)] = port

    if str(packet.dst) in self.mac_to_port:
      # Send packet out the associated port
      self.resend_packet(packet_in, self.mac_to_port[str(packet.dst)])

      # Once you have the above working, try pushing a flow entry
      # instead of resending the packet (comment out the above and
      # uncomment and complete the below.)

      log.debug("I, the controller, send a packet! What are you doing, Switch?")
      # Maybe the log statement should have source/destination/port?

      #msg = of.ofp_flow_mod()
      #
      ## Set fields to match received packet
      #msg.match = of.ofp_match.from_packet(packet)
      #
      #< Set other fields of flow_mod (timeouts? buffer_id?) >
      #
      #< Add an output action, and send -- similar to resend_packet() >

    else:
      # Flood the packet out everything but the input port
      # This part looks familiar, right?
      self.resend_packet(packet_in, of.OFPP_ALL)



  def _handle_PacketIn (self, event):
    """
    Handles packet in messages from the switch.
    """

    packet = event.parsed # This is the parsed packet data.
    if not packet.parsed:
      log.warning("Ignoring incomplete packet")
      return

    packet_in = event.ofp # The actual ofp_packet_in message.

    # Comment out the following line and uncomment the one after
    # when starting the exercise.
    #self.act_like_hub(packet, packet_in)
    self.act_like_switch(packet, packet_in,event.port)



def launch ():
  """
  Starts the component
  """
  def start_switch (event):
    log.debug("Controlling %s" % (event.connection,))
    Tutorial(event.connection)
  core.openflow.addListenerByName("ConnectionUp", start_switch)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者...
    保川阅读 6,086评论 1 13
  • 简介 用简单的话来定义tcpdump,就是:dump the traffic on a network,根据使用者...
    JasonShi6306421阅读 1,352评论 0 1
  • Wireshark 1.x针对 UNIX Like 系统的 GUI 发行版界面采用的是X Window(1987年...
    huangman阅读 1,570评论 1 0
  • mininet在SDN网络实验中可以用来快速、方便的创建网络拓扑,SDNLAB网站上有mininet相关的实验课程...
    目睹了整个事件的索先生阅读 7,881评论 0 1
  • 前言 tcpdump 是一个很常用的网络包分析工具,可以用来显示通过网络传输到本系统的 TCP/IP 以及其他网络...
    王奥OX阅读 39,913评论 0 12

友情链接更多精彩内容