Hi,

Please don't drop the mailing list of Ryu-devel.

On 2015年01月21日 18:27, 林彥宏 wrote:
> Thanks your helps
> But I don't know which function I have to add the code you told me.
> When it run to "flow.match['tcp_src']", it will show me an error.
> Could you send me a complete code?

OK.
Please check the attached files.

> 
> Thank you a lot.
> 
> 2015-01-15 14:01 GMT+08:00 Minoru TAKAHASHI <[email protected] 
> <mailto:[email protected]>>:
> 
>     Hi,
> 
>     On 2015年01月09日 18:15, 林彥宏 wrote:
>     > Hi,
>     >
>     > We got a problem to ask you.
>     >
>     > If we want to know which port that data comes in, where can we find it?
>     > Is it wrapped in ev?
>     >
>     > We tested SimpleMonitor.py and simple_switch_13.py using iperf.
>     > We can see ip and port while running simple_switch_13.py.
>     > The output is like ip=10.0.0.1 port=5001.
>     >
>     > However, the result of ip and port in SimpleMonitor.py is not what we 
> want.
>     > We also use iperf to throw some data to a specific ip and port.
>     > We print out body, then we get  flow information inside body.
>     > The outcome of ip is correct, but port is something like 1, 2, or 3, 
> seem like its number.
>     > Is it possible to get the real port in SimpleMonitor.py?
>     > Like http is 80, HTTPS is 8080.
> 
>     Information that simple monitor to get is the flow statistics and port 
> statistics.
>     Details are described in the following.
> 
>     OFSpec1.3.4
>       7.3.5.6 Port Statistics
>       7.3.5.2 Individual Flow Statistics
> 
>     These statistics do not include transfer packet own information 
> (TCP/IP/ETH...).
> 
>     > We are making a monitor that can track traffic on http, ftp and bt 
> three ports.
>     > Can SImpleMonitor do this job for us? Or is there any better 
> suggestions?
> 
>     Just an idea, if you want to track a packet of TCP_SRC=5001/8080,
>     and Why not try adding the following code.
>     (Sorry, this code is quick and dirty.)
> 
>     @@ -98,6 +98,12 @@ class SimpleSwitch13(app_manager.RyuApp):
> 
>              # install a flow to avoid packet_in next time
>              if out_port != ofproto.OFPP_FLOOD:
>     +
>     +            tcp_port = [5001,8080]
>     +            for port in tcp_port:
>     +                match = parser.OFPMatch(in_port=in_port, eth_dst=dst, 
> tcp_src=port, ip_proto=6, eth_type=2048)
>     +                self.add_flow(datapath, 2, match, actions)
>     +
>                  match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
> 
>     @@ -63,6 +63,22 @@ class SimpleMonitor(simple_switch_13.SimpleSwitch13):
>                                   stat.instructions[0].actions[0].port,
> 
>                                   stat.packet_count, stat.byte_count)
> 
> 
> 
>     +        self.logger.info <http://self.logger.info>('datapath         '
> 
>     +                         'tcp-src  in-port  eth-dst           '
> 
>     +                         'out-port packets  bytes')
> 
>     +        self.logger.info <http://self.logger.info>('---------------- '
> 
>     +                         '-------- -------- ----------------- '
> 
>     +                         '-------- -------- --------')
> 
>     +        for stat in sorted([flow for flow in body if flow.priority == 2],
> 
>     +                           key=lambda flow: (flow.match['tcp_src'],
> 
>     +                                             flow.match['in_port'],
> 
>     +                                             flow.match['eth_dst'])):
> 
>     +            self.logger.info <http://self.logger.info>('%016x %8d %8x 
> %17s %8x %8d %8d',
> 
>     +                             ev.msg.datapath.id 
> <http://ev.msg.datapath.id>,
> 
>     +                             stat.match['tcp_src'], 
> 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)
> 
>     Execution results are as follows.
> 
>     $ ryu-manager ./ryu/app/SimpleMonitor.py
>     ...
> 
>     datapath         in-port  eth-dst           out-port packets  bytes
>     ---------------- -------- ----------------- -------- -------- --------
>     0000000000000001        1 00:00:00:00:00:02        2        4      168
>     0000000000000001        2 00:00:00:00:00:01        1  1208886 56447642468
>     datapath         tcp-src  in-port  eth-dst           out-port packets  
> bytes
>     ---------------- -------- -------- ----------------- -------- -------- 
> --------
>     0000000000000001     5001        1 00:00:00:00:00:02        2   582162 
> 38491340
>     0000000000000001     5001        2 00:00:00:00:00:01        1        0    
>     0
>     0000000000000001     8080        1 00:00:00:00:00:02        2        0    
>     0
>     0000000000000001     8080        2 00:00:00:00:00:01        1        0    
>     0
>     ....
> 
> 
>     Thanks
> 
>     >
>     > Code and screenshots are attached.
>     >
>     > thanks for your help!
>     >
>     > Best regards,
>     > David Lin
>     >
>     >
>     > 
> ------------------------------------------------------------------------------
>     > Dive into the World of Parallel Programming! The Go Parallel Website,
>     > sponsored by Intel and developed in partnership with Slashdot Media, is 
> your
>     > hub for all things parallel software development, from weekly thought
>     > leadership blogs to news, videos, case studies, tutorials and more. 
> Take a
>     > look and join the conversation now. http://goparallel.sourceforge.net
>     >
>     >
>     >
>     > _______________________________________________
>     > Ryu-devel mailing list
>     > [email protected] <mailto:[email protected]>
>     > https://lists.sourceforge.net/lists/listinfo/ryu-devel
>     >
> 
> 
from operator import attrgetter

