コード例 #1
0
    def del_groups(self, datapath):
        """ Deletes all existing groups """
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        msg = parser.OFPGroupMod(datapath, ofproto.OFPGC_DELETE, 0,
                                 ofproto.OFPG_ALL)
        api.send_msg(self, msg)
コード例 #2
0
 def _send_set_async(self, br):
     """Set asynchronous configuration message for the given bridge."""
     datapath = br.datapath
     ofp = datapath.ofproto
     ofpp = datapath.ofproto_parser
     packet_in_mask = 1 << ofp.OFPR_ACTION | 1 << ofp.OFPR_INVALID_TTL
     port_status_mask = 1 << ofp.OFPPR_DELETE
     flow_removed_mask = 0
     msg = ofpp.OFPSetAsync(datapath, [packet_in_mask, 0], [port_status_mask, 0], [flow_removed_mask, 0])
     ryu_api.send_msg(app=self.ryuapp, msg=msg)
コード例 #3
0
    def del_flows(self, datapath):
        """ Deletes all existing flows """
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        msg = parser.OFPFlowMod(datapath=datapath,
                                table_id=ofproto.OFPTT_ALL,
                                command=ofproto.OFPFC_DELETE,
                                out_port=ofproto.OFPP_ANY,
                                out_group=ofproto.OFPG_ANY)
        api.send_msg(self, msg)
コード例 #4
0
 def _send_set_async(self, br):
     """Set asynchronous configuration message for the given bridge."""
     datapath = br.datapath
     ofp = datapath.ofproto
     ofpp = datapath.ofproto_parser
     packet_in_mask = 1 << ofp.OFPR_ACTION | 1 << ofp.OFPR_INVALID_TTL
     port_status_mask = 1 << ofp.OFPPR_DELETE
     flow_removed_mask = 0
     msg = ofpp.OFPSetAsync(datapath, [packet_in_mask, 0],
                            [port_status_mask, 0], [flow_removed_mask, 0])
     ryu_api.send_msg(app=self.ryuapp, msg=msg)
コード例 #5
0
 def _send_arp_reply(self, datapath, port, pkt):
     ofp = datapath.ofproto
     ofpp = datapath.ofproto_parser
     pkt.serialize()
     data = pkt.data
     actions = [ofpp.OFPActionOutput(port=port)]
     out = ofpp.OFPPacketOut(datapath=datapath,
                             buffer_id=ofp.OFP_NO_BUFFER,
                             in_port=ofp.OFPP_CONTROLLER,
                             actions=actions,
                             data=data)
     ryu_api.send_msg(self.ryuapp, out)
コード例 #6
0
 def _send_unknown_packet(self, msg, in_port, out_port):
     datapath = msg.datapath
     ofp = datapath.ofproto
     ofpp = datapath.ofproto_parser
     data = None
     if msg.buffer_id == ofp.OFP_NO_BUFFER:
         data = msg.data
     actions = [ofpp.OFPActionOutput(port=out_port)]
     out = ofpp.OFPPacketOut(datapath=datapath,
                             buffer_id=msg.buffer_id,
                             in_port=in_port,
                             actions=actions,
                             data=data)
     ryu_api.send_msg(self.ryuapp, out)
コード例 #7
0
ファイル: arp_lib.py プロジェクト: AsherBond/quantum
 def _add_flow_to_avoid_unknown_packet(self, datapath, match):
     LOG.debug("add flow to avoid an unknown packet from packet-in")
     ofp = datapath.ofproto
     ofpp = datapath.ofproto_parser
     instructions = [ofpp.OFPInstructionGotoTable(
         table_id=constants.FLOOD_TO_TUN)]
     out = ofpp.OFPFlowMod(datapath,
                           table_id=constants.PATCH_LV_TO_TUN,
                           command=ofp.OFPFC_ADD,
                           idle_timeout=5,
                           priority=20,
                           match=match,
                           instructions=instructions)
     ryu_api.send_msg(self.ryuapp, out)
コード例 #8
0
 def _add_flow_to_avoid_unknown_packet(self, datapath, match):
     LOG.debug("add flow to avoid an unknown packet from packet-in")
     ofp = datapath.ofproto
     ofpp = datapath.ofproto_parser
     instructions = [
         ofpp.OFPInstructionGotoTable(table_id=constants.FLOOD_TO_TUN)
     ]
     out = ofpp.OFPFlowMod(datapath,
                           table_id=constants.PATCH_LV_TO_TUN,
                           command=ofp.OFPFC_ADD,
                           idle_timeout=5,
                           priority=20,
                           match=match,
                           instructions=instructions)
     ryu_api.send_msg(self.ryuapp, out)
コード例 #9
0
 def get_stats(self, cookie: int = 0, cookie_mask: int = 0):
     """
     Use Ryu API to send a stats request containing cookie and cookie mask, retrieve a response and 
     convert to a Rule Record Table
     """
     parser = self._datapath.ofproto_parser
     message = parser.OFPFlowStatsRequest(datapath=self._datapath,
                                          cookie=cookie,
                                          cookie_mask=cookie_mask)
     try:
         response = ofctl_api.send_msg(self,
                                       message,
                                       reply_cls=parser.OFPFlowStatsReply,
                                       reply_multi=False)
         if response == None:
             self.logger.error(
                 "No rule records match the specified cookie and cookie mask"
             )
             return RuleRecordTable()
         else:
             usage = self._get_usage_from_flow_stat(response.body)
             record_table = RuleRecordTable(records=usage.values(),
                                            epoch=global_epoch)
             return record_table
     except (InvalidDatapath, OFError, UnexpectedMultiReply):
         self.logger.error(
             "Could not obtain rule records due to either InvalidDatapath, OFError or UnexpectedMultiReply"
         )
         return RuleRecordTable()
