Hi,

I am trying to use flow monitoring feature from OF 1.4. I see that I can
configure OVS successful to do flow monitoring via ovs-ofctl commands as
follows:

root@mininet:/setup# ovs-ofctl monitor s1 watch:\!initial
NXST_FLOW_MONITOR reply (xid=0x4):
NXST_FLOW_MONITOR reply (xid=0x0):
 event=ADDED table=1 cookie=0xa in_port="s1-eth1" actions=resubmit(,2)
NXST_FLOW_MONITOR reply (xid=0x0):
 event=DELETED reason=delete table=1 cookie=0xa in_port="s1-eth1"
actions=resubmit(,2)

And I could see the events properly.

Now I would like to extend ryu to do the same. So, I
took SimpleMonitor13.py and modified it to be derived from
simple_switch_14.SimpleSwitch14. And then in _state_change_handler function
added a call to do:
                for dp in self.datapaths.values():
                    self.send_flow_monitor_request(dp)

send_flow_monitor_request() is the example code as provided documentation
    def send_flow_monitor_request(self, datapath):
        ofp = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        monitor_flags = [ofp.OFPFMF_INITIAL, ofp.OFPFMF_ONLY_OWN]
        match = ofp_parser.OFPMatch(in_port=1)
        req = ofp_parser.OFPFlowMonitorRequest(datapath, 0, 10000,
                                               ofp.OFPP_ANY, ofp.OFPG_ANY,
                                               monitor_flags,
                                               ofp.OFPTT_ALL,
                                               ofp.OFPFMC_ADD, match)
        datapath.send_msg(req)

I see following error:

==========
SimpleMonitor14: Exception occurred during handler processing. Backtrace
from offending handler [_state_change_handler] servicing event
[EventOFPStateChange] follows.
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/dist-packages/ryu/base/app_manager.py",
line 290, in _event_loop
    handler(ev)
  File "/Users/vdasari/Developer/ryu/ryu/app/simple_monitor_13.py", line
41, in _state_change_handler
    self.send_flow_monitor_request(dp)
  File "/Users/vdasari/Developer/ryu/ryu/app/simple_monitor_13.py", line
110, in send_flow_monitor_request
    datapath.send_msg(req)
  File
"/usr/local/lib/python2.7/dist-packages/ryu/controller/controller.py", line
344, in send_msg
    msg.serialize()
  File
"/usr/local/lib/python2.7/dist-packages/ryu/ofproto/ofproto_parser.py",
line 220, in serialize
    self._serialize_body()
  File
"/usr/local/lib/python2.7/dist-packages/ryu/ofproto/ofproto_v1_4_parser.py",
line 1450, in _serialize_body
    self._serialize_stats_body()
  File
"/usr/local/lib/python2.7/dist-packages/ryu/ofproto/ofproto_v1_4_parser.py",
line 3171, in _serialize_stats_body
    self.monitor_flags, self.table_id, self.command)
  File "/usr/local/lib/python2.7/dist-packages/ryu/lib/pack_utils.py", line
25, in msg_pack_into
    struct.pack_into(fmt, buf, offset, *args)
error: cannot convert argument to integer
==========

Can you help me what is wrong with code? I am attaching the file as well.

Thanks
-Vasu

*Vasu Dasari*
# Copyright (C) 2016 Nippon Telegraph and Telephone Corporation.
#
# 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.

from operator import attrgetter

from ryu.app import simple_switch_14
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, DEAD_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.lib import hub


class SimpleMonitor14(simple_switch_14.SimpleSwitch14):

    def __init__(self, *args, **kwargs):
        super(SimpleMonitor14, self).__init__(*args, **kwargs)
        self.datapaths = {}
        self.monitor_thread = hub.spawn(self._monitor)

    @set_ev_cls(ofp_event.EventOFPStateChange,
                [MAIN_DISPATCHER, DEAD_DISPATCHER])
    def _state_change_handler(self, ev):
        datapath = ev.datapath
        if ev.state == MAIN_DISPATCHER:
            if datapath.id not in self.datapaths:
                self.logger.info('register datapath: %016x', datapath.id)
                self.datapaths[datapath.id] = datapath
                for dp in self.datapaths.values():
                    self.send_flow_monitor_request(dp)
        elif ev.state == DEAD_DISPATCHER:
            if datapath.id in self.datapaths:
                self.logger.debug('unregister datapath: %016x', datapath.id)
                del self.datapaths[datapath.id]

    def _monitor(self):
        while True:
            for dp in self.datapaths.values():
                self._request_stats(dp)
            hub.sleep(10)

    def _request_stats(self, datapath):
        self.logger.debug('send stats request: %016x', datapath.id)
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        req = parser.OFPFlowStatsRequest(datapath)
        datapath.send_msg(req)

        req = parser.OFPPortStatsRequest(datapath, 0, ofproto.OFPP_ANY)
        datapath.send_msg(req)

    @set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER)
    def _flow_stats_reply_handler(self, ev):
        body = ev.msg.body

        self.logger.info('datapath         '
                         'in-port  eth-dst           '
                         'out-port packets  bytes')
        self.logger.info('---------------- '
                         '-------- ----------------- '
                         '-------- -------- --------')
        for stat in sorted([flow for flow in body if flow.priority == 1],
                           key=lambda flow: (flow.match['in_port'],
                                             flow.match['eth_dst'])):
            self.logger.info('%016x %8x %17s %8x %8d %8d',
                             ev.msg.datapath.id,
                             stat.match['in_port'], stat.match['eth_dst'],
                             stat.instructions[0].actions[0].port,
                             stat.packet_count, stat.byte_count)

    @set_ev_cls(ofp_event.EventOFPPortStatsReply, MAIN_DISPATCHER)
    def _port_stats_reply_handler(self, ev):
        body = ev.msg.body

        self.logger.info('datapath         port     '
                         'rx-pkts  rx-bytes rx-error '
                         'tx-pkts  tx-bytes tx-error')
        self.logger.info('---------------- -------- '
                         '-------- -------- -------- '
                         '-------- -------- --------')
        for stat in sorted(body, key=attrgetter('port_no')):
            self.logger.info('%016x %8x %8d %8d %8d %8d %8d %8d',
                             ev.msg.datapath.id, stat.port_no,
                             stat.rx_packets, stat.rx_bytes, stat.rx_errors,
                             stat.tx_packets, stat.tx_bytes, stat.tx_errors)

    def send_flow_monitor_request(self, datapath):
        ofp = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        monitor_flags = [ofp.OFPFMF_INITIAL, ofp.OFPFMF_ONLY_OWN]
        match = ofp_parser.OFPMatch(in_port=1)
        req = ofp_parser.OFPFlowMonitorRequest(datapath, 0, 10000,
                                               ofp.OFPP_ANY, ofp.OFPG_ANY,
                                               monitor_flags,
                                               ofp.OFPTT_ALL,
                                               ofp.OFPFMC_ADD, match)
        datapath.send_msg(req)
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to