from ryu.app import simple_switch_13
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 SimpleMonitor(simple_switch_13.SimpleSwitch13):

    def __init__(self, *args, **kwargs):
        super(SimpleMonitor, 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 not datapath.id in self.datapaths:
                self.logger.debug('register datapath: %016x', datapath.id)
                self.datapaths[datapath.id] = datapath
        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)

        self.logger.info('datapath         '
                         'tcp-src  in-port  eth-dst           '
                         'out-port packets  bytes')
        self.logger.info('---------------- '
                         '-------- -------- ----------------- '
                         '-------- -------- --------')
        for stat in sorted([flow for flow in body if flow.priority == 2],
                           key=lambda flow: (flow.match['tcp_src'],
                                             flow.match['in_port'],
                                             flow.match['eth_dst'])):
            self.logger.info('%016x %8d %8x %17s %8x %8d %8d',
                             ev.msg.datapath.id,
                             stat.match['tcp_src'], 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)
# Copyright (C) 2011 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 ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.ofproto import ofproto_v1_3
from ryu.lib.packet import packet
from ryu.lib.packet import ethernet


class SimpleSwitch13(app_manager.RyuApp):
    OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]

    def __init__(self, *args, **kwargs):
        super(SimpleSwitch13, self).__init__(*args, **kwargs)
        self.mac_to_port = {}

    @set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
    def switch_features_handler(self, ev):
        datapath = ev.msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        # 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)

    def add_flow(self, datapath, priority, match, actions, buffer_id=None):
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        inst = [parser.OFPInstructionActions(ofproto.OFPIT_APPLY_ACTIONS,
                                             actions)]
        if buffer_id:
            mod = parser.OFPFlowMod(datapath=datapath, buffer_id=buffer_id,
                                    priority=priority, match=match,
                                    instructions=inst)
        else:
            mod = parser.OFPFlowMod(datapath=datapath, priority=priority,
                                    match=match, instructions=inst)
        datapath.send_msg(mod)

    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
    def _packet_in_handler(self, ev):
        # If you hit this you might want to increase
        # the "miss_send_length" of your switch
        if ev.msg.msg_len < ev.msg.total_len:
            self.logger.debug("packet truncated: only %s of %s bytes",
                              ev.msg.msg_len, ev.msg.total_len)
        msg = ev.msg
        datapath = msg.datapath
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        in_port = msg.match['in_port']

        pkt = packet.Packet(msg.data)
        eth = pkt.get_protocols(ethernet.ethernet)[0]

        dst = eth.dst
        src = eth.src

        dpid = datapath.id
        self.mac_to_port.setdefault(dpid, {})

        self.logger.info("packet in %s %s %s %s", dpid, src, dst, in_port)

        # learn a mac address to avoid FLOOD next time.
        self.mac_to_port[dpid][src] = in_port

        if dst in self.mac_to_port[dpid]:
            out_port = self.mac_to_port[dpid][dst]
        else:
            out_port = ofproto.OFPP_FLOOD

        actions = [parser.OFPActionOutput(out_port)]

        # install a flow to avoid packet_in next time
        if out_port != ofproto.OFPP_FLOOD:

            tcp_port = [5001,8080]
            for port in tcp_port:
                match = parser.OFPMatch(in_port=in_port, eth_dst=dst, tcp_src=port, ip_proto=6, eth_type=2048)
                self.add_flow(datapath, 2, match, actions)

            match = parser.OFPMatch(in_port=in_port, eth_dst=dst)
            # verify if we have a valid buffer_id, if yes avoid to send both
            # flow_mod & packet_out
            if msg.buffer_id != ofproto.OFP_NO_BUFFER:
                self.add_flow(datapath, 1, match, actions, msg.buffer_id)
                return
            else:
                self.add_flow(datapath, 1, match, actions)
        data = None
        if msg.buffer_id == ofproto.OFP_NO_BUFFER:
            data = msg.data

        out = parser.OFPPacketOut(datapath=datapath, buffer_id=msg.buffer_id,
                                  in_port=in_port, actions=actions, data=data)
        datapath.send_msg(out)
------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to