コード例 #10
0
ファイル: df_base_app.py プロジェクト: gampel/dragonflow
 def get_flows(self, datapath=None, table_id=None, timeout=None):
     if datapath is None:
         datapath = self.datapath
     if table_id is None:
         table_id = datapath.ofproto.OFPTT_ALL
     if not timeout:
         timeout = DEFAULT_GET_FLOWS_TIMEOUT
     parser = datapath.ofproto_parser
     msg = parser.OFPFlowStatsRequest(datapath, table_id=table_id)
     try:
         with eventlet.timeout.Timeout(seconds=timeout):
             replies = ofctl_api.send_msg(
                 self.api,
                 msg,
                 reply_cls=parser.OFPFlowStatsReply,
                 reply_multi=True)
     except BaseException:
         LOG.exception("Failed to get flows")
         return []
     if replies is None:
         LOG.error("No reply for get flows")
         return []
     flows = [body for reply in replies for body in reply.body]
     LOG.debug("Got the following flows: %s", flows)
     return flows
コード例 #11
0
 def _send_msg(self, msg, reply_cls=None, reply_multi=False):
     timeout_sec = cfg.CONF.OVS.of_request_timeout
     timeout = eventlet.Timeout(seconds=timeout_sec)
     try:
         result = ofctl_api.send_msg(self._app, msg, reply_cls, reply_multi)
     except ryu_exc.RyuException as e:
         m = _("ofctl request %(request)s error %(error)s") % {
             "request": msg,
             "error": e,
         }
         LOG.error(m)
         # NOTE(yamamoto): use RuntimeError for compat with ovs_lib
         raise RuntimeError(m)
     except eventlet.Timeout as e:
         with excutils.save_and_reraise_exception() as ctx:
             if e is timeout:
                 ctx.reraise = False
                 m = _("ofctl request %(request)s timed out") % {
                     "request": msg,
                 }
                 LOG.error(m)
                 # NOTE(yamamoto): use RuntimeError for compat with ovs_lib
                 raise RuntimeError(m)
     finally:
         timeout.cancel()
     LOG.debug("ofctl request %(request)s result %(result)s", {
         "request": msg,
         "result": result
     })
     return result
    def switch_features_handler(self, ev):
        datapath = ev.msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        # Tell the Switch to send the complete packet with packet_in messages
        req = parser.OFPSetConfig(datapath, ofproto.OFPC_FRAG_NORMAL, 2000)
        datapath.send_msg(req)
        # Request the Switch Configuration
        req = parser.OFPGetConfigRequest(datapath)
        datapath.send_msg(req)

        msg = parser.OFPPortDescStatsRequest(datapath=datapath)
        result = api.send_msg(self,
                              msg,
                              reply_cls=parser.OFPPortDescStatsReply,
                              reply_multi=True)
        if len(result) > 0:
            hub.spawn(self._init_topology, result[0].body)
            hub.spawn(self.create_rules_monitor_dhcp, datapath)
        #print(result)
        # install table-miss flow entry

        # We specify NO BUFFER to max_len of the output action due to
        # OVS bug. At this moment, if we specify a lesser number, e.g.,
        # 128, OVS will send Packet-In with invalid buffer_id and
        # truncated packet data. In that case, we cannot output packets
        # correctly.  The bug has been fixed in OVS v2.1.0.
        match = parser.OFPMatch()
        actions = [
            parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                   ofproto.OFPCML_NO_BUFFER)
        ]
        self.add_flow(datapath, 0, match, actions)
コード例 #13
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
	def aggregate_stats(self):
		datapath = self.datapath
		p = datapath.ofproto_parser
		tm = time.time()
		req = p.OFPAggregateStatsRequest(datapath)
		for msg in api.send_msg(self.app, req, reply_cls=p.OFPStatsReply, reply_multi=True):
			self.send(msg.body, req, tm)
コード例 #14
0
ファイル: ofswitch.py プロジェクト: cubeek/neutron
 def _send_msg(self, msg, reply_cls=None, reply_multi=False,
               active_bundle=None):
     timeout_sec = cfg.CONF.OVS.of_request_timeout
     timeout = eventlet.Timeout(seconds=timeout_sec)
     if active_bundle is not None:
         (dp, ofp, ofpp) = self._get_dp()
         msg = ofpp.ONFBundleAddMsg(dp, active_bundle['id'],
                                    active_bundle['bundle_flags'], msg, [])
     try:
         result = ofctl_api.send_msg(self._app, msg, reply_cls, reply_multi)
     except ryu_exc.RyuException as e:
         m = _("ofctl request %(request)s error %(error)s") % {
             "request": msg,
             "error": e,
         }
         LOG.error(m)
         # NOTE(yamamoto): use RuntimeError for compat with ovs_lib
         raise RuntimeError(m)
     except eventlet.Timeout as e:
         with excutils.save_and_reraise_exception() as ctx:
             if e is timeout:
                 ctx.reraise = False
                 m = _("ofctl request %(request)s timed out") % {
                     "request": msg,
                 }
                 LOG.error(m)
                 # NOTE(yamamoto): use RuntimeError for compat with ovs_lib
                 raise RuntimeError(m)
     finally:
         timeout.cancel()
     LOG.debug("ofctl request %(request)s result %(result)s",
               {"request": msg, "result": result})
     return result
