@@ -87,6 +87,14 @@ def OFPExpMsgKeyExtract(datapath, command, fields, table_id,bit=0):
87
87
data += struct .pack (field_extract_format ,fields [f ])
88
88
89
89
exp_type = bebaproto .OFPT_EXP_STATE_MOD
90
+
91
+ # store lookup-scopes
92
+ if command == bebaproto .OFPSC_EXP_SET_L_EXTRACTOR :
93
+ if hasattr (datapath , 'lookup_scope' ):
94
+ datapath .lookup_scope [table_id ] = fields
95
+ else :
96
+ datapath .lookup_scope = {table_id : fields }
97
+
90
98
return ofproto_parser .OFPExperimenter (datapath = datapath , experimenter = 0xBEBABEBA , exp_type = exp_type , data = data )
91
99
92
100
def OFPExpMsgSetFlowState (datapath , state , keys , table_id , idle_timeout = 0 , idle_rollback = 0 , hard_timeout = 0 , hard_rollback = 0 , state_mask = 0xffffffff ):
@@ -140,43 +148,40 @@ def OFPExpResetGlobalState(datapath):
140
148
exp_type = bebaproto .OFPT_EXP_STATE_MOD
141
149
return ofproto_parser .OFPExperimenter (datapath = datapath , experimenter = 0xBEBABEBA , exp_type = exp_type , data = data )
142
150
143
- def OFPExpStateStatsMultipartRequest (datapath , table_id = ofproto .OFPTT_ALL , state = None , match = None ):
144
- flags = 0 # Zero or ``OFPMPF_REQ_MORE``
151
+ def OFPExpStateStatsMultipartRequestBase (datapath , exp_type , table_id = ofproto .OFPTT_ALL , state = None , match = None ):
152
+ flags = 0 # Zero or ``OFPMPF_REQ_MORE``
145
153
get_from_state = 1
146
154
if state is None :
147
155
get_from_state = 0
148
156
state = 0
149
-
157
+
150
158
if match is None :
151
159
match = ofproto_parser .OFPMatch ()
152
160
153
- data = bytearray ()
161
+ data = bytearray ()
154
162
msg_pack_into (bebaproto .OFP_STATE_STATS_REQUEST_0_PACK_STR , data , 0 , table_id , get_from_state , state )
155
-
156
- offset = bebaproto .OFP_STATE_STATS_REQUEST_0_SIZE
163
+
164
+ offset = bebaproto .OFP_STATE_STATS_REQUEST_0_SIZE
157
165
match .serialize (data , offset )
158
166
159
- exp_type = bebaproto .OFPMP_EXP_STATE_STATS
160
- return ofproto_parser .OFPExperimenterStatsRequest (datapath = datapath , flags = flags , experimenter = 0xBEBABEBA , exp_type = exp_type , data = data )
167
+ return ofproto_parser .OFPExperimenterStatsRequest (datapath = datapath , flags = flags , experimenter = 0xBEBABEBA ,
168
+ exp_type = exp_type , data = data )
169
+
170
+ def OFPExpStateStatsMultipartRequest (datapath , table_id = ofproto .OFPTT_ALL , state = None , match = None ):
171
+ return OFPExpStateStatsMultipartRequestBase (datapath = datapath , exp_type = bebaproto .OFPMP_EXP_STATE_STATS ,
172
+ table_id = table_id , state = state , match = match )
161
173
162
174
def OFPExpStateStatsMultipartRequestAndDelete (datapath , table_id = ofproto .OFPTT_ALL , state = None , match = None ):
163
- flags = 0 # Zero or ``OFPMPF_REQ_MORE``
164
- get_from_state = 1
165
- if state is None :
166
- get_from_state = 0
167
- state = 0
168
-
169
- if match is None :
170
- match = ofproto_parser .OFPMatch ()
175
+ return OFPExpStateStatsMultipartRequestBase (datapath = datapath , exp_type = bebaproto .OFPMP_EXP_STATE_STATS_AND_DELETE ,
176
+ table_id = table_id , state = state , match = match )
171
177
172
- data = bytearray ()
173
- msg_pack_into (bebaproto .OFP_STATE_STATS_REQUEST_0_PACK_STR , data , 0 , table_id , get_from_state , state )
174
-
175
- offset = bebaproto .OFP_STATE_STATS_REQUEST_0_SIZE
176
- match .serialize (data , offset )
178
+ def OFPExpStateStatsMultipartRequestShort (datapath , table_id = ofproto .OFPTT_ALL , state = None , match = None ):
179
+ return OFPExpStateStatsMultipartRequestBase (datapath = datapath , exp_type = bebaproto .OFPMP_EXP_STATE_STATS_SHORT ,
180
+ table_id = table_id , state = state , match = match )
177
181
178
- exp_type = bebaproto .OFPMP_EXP_STATE_STATS_AND_DELETE
179
- return ofproto_parser .OFPExperimenterStatsRequest (datapath = datapath , flags = flags , experimenter = 0xBEBABEBA , exp_type = exp_type , data = data )
182
+ def OFPExpStateStatsMultipartRequestAndDeleteShort (datapath , table_id = ofproto .OFPTT_ALL , state = None , match = None ):
183
+ return OFPExpStateStatsMultipartRequestBase (datapath = datapath , exp_type = bebaproto .OFPMP_EXP_STATE_STATS_AND_DELETE_SHORT ,
184
+ table_id = table_id , state = state , match = match )
180
185
181
186
"""
182
187
State Sync: Controller asks for flows in a specific state
@@ -306,28 +311,22 @@ def __init__(self, key_count=None, key=None, state=None):
306
311
self .state = state
307
312
308
313
@classmethod
309
- def parser (cls , buf , offset ):
310
- entry = OFPStateEntry ()
314
+ def parser (cls , buf , offset , key_count , state ):
315
+ entry = OFPStateEntry (key_count = key_count , state = state )
311
316
312
- key_count = struct .unpack_from ('!I' , buf , offset )
313
- entry .key_count = key_count [0 ]
314
- offset += 4
315
- entry .key = []
317
+ entry .key = []
316
318
if entry .key_count <= bebaproto .MAX_KEY_LEN :
317
319
for f in range (entry .key_count ):
318
320
key = struct .unpack_from ('!B' ,buf ,offset ,)
319
321
entry .key .append (key [0 ])
320
322
offset += 1
321
- offset += (bebaproto .MAX_KEY_LEN - entry .key_count )
322
323
323
- state = struct .unpack_from ('!I' , buf , offset )
324
- entry .state = state [0 ]
325
- offset += 4
324
+ offset += (utils .round_up (entry .key_count , 8 ) - entry .key_count )
326
325
327
- return entry
326
+ return entry , offset
328
327
329
328
class OFPStateStats (StringifyMixin ):
330
- def __init__ (self , table_id = None , dur_sec = None , dur_nsec = None , field_count = None , fields = None ,
329
+ def __init__ (self , table_id = None , dur_sec = None , dur_nsec = None , field_count = None , fields = None ,
331
330
entry = None ,length = None , hard_rb = None , idle_rb = None , hard_to = None , idle_to = None ):
332
331
super (OFPStateStats , self ).__init__ ()
333
332
self .length = 0
@@ -343,35 +342,73 @@ def __init__(self, table_id=None, dur_sec=None, dur_nsec=None, field_count=None,
343
342
self .hard_rb = hard_rb
344
343
345
344
@classmethod
346
- def parser (cls , buf , offset = 0 ):
345
+ def parser (cls , msg , offset = 0 ):
347
346
state_stats_list = []
348
-
349
- for i in range (len (buf )/ bebaproto .OFP_STATE_STATS_SIZE ):
347
+
348
+ buf = msg .body .data
349
+
350
+ while len (buf )- offset > 0 :
351
+ state_stats = cls ()
352
+
353
+ (state_stats .length , state_stats .table_id , state_stats .key_len , state_stats .dur_sec ,
354
+ state_stats .dur_nsec , state_stats .hard_rb , state_stats .idle_rb ,state_stats .hard_to ,
355
+ state_stats .idle_to , state_stats .state ) = struct .unpack_from (
356
+ bebaproto .OFP_STATE_STATS_PACK_STR , buf , offset )
357
+ offset += bebaproto .OFP_STATE_STATS_SIZE
358
+
359
+ if state_stats .table_id not in msg .datapath .lookup_scope :
360
+ continue
361
+ state_stats .fields = msg .datapath .lookup_scope [state_stats .table_id ]
362
+ state_stats .field_count = len (state_stats .fields )
363
+
364
+ state_stats .entry , offset = OFPStateEntry .parser (buf , offset , state_stats .key_len , state_stats .state )
365
+
366
+ state_stats_list .append (state_stats )
367
+
368
+ return state_stats_list
369
+
370
+
371
+ class OFPStateStatsShort (StringifyMixin ):
372
+ def __init__ (self , table_id = None , dur_sec = None , dur_nsec = None , field_count = None , fields = None ,
373
+ entry = None , length = None , hard_rb = None , idle_rb = None , hard_to = None , idle_to = None ):
374
+ super (OFPStateStatsShort , self ).__init__ ()
375
+ self .length = 0
376
+ self .table_id = table_id
377
+ self .dur_sec = dur_sec
378
+ self .dur_nsec = dur_nsec
379
+ self .field_count = field_count
380
+ self .fields = fields
381
+ self .entry = entry
382
+ self .hard_to = hard_to
383
+ self .hard_rb = hard_rb
384
+ self .idle_to = idle_to
385
+ self .hard_rb = hard_rb
386
+
387
+ @classmethod
388
+ def parser (cls , msg , offset = 0 ):
389
+ state_stats_list = []
390
+
391
+ buf = msg .body .data
392
+
393
+ while len (buf ) - offset > 0 :
350
394
state_stats = cls ()
351
395
352
- (state_stats .length , state_stats .table_id , state_stats .dur_sec ,
353
- state_stats .dur_nsec , state_stats .field_count ) = struct .unpack_from (
354
- bebaproto .OFP_STATE_STATS_0_PACK_STR , buf , offset )
355
- offset += bebaproto .OFP_STATE_STATS_0_SIZE
356
-
357
- state_stats .fields = []
358
- field_extract_format = '!I'
359
- if state_stats .field_count <= bebaproto .MAX_FIELD_COUNT :
360
- for f in range (state_stats .field_count ):
361
- field = struct .unpack_from (field_extract_format ,buf ,offset )
362
- state_stats .fields .append (field [0 ])
363
- offset += 4
364
- offset += ((bebaproto .MAX_FIELD_COUNT - state_stats .field_count )* 4 )
365
- state_stats .entry = OFPStateEntry .parser (buf , offset )
366
- offset += bebaproto .OFP_STATE_STATS_ENTRY_SIZE
367
-
368
- (state_stats .hard_rb , state_stats .idle_rb ,state_stats .hard_to , state_stats .idle_to ) = struct .unpack_from (
369
- bebaproto .OFP_STATE_STATS_1_PACK_STR , buf , offset )
370
- offset += bebaproto .OFP_STATE_STATS_1_SIZE
396
+ (state_stats .length , state_stats .table_id , state_stats .key_len , state_stats .state ) = struct .unpack_from (
397
+ bebaproto .OFP_STATE_STATS_SHORT_PACK_STR , buf , offset )
398
+ offset += bebaproto .OFP_STATE_STATS_SHORT_SIZE
399
+
400
+ if state_stats .table_id not in msg .datapath .lookup_scope :
401
+ continue
402
+ state_stats .fields = msg .datapath .lookup_scope [state_stats .table_id ]
403
+ state_stats .field_count = len (state_stats .fields )
404
+
405
+ state_stats .entry , offset = OFPStateEntry .parser (buf , offset , state_stats .key_len , state_stats .state )
406
+
371
407
state_stats_list .append (state_stats )
372
408
373
409
return state_stats_list
374
410
411
+
375
412
class OFPGlobalStateStats (StringifyMixin ):
376
413
def __init__ (self , global_state = None ):
377
414
super (OFPGlobalStateStats , self ).__init__ ()
0 commit comments