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