コード例 #15
0
ファイル: ofswitch.py プロジェクト: davidcusatis/neutron
 def _send_msg(self, msg, reply_cls=None, reply_multi=False):
     timeout_sec = cfg.CONF.OVS.of_request_timeout
     timeout = eventlet.timeout.Timeout(seconds=timeout_sec)
     try:
         result = ofctl_api.send_msg(self._app, msg, reply_cls, reply_multi)
     except ryu_exc.RyuException as e:
         m = _LE("ofctl request %(request)s error %(error)s") % {
             "request": msg,
             "error": e,
         }
         LOG.error(m)
         # NOTE(yamamoto): use RuntimeError for compat with ovs_lib
         raise RuntimeError(m)
     except eventlet.timeout.Timeout as e:
         with excutils.save_and_reraise_exception() as ctx:
             if e is timeout:
                 ctx.reraise = False
                 m = _LE("ofctl request %(request)s timed out") % {
                     "request": msg,
                 }
                 LOG.error(m)
                 # NOTE(yamamoto): use RuntimeError for compat with ovs_lib
                 raise RuntimeError(m)
     finally:
         timeout.cancel()
     LOG.debug("ofctl request %(request)s result %(result)s",
               {"request": msg, "result": result})
     return result
コード例 #16
0
 def _send_msg(self, msg, reply_cls=None, reply_multi=False,
               active_bundle=None):
     timeout_sec = constants.OF_REQUEST_TIMEOUT
     timeout = eventlet.Timeout(seconds=timeout_sec)
     if active_bundle is not None:
         (dp, ofp, ofpp) = self._get_dp()
         msg = ofpp.ONFBundleAddMsg(dp, active_bundle['id'],
                                    active_bundle['bundle_flags'], msg, [])
     try:
         result = ofctl_api.send_msg(self._app, msg, reply_cls, reply_multi)
     except ryu_exc.RyuException as e:
         m = _("ofctl request %(request)s error %(error)s") % {
             "request": msg,
             "error": e,
         }
         LOG.error(m)
         # NOTE(yamamoto): use RuntimeError for compat with ovs_lib
         raise RuntimeError(m)
     except eventlet.Timeout as e:
         with excutils.save_and_reraise_exception() as ctx:
             if e is timeout:
                 ctx.reraise = False
                 m = "ofctl request %(request)s timed out" % {
                     "request": msg,
                 }
                 LOG.error(m)
                 # NOTE(yamamoto): use RuntimeError for compat with ovs_lib
                 raise RuntimeError(m)
     finally:
         timeout.cancel()
     LOG.debug("ofctl request %(request)s result %(result)s",
               {"request": msg, "result": result})
     return result
コード例 #17
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
	def port_stats(self):
		datapath = self.datapath
		p = datapath.ofproto_parser
		tm = time.time()
		req = p.OFPPortStatsRequest(datapath, flags=0, port_no=datapath.ofproto.OFPP_ANY)
		for msg in api.send_msg(self.app, req, reply_cls=p.OFPPortStatsReply, reply_multi=True):
			for b in msg.body:
				self.send(b, req, tm)
コード例 #18
0
 def _send_unknown_packet(self, msg, in_port, out_port):
     LOG.debug("unknown packet-out in-port %(in_port)s "
               "out-port %(out_port)s msg %(msg)s",
               {'in_port': in_port, 'out_port': out_port, 'msg': msg})
     datapath = msg.datapath
     ofp = datapath.ofproto
     ofpp = datapath.ofproto_parser
     data = None
     if msg.buffer_id == ofp.OFP_NO_BUFFER:
         data = msg.data
     actions = [ofpp.OFPActionOutput(port=out_port)]
     out = ofpp.OFPPacketOut(datapath=datapath,
                             buffer_id=msg.buffer_id,
                             in_port=in_port,
                             actions=actions,
                             data=data)
     ryu_api.send_msg(self.ryuapp, out)
コード例 #19
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
	def flow_stats(self):
		datapath = self.datapath
		p = datapath.ofproto_parser
		tm = time.time()
		req = p.OFPFlowStatsRequest(datapath)
		for msg in api.send_msg(self.app, req, reply_cls=p.OFPFlowStatsReply, reply_multi=True):
			for b in msg.body:
				self.send(b, req, tm)
コード例 #20
0
 def _get_ports(self, br):
     """Generate ports.Port instances for the given bridge."""
     datapath = br.datapath
     ofpp = datapath.ofproto_parser
     msg = ofpp.OFPPortDescStatsRequest(datapath=datapath)
     descs = ryu_api.send_msg(app=self.ryuapp, msg=msg, reply_cls=ofpp.OFPPortDescStatsReply, reply_multi=True)
     for d in descs:
         for p in d.body:
             yield ports.Port.from_ofp_port(p)
