English
联系我们
网站地图
邮箱
旧版回顾



杨颖工作室晒日记_RyuBook1.0案例三:REST Linkage

REST Linkage

该小结主要介绍如何添加一个REST Link 函数

RYU本身提供了一个类似WSGI的web服务器功能。借助这个功能,我们可以创建一个REST API。
基于创建的REST API,可以快速的将RYU系统与其他系统或者是浏览器相连接,非常实用的一个功能。

程序解析

在案例中,实现了两个类

  • SimpleSwitchRest13
    • 继承SimpleSwitch13的功能,即具备父类的三层交换机的基本功能。
    • 注册WSGI服务
    • 配置mac_to_port
  • SimpleSwitchController
    • REST API功能实现的主体类
    • 返回指定交换机的mac_table
    • 更新指定的mac_table条目

SimpleSwitchRest13类实现

_CONTEXTS = {"wsgi": WSGIApplication}

该成员变量用于指明Ryu的兼容WSGI的web服务对象。

wsgi = kwargs["wsgi"]
wsgi.register(SimpleSwitchController,
              {simple_switch_instance_name: self})

通过上一步设置的_CONTEXTS成员变量,可以通过kwargs进行实例化一个WSGIApplication。同时使用register方法注册该服务到
controller类上。

@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
    super(SimpleSwitchRest13, self).switch_features_handler(ev)
    datapath = ev.msg.datapath
    self.switches[datapath.id] = datapath
    self.mac_to_port.setdefault(datapath.id, {})

重写父类的switch_features_handler函数

  • 存储datapath到switches
  • 初始化MAC 地址表
def set_mac_to_port(self, dpid, entry):
    # 获取MAC table
    mac_table = self.mac_to_port.setdefault(dpid, {})
    
    # 获取datapath,如果为None,证明没有该交换机
    datapath = self.switches.get(dpid)

    entry_port = entry["port"]
    entry_mac = entry["mac"]

    if datapath is not None:
        parser = datapath.ofproto_parser
        # 如果entry_port不在mac_table中
        if entry_port not in mac_table.values():
            # 下发流表
            for mac, port in mac_table.items():

                # from known device to new device
                actions = [parser.OFPActionOutput(entry_port)]
                match = parser.OFPMatch(in_port=port, eth_dst=entry_mac)
                self.add_flow(datapath, 1, match, actions)

                # from new device to known device
                actions = [parser.OFPActionOutput(port)]
                match = parser.OFPMatch(in_port=entry_port, eth_dst=mac)
                self.add_flow(datapath, 1, match, actions)

            # 添加entry_mac, entry_port到mac_table
            mac_table.update({entry_mac: entry_port})
    return mac_table

该方法将MAC地址和端口注册到指定的交换机。该方法主要被REST API的PUT方法所调用。

SimpleSwitchController类实现

@route("simpleswitch", url, methods=["GET"],
           requirements={"dpid": dpid_lib.DPID_PATTERN})

