2016-07-05 20 views
0

habe ich ein einfaches Netzwerk in der mininet Umgebung mit dem folgenden Befehl:Ryu (SDN) Lotse aus (Beispiel) Host 1

$ sudo mn --topo single,3 --mac --controller remote --switch ovsk 

I RYU CONTROLLER möchte verwenden, um Bandbreitenverkehr auf speziellen Port des Schalters berechnet werden. Ich denke an die Verwendung eines OFPEVENTPacketIn Ereignisses für das ankommende Paket, aber ich habe keine Ahnung für den kommenden Paketform-Port.

Mein Code:

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_handler1(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', 
       if stat.match['in_port']==1: 
        self.logger.info('%x %x %s %x %d %d', 
          ev.msg.datapath.id, 
          stat.match['in_port'], stat.match['eth_dst'], 
          stat.instructions[0].actions[0].port, 
          stat.packet_count, stat.byte_count) 

     #for stat in [1234]#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', 
       # if stat.match['in_port']==1: 
        # self.logger.info('%x %x %s %x %d %d', 
        #   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')): 
      if stat.port_no==1: 

       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) 

Bitte helfen Sie mir diesen Code bearbeiten meine Frage zu beantworten. Vielen Dank.

Antwort

1

Sie müssen zwei Methoden in Ihrem Controller hinzufügen: 1) eine Methode, die Statistiken anfordert 2) eine Methode, die die Antworten von Switches erfasst.

Das Verfahren zur Statistik zu beantworten ist die folgende:

def send_flow_stats_request(self, datapath): 
    ofp = datapath.ofproto 
    ofp_parser = datapath.ofproto_parser 
cookie = cookie_mask = 0 
match = ofp_parser.OFPMatch(in_port=1) 
req = ofp_parser.OFPFlowStatsRequest(datapath, 0, 
            ofp.OFPTT_ALL, 
            ofp.OFPP_ANY, ofp.OFPG_ANY, 
            cookie, cookie_mask, 
            match) 
datapath.send_msg(req) 

Die Methode Antworten für die Erfassung ist diese:

@set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER) 
def flow_stats_reply_handler(self, ev): 
    flows = [] 
    for stat in ev.msg.body: 
     flows.append('table_id=%s ' 
        'duration_sec=%d duration_nsec=%d ' 
        'priority=%d ' 
        'idle_timeout=%d hard_timeout=%d flags=0x%04x ' 
        'cookie=%d packet_count=%d byte_count=%d ' 
        'match=%s instructions=%s' % 
        (stat.table_id, 
         stat.duration_sec, stat.duration_nsec, 
         stat.priority, 
         stat.idle_timeout, stat.hard_timeout, stat.flags, 
         stat.cookie, stat.packet_count, stat.byte_count, 
         stat.match, stat.instructions)) 
    self.logger.debug('FlowStats: %s', flows) 

Sobald Sie Statistiken erfassen Sie die Bandbreitennutzung berechnen kann.

Sie haben jedoch auch andere Arten von Anfragen, die Sie ausführen können, also empfehle ich Ihnen, den Roggen Doc zu lesen.

http://ryu.readthedocs.io/en/latest/