コード例 #21
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
	def queue_stats(self):
		datapath = self.datapath
		p = datapath.ofproto_parser
		tm = time.time()
		req = p.OFPQueueStatsRequest(datapath, 0,
			datapath.ofproto.OFPP_ALL,
			datapath.ofproto.OFPQ_ALL)
		for msg in api.send_msg(self.app, req, reply_cls=p.OFPQueueStatsReply, reply_multi=True):
			for b in msg.body:
				self.send(b, req, tm)
コード例 #22
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
 def aggregate_stats(self):
     datapath = self.datapath
     p = datapath.ofproto_parser
     tm = time.time()
     req = p.OFPAggregateStatsRequest(datapath)
     for msg in api.send_msg(self.app,
                             req,
                             reply_cls=p.OFPStatsReply,
                             reply_multi=True):
         self.send(msg.body, req, tm)
コード例 #23
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
	def aggregate_stats(self):
		datapath = self.datapath
		p = datapath.ofproto_parser
		tm = time.time()
		req = p.OFPAggregateStatsRequest(datapath, 0,
			datapath.ofproto_parser.OFPMatch(),
			0xff,
			datapath.ofproto.OFPP_NONE)
		for msg in api.send_msg(self.app, req, reply_cls=p.OFPAggregateStatsReply, reply_multi=True):
			for body in msg.body:
				self.send(body, req, tm)
コード例 #24
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
	def aggregate_stats(self):
		datapath = self.datapath
		p = datapath.ofproto_parser
		tm = time.time()
		req = p.OFPAggregateStatsRequest(datapath, 0,
			datapath.ofproto.OFPTT_ALL,
			datapath.ofproto.OFPP_ANY,
			datapath.ofproto.OFPG_ANY, 0, 0,
			datapath.ofproto_parser.OFPMatch())
		for msg in api.send_msg(self.app, req, reply_cls=p.OFPAggregateStatsReply, reply_multi=True):
			self.send(msg.body, req, tm)
コード例 #25
0
 def _get_ports(self, br):
     """Generate ports.Port instances for the given bridge."""
     datapath = br.datapath
     ofpp = datapath.ofproto_parser
     msg = ofpp.OFPPortDescStatsRequest(datapath=datapath)
     descs = ryu_api.send_msg(app=self.ryuapp, msg=msg,
                              reply_cls=ofpp.OFPPortDescStatsReply,
                              reply_multi=True)
     for d in descs:
         for p in d.body:
             yield ports.Port.from_ofp_port(p)
コード例 #26
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
 def port_stats(self):
     datapath = self.datapath
     p = datapath.ofproto_parser
     tm = time.time()
     req = p.OFPPortStatsRequest(datapath, 0, datapath.ofproto.OFPP_NONE)
     for msg in api.send_msg(self.app,
                             req,
                             reply_cls=p.OFPPortStatsReply,
                             reply_multi=True):
         for b in msg.body:
             self.send(b, req, tm)
コード例 #27
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
 def group_stats(self):
     datapath = self.datapath
     p = datapath.ofproto_parser
     tm = time.time()
     req = p.OFPGroupStatsRequest(datapath)
     for msg in api.send_msg(self.app,
                             req,
                             reply_cls=p.OFPStatsReply,
                             reply_multi=True):
         for b in msg.body:
             self.send(b, req, tm)
コード例 #28
0
ファイル: ryu_buf.py プロジェクト: hkwi/ryuapps
def send_msg(app, datapath, buf):
    '''
	send a binary openflow message
	@return same as ryu.app.ofctl.api.send_msg
	
	useful with ofpstr, for example
	
	class X(ryu.base.app_manager.RyuApp):
		@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
		def on_switch_ready(self, ev):
			rule="in_port=1,@apply,output=2"
			send_bin(self, ev.msg.datapath, ofpstr.ofp4.str2mod(rule))
	'''
    msg_cls = dict()
    stats_cls = dict()
    for name in dir(datapath.ofproto_parser):
        t = getattr(datapath.ofproto_parser, name)
        if type(t) == type and issubclass(t, MsgBase) and hasattr(
                t, "cls_msg_type"):
            if hasattr(t, "cls_stats_type"):
                stats_cls[name] = t
            else:
                msg_cls[name] = t

    phdr = struct.unpack_from("!BBHI", buf)

    reply_cls = None
    reply_multi = False
    for cls in stats_cls.values():
        if phdr[1] == cls.cls_msg_type:
            reply_multi = True
            break

    if reply_multi:
        stats_type = struct.unpack_from("!H", pmsg, 8)[0]
        for cls in stats_cls.values():
            if cls.cls_stats_type != stats_type:
                continue
            if cls.cls_msg_type == phdr[1]:
                continue
            reply_cls = cls
            break
    else:
        for name, req in msg_cls.items():
            if req.cls_msg_type == phdr[1]:
                rname = api_expect.get(name)
                if rname:
                    reply_cls = msg_cls[rname]

    return api.send_msg(app,
                        RawMsg(datapath, buf),
                        reply_cls=reply_cls,
                        reply_multi=reply_multi)