借助route装饰器关联方法和URL。参数如下:

  • 第一个参数:任何自定义名称
  • 第二个参数:指明URL
  • 第三个参数:指定http方法
  • 第四个参数:指明指定位置的格式,URL(/simpleswitch/mactable/{dpid} 匹配DPID_PATTERN的描述

当使用GET方式访问到该REST API接口时,调用list_mac_table函数

def list_mac_table(self, req, **kwargs):
    simple_switch = self.simple_switch_app
    # 获取{dpid}
    dpid = dpid_lib.str_to_dpid(kwargs["dpid"])
    
    # 如果没有dpid,返回404
    if dpid not in simple_switch.mac_to_port:
        return Response(status=404)

    # 获取mac_table
    mac_table = simple_switch.mac_to_port.get(dpid, {})
    body = json.dumps(mac_table)
    return Response(content_type="application/json", body=body)
# 使用PUT方式设置mac_table
@route("simpleswitch", url, methods=["PUT"],
           requirements={"dpid": dpid_lib.DPID_PATTERN})
    def put_mac_table(self, req, **kwargs):
        simple_switch = self.simple_switch_app
        dpid = dpid_lib.str_to_dpid(kwargs["dpid"])
        try:
            new_entry = req.json if req.body else {}
        except ValueError:
            raise Response(status=400)

        if dpid not in simple_switch.mac_to_port:
            return Response(status=404)

        try:
            mac_table = simple_switch.set_mac_to_port(dpid, new_entry)
            body = json.dumps(mac_table)
            return Response(content_type="application/json", body=body)
        except Exception as e:
            return Response(status=500)

运行分析

启动mininet创建网络拓扑图

sudo mn --topo single,3 --mac --switch ovsk,protocols=OpenFlow13 --controller remote -x

启动控制器程序,打印log信息如下:

debugging is available (--enable-debugger option is turned on)
loading app SimpleSwitchRest13
loading app ryu.controller.ofp_handler
creating context wsgi
instantiating app SimpleSwitchRest13 of SimpleSwitchRest13
instantiating app ryu.controller.ofp_handler of OFPHandler
BRICK SimpleSwitchRest13
  CONSUMES EventOFPPacketIn
  CONSUMES EventOFPSwitchFeatures
BRICK ofp_event
  PROVIDES EventOFPPacketIn TO {"SimpleSwitchRest13": set(["main"])}
  PROVIDES EventOFPSwitchFeatures TO {"SimpleSwitchRest13": set(["config"])}
  CONSUMES EventOFPEchoReply
  CONSUMES EventOFPSwitchFeatures
  CONSUMES EventOFPPortDescStatsReply
  CONSUMES EventOFPHello
  CONSUMES EventOFPErrorMsg
  CONSUMES EventOFPEchoRequest
  CONSUMES EventOFPPortStatus
(22238) wsgi starting up on http://0.0.0.0:8080

这里我们可以看到,wsgi服务已经启动,端口号为8080

查询s1的默认MAC table

curl -X GET http://127.0.0.1:8080/simpleswitch/mactable/0000000000000001

返回为{}

在mininet中执行

mininet> h1 ping -c 1 h2

log信息打印如下信息:

EVENT ofp_event->SimpleSwitchRest13 EventOFPPacketIn
packet in 1 00:00:00:00:00:01 ff:ff:ff:ff:ff:ff 1
EVENT ofp_event->SimpleSwitchRest13 EventOFPPacketIn
packet in 1 00:00:00:00:00:02 00:00:00:00:00:01 2
EVENT ofp_event->SimpleSwitchRest13 EventOFPPacketIn
packet in 1 00:00:00:00:00:01 00:00:00:00:00:02 1

返回了三条PackageIn消息(ARP过程)

  1. host1发起的ARP请求,并广播
  2. host2发起的ARP请求,MAC地址是host1
  3. ICMP echo reply request 从host1 发生到host2

此刻按照设计,已经添加了两条条目到MAC table,再次查询进行验证。

curl -X GET http://127.0.0.1:8080/simpleswitch/mactable/0000000000000001

返回如下,证明符合实验预期:

{"00:00:00:00:00:02": 2, "00:00:00:00:00:01": 1}

测试POST API接口,添加h3到MAC Table

curl -X PUT -d "{"mac" : "00:00:00:00:00:03", "port" : 3}" http://127.0.0.1:8080/simpleswitch/mactable/0000000000000001

返回:

{"00:00:00:00:00:03": 3, "00:00:00:00:00:02": 2, "00:00:00:00:00:01": 1}

证明h3 mac已经被添加到MAC table。因为h3已经被添加到MAC Table中,所以理论上当h1 ping h3时将不再通过ARP查找到h3.

" 00: 00: 00: 00: 00: 03": 3, " 00: 00: 00: 00: 00: 02": 2, " 00: 00: 00: 00: 00: 01": 1 zheng ming h3 mac yi jing bei tian jia dao MAC table. yin wei h3 yi jing bei tian jia dao MAC Table zhong, suo yi li lun shang dang h1 ping h3 shi jiang bu zai tong guo ARP cha zhao dao h3.

测试:在mininet中执行命令

mininet> h1 ping c1 h3
PING 10.0.0.3 (10.0.0.3) 56(84) bytes of data.
64 bytes from 10.0.0.3: icmp_seq=1 ttl=64 time=2.48 ms

--- 10.0.0.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 2.480/2.480/2.480/0.000 ms

控制器log信息如下:

EVENT ofp_event->SimpleSwitchRest13 EventOFPPacketIn
packet in 1 00:00:00:00:00:01 ff:ff:ff:ff:ff:ff 1

我们可以看到,只有h1在不知道h3地址的情况下,发起ARP广播,将PackageIn消息发送到控制器,而不再出现以后的一系列消息。这证明
MAC Table中添加的条目成功生效,符合预期情况。

当前文章:http://www.gas-360.com/cge/460532-1331814-67774.html

发布时间:20:15:51

彩霸王开奖现场??www.5885kj.com??6789kj开奖直播??香港本期开奖结果??最快开奖现场报码??开奖直播室??开奖直播??香港挂牌完整篇??333740.com??天下彩本港台开奖直播??

专题推荐

相关新闻


? 1996 - 蜘蛛资讯网 版权所有?? 联系我们

地址:北京市三里河路52号 邮编:100864