基于Ryu的流量采集代码实现

 

  1 from __future__ import division
  2 import time
  3 import math
  4 import xlwt
  5 from ryu.controller import ofp_event
  6 from ryu.controller.handler import MAIN_DISPATCHER, DEAD_DISPATCHER
  7 from ryu.controller.handler import set_ev_cls
  8 from ryu.ofproto import ofproto_v1_3
  9 from ryu.lib import hub
 10 
 11 FEATURE = {}
 12 
 13 
 14 class FlowFeatureExaction(RyuApp):
 15 
 16     OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]
 17 
 18     def __init__(self, *args, **kwargs):
 19         super(FlowFeatureExaction, self).__init__(*args, **kwargs)
 20 
 21         self.name = 'flow_feature_exaction'
 22         self.datapaths = {}
 23 
 24         self.src_to_dst = {}
 25         self.flows = []
 26         self.flow_feature = {}
 27 
 28         self.monitor_thread = hub.spawn(self._monitor)
 29 
 30     @set_ev_cls(ofp_event.EventOFPStateChange, [MAIN_DISPATCHER, DEAD_DISPATCHER])
 31     def _state_change_handler(self, ev):
 32         global FEATURE
 33         datapath = ev.datapath
 34         dpid = datapath.id
 35         if ev.state == MAIN_DISPATCHER:
 36             if datapath.id not in self.datapaths:
 37                 self.logger.debug('register datapath: %016x', datapath.id)
 38                 self.datapaths[datapath.id] = datapath
 39                 FEATURE.setdefault(dpid, {})
 40                 FEATURE[dpid].setdefault('flow_feature', {})
 41 
 42         elif ev.state == DEAD_DISPATCHER:
 43             if datapath.id in self.datapaths:
 44                 self.logger.debug('unregister datapath: %016x', datapath.id)
 45                 del self.datapaths[datapath.id]
 46                 FEATURE.pop(dpid)
 47 
 48     def _monitor(self):
 49         while True:
 50             for dp in self.datapaths.values():
 51                 self.send_flow_stats_request(dp)
 52 
 53             self.flows = []
 54             hub.sleep(10)
 55             # self.print_feature()
 56 
 57     def send_flow_stats_request(self, datapath):
 58         ofproto = datapath.ofproto
 59         parser = datapath.ofproto_parser
 60         req = parser.OFPFlowStatsRequest(datapath)
 61         datapath.send_msg(req)
 62 
 63     @set_ev_cls(ofp_event.EventOFPFlowStatsReply, MAIN_DISPATCHER)
 64     def flow_stats_reply_handler(self, ev):
 65 
 66         flow_counter = 0
 67         current_time = time.time()
 68         dpid = ev.msg.datapath.id
 69         self.flow_feature.setdefault(dpid, {})
 70         for stat in ev.msg.body:
 71             self.flows.append('time=%s datapath=%d table_id=%s '
 72                               'duration_sec=%d duration_nsec=%d '
 73                               'priority=%d '
 74                               'idle_timeout=%d hard_timeout=%d flags=0x%04x '
 75                               'cookie=%d packet_count=%d byte_count=%d '
 76                               'match=%s instructions=%s ' %
 77                               (time.time(), dpid, stat.table_id,
 78                                stat.duration_sec, stat.duration_nsec,
 79                                stat.priority,
 80                                stat.idle_timeout, stat.hard_timeout, stat.flags,
 81                                stat.cookie, stat.packet_count, stat.byte_count,
 82                                stat.match, stat.instructions))
 83             # flow_no = stat.match['eth_type'] + stat.match['ipv4_src'] + stat.match['in_port'] + stat.match['ipv4_dst']
 84             flow_no = flow_counter
 85             if (dpid in self.flow_feature) and (flow_no not in self.flow_feature[dpid]):
 86                 self.flow_feature[dpid].setdefault(flow_no, {})
 87                 self.flow_feature[dpid][flow_no] = {'datapath': 0, 'duration': 0,'priority': 0,
 88                                                     'packet_count': 0, 'byte_count': 0,
 89                                                     'ipv4_src': 0, 'ipv4_dst': 0,
 90                                                     'in_port': 0,'output': 0,
 91                                                     'pkt_rate': 0, 'byte_rate': 0,
 92                                                     'pkt_asym': 0, 'byte_asym': 0,
 93                                                     'growth_flow_interval': 0, 'switch_flow_count': 0,
 94                                                     'mean_bytes_per_pkt': 0, 'time': 0}
 95 
 96             time_interval = current_time-self.flow_feature[dpid][flow_no]['time']
 97             pkt_rate = (stat.packet_count-self.flow_feature[dpid][flow_no]['packet_count'])/time_interval
 98             byte_rate = (stat.byte_count-self.flow_feature[dpid][flow_no]['byte_count'])/time_interval
 99             self.flow_feature[dpid][flow_no] = {'datapath': dpid, 'duration': stat.duration_sec, 'priority': stat.priority,
100                                                 'packet_count': stat.packet_count, 'byte_count': stat.byte_count,
101                                                 'ipv4_src': 0, 'ipv4_dst': 0,
102                                                 'in_port': 0,'output': stat.instructions[0].actions[0].port,
103                                                 'pkt_rate': pkt_rate,'byte_rate': byte_rate,
104                                                 'pkt_asym': 0, 'byte_asym': 0,
105                                                 'growth_flow_interval': 0, 'switch_flow_count': 0,
106                                                 'mean_bytes_per_pkt': 0, 'time': current_time}
107 
108             for key, value in stat.match.items():
109                 self.flow_feature[dpid][flow_no][key] = value
110 
111             if pkt_rate != 0:
112                 self.flow_feature[dpid][flow_no]['mean_bytes_per_pkt'] = byte_rate/pkt_rate
113 
114             if self.flow_feature[dpid][flow_no]['ipv4_src'] != 0:
115                 src = self.flow_feature[dpid][flow_no]['ipv4_src']
116                 dst = self.flow_feature[dpid][flow_no]['ipv4_dst']
117                 self.src_to_dst.setdefault(src, {})
118                 self.src_to_dst[src].setdefault(dst, {})
119                 self.src_to_dst[src][dst] = {'pkt_count': stat.packet_count, 'byte_count': stat.byte_count,}
120             flow_counter += 1
121 
122         for flow_no in self.flow_feature[dpid].keys():
123             self.flow_feature[dpid][flow_no]['growth_flow_interval'] = \
124                 flow_counter - self.flow_feature[dpid][flow_no]['switch_flow_count']
125             self.flow_feature[dpid][flow_no]['switch_flow_count'] = flow_counter
126             if 'ipv4_src' in self.flow_feature[dpid][flow_no].keys():
127                 for src in self.src_to_dst.keys():
128                     if src == self.flow_feature[dpid][flow_no]['ipv4_dst']:
129                         for dst in self.src_to_dst[src].keys():
130                             if dst == self.flow_feature[dpid][flow_no]['ipv4_src']:
131                                 self.flow_feature[dpid][flow_no]['pkt_asym'] = \
132                                     self.src_to_dst[src][dst]['pkt_count']/(1+self.flow_feature[dpid][flow_no]['packet_count'])
133                                 self.flow_feature[dpid][flow_no]['bytes_asym'] = \
134                                     self.src_to_dst[src][dst]['byte_count'] / (1+self.flow_feature[dpid][flow_no]['byte_count'])
135         global FEATURE
136         FEATURE[dpid]['flow_feature'] = self.flow_feature[dpid]
137 
138         # data = open("switch_flows", mode='w+')
139         # for flow in self.flows:
140         #      data.write(str(flow) + '\n')
141         # data.close()
142 
143         data = open("feature", 'w')
144         for dpid in FEATURE.keys():
145             data.write('DatapathId ' + str(dpid) + ':{')
146             for feature_type in FEATURE[dpid].keys():
147                 data.write('\n        '+str(feature_type)+':')
148                 data.write(str(FEATURE[dpid][feature_type]) + '}\n')
149             data.write('\n')
150         data.close()
151 
152         # workbook = xlwt.Workbook(encoding='utf-8')
153         # worksheet = workbook.add_sheet('Flow Feature')
154         # worksheet.write()
155         # workbook.save('flow_feature.xls')
156         pass

 

posted @ 2021-07-09 12:13  Jcpeng_std  阅读(385)  评论(1编辑  收藏  举报