コード例 #29
0
 def _send_unknown_packet(self, msg, in_port, out_port):
     LOG.debug(
         "unknown packet-out in-port %(in_port)s "
         "out-port %(out_port)s msg %(msg)s", {
             'in_port': in_port,
             'out_port': out_port,
             'msg': msg
         })
     datapath = msg.datapath
     ofp = datapath.ofproto
     ofpp = datapath.ofproto_parser
     data = None
     if msg.buffer_id == ofp.OFP_NO_BUFFER:
         data = msg.data
     actions = [ofpp.OFPActionOutput(port=out_port)]
     out = ofpp.OFPPacketOut(datapath=datapath,
                             buffer_id=msg.buffer_id,
                             in_port=in_port,
                             actions=actions,
                             data=data)
     ryu_api.send_msg(self.ryuapp, out)
コード例 #30
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
 def aggregate_stats(self):
     datapath = self.datapath
     p = datapath.ofproto_parser
     tm = time.time()
     req = p.OFPAggregateStatsRequest(datapath, 0,
                                      datapath.ofproto_parser.OFPMatch(),
                                      0xff, datapath.ofproto.OFPP_NONE)
     for msg in api.send_msg(self.app,
                             req,
                             reply_cls=p.OFPAggregateStatsReply,
                             reply_multi=True):
         for body in msg.body:
             self.send(body, req, tm)
コード例 #31
0
ファイル: ryu_buf.py プロジェクト: hkwi/ryuapps
def send_msg(app, datapath, buf):
	'''
	send a binary openflow message
	@return same as ryu.app.ofctl.api.send_msg
	
	useful with ofpstr, for example
	
	class X(ryu.base.app_manager.RyuApp):
		@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
		def on_switch_ready(self, ev):
			rule="in_port=1,@apply,output=2"
			send_bin(self, ev.msg.datapath, ofpstr.ofp4.str2mod(rule))
	'''
	msg_cls = dict()
	stats_cls = dict()
	for name in dir(datapath.ofproto_parser):
		t = getattr(datapath.ofproto_parser, name)
		if type(t)==type and issubclass(t, MsgBase) and hasattr(t, "cls_msg_type"):
			if hasattr(t, "cls_stats_type"):
				stats_cls[name] = t
			else:
				msg_cls[name] = t
	
	phdr = struct.unpack_from("!BBHI", buf)
	
	reply_cls = None
	reply_multi = False
	for cls in stats_cls.values():
		if phdr[1] == cls.cls_msg_type:
			reply_multi = True
			break
	
	if reply_multi:
		stats_type = struct.unpack_from("!H", pmsg, 8)[0]
		for cls in stats_cls.values():
			if cls.cls_stats_type != stats_type:
				continue
			if cls.cls_msg_type == phdr[1]:
				continue
			reply_cls = cls
			break
	else:
		for name, req in msg_cls.items():
			if req.cls_msg_type == phdr[1]:
				rname = api_expect.get(name)
				if rname:
					reply_cls = msg_cls[rname]
	
	return api.send_msg(app, RawMsg(datapath, buf),
			reply_cls=reply_cls,
			reply_multi=reply_multi)
コード例 #32
0
ファイル: ryu_logstash.py プロジェクト: hkwi/ryuapps
 def aggregate_stats(self):
     datapath = self.datapath
     p = datapath.ofproto_parser
     tm = time.time()
     req = p.OFPAggregateStatsRequest(datapath, 0,
                                      datapath.ofproto.OFPTT_ALL,
                                      datapath.ofproto.OFPP_ANY,
                                      datapath.ofproto.OFPG_ANY, 0, 0,
                                      datapath.ofproto_parser.OFPMatch())
     for msg in api.send_msg(self.app,
                             req,
                             reply_cls=p.OFPAggregateStatsReply,
                             reply_multi=True):
         self.send(msg.body, req, tm)
コード例 #33
0
    def get_stats(self, cookie: int = 0, cookie_mask: int = 0):
        """
        Use Ryu API to send a stats request containing cookie and cookie mask, retrieve a response and
        convert to a Rule Record Table and remove old flows
        """
        if not self._datapath:
            self.logger.error(
                "Could not initialize datapath for stats retrieval")
            return RuleRecordTable()
        parser = self._datapath.ofproto_parser
        message = parser.OFPFlowStatsRequest(
            datapath=self._datapath,
            table_id=self.tbl_num,
            cookie=cookie,
            cookie_mask=cookie_mask,
        )
        try:
            response = ofctl_api.send_msg(
                self,
                message,
                reply_cls=parser.OFPFlowStatsReply,
                reply_multi=True,
            )
            if not response:
                self.logger.error(
                    "No rule records match the specified cookie and cookie mask"
                )
                return RuleRecordTable()

            aggregated_msgs = []
            for r in response:
                aggregated_msgs += r.body

            usage = self._get_usage_from_flow_stat(aggregated_msgs)
            self.loop.call_soon_threadsafe(self._delete_old_flows,
                                           usage.values())
            record_table = RuleRecordTable(
                records=usage.values(),
                epoch=global_epoch,
            )
            return record_table
        except (InvalidDatapath, OFError, UnexpectedMultiReply):
            self.logger.error(
                "Could not obtain rule records due to either InvalidDatapath, OFError or UnexpectedMultiReply"
            )
            return RuleRecordTable()
