RyuBook1.0案例 REST Linkage

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)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值