Discussion:
[Ryu-devel] Modify simple switch app to show flow stats - IP TCP/UDP Protocols
Boyan Mladenov
2017-07-25 00:41:26 UTC
Permalink
Dear, all

I am trying to modify the simple_switch_13.py so that i can extract and
save flow statistics about the IP src/dst TCP/UDP sport/dport. I got
familiar with the simple switch and the traffic monitor from where i get
the function for continuously showing and the data. Also the functions
about flow stats request and reply.

I am having problems creating the match fields in order to modify the flow
table to show ip_src, ip_dst, tcp_sport, tcp_dport, protocols.
I have to create each single line (flow) in the table, In simple switch the
match is the ingress port, but in my case i have to modify it in order to
display the IPs IPd TCPs UDPs TCPd UDPd.
Probably the steps to follow are to extract the info from the packet in,
building a table like mac_to_port in order to get the instructions out to
specific port build the flow mod, putting together the match and the action
and send it to the switch - to fill the table.
I have read the ryubook and ryureadthedocs - saw the functions under
messages and structures, and other but still çan't figure out where to to
write the new functions, and what to leave from the simple switch.

I will greatly appreciate if someone is willing to help me. it will be
really nice to see an example of match field of IPs/d build into the
simplle switch.
Thank you in advance .

from operator import attrgetter
from ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import CONFIG_DISPATCHER, MAIN_DISPATCHER,
DEAD_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 ipv4
from ryu.lib.packet import tcp
from ryu.lib.packet import ethernet
from ryu.lib.packet import ether_types
from ryu.lib import hub


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 = {}
self.datapaths = {}
self.monitor_thread = hub.spawn(self._monitor)

@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
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 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_protocol(ethernet.ethernet)

Loading...