コード例 #34
0
ファイル: ofswitch.py プロジェクト: FrankDuan/df_code
 def _send_msg(self, msg, reply_cls=None, reply_multi=False):
     timeout_sec = 20  # TODO(heshan) should be configured in cfg file
     timeout = eventlet.timeout.Timeout(seconds=timeout_sec)
     result = None
     try:
         result = ofctl_api.send_msg(self._app, msg, reply_cls, reply_multi)
     except ryu_exc.RyuException as e:
         m = _LE("ofctl request %(request)s error %(error)s") % {
                 "request": msg,
                 "error": e,
         }
         LOG.error(_LE("exception occurred, %s"), m)
     except eventlet.timeout.Timeout as e:
         LOG.error(_LE("exception occurred, %s"), e)
     finally:
         timeout.cancel()
     LOG.debug("ofctl request %(request)s result %(result)s",
               {"request": msg, "result": result})
     return result
コード例 #35
0
 def _send_msg(self, msg, reply_cls=None, reply_multi=False):
     timeout_sec = 20  # TODO(heshan) should be configured in cfg file
     timeout = eventlet.timeout.Timeout(seconds=timeout_sec)
     result = None
     try:
         result = ofctl_api.send_msg(self._app, msg, reply_cls, reply_multi)
     except ryu_exc.RyuException as e:
         m = _LE("ofctl request %(request)s error %(error)s") % {
             "request": msg,
             "error": e,
         }
         LOG.error(_LE("exception occurred, %s"), m)
     except eventlet.timeout.Timeout as e:
         LOG.error(_LE("exception occurred, %s"), e)
     finally:
         timeout.cancel()
     LOG.debug("ofctl request %(request)s result %(result)s", {
         "request": msg,
         "result": result
     })
     return result
コード例 #36
0
 def _send_msg(self, msg):
     return ofctl_api.send_msg(self._app, msg)
コード例 #37
0
    def handle_datapath(self, ev):
        if not ev.enter or self.done:
            print('Skipping')
            return
        self.done = True
        dp = ev.dp
        parser = dp.ofproto_parser

        print('Switch connected')
        print('Collecting')

        # Request switch features XXX TODO FAILING
        try:
            msg = parser.OFPFeaturesRequest(dp)
            res = api.send_msg(self, msg, reply_cls=parser.OFPSwitchFeatures)
            self.collection['switch_features'] = res.to_json() if res else res
            print('Switch Features')
        except Exception as e:
            print("Exception collecting Switch Features")
            print(e)

        # Request config - non multipart
        try:
            msg = parser.OFPGetConfigRequest(dp)
            res = api.send_msg(self, msg, reply_cls=parser.OFPGetConfigReply)
            self.collection['config'] = ({
                "flags": res.flags,
                "miss_send_len": res.miss_send_len
            } if res else res)
            print('Switch Config')
        except Exception as e:
            print("Exception collecting Switch Config")
            print(e)

        # Request switch description - multipart single item
        try:
            msg = parser.OFPDescStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPDescStatsReply,
                               reply_multi=True)
            if len(res) != 1:
                raise Exception(('Expecting only a single response from'
                                 ' switch description', res))
            self.collection['desc'] = res[0].body
            print('Switch Description')
        except Exception as e:
            print("Exception collecting Switch Descripton")
            print(e)

        # Request all stats from all tables - multipart list
        try:
            msg = parser.OFPFlowStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPFlowStatsReply,
                               reply_multi=True)
            l = [stat for stats in res for stat in stats.body]
            self.collection['flow_stats'] = l
            print('Flows Stats')
        except Exception as e:
            print("Exception collecting Flow Stats")
            print(e)

        # Request table stats - multipart list
        try:
            msg = parser.OFPTableStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPTableStatsReply,
                               reply_multi=True)
            l = [table for tables in res for table in tables.body]
            self.collection['table_stats'] = l
            print('Table Stats')
        except Exception as e:
            print("Exception collecting Table Stats")
            print(e)

        # Request port stats - multipart list
        try:
            msg = parser.OFPPortStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPPortStatsReply,
                               reply_multi=True)
            l = [port for ports in res for port in ports.body]
            self.collection['port_stats'] = l
            print('Port Stats')
        except Exception as e:
            print("Exception collecting Port Stats")
            print(e)

        # Request port descriptions - multipart list
        try:
            msg = parser.OFPPortDescStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPPortDescStatsReply,
                               reply_multi=True)
            l = [port for ports in res for port in ports.body]
            self.collection['port_desc'] = l
            print('Port Description')
        except Exception as e:
            print("Exception collecting Port Description")
            print(e)

        # Request queue stats - mulitpart list
        try:
            msg = parser.OFPQueueStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPQueueStatsReply,
                               reply_multi=True)
            l = [queue for queues in res for queue in queues.body]
            self.collection['queue_stats'] = l
            print('Queue Stats')
        except Exception as e:
            print("Exception collecting Queue Stats")
            print(e)

        # Request group stats - multipart list
        try:
            msg = parser.OFPGroupStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPGroupStatsReply,
                               reply_multi=True)
            l = [group for groups in res for group in groups.body]
            self.collection['group_stats'] = l
            print('Group Stats')
        except Exception as e:
            print("Exception collecting Group Stats")
            print(e)

        # Request group desc - multipart list
        try:
            msg = parser.OFPGroupDescStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPGroupDescStatsReply,
                               reply_multi=True)
            l = [group for groups in res for group in groups.body]
            self.collection['group_desc'] = l
            print('Group Description')
        except Exception as e:
            print("Exception collecting Group Description")
            print(e)

        # Request group features - multipart single item
        try:
            msg = parser.OFPGroupFeaturesStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPGroupFeaturesStatsReply,
                               reply_multi=True)
            if len(res) != 1:
                raise Exception(('Expecting only a single response from'
                                 ' group features', res))
            self.collection['group_features'] = res[0].body
            print('Group Features')
        except Exception as e:
            print("Exception collecting Group Features")
            print(e)

        # Request meter stats - multipart list
        try:
            msg = parser.OFPMeterStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPMeterStatsReply,
                               reply_multi=True)
            l = [meter for meters in res for meter in meters.body]
            self.collection['meter_stats'] = l
            print('Meter Stats')
        except Exception as e:
            print("Exception collecting Meter Stats")
            print(e)

        # Request meter config - multipart list
        try:
            msg = parser.OFPMeterConfigStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPMeterConfigStatsReply,
                               reply_multi=True)
            l = [meter for meters in res for meter in meters.body]
            self.collection['meter_config'] = l
            print('Meter Config')
        except Exception as e:
            print("Exception collecting Meter Config")
            print(e)

        # Request meter features - single item
        try:
            msg = parser.OFPMeterFeaturesStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPMeterFeaturesStatsReply,
                               reply_multi=True)
            if len(res) != 1:
                raise Exception(('Expecting only a single response from'
                                 ' meter features', res))
            self.collection['meter_features'] = res[0].body
            print('Meter Features')
        except Exception as e:
            print("Exception collecting Meter Features")
            print(e)

        # Request table features, this can be very large
        try:
            msg = parser.OFPTableFeaturesStatsRequest(dp)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPTableFeaturesStatsReply,
                               reply_multi=True)
            l = [table for tables in res for table in tables.body]
            self.collection['table_features'] = l
            print('Table Features')
        except Exception as e:
            print("Exception collecting Table Features")
            print(e)

        # Request queue config (this is done on a per port basis) so
        # querying all does not work so well.
        # Not multipart!?
        try:
            msg = parser.OFPQueueGetConfigRequest(dp, ofproto_v1_3.OFPP_ANY)
            res = api.send_msg(self,
                               msg,
                               reply_cls=parser.OFPQueueGetConfigReply)
            self.collection['queue_config'] = res.queues if res else res
            print('Queue Config')
        except Exception as e:
            print("Exception collecting Queue Config")
            print(e)

        pickle.dump(self.collection, open("switch_state.pickle", "wb"))
        print('Switch dumped successfully')
コード例 #38
0
ファイル: controller.py プロジェクト: uchicago-cs/chirouter
    def switch_features_handler(self, ev):
        datapath = ev.msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        dpid = datapath.id
        topo_node = self.topology.nodes.get(dpid)

        if topo_node is None:
            self.logger.error(
                f"Received information about unknown switch id={dpid}")
            return

        self.logger.info(f"Received information about switch id={dpid}")

        if isinstance(topo_node, topo.Router):
            self.logger.info(f"Switch {dpid} is a chirouter-managed router")
            self.router_dpids.add(dpid)

            # Request information about the router's ports
            msg = parser.OFPPortDescStatsRequest(datapath=datapath)
            result = ofctl_api.send_msg(self,
                                        msg,
                                        reply_cls=parser.OFPPortDescStatsReply,
                                        reply_multi=True)
            for reply in result:
                for port in reply.body:
                    port_name = port.name.decode('UTF-8')

                    if not "-" in port_name:
                        continue

                    node_name, iface_name = port_name.split("-")

                    if iface_name in topo_node.interfaces:
                        self.logger.info(f"Processing port {port_name}")
                        iface = topo_node.interfaces[iface_name]
                        self.of2topo[(dpid, port.port_no)] = iface
                        self.topo2of[iface] = (dpid, port.port_no)
                        iface.hwaddr = str(port.hw_addr)

            if len(self.router_dpids) == self.topology.num_routers:
                self.logger.info(
                    "All routers accounted for. Connecting to chirouter...")

                self.client.connect()

                message_thread = threading.Thread(target=self.process_messages)
                message_thread.daemon = True
                message_thread.start()

        elif isinstance(topo_node, topo.Switch):
            self.logger.info(f"Switch {dpid} is a regular switch")
            self.switch_dpids.add(dpid)

        print()

        # Install table-miss flow entry (so frames are sent to
        # the controller for processing)
        match = parser.OFPMatch()
        actions = [
            parser.OFPActionOutput(ofproto.OFPP_CONTROLLER,
                                   ofproto.OFPCML_NO_BUFFER)
        ]
        self.add_flow(datapath, 0, match, actions)
コード例 #39
0
ファイル: ryu_rproxy.py プロジェクト: hkwi/ryuapps
    def rhandle(self, dpid, sock):
        datapath = self.dpset.get(dpid)
        msg_cls = dict()
        stats_cls = dict()
        for name in dir(datapath.ofproto_parser):
            t = getattr(datapath.ofproto_parser, name)
            if type(t) == type and issubclass(t, MsgBase) and hasattr(
                    t, "cls_msg_type"):
                if hasattr(t, "cls_stats_type"):
                    stats_cls[name] = t
                else:
                    msg_cls[name] = t

        barrier = msg_cls.get("OFPBarrierRequest")

        xid = 0
        sock.send(struct.pack("!BBHI", datapath.ofproto.OFP_VERSION, 0, 8, 1))
        while self.accepting_sockets[dpid]:
            pmsg = sock.recv(8)
            if not pmsg:
                break
            phdr = struct.unpack("!BBHI", pmsg)
            if phdr[2] > 8:
                pmsg = pmsg + sock.recv(phdr[2] - 8)

            if phdr[1] == 0:
                continue  # skip hello

            if barrier and barrier.cls_msg_type == phdr[1]:
                # api wants to handle barrier
                rmsg = struct.pack("!BBHI", phdr[0],
                                   msg_cls["OFPBarrierReply"].cls_msg_type, 8,
                                   phdr[3])
                sock.send(rmsg)
                continue

            reply_cls = None
            reply_multi = False
            for cls in stats_cls.values():
                if phdr[1] == cls.cls_msg_type:
                    reply_multi = True
                    break

            if reply_multi:
                stats_type = struct.unpack_from("!H", pmsg, 8)[0]
                for cls in stats_cls.values():
                    if cls.cls_stats_type != stats_type:
                        continue
                    if cls.cls_msg_type == phdr[1]:
                        continue
                    reply_cls = cls
                    break
            else:
                for name, req in msg_cls.items():
                    if req.cls_msg_type == phdr[1]:
                        rname = api_expect.get(name)
                        if rname:
                            reply_cls = msg_cls[rname]

            rmsgs = api.send_msg(self,
                                 RawMsg(self.dpset.get(dpid), pmsg),
                                 reply_cls=reply_cls,
                                 reply_multi=reply_multi)
            if reply_multi:
                for r in rmsgs:
                    h = struct.unpack_from("!BBHI", r.buf)
                    sock.send(
                        struct.pack("!BBHI", h[0], h[1], h[2], phdr[3]) +
                        r.buf[8:])
            elif rmsgs:
                h = struct.unpack_from("!BBHI", rmsgs.buf)
                sock.send(
                    struct.pack("!BBHI", h[0], h[1], h[2], phdr[3]) +
                    rmsgs.buf[8:])

        sock.close()
コード例 #40
0
ファイル: ryu_rproxy.py プロジェクト: hkwi/ryuapps
	def rhandle(self, dpid, sock):
		datapath = self.dpset.get(dpid)
		msg_cls = dict()
		stats_cls = dict()
		for name in dir(datapath.ofproto_parser):
			t = getattr(datapath.ofproto_parser, name)
			if type(t)==type and issubclass(t, MsgBase) and hasattr(t, "cls_msg_type"):
				if hasattr(t, "cls_stats_type"):
					stats_cls[name] = t
				else:
					msg_cls[name] = t
		
		barrier = msg_cls.get("OFPBarrierRequest")
		
		xid = 0
		sock.send(struct.pack("!BBHI", datapath.ofproto.OFP_VERSION, 0, 8, 1))
		while self.accepting_sockets[dpid]:
			pmsg = sock.recv(8)
			if not pmsg:
				break
			phdr = struct.unpack("!BBHI", pmsg)
			if phdr[2] > 8:
				pmsg = pmsg + sock.recv(phdr[2]-8)
			
			if phdr[1] == 0:
				continue # skip hello
			
			if barrier and barrier.cls_msg_type==phdr[1]:
				# api wants to handle barrier
				rmsg = struct.pack("!BBHI", phdr[0], msg_cls["OFPBarrierReply"].cls_msg_type, 8, phdr[3])
				sock.send(rmsg)
				continue
			
			reply_cls = None
			reply_multi = False
			for cls in stats_cls.values():
				if phdr[1] == cls.cls_msg_type:
					reply_multi = True
					break
			
			if reply_multi:
				stats_type = struct.unpack_from("!H", pmsg, 8)[0]
				for cls in stats_cls.values():
					if cls.cls_stats_type != stats_type:
						continue
					if cls.cls_msg_type == phdr[1]:
						continue
					reply_cls = cls
					break
			else:
				for name, req in msg_cls.items():
					if req.cls_msg_type == phdr[1]:
						rname = api_expect.get(name)
						if rname:
							reply_cls = msg_cls[rname]
			
			rmsgs = api.send_msg(self, RawMsg(self.dpset.get(dpid), pmsg),
					reply_cls=reply_cls,
					reply_multi=reply_multi)
			if reply_multi:
				for r in rmsgs:
					h = struct.unpack_from("!BBHI", r.buf)
					sock.send(struct.pack("!BBHI", h[0], h[1], h[2], phdr[3])+r.buf[8:])
			elif rmsgs:
				h = struct.unpack_from("!BBHI", rmsgs.buf)
				sock.send(struct.pack("!BBHI", h[0], h[1], h[2], phdr[3])+rmsgs.buf[8:])
		
		sock.close()
コード例 #41
0
ファイル: ofswitch.py プロジェクト: CiscoSystems/neutron
 def _send_msg(self, msg):
     return ofctl_api.send_msg(self._app, msg)