blob: 889bbdf5a85ec7c82ed036de51420bd45feb4ae0 [file] [log] [blame]
Rich Lane6242d9f2013-01-06 17:35:39 -08001
2# Python OpenFlow message wrapper classes
3
Rich Lanef6883512013-03-11 17:00:09 -07004import logging
Rich Lane6242d9f2013-01-06 17:35:39 -08005from cstruct import *
6from action_list import action_list
7from error import *
8
9# Define templates for documentation
10class ofp_template_msg:
11 """
12 Sample base class for template_msg; normally auto generated
13 This class should live in the of_header name space and provides the
14 base class for this type of message. It will be wrapped for the
15 high level API.
16
17 """
18 def __init__(self):
19 """
20 Constructor for base class
21
22 """
Rich Lane6242d9f2013-01-06 17:35:39 -080023 # Additional base data members declared here
24
25 # Normally will define pack, unpack, __len__ functions
26
27class template_msg(ofp_template_msg):
28 """
29 Sample class wrapper for template_msg
30 This class should live in the of_message name space and provides the
31 high level API for an OpenFlow message object. These objects must
32 implement the functions indicated in this template.
33
34 """
35 def __init__(self):
36 """
37 Constructor
38 Must set the header type value appropriately for the message
39
40 """
41
42 ##@var header
43 # OpenFlow message header: length, version, xid, type
44 ofp_template_msg.__init__(self)
Rich Lane6242d9f2013-01-06 17:35:39 -080045 # For a real message, will be set to an integer
Rich Laneb73808c2013-03-11 15:22:23 -070046 self.type = "TEMPLATE_MSG_VALUE"
Rich Lane6242d9f2013-01-06 17:35:39 -080047 def pack(self):
48 """
49 Pack object into string
50
51 @return The packed string which can go on the wire
52
53 """
54 pass
55 def unpack(self, binary_string):
56 """
57 Unpack object from a binary string
58
59 @param binary_string The wire protocol byte string holding the object
60 represented as an array of bytes.
61
62 @return Typically returns the remainder of binary_string that
63 was not parsed. May give a warning if that string is non-empty
64
65 """
66 pass
67 def __len__(self):
68 """
69 Return the length of this object once packed into a string
70
71 @return An integer representing the number bytes in the packed
72 string.
73
74 """
75 pass
76 def show(self, prefix=''):
77 """
78 Generate a string (with multiple lines) describing the contents
79 of the object in a readable manner
80
81 @param prefix Pre-pended at the beginning of each line.
82
83 """
84 pass
85 def __eq__(self, other):
86 """
87 Return True if self and other hold the same data
88
89 @param other Other object in comparison
90
91 """
92 pass
93 def __ne__(self, other):
94 """
95 Return True if self and other do not hold the same data
96
97 @param other Other object in comparison
98
99 """
100 pass
101
102
103################################################################
104#
105# OpenFlow Message Definitions
106#
107################################################################
108
Rich Laneb73808c2013-03-11 15:22:23 -0700109class barrier_reply(ofp_header):
Rich Lane6242d9f2013-01-06 17:35:39 -0800110 """
111 Wrapper class for barrier_reply
112
113 OpenFlow message header: length, version, xid, type
114 @arg length: The total length of the message
115 @arg version: The OpenFlow version (1)
116 @arg xid: The transaction ID
117 @arg type: The message type (OFPT_BARRIER_REPLY=19)
118
Rich Laneb73808c2013-03-11 15:22:23 -0700119 Data members inherited from ofp_header:
120 @arg version
121 @arg type
122 @arg length
123 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -0800124
125 """
126
127 def __init__(self, **kwargs):
Rich Laneb73808c2013-03-11 15:22:23 -0700128 ofp_header.__init__(self)
129 self.version = OFP_VERSION
130 self.type = OFPT_BARRIER_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -0700131 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -0800132 for (k, v) in kwargs.items():
133 if hasattr(self, k):
134 setattr(self, k, v)
135 else:
136 raise NameError("field %s does not exist in %s" % (k, self.__class__))
137
138
139 def pack(self):
140 """
141 Pack object into string
142
143 @return The packed string which can go on the wire
144
145 """
Rich Laneb73808c2013-03-11 15:22:23 -0700146 self.length = len(self)
147 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -0800148
Rich Laneb73808c2013-03-11 15:22:23 -0700149 packed += ofp_header.pack(self)
Rich Lane6242d9f2013-01-06 17:35:39 -0800150 return packed
151
152 def unpack(self, binary_string):
153 """
154 Unpack object from a binary string
155
156 @param binary_string The wire protocol byte string holding the object
157 represented as an array of bytes.
158 @return The remainder of binary_string that was not parsed.
159
160 """
Rich Lane6242d9f2013-01-06 17:35:39 -0800161
Rich Laneb73808c2013-03-11 15:22:23 -0700162 binary_string = ofp_header.unpack(self, binary_string)
Rich Lane6242d9f2013-01-06 17:35:39 -0800163 # Fixme: If no self.data, add check for data remaining
164 return binary_string
165
166 def __len__(self):
167 """
168 Return the length of this object once packed into a string
169
170 @return An integer representing the number bytes in the packed
171 string.
172
173 """
Rich Laneb73808c2013-03-11 15:22:23 -0700174 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -0800175
Rich Laneb73808c2013-03-11 15:22:23 -0700176 length += ofp_header.__len__(self)
Rich Lane6242d9f2013-01-06 17:35:39 -0800177 return length
178
179 def show(self, prefix=''):
180 """
181 Generate a string (with multiple lines) describing the contents
182 of the object in a readable manner
183
184 @param prefix Pre-pended at the beginning of each line.
185
186 """
187
188 outstr = prefix + 'barrier_reply (OFPT_BARRIER_REPLY)\n'
189 prefix += ' '
190 outstr += prefix + 'ofp header\n'
Rich Laneb73808c2013-03-11 15:22:23 -0700191 outstr += ofp_header.show(self, prefix)
Rich Lane6242d9f2013-01-06 17:35:39 -0800192 return outstr
193
194 def __eq__(self, other):
195 """
196 Return True if self and other hold the same data
197
198 @param other Other object in comparison
199
200 """
201 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800202
Rich Laneb73808c2013-03-11 15:22:23 -0700203 if not ofp_header.__eq__(self, other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800204 return True
205
206 def __ne__(self, other):
207 """
208 Return True if self and other do not hold the same data
209
210 @param other Other object in comparison
211
212 """
213 return not self.__eq__(other)
214
215
Rich Laneb73808c2013-03-11 15:22:23 -0700216class barrier_request(ofp_header):
Rich Lane6242d9f2013-01-06 17:35:39 -0800217 """
218 Wrapper class for barrier_request
219
220 OpenFlow message header: length, version, xid, type
221 @arg length: The total length of the message
222 @arg version: The OpenFlow version (1)
223 @arg xid: The transaction ID
224 @arg type: The message type (OFPT_BARRIER_REQUEST=18)
225
Rich Laneb73808c2013-03-11 15:22:23 -0700226 Data members inherited from ofp_header:
227 @arg version
228 @arg type
229 @arg length
230 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -0800231
232 """
233
234 def __init__(self, **kwargs):
Rich Laneb73808c2013-03-11 15:22:23 -0700235 ofp_header.__init__(self)
236 self.version = OFP_VERSION
237 self.type = OFPT_BARRIER_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -0700238 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -0800239 for (k, v) in kwargs.items():
240 if hasattr(self, k):
241 setattr(self, k, v)
242 else:
243 raise NameError("field %s does not exist in %s" % (k, self.__class__))
244
245
246 def pack(self):
247 """
248 Pack object into string
249
250 @return The packed string which can go on the wire
251
252 """
Rich Laneb73808c2013-03-11 15:22:23 -0700253 self.length = len(self)
254 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -0800255
Rich Laneb73808c2013-03-11 15:22:23 -0700256 packed += ofp_header.pack(self)
Rich Lane6242d9f2013-01-06 17:35:39 -0800257 return packed
258
259 def unpack(self, binary_string):
260 """
261 Unpack object from a binary string
262
263 @param binary_string The wire protocol byte string holding the object
264 represented as an array of bytes.
265 @return The remainder of binary_string that was not parsed.
266
267 """
Rich Lane6242d9f2013-01-06 17:35:39 -0800268
Rich Laneb73808c2013-03-11 15:22:23 -0700269 binary_string = ofp_header.unpack(self, binary_string)
Rich Lane6242d9f2013-01-06 17:35:39 -0800270 # Fixme: If no self.data, add check for data remaining
271 return binary_string
272
273 def __len__(self):
274 """
275 Return the length of this object once packed into a string
276
277 @return An integer representing the number bytes in the packed
278 string.
279
280 """
Rich Laneb73808c2013-03-11 15:22:23 -0700281 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -0800282
Rich Laneb73808c2013-03-11 15:22:23 -0700283 length += ofp_header.__len__(self)
Rich Lane6242d9f2013-01-06 17:35:39 -0800284 return length
285
286 def show(self, prefix=''):
287 """
288 Generate a string (with multiple lines) describing the contents
289 of the object in a readable manner
290
291 @param prefix Pre-pended at the beginning of each line.
292
293 """
294
295 outstr = prefix + 'barrier_request (OFPT_BARRIER_REQUEST)\n'
296 prefix += ' '
297 outstr += prefix + 'ofp header\n'
Rich Laneb73808c2013-03-11 15:22:23 -0700298 outstr += ofp_header.show(self, prefix)
Rich Lane6242d9f2013-01-06 17:35:39 -0800299 return outstr
300
301 def __eq__(self, other):
302 """
303 Return True if self and other hold the same data
304
305 @param other Other object in comparison
306
307 """
308 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800309
Rich Laneb73808c2013-03-11 15:22:23 -0700310 if not ofp_header.__eq__(self, other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800311 return True
312
313 def __ne__(self, other):
314 """
315 Return True if self and other do not hold the same data
316
317 @param other Other object in comparison
318
319 """
320 return not self.__eq__(other)
321
322
Rich Laneb73808c2013-03-11 15:22:23 -0700323class echo_reply(ofp_header):
Rich Lane6242d9f2013-01-06 17:35:39 -0800324 """
325 Wrapper class for echo_reply
326
327 OpenFlow message header: length, version, xid, type
328 @arg length: The total length of the message
329 @arg version: The OpenFlow version (1)
330 @arg xid: The transaction ID
331 @arg type: The message type (OFPT_ECHO_REPLY=3)
332
Rich Laneb73808c2013-03-11 15:22:23 -0700333 Data members inherited from ofp_header:
334 @arg version
335 @arg type
336 @arg length
337 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -0800338 @arg data: Binary string following message members
339
340 """
341
342 def __init__(self, **kwargs):
Rich Laneb73808c2013-03-11 15:22:23 -0700343 ofp_header.__init__(self)
344 self.version = OFP_VERSION
345 self.type = OFPT_ECHO_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -0700346 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -0800347 self.data = ""
348 for (k, v) in kwargs.items():
349 if hasattr(self, k):
350 setattr(self, k, v)
351 else:
352 raise NameError("field %s does not exist in %s" % (k, self.__class__))
353
354
355 def pack(self):
356 """
357 Pack object into string
358
359 @return The packed string which can go on the wire
360
361 """
Rich Laneb73808c2013-03-11 15:22:23 -0700362 self.length = len(self)
363 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -0800364
Rich Laneb73808c2013-03-11 15:22:23 -0700365 packed += ofp_header.pack(self)
Rich Lane6242d9f2013-01-06 17:35:39 -0800366 packed += self.data
367 return packed
368
369 def unpack(self, binary_string):
370 """
371 Unpack object from a binary string
372
373 @param binary_string The wire protocol byte string holding the object
374 represented as an array of bytes.
375 @return The remainder of binary_string that was not parsed.
376
377 """
Rich Lane6242d9f2013-01-06 17:35:39 -0800378
Rich Laneb73808c2013-03-11 15:22:23 -0700379 binary_string = ofp_header.unpack(self, binary_string)
Rich Lane6242d9f2013-01-06 17:35:39 -0800380 self.data = binary_string
381 binary_string = ''
382 return binary_string
383
384 def __len__(self):
385 """
386 Return the length of this object once packed into a string
387
388 @return An integer representing the number bytes in the packed
389 string.
390
391 """
Rich Laneb73808c2013-03-11 15:22:23 -0700392 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -0800393
Rich Laneb73808c2013-03-11 15:22:23 -0700394 length += ofp_header.__len__(self)
Rich Lane6242d9f2013-01-06 17:35:39 -0800395 length += len(self.data)
396 return length
397
398 def show(self, prefix=''):
399 """
400 Generate a string (with multiple lines) describing the contents
401 of the object in a readable manner
402
403 @param prefix Pre-pended at the beginning of each line.
404
405 """
406
407 outstr = prefix + 'echo_reply (OFPT_ECHO_REPLY)\n'
408 prefix += ' '
409 outstr += prefix + 'ofp header\n'
Rich Laneb73808c2013-03-11 15:22:23 -0700410 outstr += ofp_header.show(self, prefix)
Rich Lane6242d9f2013-01-06 17:35:39 -0800411 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
412 ##@todo Fix this circular reference
413 # if len(self.data) > 0:
414 # obj = of_message_parse(self.data)
415 # if obj != None:
416 # outstr += obj.show(prefix)
417 # else:
418 # outstr += prefix + "Unable to parse data\n"
419 return outstr
420
421 def __eq__(self, other):
422 """
423 Return True if self and other hold the same data
424
425 @param other Other object in comparison
426
427 """
428 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800429
Rich Laneb73808c2013-03-11 15:22:23 -0700430 if not ofp_header.__eq__(self, other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800431 if self.data != other.data: return False
432 return True
433
434 def __ne__(self, other):
435 """
436 Return True if self and other do not hold the same data
437
438 @param other Other object in comparison
439
440 """
441 return not self.__eq__(other)
442
443
Rich Laneb73808c2013-03-11 15:22:23 -0700444class echo_request(ofp_header):
Rich Lane6242d9f2013-01-06 17:35:39 -0800445 """
446 Wrapper class for echo_request
447
448 OpenFlow message header: length, version, xid, type
449 @arg length: The total length of the message
450 @arg version: The OpenFlow version (1)
451 @arg xid: The transaction ID
452 @arg type: The message type (OFPT_ECHO_REQUEST=2)
453
Rich Laneb73808c2013-03-11 15:22:23 -0700454 Data members inherited from ofp_header:
455 @arg version
456 @arg type
457 @arg length
458 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -0800459 @arg data: Binary string following message members
460
461 """
462
463 def __init__(self, **kwargs):
Rich Laneb73808c2013-03-11 15:22:23 -0700464 ofp_header.__init__(self)
465 self.version = OFP_VERSION
466 self.type = OFPT_ECHO_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -0700467 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -0800468 self.data = ""
469 for (k, v) in kwargs.items():
470 if hasattr(self, k):
471 setattr(self, k, v)
472 else:
473 raise NameError("field %s does not exist in %s" % (k, self.__class__))
474
475
476 def pack(self):
477 """
478 Pack object into string
479
480 @return The packed string which can go on the wire
481
482 """
Rich Laneb73808c2013-03-11 15:22:23 -0700483 self.length = len(self)
484 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -0800485
Rich Laneb73808c2013-03-11 15:22:23 -0700486 packed += ofp_header.pack(self)
Rich Lane6242d9f2013-01-06 17:35:39 -0800487 packed += self.data
488 return packed
489
490 def unpack(self, binary_string):
491 """
492 Unpack object from a binary string
493
494 @param binary_string The wire protocol byte string holding the object
495 represented as an array of bytes.
496 @return The remainder of binary_string that was not parsed.
497
498 """
Rich Lane6242d9f2013-01-06 17:35:39 -0800499
Rich Laneb73808c2013-03-11 15:22:23 -0700500 binary_string = ofp_header.unpack(self, binary_string)
Rich Lane6242d9f2013-01-06 17:35:39 -0800501 self.data = binary_string
502 binary_string = ''
503 return binary_string
504
505 def __len__(self):
506 """
507 Return the length of this object once packed into a string
508
509 @return An integer representing the number bytes in the packed
510 string.
511
512 """
Rich Laneb73808c2013-03-11 15:22:23 -0700513 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -0800514
Rich Laneb73808c2013-03-11 15:22:23 -0700515 length += ofp_header.__len__(self)
Rich Lane6242d9f2013-01-06 17:35:39 -0800516 length += len(self.data)
517 return length
518
519 def show(self, prefix=''):
520 """
521 Generate a string (with multiple lines) describing the contents
522 of the object in a readable manner
523
524 @param prefix Pre-pended at the beginning of each line.
525
526 """
527
528 outstr = prefix + 'echo_request (OFPT_ECHO_REQUEST)\n'
529 prefix += ' '
530 outstr += prefix + 'ofp header\n'
Rich Laneb73808c2013-03-11 15:22:23 -0700531 outstr += ofp_header.show(self, prefix)
Rich Lane6242d9f2013-01-06 17:35:39 -0800532 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
533 ##@todo Fix this circular reference
534 # if len(self.data) > 0:
535 # obj = of_message_parse(self.data)
536 # if obj != None:
537 # outstr += obj.show(prefix)
538 # else:
539 # outstr += prefix + "Unable to parse data\n"
540 return outstr
541
542 def __eq__(self, other):
543 """
544 Return True if self and other hold the same data
545
546 @param other Other object in comparison
547
548 """
549 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800550
Rich Laneb73808c2013-03-11 15:22:23 -0700551 if not ofp_header.__eq__(self, other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800552 if self.data != other.data: return False
553 return True
554
555 def __ne__(self, other):
556 """
557 Return True if self and other do not hold the same data
558
559 @param other Other object in comparison
560
561 """
562 return not self.__eq__(other)
563
564
565class error(ofp_error_msg):
566 """
567 Wrapper class for error
568
569 OpenFlow message header: length, version, xid, type
570 @arg length: The total length of the message
571 @arg version: The OpenFlow version (1)
572 @arg xid: The transaction ID
573 @arg type: The message type (OFPT_ERROR=1)
574
575 Data members inherited from ofp_error_msg:
Rich Laneb73808c2013-03-11 15:22:23 -0700576 @arg version
577 @arg type
578 @arg length
579 @arg xid
Rich Lane4e361bb2013-03-11 13:57:31 -0700580 @arg err_type
Rich Lane6242d9f2013-01-06 17:35:39 -0800581 @arg code
582 @arg data: Binary string following message members
583
584 """
585
586 def __init__(self, **kwargs):
587 ofp_error_msg.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -0700588 self.version = OFP_VERSION
589 self.type = OFPT_ERROR
Rich Lane8fbfd662013-03-11 15:30:44 -0700590 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -0800591 self.data = ""
592 for (k, v) in kwargs.items():
593 if hasattr(self, k):
594 setattr(self, k, v)
595 else:
596 raise NameError("field %s does not exist in %s" % (k, self.__class__))
597
598
599 def pack(self):
600 """
601 Pack object into string
602
603 @return The packed string which can go on the wire
604
605 """
Rich Laneb73808c2013-03-11 15:22:23 -0700606 self.length = len(self)
607 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -0800608
609 packed += ofp_error_msg.pack(self)
610 packed += self.data
611 return packed
612
613 def unpack(self, binary_string):
614 """
615 Unpack object from a binary string
616
617 @param binary_string The wire protocol byte string holding the object
618 represented as an array of bytes.
619 @return The remainder of binary_string that was not parsed.
620
621 """
Rich Lane6242d9f2013-01-06 17:35:39 -0800622
623 binary_string = ofp_error_msg.unpack(self, binary_string)
624 self.data = binary_string
625 binary_string = ''
626 return binary_string
627
628 def __len__(self):
629 """
630 Return the length of this object once packed into a string
631
632 @return An integer representing the number bytes in the packed
633 string.
634
635 """
Rich Laneb73808c2013-03-11 15:22:23 -0700636 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -0800637
638 length += ofp_error_msg.__len__(self)
639 length += len(self.data)
640 return length
641
642 def show(self, prefix=''):
643 """
644 Generate a string (with multiple lines) describing the contents
645 of the object in a readable manner
646
647 @param prefix Pre-pended at the beginning of each line.
648
649 """
650
651 outstr = prefix + 'error (OFPT_ERROR)\n'
652 prefix += ' '
653 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -0800654 outstr += ofp_error_msg.show(self, prefix)
655 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
656 ##@todo Fix this circular reference
657 # if len(self.data) > 0:
658 # obj = of_message_parse(self.data)
659 # if obj != None:
660 # outstr += obj.show(prefix)
661 # else:
662 # outstr += prefix + "Unable to parse data\n"
663 return outstr
664
665 def __eq__(self, other):
666 """
667 Return True if self and other hold the same data
668
669 @param other Other object in comparison
670
671 """
672 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800673
674 if not ofp_error_msg.__eq__(self, other): return False
675 if self.data != other.data: return False
676 return True
677
678 def __ne__(self, other):
679 """
680 Return True if self and other do not hold the same data
681
682 @param other Other object in comparison
683
684 """
685 return not self.__eq__(other)
686
687
688class features_reply(ofp_switch_features):
689 """
690 Wrapper class for features_reply
691
692 OpenFlow message header: length, version, xid, type
693 @arg length: The total length of the message
694 @arg version: The OpenFlow version (1)
695 @arg xid: The transaction ID
696 @arg type: The message type (OFPT_FEATURES_REPLY=6)
697
698 Data members inherited from ofp_switch_features:
Rich Laneb73808c2013-03-11 15:22:23 -0700699 @arg version
700 @arg type
701 @arg length
702 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -0800703 @arg datapath_id
704 @arg n_buffers
705 @arg n_tables
706 @arg capabilities
707 @arg actions
708 @arg ports: Variable length array of TBD
709
710 """
711
712 def __init__(self, **kwargs):
713 ofp_switch_features.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -0700714 self.version = OFP_VERSION
715 self.type = OFPT_FEATURES_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -0700716 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -0800717 self.ports = []
718 for (k, v) in kwargs.items():
719 if hasattr(self, k):
720 setattr(self, k, v)
721 else:
722 raise NameError("field %s does not exist in %s" % (k, self.__class__))
723
724
725 def pack(self):
726 """
727 Pack object into string
728
729 @return The packed string which can go on the wire
730
731 """
Rich Laneb73808c2013-03-11 15:22:23 -0700732 self.length = len(self)
733 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -0800734
735 packed += ofp_switch_features.pack(self)
736 for obj in self.ports:
737 packed += obj.pack()
738 return packed
739
740 def unpack(self, binary_string):
741 """
742 Unpack object from a binary string
743
744 @param binary_string The wire protocol byte string holding the object
745 represented as an array of bytes.
746 @return The remainder of binary_string that was not parsed.
747
748 """
Rich Lane6242d9f2013-01-06 17:35:39 -0800749
750 binary_string = ofp_switch_features.unpack(self, binary_string)
751 while len(binary_string) >= OFP_PHY_PORT_BYTES:
752 new_port = ofp_phy_port()
753 binary_string = new_port.unpack(binary_string)
754 self.ports.append(new_port)
755 # Fixme: If no self.data, add check for data remaining
756 return binary_string
757
758 def __len__(self):
759 """
760 Return the length of this object once packed into a string
761
762 @return An integer representing the number bytes in the packed
763 string.
764
765 """
Rich Laneb73808c2013-03-11 15:22:23 -0700766 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -0800767
768 length += ofp_switch_features.__len__(self)
769 for obj in self.ports:
770 length += len(obj)
771 return length
772
773 def show(self, prefix=''):
774 """
775 Generate a string (with multiple lines) describing the contents
776 of the object in a readable manner
777
778 @param prefix Pre-pended at the beginning of each line.
779
780 """
781
782 outstr = prefix + 'features_reply (OFPT_FEATURES_REPLY)\n'
783 prefix += ' '
784 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -0800785 outstr += ofp_switch_features.show(self, prefix)
786 outstr += prefix + "Array ports\n"
787 for obj in self.ports:
788 outstr += obj.show(prefix + ' ')
789 return outstr
790
791 def __eq__(self, other):
792 """
793 Return True if self and other hold the same data
794
795 @param other Other object in comparison
796
797 """
798 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800799
800 if not ofp_switch_features.__eq__(self, other): return False
801 if self.ports != other.ports: return False
802 return True
803
804 def __ne__(self, other):
805 """
806 Return True if self and other do not hold the same data
807
808 @param other Other object in comparison
809
810 """
811 return not self.__eq__(other)
812
813
Rich Laneb73808c2013-03-11 15:22:23 -0700814class features_request(ofp_header):
Rich Lane6242d9f2013-01-06 17:35:39 -0800815 """
816 Wrapper class for features_request
817
818 OpenFlow message header: length, version, xid, type
819 @arg length: The total length of the message
820 @arg version: The OpenFlow version (1)
821 @arg xid: The transaction ID
822 @arg type: The message type (OFPT_FEATURES_REQUEST=5)
823
Rich Laneb73808c2013-03-11 15:22:23 -0700824 Data members inherited from ofp_header:
825 @arg version
826 @arg type
827 @arg length
828 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -0800829
830 """
831
832 def __init__(self, **kwargs):
Rich Laneb73808c2013-03-11 15:22:23 -0700833 ofp_header.__init__(self)
834 self.version = OFP_VERSION
835 self.type = OFPT_FEATURES_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -0700836 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -0800837 for (k, v) in kwargs.items():
838 if hasattr(self, k):
839 setattr(self, k, v)
840 else:
841 raise NameError("field %s does not exist in %s" % (k, self.__class__))
842
843
844 def pack(self):
845 """
846 Pack object into string
847
848 @return The packed string which can go on the wire
849
850 """
Rich Laneb73808c2013-03-11 15:22:23 -0700851 self.length = len(self)
852 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -0800853
Rich Laneb73808c2013-03-11 15:22:23 -0700854 packed += ofp_header.pack(self)
Rich Lane6242d9f2013-01-06 17:35:39 -0800855 return packed
856
857 def unpack(self, binary_string):
858 """
859 Unpack object from a binary string
860
861 @param binary_string The wire protocol byte string holding the object
862 represented as an array of bytes.
863 @return The remainder of binary_string that was not parsed.
864
865 """
Rich Lane6242d9f2013-01-06 17:35:39 -0800866
Rich Laneb73808c2013-03-11 15:22:23 -0700867 binary_string = ofp_header.unpack(self, binary_string)
Rich Lane6242d9f2013-01-06 17:35:39 -0800868 # Fixme: If no self.data, add check for data remaining
869 return binary_string
870
871 def __len__(self):
872 """
873 Return the length of this object once packed into a string
874
875 @return An integer representing the number bytes in the packed
876 string.
877
878 """
Rich Laneb73808c2013-03-11 15:22:23 -0700879 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -0800880
Rich Laneb73808c2013-03-11 15:22:23 -0700881 length += ofp_header.__len__(self)
Rich Lane6242d9f2013-01-06 17:35:39 -0800882 return length
883
884 def show(self, prefix=''):
885 """
886 Generate a string (with multiple lines) describing the contents
887 of the object in a readable manner
888
889 @param prefix Pre-pended at the beginning of each line.
890
891 """
892
893 outstr = prefix + 'features_request (OFPT_FEATURES_REQUEST)\n'
894 prefix += ' '
895 outstr += prefix + 'ofp header\n'
Rich Laneb73808c2013-03-11 15:22:23 -0700896 outstr += ofp_header.show(self, prefix)
Rich Lane6242d9f2013-01-06 17:35:39 -0800897 return outstr
898
899 def __eq__(self, other):
900 """
901 Return True if self and other hold the same data
902
903 @param other Other object in comparison
904
905 """
906 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800907
Rich Laneb73808c2013-03-11 15:22:23 -0700908 if not ofp_header.__eq__(self, other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -0800909 return True
910
911 def __ne__(self, other):
912 """
913 Return True if self and other do not hold the same data
914
915 @param other Other object in comparison
916
917 """
918 return not self.__eq__(other)
919
920
921class flow_mod(ofp_flow_mod):
922 """
923 Wrapper class for flow_mod
924
925 OpenFlow message header: length, version, xid, type
926 @arg length: The total length of the message
927 @arg version: The OpenFlow version (1)
928 @arg xid: The transaction ID
929 @arg type: The message type (OFPT_FLOW_MOD=14)
930
931 Data members inherited from ofp_flow_mod:
Rich Laneb73808c2013-03-11 15:22:23 -0700932 @arg version
933 @arg type
934 @arg length
935 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -0800936 @arg match
937 @arg cookie
938 @arg command
939 @arg idle_timeout
940 @arg hard_timeout
941 @arg priority
942 @arg buffer_id
943 @arg out_port
944 @arg flags
945 @arg actions: Object of type action_list
946
947 """
948
949 def __init__(self, **kwargs):
950 ofp_flow_mod.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -0700951 self.version = OFP_VERSION
952 self.type = OFPT_FLOW_MOD
Rich Lane8fbfd662013-03-11 15:30:44 -0700953 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -0800954 self.actions = []
955 for (k, v) in kwargs.items():
956 if hasattr(self, k):
957 setattr(self, k, v)
958 else:
959 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane6242d9f2013-01-06 17:35:39 -0800960
961
962 def pack(self):
963 """
964 Pack object into string
965
966 @return The packed string which can go on the wire
967
968 """
Rich Laneb73808c2013-03-11 15:22:23 -0700969 self.length = len(self)
970 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -0800971
972 packed += ofp_flow_mod.pack(self)
Rich Lane62e96852013-03-11 12:04:45 -0700973 packed += action_list(self.actions).pack()
Rich Lane6242d9f2013-01-06 17:35:39 -0800974 return packed
975
976 def unpack(self, binary_string):
977 """
978 Unpack object from a binary string
979
980 @param binary_string The wire protocol byte string holding the object
981 represented as an array of bytes.
982 @return The remainder of binary_string that was not parsed.
983
984 """
Rich Lane6242d9f2013-01-06 17:35:39 -0800985
986 binary_string = ofp_flow_mod.unpack(self, binary_string)
Rich Laneb73808c2013-03-11 15:22:23 -0700987 ai_len = self.length - (OFP_FLOW_MOD_BYTES + OFP_HEADER_BYTES)
Rich Lane62e96852013-03-11 12:04:45 -0700988 obj = action_list()
989 binary_string = obj.unpack(binary_string, bytes=ai_len)
990 self.actions = list(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -0800991 # Fixme: If no self.data, add check for data remaining
992 return binary_string
993
994 def __len__(self):
995 """
996 Return the length of this object once packed into a string
997
998 @return An integer representing the number bytes in the packed
999 string.
1000
1001 """
Rich Laneb73808c2013-03-11 15:22:23 -07001002 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08001003
1004 length += ofp_flow_mod.__len__(self)
Rich Lane62e96852013-03-11 12:04:45 -07001005 for obj in self.actions:
1006 length += len(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08001007 return length
1008
1009 def show(self, prefix=''):
1010 """
1011 Generate a string (with multiple lines) describing the contents
1012 of the object in a readable manner
1013
1014 @param prefix Pre-pended at the beginning of each line.
1015
1016 """
1017
1018 outstr = prefix + 'flow_mod (OFPT_FLOW_MOD)\n'
1019 prefix += ' '
1020 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08001021 outstr += ofp_flow_mod.show(self, prefix)
1022 outstr += prefix + "List actions\n"
Rich Lanee6ea3fe2013-03-08 17:54:38 -08001023 for obj in self.actions:
1024 outstr += obj.show(prefix + " ")
Rich Lane6242d9f2013-01-06 17:35:39 -08001025 return outstr
1026
1027 def __eq__(self, other):
1028 """
1029 Return True if self and other hold the same data
1030
1031 @param other Other object in comparison
1032
1033 """
1034 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001035
1036 if not ofp_flow_mod.__eq__(self, other): return False
1037 if self.actions != other.actions: return False
1038 return True
1039
1040 def __ne__(self, other):
1041 """
1042 Return True if self and other do not hold the same data
1043
1044 @param other Other object in comparison
1045
1046 """
1047 return not self.__eq__(other)
1048
1049
1050class flow_removed(ofp_flow_removed):
1051 """
1052 Wrapper class for flow_removed
1053
1054 OpenFlow message header: length, version, xid, type
1055 @arg length: The total length of the message
1056 @arg version: The OpenFlow version (1)
1057 @arg xid: The transaction ID
1058 @arg type: The message type (OFPT_FLOW_REMOVED=11)
1059
1060 Data members inherited from ofp_flow_removed:
Rich Laneb73808c2013-03-11 15:22:23 -07001061 @arg version
1062 @arg type
1063 @arg length
1064 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08001065 @arg match
1066 @arg cookie
1067 @arg priority
1068 @arg reason
1069 @arg duration_sec
1070 @arg duration_nsec
1071 @arg idle_timeout
1072 @arg packet_count
1073 @arg byte_count
1074
1075 """
1076
1077 def __init__(self, **kwargs):
1078 ofp_flow_removed.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07001079 self.version = OFP_VERSION
1080 self.type = OFPT_FLOW_REMOVED
Rich Lane8fbfd662013-03-11 15:30:44 -07001081 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08001082 for (k, v) in kwargs.items():
1083 if hasattr(self, k):
1084 setattr(self, k, v)
1085 else:
1086 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1087
1088
1089 def pack(self):
1090 """
1091 Pack object into string
1092
1093 @return The packed string which can go on the wire
1094
1095 """
Rich Laneb73808c2013-03-11 15:22:23 -07001096 self.length = len(self)
1097 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08001098
1099 packed += ofp_flow_removed.pack(self)
1100 return packed
1101
1102 def unpack(self, binary_string):
1103 """
1104 Unpack object from a binary string
1105
1106 @param binary_string The wire protocol byte string holding the object
1107 represented as an array of bytes.
1108 @return The remainder of binary_string that was not parsed.
1109
1110 """
Rich Lane6242d9f2013-01-06 17:35:39 -08001111
1112 binary_string = ofp_flow_removed.unpack(self, binary_string)
1113 # Fixme: If no self.data, add check for data remaining
1114 return binary_string
1115
1116 def __len__(self):
1117 """
1118 Return the length of this object once packed into a string
1119
1120 @return An integer representing the number bytes in the packed
1121 string.
1122
1123 """
Rich Laneb73808c2013-03-11 15:22:23 -07001124 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08001125
1126 length += ofp_flow_removed.__len__(self)
1127 return length
1128
1129 def show(self, prefix=''):
1130 """
1131 Generate a string (with multiple lines) describing the contents
1132 of the object in a readable manner
1133
1134 @param prefix Pre-pended at the beginning of each line.
1135
1136 """
1137
1138 outstr = prefix + 'flow_removed (OFPT_FLOW_REMOVED)\n'
1139 prefix += ' '
1140 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08001141 outstr += ofp_flow_removed.show(self, prefix)
1142 return outstr
1143
1144 def __eq__(self, other):
1145 """
1146 Return True if self and other hold the same data
1147
1148 @param other Other object in comparison
1149
1150 """
1151 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001152
1153 if not ofp_flow_removed.__eq__(self, other): return False
1154 return True
1155
1156 def __ne__(self, other):
1157 """
1158 Return True if self and other do not hold the same data
1159
1160 @param other Other object in comparison
1161
1162 """
1163 return not self.__eq__(other)
1164
1165
1166class get_config_reply(ofp_switch_config):
1167 """
1168 Wrapper class for get_config_reply
1169
1170 OpenFlow message header: length, version, xid, type
1171 @arg length: The total length of the message
1172 @arg version: The OpenFlow version (1)
1173 @arg xid: The transaction ID
1174 @arg type: The message type (OFPT_GET_CONFIG_REPLY=8)
1175
1176 Data members inherited from ofp_switch_config:
Rich Laneb73808c2013-03-11 15:22:23 -07001177 @arg version
1178 @arg type
1179 @arg length
1180 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08001181 @arg flags
1182 @arg miss_send_len
1183
1184 """
1185
1186 def __init__(self, **kwargs):
1187 ofp_switch_config.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07001188 self.version = OFP_VERSION
1189 self.type = OFPT_GET_CONFIG_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -07001190 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08001191 for (k, v) in kwargs.items():
1192 if hasattr(self, k):
1193 setattr(self, k, v)
1194 else:
1195 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1196
1197
1198 def pack(self):
1199 """
1200 Pack object into string
1201
1202 @return The packed string which can go on the wire
1203
1204 """
Rich Laneb73808c2013-03-11 15:22:23 -07001205 self.length = len(self)
1206 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08001207
1208 packed += ofp_switch_config.pack(self)
1209 return packed
1210
1211 def unpack(self, binary_string):
1212 """
1213 Unpack object from a binary string
1214
1215 @param binary_string The wire protocol byte string holding the object
1216 represented as an array of bytes.
1217 @return The remainder of binary_string that was not parsed.
1218
1219 """
Rich Lane6242d9f2013-01-06 17:35:39 -08001220
1221 binary_string = ofp_switch_config.unpack(self, binary_string)
1222 # Fixme: If no self.data, add check for data remaining
1223 return binary_string
1224
1225 def __len__(self):
1226 """
1227 Return the length of this object once packed into a string
1228
1229 @return An integer representing the number bytes in the packed
1230 string.
1231
1232 """
Rich Laneb73808c2013-03-11 15:22:23 -07001233 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08001234
1235 length += ofp_switch_config.__len__(self)
1236 return length
1237
1238 def show(self, prefix=''):
1239 """
1240 Generate a string (with multiple lines) describing the contents
1241 of the object in a readable manner
1242
1243 @param prefix Pre-pended at the beginning of each line.
1244
1245 """
1246
1247 outstr = prefix + 'get_config_reply (OFPT_GET_CONFIG_REPLY)\n'
1248 prefix += ' '
1249 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08001250 outstr += ofp_switch_config.show(self, prefix)
1251 return outstr
1252
1253 def __eq__(self, other):
1254 """
1255 Return True if self and other hold the same data
1256
1257 @param other Other object in comparison
1258
1259 """
1260 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001261
1262 if not ofp_switch_config.__eq__(self, other): return False
1263 return True
1264
1265 def __ne__(self, other):
1266 """
1267 Return True if self and other do not hold the same data
1268
1269 @param other Other object in comparison
1270
1271 """
1272 return not self.__eq__(other)
1273
1274
Rich Laneb73808c2013-03-11 15:22:23 -07001275class get_config_request(ofp_header):
Rich Lane6242d9f2013-01-06 17:35:39 -08001276 """
1277 Wrapper class for get_config_request
1278
1279 OpenFlow message header: length, version, xid, type
1280 @arg length: The total length of the message
1281 @arg version: The OpenFlow version (1)
1282 @arg xid: The transaction ID
1283 @arg type: The message type (OFPT_GET_CONFIG_REQUEST=7)
1284
Rich Laneb73808c2013-03-11 15:22:23 -07001285 Data members inherited from ofp_header:
1286 @arg version
1287 @arg type
1288 @arg length
1289 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08001290
1291 """
1292
1293 def __init__(self, **kwargs):
Rich Laneb73808c2013-03-11 15:22:23 -07001294 ofp_header.__init__(self)
1295 self.version = OFP_VERSION
1296 self.type = OFPT_GET_CONFIG_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -07001297 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08001298 for (k, v) in kwargs.items():
1299 if hasattr(self, k):
1300 setattr(self, k, v)
1301 else:
1302 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1303
1304
1305 def pack(self):
1306 """
1307 Pack object into string
1308
1309 @return The packed string which can go on the wire
1310
1311 """
Rich Laneb73808c2013-03-11 15:22:23 -07001312 self.length = len(self)
1313 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08001314
Rich Laneb73808c2013-03-11 15:22:23 -07001315 packed += ofp_header.pack(self)
Rich Lane6242d9f2013-01-06 17:35:39 -08001316 return packed
1317
1318 def unpack(self, binary_string):
1319 """
1320 Unpack object from a binary string
1321
1322 @param binary_string The wire protocol byte string holding the object
1323 represented as an array of bytes.
1324 @return The remainder of binary_string that was not parsed.
1325
1326 """
Rich Lane6242d9f2013-01-06 17:35:39 -08001327
Rich Laneb73808c2013-03-11 15:22:23 -07001328 binary_string = ofp_header.unpack(self, binary_string)
Rich Lane6242d9f2013-01-06 17:35:39 -08001329 # Fixme: If no self.data, add check for data remaining
1330 return binary_string
1331
1332 def __len__(self):
1333 """
1334 Return the length of this object once packed into a string
1335
1336 @return An integer representing the number bytes in the packed
1337 string.
1338
1339 """
Rich Laneb73808c2013-03-11 15:22:23 -07001340 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08001341
Rich Laneb73808c2013-03-11 15:22:23 -07001342 length += ofp_header.__len__(self)
Rich Lane6242d9f2013-01-06 17:35:39 -08001343 return length
1344
1345 def show(self, prefix=''):
1346 """
1347 Generate a string (with multiple lines) describing the contents
1348 of the object in a readable manner
1349
1350 @param prefix Pre-pended at the beginning of each line.
1351
1352 """
1353
1354 outstr = prefix + 'get_config_request (OFPT_GET_CONFIG_REQUEST)\n'
1355 prefix += ' '
1356 outstr += prefix + 'ofp header\n'
Rich Laneb73808c2013-03-11 15:22:23 -07001357 outstr += ofp_header.show(self, prefix)
Rich Lane6242d9f2013-01-06 17:35:39 -08001358 return outstr
1359
1360 def __eq__(self, other):
1361 """
1362 Return True if self and other hold the same data
1363
1364 @param other Other object in comparison
1365
1366 """
1367 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001368
Rich Laneb73808c2013-03-11 15:22:23 -07001369 if not ofp_header.__eq__(self, other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001370 return True
1371
1372 def __ne__(self, other):
1373 """
1374 Return True if self and other do not hold the same data
1375
1376 @param other Other object in comparison
1377
1378 """
1379 return not self.__eq__(other)
1380
1381
Rich Laneb73808c2013-03-11 15:22:23 -07001382class hello(ofp_header):
Rich Lane6242d9f2013-01-06 17:35:39 -08001383 """
1384 Wrapper class for hello
1385
1386 OpenFlow message header: length, version, xid, type
1387 @arg length: The total length of the message
1388 @arg version: The OpenFlow version (1)
1389 @arg xid: The transaction ID
1390 @arg type: The message type (OFPT_HELLO=0)
1391
Rich Laneb73808c2013-03-11 15:22:23 -07001392 Data members inherited from ofp_header:
1393 @arg version
1394 @arg type
1395 @arg length
1396 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08001397 @arg data: Binary string following message members
1398
1399 """
1400
1401 def __init__(self, **kwargs):
Rich Laneb73808c2013-03-11 15:22:23 -07001402 ofp_header.__init__(self)
1403 self.version = OFP_VERSION
1404 self.type = OFPT_HELLO
Rich Lane8fbfd662013-03-11 15:30:44 -07001405 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08001406 self.data = ""
1407 for (k, v) in kwargs.items():
1408 if hasattr(self, k):
1409 setattr(self, k, v)
1410 else:
1411 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1412
1413
1414 def pack(self):
1415 """
1416 Pack object into string
1417
1418 @return The packed string which can go on the wire
1419
1420 """
Rich Laneb73808c2013-03-11 15:22:23 -07001421 self.length = len(self)
1422 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08001423
Rich Laneb73808c2013-03-11 15:22:23 -07001424 packed += ofp_header.pack(self)
Rich Lane6242d9f2013-01-06 17:35:39 -08001425 packed += self.data
1426 return packed
1427
1428 def unpack(self, binary_string):
1429 """
1430 Unpack object from a binary string
1431
1432 @param binary_string The wire protocol byte string holding the object
1433 represented as an array of bytes.
1434 @return The remainder of binary_string that was not parsed.
1435
1436 """
Rich Lane6242d9f2013-01-06 17:35:39 -08001437
Rich Laneb73808c2013-03-11 15:22:23 -07001438 binary_string = ofp_header.unpack(self, binary_string)
Rich Lane6242d9f2013-01-06 17:35:39 -08001439 self.data = binary_string
1440 binary_string = ''
1441 return binary_string
1442
1443 def __len__(self):
1444 """
1445 Return the length of this object once packed into a string
1446
1447 @return An integer representing the number bytes in the packed
1448 string.
1449
1450 """
Rich Laneb73808c2013-03-11 15:22:23 -07001451 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08001452
Rich Laneb73808c2013-03-11 15:22:23 -07001453 length += ofp_header.__len__(self)
Rich Lane6242d9f2013-01-06 17:35:39 -08001454 length += len(self.data)
1455 return length
1456
1457 def show(self, prefix=''):
1458 """
1459 Generate a string (with multiple lines) describing the contents
1460 of the object in a readable manner
1461
1462 @param prefix Pre-pended at the beginning of each line.
1463
1464 """
1465
1466 outstr = prefix + 'hello (OFPT_HELLO)\n'
1467 prefix += ' '
1468 outstr += prefix + 'ofp header\n'
Rich Laneb73808c2013-03-11 15:22:23 -07001469 outstr += ofp_header.show(self, prefix)
Rich Lane6242d9f2013-01-06 17:35:39 -08001470 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
1471 ##@todo Fix this circular reference
1472 # if len(self.data) > 0:
1473 # obj = of_message_parse(self.data)
1474 # if obj != None:
1475 # outstr += obj.show(prefix)
1476 # else:
1477 # outstr += prefix + "Unable to parse data\n"
1478 return outstr
1479
1480 def __eq__(self, other):
1481 """
1482 Return True if self and other hold the same data
1483
1484 @param other Other object in comparison
1485
1486 """
1487 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001488
Rich Laneb73808c2013-03-11 15:22:23 -07001489 if not ofp_header.__eq__(self, other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001490 if self.data != other.data: return False
1491 return True
1492
1493 def __ne__(self, other):
1494 """
1495 Return True if self and other do not hold the same data
1496
1497 @param other Other object in comparison
1498
1499 """
1500 return not self.__eq__(other)
1501
1502
1503class packet_in(ofp_packet_in):
1504 """
1505 Wrapper class for packet_in
1506
1507 OpenFlow message header: length, version, xid, type
1508 @arg length: The total length of the message
1509 @arg version: The OpenFlow version (1)
1510 @arg xid: The transaction ID
1511 @arg type: The message type (OFPT_PACKET_IN=10)
1512
1513 Data members inherited from ofp_packet_in:
Rich Laneb73808c2013-03-11 15:22:23 -07001514 @arg version
1515 @arg type
1516 @arg length
1517 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08001518 @arg buffer_id
1519 @arg total_len
1520 @arg in_port
1521 @arg reason
1522 @arg data: Binary string following message members
1523
1524 """
1525
1526 def __init__(self, **kwargs):
1527 ofp_packet_in.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07001528 self.version = OFP_VERSION
1529 self.type = OFPT_PACKET_IN
Rich Lane8fbfd662013-03-11 15:30:44 -07001530 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08001531 self.data = ""
1532 for (k, v) in kwargs.items():
1533 if hasattr(self, k):
1534 setattr(self, k, v)
1535 else:
1536 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1537
1538
1539 def pack(self):
1540 """
1541 Pack object into string
1542
1543 @return The packed string which can go on the wire
1544
1545 """
Rich Laneb73808c2013-03-11 15:22:23 -07001546 self.length = len(self)
1547 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08001548
1549 packed += ofp_packet_in.pack(self)
1550 packed += self.data
1551 return packed
1552
1553 def unpack(self, binary_string):
1554 """
1555 Unpack object from a binary string
1556
1557 @param binary_string The wire protocol byte string holding the object
1558 represented as an array of bytes.
1559 @return The remainder of binary_string that was not parsed.
1560
1561 """
Rich Lane6242d9f2013-01-06 17:35:39 -08001562
1563 binary_string = ofp_packet_in.unpack(self, binary_string)
1564 self.data = binary_string
1565 binary_string = ''
1566 return binary_string
1567
1568 def __len__(self):
1569 """
1570 Return the length of this object once packed into a string
1571
1572 @return An integer representing the number bytes in the packed
1573 string.
1574
1575 """
Rich Laneb73808c2013-03-11 15:22:23 -07001576 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08001577
1578 length += ofp_packet_in.__len__(self)
1579 length += len(self.data)
1580 return length
1581
1582 def show(self, prefix=''):
1583 """
1584 Generate a string (with multiple lines) describing the contents
1585 of the object in a readable manner
1586
1587 @param prefix Pre-pended at the beginning of each line.
1588
1589 """
1590
1591 outstr = prefix + 'packet_in (OFPT_PACKET_IN)\n'
1592 prefix += ' '
1593 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08001594 outstr += ofp_packet_in.show(self, prefix)
1595 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
1596 ##@todo Fix this circular reference
1597 # if len(self.data) > 0:
1598 # obj = of_message_parse(self.data)
1599 # if obj != None:
1600 # outstr += obj.show(prefix)
1601 # else:
1602 # outstr += prefix + "Unable to parse data\n"
1603 return outstr
1604
1605 def __eq__(self, other):
1606 """
1607 Return True if self and other hold the same data
1608
1609 @param other Other object in comparison
1610
1611 """
1612 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001613
1614 if not ofp_packet_in.__eq__(self, other): return False
1615 if self.data != other.data: return False
1616 return True
1617
1618 def __ne__(self, other):
1619 """
1620 Return True if self and other do not hold the same data
1621
1622 @param other Other object in comparison
1623
1624 """
1625 return not self.__eq__(other)
1626
1627
1628class packet_out(ofp_packet_out):
1629 """
1630 Wrapper class for packet_out
1631
1632 OpenFlow message header: length, version, xid, type
1633 @arg length: The total length of the message
1634 @arg version: The OpenFlow version (1)
1635 @arg xid: The transaction ID
1636 @arg type: The message type (OFPT_PACKET_OUT=13)
1637
1638 Data members inherited from ofp_packet_out:
Rich Laneb73808c2013-03-11 15:22:23 -07001639 @arg version
1640 @arg type
1641 @arg length
1642 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08001643 @arg buffer_id
1644 @arg in_port
1645 @arg actions_len
1646 @arg actions: Object of type action_list
1647 @arg data: Binary string following message members
1648
1649 """
1650
1651 def __init__(self, **kwargs):
1652 ofp_packet_out.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07001653 self.version = OFP_VERSION
1654 self.type = OFPT_PACKET_OUT
Rich Lane8fbfd662013-03-11 15:30:44 -07001655 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08001656 self.actions = []
1657 self.data = ""
1658 for (k, v) in kwargs.items():
1659 if hasattr(self, k):
1660 setattr(self, k, v)
1661 else:
1662 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane6242d9f2013-01-06 17:35:39 -08001663
1664
1665 def pack(self):
1666 """
1667 Pack object into string
1668
1669 @return The packed string which can go on the wire
1670
1671 """
Rich Laneb73808c2013-03-11 15:22:23 -07001672 self.length = len(self)
1673 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08001674
Rich Lane62e96852013-03-11 12:04:45 -07001675 self.actions_len = 0
1676 for obj in self.actions:
1677 self.actions_len += len(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08001678 packed += ofp_packet_out.pack(self)
Rich Lane62e96852013-03-11 12:04:45 -07001679 packed += action_list(self.actions).pack()
Rich Lane6242d9f2013-01-06 17:35:39 -08001680 packed += self.data
1681 return packed
1682
1683 def unpack(self, binary_string):
1684 """
1685 Unpack object from a binary string
1686
1687 @param binary_string The wire protocol byte string holding the object
1688 represented as an array of bytes.
1689 @return The remainder of binary_string that was not parsed.
1690
1691 """
Rich Lane6242d9f2013-01-06 17:35:39 -08001692
1693 binary_string = ofp_packet_out.unpack(self, binary_string)
Rich Lane62e96852013-03-11 12:04:45 -07001694 obj = action_list()
1695 binary_string = obj.unpack(binary_string, bytes=self.actions_len)
1696 self.actions = list(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08001697 self.data = binary_string
1698 binary_string = ''
1699 return binary_string
1700
1701 def __len__(self):
1702 """
1703 Return the length of this object once packed into a string
1704
1705 @return An integer representing the number bytes in the packed
1706 string.
1707
1708 """
Rich Laneb73808c2013-03-11 15:22:23 -07001709 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08001710
1711 length += ofp_packet_out.__len__(self)
Rich Lane62e96852013-03-11 12:04:45 -07001712 for obj in self.actions:
1713 length += len(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08001714 length += len(self.data)
1715 return length
1716
1717 def show(self, prefix=''):
1718 """
1719 Generate a string (with multiple lines) describing the contents
1720 of the object in a readable manner
1721
1722 @param prefix Pre-pended at the beginning of each line.
1723
1724 """
1725
1726 outstr = prefix + 'packet_out (OFPT_PACKET_OUT)\n'
1727 prefix += ' '
1728 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08001729 outstr += ofp_packet_out.show(self, prefix)
1730 outstr += prefix + "List actions\n"
Rich Lanee6ea3fe2013-03-08 17:54:38 -08001731 for obj in self.actions:
1732 outstr += obj.show(prefix + " ")
Rich Lane6242d9f2013-01-06 17:35:39 -08001733 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
1734 ##@todo Fix this circular reference
1735 # if len(self.data) > 0:
1736 # obj = of_message_parse(self.data)
1737 # if obj != None:
1738 # outstr += obj.show(prefix)
1739 # else:
1740 # outstr += prefix + "Unable to parse data\n"
1741 return outstr
1742
1743 def __eq__(self, other):
1744 """
1745 Return True if self and other hold the same data
1746
1747 @param other Other object in comparison
1748
1749 """
1750 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001751
1752 if not ofp_packet_out.__eq__(self, other): return False
1753 if self.data != other.data: return False
1754 if self.actions != other.actions: return False
1755 return True
1756
1757 def __ne__(self, other):
1758 """
1759 Return True if self and other do not hold the same data
1760
1761 @param other Other object in comparison
1762
1763 """
1764 return not self.__eq__(other)
1765
1766
1767class port_mod(ofp_port_mod):
1768 """
1769 Wrapper class for port_mod
1770
1771 OpenFlow message header: length, version, xid, type
1772 @arg length: The total length of the message
1773 @arg version: The OpenFlow version (1)
1774 @arg xid: The transaction ID
1775 @arg type: The message type (OFPT_PORT_MOD=15)
1776
1777 Data members inherited from ofp_port_mod:
Rich Laneb73808c2013-03-11 15:22:23 -07001778 @arg version
1779 @arg type
1780 @arg length
1781 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08001782 @arg port_no
1783 @arg hw_addr
1784 @arg config
1785 @arg mask
1786 @arg advertise
1787
1788 """
1789
1790 def __init__(self, **kwargs):
1791 ofp_port_mod.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07001792 self.version = OFP_VERSION
1793 self.type = OFPT_PORT_MOD
Rich Lane8fbfd662013-03-11 15:30:44 -07001794 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08001795 for (k, v) in kwargs.items():
1796 if hasattr(self, k):
1797 setattr(self, k, v)
1798 else:
1799 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1800
1801
1802 def pack(self):
1803 """
1804 Pack object into string
1805
1806 @return The packed string which can go on the wire
1807
1808 """
Rich Laneb73808c2013-03-11 15:22:23 -07001809 self.length = len(self)
1810 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08001811
1812 packed += ofp_port_mod.pack(self)
1813 return packed
1814
1815 def unpack(self, binary_string):
1816 """
1817 Unpack object from a binary string
1818
1819 @param binary_string The wire protocol byte string holding the object
1820 represented as an array of bytes.
1821 @return The remainder of binary_string that was not parsed.
1822
1823 """
Rich Lane6242d9f2013-01-06 17:35:39 -08001824
1825 binary_string = ofp_port_mod.unpack(self, binary_string)
1826 # Fixme: If no self.data, add check for data remaining
1827 return binary_string
1828
1829 def __len__(self):
1830 """
1831 Return the length of this object once packed into a string
1832
1833 @return An integer representing the number bytes in the packed
1834 string.
1835
1836 """
Rich Laneb73808c2013-03-11 15:22:23 -07001837 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08001838
1839 length += ofp_port_mod.__len__(self)
1840 return length
1841
1842 def show(self, prefix=''):
1843 """
1844 Generate a string (with multiple lines) describing the contents
1845 of the object in a readable manner
1846
1847 @param prefix Pre-pended at the beginning of each line.
1848
1849 """
1850
1851 outstr = prefix + 'port_mod (OFPT_PORT_MOD)\n'
1852 prefix += ' '
1853 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08001854 outstr += ofp_port_mod.show(self, prefix)
1855 return outstr
1856
1857 def __eq__(self, other):
1858 """
1859 Return True if self and other hold the same data
1860
1861 @param other Other object in comparison
1862
1863 """
1864 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001865
1866 if not ofp_port_mod.__eq__(self, other): return False
1867 return True
1868
1869 def __ne__(self, other):
1870 """
1871 Return True if self and other do not hold the same data
1872
1873 @param other Other object in comparison
1874
1875 """
1876 return not self.__eq__(other)
1877
1878
1879class port_status(ofp_port_status):
1880 """
1881 Wrapper class for port_status
1882
1883 OpenFlow message header: length, version, xid, type
1884 @arg length: The total length of the message
1885 @arg version: The OpenFlow version (1)
1886 @arg xid: The transaction ID
1887 @arg type: The message type (OFPT_PORT_STATUS=12)
1888
1889 Data members inherited from ofp_port_status:
Rich Laneb73808c2013-03-11 15:22:23 -07001890 @arg version
1891 @arg type
1892 @arg length
1893 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08001894 @arg reason
1895 @arg desc
1896
1897 """
1898
1899 def __init__(self, **kwargs):
1900 ofp_port_status.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07001901 self.version = OFP_VERSION
1902 self.type = OFPT_PORT_STATUS
Rich Lane8fbfd662013-03-11 15:30:44 -07001903 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08001904 for (k, v) in kwargs.items():
1905 if hasattr(self, k):
1906 setattr(self, k, v)
1907 else:
1908 raise NameError("field %s does not exist in %s" % (k, self.__class__))
1909
1910
1911 def pack(self):
1912 """
1913 Pack object into string
1914
1915 @return The packed string which can go on the wire
1916
1917 """
Rich Laneb73808c2013-03-11 15:22:23 -07001918 self.length = len(self)
1919 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08001920
1921 packed += ofp_port_status.pack(self)
1922 return packed
1923
1924 def unpack(self, binary_string):
1925 """
1926 Unpack object from a binary string
1927
1928 @param binary_string The wire protocol byte string holding the object
1929 represented as an array of bytes.
1930 @return The remainder of binary_string that was not parsed.
1931
1932 """
Rich Lane6242d9f2013-01-06 17:35:39 -08001933
1934 binary_string = ofp_port_status.unpack(self, binary_string)
1935 # Fixme: If no self.data, add check for data remaining
1936 return binary_string
1937
1938 def __len__(self):
1939 """
1940 Return the length of this object once packed into a string
1941
1942 @return An integer representing the number bytes in the packed
1943 string.
1944
1945 """
Rich Laneb73808c2013-03-11 15:22:23 -07001946 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08001947
1948 length += ofp_port_status.__len__(self)
1949 return length
1950
1951 def show(self, prefix=''):
1952 """
1953 Generate a string (with multiple lines) describing the contents
1954 of the object in a readable manner
1955
1956 @param prefix Pre-pended at the beginning of each line.
1957
1958 """
1959
1960 outstr = prefix + 'port_status (OFPT_PORT_STATUS)\n'
1961 prefix += ' '
1962 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08001963 outstr += ofp_port_status.show(self, prefix)
1964 return outstr
1965
1966 def __eq__(self, other):
1967 """
1968 Return True if self and other hold the same data
1969
1970 @param other Other object in comparison
1971
1972 """
1973 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08001974
1975 if not ofp_port_status.__eq__(self, other): return False
1976 return True
1977
1978 def __ne__(self, other):
1979 """
1980 Return True if self and other do not hold the same data
1981
1982 @param other Other object in comparison
1983
1984 """
1985 return not self.__eq__(other)
1986
1987
1988class queue_get_config_reply(ofp_queue_get_config_reply):
1989 """
1990 Wrapper class for queue_get_config_reply
1991
1992 OpenFlow message header: length, version, xid, type
1993 @arg length: The total length of the message
1994 @arg version: The OpenFlow version (1)
1995 @arg xid: The transaction ID
1996 @arg type: The message type (OFPT_QUEUE_GET_CONFIG_REPLY=21)
1997
1998 Data members inherited from ofp_queue_get_config_reply:
Rich Laneb73808c2013-03-11 15:22:23 -07001999 @arg version
2000 @arg type
2001 @arg length
2002 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08002003 @arg port
2004 @arg queues: Variable length array of TBD
2005
2006 """
2007
2008 def __init__(self, **kwargs):
2009 ofp_queue_get_config_reply.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002010 self.version = OFP_VERSION
2011 self.type = OFPT_QUEUE_GET_CONFIG_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -07002012 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08002013 self.queues = []
2014 for (k, v) in kwargs.items():
2015 if hasattr(self, k):
2016 setattr(self, k, v)
2017 else:
2018 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2019
2020
2021 def pack(self):
2022 """
2023 Pack object into string
2024
2025 @return The packed string which can go on the wire
2026
2027 """
Rich Laneb73808c2013-03-11 15:22:23 -07002028 self.length = len(self)
2029 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08002030
2031 packed += ofp_queue_get_config_reply.pack(self)
2032 for obj in self.queues:
2033 packed += obj.pack()
2034 return packed
2035
2036 def unpack(self, binary_string):
2037 """
2038 Unpack object from a binary string
2039
2040 @param binary_string The wire protocol byte string holding the object
2041 represented as an array of bytes.
2042 @return The remainder of binary_string that was not parsed.
2043
2044 """
Rich Lane6242d9f2013-01-06 17:35:39 -08002045
2046 binary_string = ofp_queue_get_config_reply.unpack(self, binary_string)
2047 for obj in self.queues:
2048 binary_string = obj.unpack(binary_string)
2049 # Fixme: If no self.data, add check for data remaining
2050 return binary_string
2051
2052 def __len__(self):
2053 """
2054 Return the length of this object once packed into a string
2055
2056 @return An integer representing the number bytes in the packed
2057 string.
2058
2059 """
Rich Laneb73808c2013-03-11 15:22:23 -07002060 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08002061
2062 length += ofp_queue_get_config_reply.__len__(self)
2063 for obj in self.queues:
2064 length += len(obj)
2065 return length
2066
2067 def show(self, prefix=''):
2068 """
2069 Generate a string (with multiple lines) describing the contents
2070 of the object in a readable manner
2071
2072 @param prefix Pre-pended at the beginning of each line.
2073
2074 """
2075
2076 outstr = prefix + 'queue_get_config_reply (OFPT_QUEUE_GET_CONFIG_REPLY)\n'
2077 prefix += ' '
2078 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08002079 outstr += ofp_queue_get_config_reply.show(self, prefix)
2080 outstr += prefix + "Array queues\n"
2081 for obj in self.queues:
2082 outstr += obj.show(prefix + ' ')
2083 return outstr
2084
2085 def __eq__(self, other):
2086 """
2087 Return True if self and other hold the same data
2088
2089 @param other Other object in comparison
2090
2091 """
2092 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08002093
2094 if not ofp_queue_get_config_reply.__eq__(self, other): return False
2095 if self.queues != other.queues: return False
2096 return True
2097
2098 def __ne__(self, other):
2099 """
2100 Return True if self and other do not hold the same data
2101
2102 @param other Other object in comparison
2103
2104 """
2105 return not self.__eq__(other)
2106
2107
2108class queue_get_config_request(ofp_queue_get_config_request):
2109 """
2110 Wrapper class for queue_get_config_request
2111
2112 OpenFlow message header: length, version, xid, type
2113 @arg length: The total length of the message
2114 @arg version: The OpenFlow version (1)
2115 @arg xid: The transaction ID
2116 @arg type: The message type (OFPT_QUEUE_GET_CONFIG_REQUEST=20)
2117
2118 Data members inherited from ofp_queue_get_config_request:
Rich Laneb73808c2013-03-11 15:22:23 -07002119 @arg version
2120 @arg type
2121 @arg length
2122 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08002123 @arg port
2124
2125 """
2126
2127 def __init__(self, **kwargs):
2128 ofp_queue_get_config_request.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002129 self.version = OFP_VERSION
2130 self.type = OFPT_QUEUE_GET_CONFIG_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -07002131 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08002132 for (k, v) in kwargs.items():
2133 if hasattr(self, k):
2134 setattr(self, k, v)
2135 else:
2136 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2137
2138
2139 def pack(self):
2140 """
2141 Pack object into string
2142
2143 @return The packed string which can go on the wire
2144
2145 """
Rich Laneb73808c2013-03-11 15:22:23 -07002146 self.length = len(self)
2147 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08002148
2149 packed += ofp_queue_get_config_request.pack(self)
2150 return packed
2151
2152 def unpack(self, binary_string):
2153 """
2154 Unpack object from a binary string
2155
2156 @param binary_string The wire protocol byte string holding the object
2157 represented as an array of bytes.
2158 @return The remainder of binary_string that was not parsed.
2159
2160 """
Rich Lane6242d9f2013-01-06 17:35:39 -08002161
2162 binary_string = ofp_queue_get_config_request.unpack(self, binary_string)
2163 # Fixme: If no self.data, add check for data remaining
2164 return binary_string
2165
2166 def __len__(self):
2167 """
2168 Return the length of this object once packed into a string
2169
2170 @return An integer representing the number bytes in the packed
2171 string.
2172
2173 """
Rich Laneb73808c2013-03-11 15:22:23 -07002174 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08002175
2176 length += ofp_queue_get_config_request.__len__(self)
2177 return length
2178
2179 def show(self, prefix=''):
2180 """
2181 Generate a string (with multiple lines) describing the contents
2182 of the object in a readable manner
2183
2184 @param prefix Pre-pended at the beginning of each line.
2185
2186 """
2187
2188 outstr = prefix + 'queue_get_config_request (OFPT_QUEUE_GET_CONFIG_REQUEST)\n'
2189 prefix += ' '
2190 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08002191 outstr += ofp_queue_get_config_request.show(self, prefix)
2192 return outstr
2193
2194 def __eq__(self, other):
2195 """
2196 Return True if self and other hold the same data
2197
2198 @param other Other object in comparison
2199
2200 """
2201 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08002202
2203 if not ofp_queue_get_config_request.__eq__(self, other): return False
2204 return True
2205
2206 def __ne__(self, other):
2207 """
2208 Return True if self and other do not hold the same data
2209
2210 @param other Other object in comparison
2211
2212 """
2213 return not self.__eq__(other)
2214
2215
2216class set_config(ofp_switch_config):
2217 """
2218 Wrapper class for set_config
2219
2220 OpenFlow message header: length, version, xid, type
2221 @arg length: The total length of the message
2222 @arg version: The OpenFlow version (1)
2223 @arg xid: The transaction ID
2224 @arg type: The message type (OFPT_SET_CONFIG=9)
2225
2226 Data members inherited from ofp_switch_config:
Rich Laneb73808c2013-03-11 15:22:23 -07002227 @arg version
2228 @arg type
2229 @arg length
2230 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08002231 @arg flags
2232 @arg miss_send_len
2233
2234 """
2235
2236 def __init__(self, **kwargs):
2237 ofp_switch_config.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002238 self.version = OFP_VERSION
2239 self.type = OFPT_SET_CONFIG
Rich Lane8fbfd662013-03-11 15:30:44 -07002240 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08002241 for (k, v) in kwargs.items():
2242 if hasattr(self, k):
2243 setattr(self, k, v)
2244 else:
2245 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2246
2247
2248 def pack(self):
2249 """
2250 Pack object into string
2251
2252 @return The packed string which can go on the wire
2253
2254 """
Rich Laneb73808c2013-03-11 15:22:23 -07002255 self.length = len(self)
2256 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08002257
2258 packed += ofp_switch_config.pack(self)
2259 return packed
2260
2261 def unpack(self, binary_string):
2262 """
2263 Unpack object from a binary string
2264
2265 @param binary_string The wire protocol byte string holding the object
2266 represented as an array of bytes.
2267 @return The remainder of binary_string that was not parsed.
2268
2269 """
Rich Lane6242d9f2013-01-06 17:35:39 -08002270
2271 binary_string = ofp_switch_config.unpack(self, binary_string)
2272 # Fixme: If no self.data, add check for data remaining
2273 return binary_string
2274
2275 def __len__(self):
2276 """
2277 Return the length of this object once packed into a string
2278
2279 @return An integer representing the number bytes in the packed
2280 string.
2281
2282 """
Rich Laneb73808c2013-03-11 15:22:23 -07002283 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08002284
2285 length += ofp_switch_config.__len__(self)
2286 return length
2287
2288 def show(self, prefix=''):
2289 """
2290 Generate a string (with multiple lines) describing the contents
2291 of the object in a readable manner
2292
2293 @param prefix Pre-pended at the beginning of each line.
2294
2295 """
2296
2297 outstr = prefix + 'set_config (OFPT_SET_CONFIG)\n'
2298 prefix += ' '
2299 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08002300 outstr += ofp_switch_config.show(self, prefix)
2301 return outstr
2302
2303 def __eq__(self, other):
2304 """
2305 Return True if self and other hold the same data
2306
2307 @param other Other object in comparison
2308
2309 """
2310 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08002311
2312 if not ofp_switch_config.__eq__(self, other): return False
2313 return True
2314
2315 def __ne__(self, other):
2316 """
2317 Return True if self and other do not hold the same data
2318
2319 @param other Other object in comparison
2320
2321 """
2322 return not self.__eq__(other)
2323
2324
2325class stats_reply(ofp_stats_reply):
2326 """
2327 Wrapper class for stats_reply
2328
2329 OpenFlow message header: length, version, xid, type
2330 @arg length: The total length of the message
2331 @arg version: The OpenFlow version (1)
2332 @arg xid: The transaction ID
2333 @arg type: The message type (OFPT_STATS_REPLY=17)
2334
2335 Data members inherited from ofp_stats_reply:
Rich Laneb73808c2013-03-11 15:22:23 -07002336 @arg version
2337 @arg type
2338 @arg length
2339 @arg xid
Rich Lane7c7342a2013-03-11 14:16:58 -07002340 @arg stats_type
Rich Lane6242d9f2013-01-06 17:35:39 -08002341 @arg flags
2342
2343 """
2344
2345 def __init__(self, **kwargs):
2346 ofp_stats_reply.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002347 self.version = OFP_VERSION
2348 self.type = OFPT_STATS_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -07002349 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08002350 for (k, v) in kwargs.items():
2351 if hasattr(self, k):
2352 setattr(self, k, v)
2353 else:
2354 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2355
2356
2357 def pack(self):
2358 """
2359 Pack object into string
2360
2361 @return The packed string which can go on the wire
2362
2363 """
Rich Laneb73808c2013-03-11 15:22:23 -07002364 self.length = len(self)
2365 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08002366
2367 packed += ofp_stats_reply.pack(self)
2368 return packed
2369
2370 def unpack(self, binary_string):
2371 """
2372 Unpack object from a binary string
2373
2374 @param binary_string The wire protocol byte string holding the object
2375 represented as an array of bytes.
2376 @return The remainder of binary_string that was not parsed.
2377
2378 """
Rich Lane6242d9f2013-01-06 17:35:39 -08002379
2380 binary_string = ofp_stats_reply.unpack(self, binary_string)
2381 # Fixme: If no self.data, add check for data remaining
2382 return binary_string
2383
2384 def __len__(self):
2385 """
2386 Return the length of this object once packed into a string
2387
2388 @return An integer representing the number bytes in the packed
2389 string.
2390
2391 """
Rich Laneb73808c2013-03-11 15:22:23 -07002392 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08002393
2394 length += ofp_stats_reply.__len__(self)
2395 return length
2396
2397 def show(self, prefix=''):
2398 """
2399 Generate a string (with multiple lines) describing the contents
2400 of the object in a readable manner
2401
2402 @param prefix Pre-pended at the beginning of each line.
2403
2404 """
2405
2406 outstr = prefix + 'stats_reply (OFPT_STATS_REPLY)\n'
2407 prefix += ' '
2408 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08002409 outstr += ofp_stats_reply.show(self, prefix)
2410 return outstr
2411
2412 def __eq__(self, other):
2413 """
2414 Return True if self and other hold the same data
2415
2416 @param other Other object in comparison
2417
2418 """
2419 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08002420
2421 if not ofp_stats_reply.__eq__(self, other): return False
2422 return True
2423
2424 def __ne__(self, other):
2425 """
2426 Return True if self and other do not hold the same data
2427
2428 @param other Other object in comparison
2429
2430 """
2431 return not self.__eq__(other)
2432
2433
2434class stats_request(ofp_stats_request):
2435 """
2436 Wrapper class for stats_request
2437
2438 OpenFlow message header: length, version, xid, type
2439 @arg length: The total length of the message
2440 @arg version: The OpenFlow version (1)
2441 @arg xid: The transaction ID
2442 @arg type: The message type (OFPT_STATS_REQUEST=16)
2443
2444 Data members inherited from ofp_stats_request:
Rich Laneb73808c2013-03-11 15:22:23 -07002445 @arg version
2446 @arg type
2447 @arg length
2448 @arg xid
Rich Lane7c7342a2013-03-11 14:16:58 -07002449 @arg stats_type
Rich Lane6242d9f2013-01-06 17:35:39 -08002450 @arg flags
2451
2452 """
2453
2454 def __init__(self, **kwargs):
2455 ofp_stats_request.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002456 self.version = OFP_VERSION
2457 self.type = OFPT_STATS_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -07002458 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08002459 for (k, v) in kwargs.items():
2460 if hasattr(self, k):
2461 setattr(self, k, v)
2462 else:
2463 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2464
2465
2466 def pack(self):
2467 """
2468 Pack object into string
2469
2470 @return The packed string which can go on the wire
2471
2472 """
Rich Laneb73808c2013-03-11 15:22:23 -07002473 self.length = len(self)
2474 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08002475
2476 packed += ofp_stats_request.pack(self)
2477 return packed
2478
2479 def unpack(self, binary_string):
2480 """
2481 Unpack object from a binary string
2482
2483 @param binary_string The wire protocol byte string holding the object
2484 represented as an array of bytes.
2485 @return The remainder of binary_string that was not parsed.
2486
2487 """
Rich Lane6242d9f2013-01-06 17:35:39 -08002488
2489 binary_string = ofp_stats_request.unpack(self, binary_string)
2490 # Fixme: If no self.data, add check for data remaining
2491 return binary_string
2492
2493 def __len__(self):
2494 """
2495 Return the length of this object once packed into a string
2496
2497 @return An integer representing the number bytes in the packed
2498 string.
2499
2500 """
Rich Laneb73808c2013-03-11 15:22:23 -07002501 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08002502
2503 length += ofp_stats_request.__len__(self)
2504 return length
2505
2506 def show(self, prefix=''):
2507 """
2508 Generate a string (with multiple lines) describing the contents
2509 of the object in a readable manner
2510
2511 @param prefix Pre-pended at the beginning of each line.
2512
2513 """
2514
2515 outstr = prefix + 'stats_request (OFPT_STATS_REQUEST)\n'
2516 prefix += ' '
2517 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08002518 outstr += ofp_stats_request.show(self, prefix)
2519 return outstr
2520
2521 def __eq__(self, other):
2522 """
2523 Return True if self and other hold the same data
2524
2525 @param other Other object in comparison
2526
2527 """
2528 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08002529
2530 if not ofp_stats_request.__eq__(self, other): return False
2531 return True
2532
2533 def __ne__(self, other):
2534 """
2535 Return True if self and other do not hold the same data
2536
2537 @param other Other object in comparison
2538
2539 """
2540 return not self.__eq__(other)
2541
2542
2543class vendor(ofp_vendor_header):
2544 """
2545 Wrapper class for vendor
2546
2547 OpenFlow message header: length, version, xid, type
2548 @arg length: The total length of the message
2549 @arg version: The OpenFlow version (1)
2550 @arg xid: The transaction ID
2551 @arg type: The message type (OFPT_VENDOR=4)
2552
2553 Data members inherited from ofp_vendor_header:
Rich Laneb73808c2013-03-11 15:22:23 -07002554 @arg version
2555 @arg type
2556 @arg length
2557 @arg xid
Rich Lane6242d9f2013-01-06 17:35:39 -08002558 @arg vendor
2559 @arg data: Binary string following message members
2560
2561 """
2562
2563 def __init__(self, **kwargs):
2564 ofp_vendor_header.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002565 self.version = OFP_VERSION
2566 self.type = OFPT_VENDOR
Rich Lane8fbfd662013-03-11 15:30:44 -07002567 self.xid = None
Rich Lane6242d9f2013-01-06 17:35:39 -08002568 self.data = ""
2569 for (k, v) in kwargs.items():
2570 if hasattr(self, k):
2571 setattr(self, k, v)
2572 else:
2573 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2574
2575
2576 def pack(self):
2577 """
2578 Pack object into string
2579
2580 @return The packed string which can go on the wire
2581
2582 """
Rich Laneb73808c2013-03-11 15:22:23 -07002583 self.length = len(self)
2584 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08002585
2586 packed += ofp_vendor_header.pack(self)
2587 packed += self.data
2588 return packed
2589
2590 def unpack(self, binary_string):
2591 """
2592 Unpack object from a binary string
2593
2594 @param binary_string The wire protocol byte string holding the object
2595 represented as an array of bytes.
2596 @return The remainder of binary_string that was not parsed.
2597
2598 """
Rich Lane6242d9f2013-01-06 17:35:39 -08002599
2600 binary_string = ofp_vendor_header.unpack(self, binary_string)
2601 self.data = binary_string
2602 binary_string = ''
2603 return binary_string
2604
2605 def __len__(self):
2606 """
2607 Return the length of this object once packed into a string
2608
2609 @return An integer representing the number bytes in the packed
2610 string.
2611
2612 """
Rich Laneb73808c2013-03-11 15:22:23 -07002613 length = 0
Rich Lane6242d9f2013-01-06 17:35:39 -08002614
2615 length += ofp_vendor_header.__len__(self)
2616 length += len(self.data)
2617 return length
2618
2619 def show(self, prefix=''):
2620 """
2621 Generate a string (with multiple lines) describing the contents
2622 of the object in a readable manner
2623
2624 @param prefix Pre-pended at the beginning of each line.
2625
2626 """
2627
2628 outstr = prefix + 'vendor (OFPT_VENDOR)\n'
2629 prefix += ' '
2630 outstr += prefix + 'ofp header\n'
Rich Lane6242d9f2013-01-06 17:35:39 -08002631 outstr += ofp_vendor_header.show(self, prefix)
2632 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
2633 ##@todo Fix this circular reference
2634 # if len(self.data) > 0:
2635 # obj = of_message_parse(self.data)
2636 # if obj != None:
2637 # outstr += obj.show(prefix)
2638 # else:
2639 # outstr += prefix + "Unable to parse data\n"
2640 return outstr
2641
2642 def __eq__(self, other):
2643 """
2644 Return True if self and other hold the same data
2645
2646 @param other Other object in comparison
2647
2648 """
2649 if type(self) != type(other): return False
Rich Lane6242d9f2013-01-06 17:35:39 -08002650
2651 if not ofp_vendor_header.__eq__(self, other): return False
2652 if self.data != other.data: return False
2653 return True
2654
2655 def __ne__(self, other):
2656 """
2657 Return True if self and other do not hold the same data
2658
2659 @param other Other object in comparison
2660
2661 """
2662 return not self.__eq__(other)
2663
2664
2665
2666################################################################
2667#
2668# Stats request and reply subclass definitions
2669#
2670################################################################
2671
2672
2673# Stats request bodies for desc and table stats are not defined in the
2674# OpenFlow header; We define them here. They are empty classes, really
2675
2676class ofp_desc_stats_request:
2677 """
2678 Forced definition of ofp_desc_stats_request (empty class)
2679 """
2680 def __init__(self):
2681 pass
2682 def pack(self, assertstruct=True):
2683 return ""
2684 def unpack(self, binary_string):
2685 return binary_string
2686 def __len__(self):
2687 return 0
2688 def show(self, prefix=''):
2689 return prefix + "ofp_desc_stats_request (empty)\n"
2690 def __eq__(self, other):
2691 return type(self) == type(other)
2692 def __ne__(self, other):
2693 return type(self) != type(other)
2694
2695OFP_DESC_STATS_REQUEST_BYTES = 0
2696
2697class ofp_table_stats_request:
2698 """
2699 Forced definition of ofp_table_stats_request (empty class)
2700 """
2701 def __init__(self):
2702 pass
2703 def pack(self, assertstruct=True):
2704 return ""
2705 def unpack(self, binary_string):
2706 return binary_string
2707 def __len__(self):
2708 return 0
2709 def show(self, prefix=''):
2710 return prefix + "ofp_table_stats_request (empty)\n"
2711 def __eq__(self, other):
2712 return type(self) == type(other)
2713 def __ne__(self, other):
2714 return type(self) != type(other)
2715
2716OFP_TABLE_STATS_REQUEST_BYTES = 0
2717
2718
2719
2720# Stats entries define the content of one element in a stats
2721# reply for the indicated type; define _entry for consistency
2722
2723aggregate_stats_entry = ofp_aggregate_stats_reply
2724desc_stats_entry = ofp_desc_stats
2725port_stats_entry = ofp_port_stats
2726queue_stats_entry = ofp_queue_stats
2727table_stats_entry = ofp_table_stats
2728
2729
2730#
2731# Flow stats entry contains an action list of variable length, so
2732# it is done by hand
2733#
2734
2735class flow_stats_entry(ofp_flow_stats):
2736 """
2737 Special case flow stats entry to handle action list object
2738 """
2739 def __init__(self):
2740 ofp_flow_stats.__init__(self)
Rich Lane62e96852013-03-11 12:04:45 -07002741 self.actions = []
Rich Lane6242d9f2013-01-06 17:35:39 -08002742
2743 def pack(self, assertstruct=True):
2744 self.length = len(self)
2745 packed = ofp_flow_stats.pack(self, assertstruct)
Rich Lane62e96852013-03-11 12:04:45 -07002746 packed += action_list(self.actions).pack()
Rich Lane6242d9f2013-01-06 17:35:39 -08002747 if len(packed) != self.length:
2748 print("ERROR: flow_stats_entry pack length not equal",
2749 self.length, len(packed))
2750 return packed
2751
2752 def unpack(self, binary_string):
2753 binary_string = ofp_flow_stats.unpack(self, binary_string)
2754 ai_len = self.length - OFP_FLOW_STATS_BYTES
2755 if ai_len < 0:
2756 print("ERROR: flow_stats_entry unpack length too small",
2757 self.length)
Rich Lane62e96852013-03-11 12:04:45 -07002758 obj = action_list()
2759 binary_string = obj.unpack(binary_string, bytes=ai_len)
2760 self.actions = list(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08002761 return binary_string
2762
2763 def __len__(self):
2764 return OFP_FLOW_STATS_BYTES + len(self.actions)
2765
2766 def show(self, prefix=''):
2767 outstr = prefix + "flow_stats_entry\n"
2768 outstr += ofp_flow_stats.show(self, prefix + ' ')
Rich Lanee6ea3fe2013-03-08 17:54:38 -08002769 outstr += prefix + "List actions\n"
2770 for obj in self.actions:
2771 outstr += obj.show(prefix + ' ')
Rich Lane6242d9f2013-01-06 17:35:39 -08002772 return outstr
2773
2774 def __eq__(self, other):
2775 if type(self) != type(other): return False
2776 return (ofp_flow_stats.__eq__(self, other) and
2777 self.actions == other.actions)
2778
2779 def __ne__(self, other): return not self.__eq__(other)
2780
2781
2782class aggregate_stats_request(ofp_stats_request, ofp_aggregate_stats_request):
2783 """
2784 Wrapper class for aggregate stats request message
2785 """
2786 def __init__(self, **kwargs):
Rich Lane6242d9f2013-01-06 17:35:39 -08002787 ofp_stats_request.__init__(self)
2788 ofp_aggregate_stats_request.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002789 self.version = OFP_VERSION
2790 self.type = OFPT_STATS_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -07002791 self.xid = None
Rich Lane7c7342a2013-03-11 14:16:58 -07002792 self.stats_type = OFPST_AGGREGATE
Rich Lane6242d9f2013-01-06 17:35:39 -08002793 for (k, v) in kwargs.items():
2794 if hasattr(self, k):
2795 setattr(self, k, v)
2796 else:
2797 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2798
2799 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07002800 self.length = len(self)
2801 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08002802 packed += ofp_stats_request.pack(self)
2803 packed += ofp_aggregate_stats_request.pack(self)
2804 return packed
2805
2806 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08002807 binary_string = ofp_stats_request.unpack(self, binary_string)
2808 binary_string = ofp_aggregate_stats_request.unpack(self, binary_string)
2809 if len(binary_string) != 0:
2810 print "ERROR unpacking aggregate: extra data"
2811 return binary_string
2812
2813 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07002814 return OFP_STATS_REQUEST_BYTES + \
Rich Lane6242d9f2013-01-06 17:35:39 -08002815 OFP_AGGREGATE_STATS_REQUEST_BYTES
2816
2817 def show(self, prefix=''):
2818 outstr = prefix + "aggregate_stats_request\n"
2819 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08002820 outstr += ofp_stats_request.show(self)
2821 outstr += ofp_aggregate_stats_request.show(self)
2822 return outstr
2823
2824 def __eq__(self, other):
2825 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07002826 return (ofp_stats_request.__eq__(self, other) and
Rich Lane6242d9f2013-01-06 17:35:39 -08002827 ofp_aggregate_stats_request.__eq__(self, other))
2828
2829 def __ne__(self, other): return not self.__eq__(other)
2830
2831
2832class aggregate_stats_reply(ofp_stats_reply):
2833 """
2834 Wrapper class for aggregate stats reply
2835 """
2836 def __init__(self):
Rich Lane6242d9f2013-01-06 17:35:39 -08002837 ofp_stats_reply.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002838 self.version = OFP_VERSION
2839 self.type = OFPT_STATS_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -07002840 self.xid = None
Rich Laneb73808c2013-03-11 15:22:23 -07002841 self.stats_type = OFPST_AGGREGATE
Rich Lane6242d9f2013-01-06 17:35:39 -08002842 # stats: Array of type aggregate_stats_entry
Rich Lane5fd6faf2013-03-11 13:30:20 -07002843 self.entries = []
Rich Lane6242d9f2013-01-06 17:35:39 -08002844
2845 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07002846 self.length = len(self)
2847 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08002848 packed += ofp_stats_reply.pack(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07002849 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08002850 packed += obj.pack()
2851 return packed
2852
2853 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08002854 binary_string = ofp_stats_reply.unpack(self, binary_string)
2855 dummy = aggregate_stats_entry()
2856 while len(binary_string) >= len(dummy):
2857 obj = aggregate_stats_entry()
2858 binary_string = obj.unpack(binary_string)
Rich Lane5fd6faf2013-03-11 13:30:20 -07002859 self.entries.append(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08002860 if len(binary_string) != 0:
2861 print "ERROR unpacking aggregate stats string: extra bytes"
2862 return binary_string
2863
2864 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07002865 length = OFP_STATS_REPLY_BYTES
Rich Lane5fd6faf2013-03-11 13:30:20 -07002866 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08002867 length += len(obj)
2868 return length
2869
2870 def show(self, prefix=''):
2871 outstr = prefix + "aggregate_stats_reply\n"
2872 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08002873 outstr += ofp_stats_reply.show(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07002874 outstr += prefix + "Stats array of length " + str(len(self.entries)) + '\n'
2875 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08002876 outstr += obj.show()
2877 return outstr
2878
2879 def __eq__(self, other):
2880 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07002881 return (ofp_stats_reply.__eq__(self, other) and
Rich Lane5fd6faf2013-03-11 13:30:20 -07002882 self.entries == other.entries)
Rich Lane6242d9f2013-01-06 17:35:39 -08002883
2884 def __ne__(self, other): return not self.__eq__(other)
2885
2886
2887class desc_stats_request(ofp_stats_request, ofp_desc_stats_request):
2888 """
2889 Wrapper class for desc stats request message
2890 """
2891 def __init__(self, **kwargs):
Rich Lane6242d9f2013-01-06 17:35:39 -08002892 ofp_stats_request.__init__(self)
2893 ofp_desc_stats_request.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002894 self.version = OFP_VERSION
2895 self.type = OFPT_STATS_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -07002896 self.xid = None
Rich Lane7c7342a2013-03-11 14:16:58 -07002897 self.stats_type = OFPST_DESC
Rich Lane6242d9f2013-01-06 17:35:39 -08002898 for (k, v) in kwargs.items():
2899 if hasattr(self, k):
2900 setattr(self, k, v)
2901 else:
2902 raise NameError("field %s does not exist in %s" % (k, self.__class__))
2903
2904 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07002905 self.length = len(self)
2906 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08002907 packed += ofp_stats_request.pack(self)
2908 packed += ofp_desc_stats_request.pack(self)
2909 return packed
2910
2911 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08002912 binary_string = ofp_stats_request.unpack(self, binary_string)
2913 binary_string = ofp_desc_stats_request.unpack(self, binary_string)
2914 if len(binary_string) != 0:
2915 print "ERROR unpacking desc: extra data"
2916 return binary_string
2917
2918 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07002919 return OFP_STATS_REQUEST_BYTES + \
Rich Lane6242d9f2013-01-06 17:35:39 -08002920 OFP_DESC_STATS_REQUEST_BYTES
2921
2922 def show(self, prefix=''):
2923 outstr = prefix + "desc_stats_request\n"
2924 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08002925 outstr += ofp_stats_request.show(self)
2926 outstr += ofp_desc_stats_request.show(self)
2927 return outstr
2928
2929 def __eq__(self, other):
2930 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07002931 return (ofp_stats_request.__eq__(self, other) and
Rich Lane6242d9f2013-01-06 17:35:39 -08002932 ofp_desc_stats_request.__eq__(self, other))
2933
2934 def __ne__(self, other): return not self.__eq__(other)
2935
2936
2937class desc_stats_reply(ofp_stats_reply):
2938 """
2939 Wrapper class for desc stats reply
2940 """
2941 def __init__(self):
Rich Lane6242d9f2013-01-06 17:35:39 -08002942 ofp_stats_reply.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002943 self.version = OFP_VERSION
2944 self.type = OFPT_STATS_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -07002945 self.xid = None
Rich Laneb73808c2013-03-11 15:22:23 -07002946 self.stats_type = OFPST_DESC
Rich Lane6242d9f2013-01-06 17:35:39 -08002947 # stats: Array of type desc_stats_entry
Rich Lane5fd6faf2013-03-11 13:30:20 -07002948 self.entries = []
Rich Lane6242d9f2013-01-06 17:35:39 -08002949
2950 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07002951 self.length = len(self)
2952 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08002953 packed += ofp_stats_reply.pack(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07002954 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08002955 packed += obj.pack()
2956 return packed
2957
2958 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08002959 binary_string = ofp_stats_reply.unpack(self, binary_string)
2960 dummy = desc_stats_entry()
2961 while len(binary_string) >= len(dummy):
2962 obj = desc_stats_entry()
2963 binary_string = obj.unpack(binary_string)
Rich Lane5fd6faf2013-03-11 13:30:20 -07002964 self.entries.append(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08002965 if len(binary_string) != 0:
2966 print "ERROR unpacking desc stats string: extra bytes"
2967 return binary_string
2968
2969 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07002970 length = OFP_STATS_REPLY_BYTES
Rich Lane5fd6faf2013-03-11 13:30:20 -07002971 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08002972 length += len(obj)
2973 return length
2974
2975 def show(self, prefix=''):
2976 outstr = prefix + "desc_stats_reply\n"
2977 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08002978 outstr += ofp_stats_reply.show(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07002979 outstr += prefix + "Stats array of length " + str(len(self.entries)) + '\n'
2980 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08002981 outstr += obj.show()
2982 return outstr
2983
2984 def __eq__(self, other):
2985 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07002986 return (ofp_stats_reply.__eq__(self, other) and
Rich Lane5fd6faf2013-03-11 13:30:20 -07002987 self.entries == other.entries)
Rich Lane6242d9f2013-01-06 17:35:39 -08002988
2989 def __ne__(self, other): return not self.__eq__(other)
2990
2991
2992class flow_stats_request(ofp_stats_request, ofp_flow_stats_request):
2993 """
2994 Wrapper class for flow stats request message
2995 """
2996 def __init__(self, **kwargs):
Rich Lane6242d9f2013-01-06 17:35:39 -08002997 ofp_stats_request.__init__(self)
2998 ofp_flow_stats_request.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07002999 self.version = OFP_VERSION
3000 self.type = OFPT_STATS_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -07003001 self.xid = None
Rich Lane7c7342a2013-03-11 14:16:58 -07003002 self.stats_type = OFPST_FLOW
Rich Lane6242d9f2013-01-06 17:35:39 -08003003 for (k, v) in kwargs.items():
3004 if hasattr(self, k):
3005 setattr(self, k, v)
3006 else:
3007 raise NameError("field %s does not exist in %s" % (k, self.__class__))
3008
3009 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07003010 self.length = len(self)
3011 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08003012 packed += ofp_stats_request.pack(self)
3013 packed += ofp_flow_stats_request.pack(self)
3014 return packed
3015
3016 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08003017 binary_string = ofp_stats_request.unpack(self, binary_string)
3018 binary_string = ofp_flow_stats_request.unpack(self, binary_string)
3019 if len(binary_string) != 0:
3020 print "ERROR unpacking flow: extra data"
3021 return binary_string
3022
3023 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07003024 return OFP_STATS_REQUEST_BYTES + \
Rich Lane6242d9f2013-01-06 17:35:39 -08003025 OFP_FLOW_STATS_REQUEST_BYTES
3026
3027 def show(self, prefix=''):
3028 outstr = prefix + "flow_stats_request\n"
3029 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08003030 outstr += ofp_stats_request.show(self)
3031 outstr += ofp_flow_stats_request.show(self)
3032 return outstr
3033
3034 def __eq__(self, other):
3035 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07003036 return (ofp_stats_request.__eq__(self, other) and
Rich Lane6242d9f2013-01-06 17:35:39 -08003037 ofp_flow_stats_request.__eq__(self, other))
3038
3039 def __ne__(self, other): return not self.__eq__(other)
3040
3041
3042class flow_stats_reply(ofp_stats_reply):
3043 """
3044 Wrapper class for flow stats reply
3045 """
3046 def __init__(self):
Rich Lane6242d9f2013-01-06 17:35:39 -08003047 ofp_stats_reply.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07003048 self.version = OFP_VERSION
3049 self.type = OFPT_STATS_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -07003050 self.xid = None
Rich Laneb73808c2013-03-11 15:22:23 -07003051 self.stats_type = OFPST_FLOW
Rich Lane6242d9f2013-01-06 17:35:39 -08003052 # stats: Array of type flow_stats_entry
Rich Lane5fd6faf2013-03-11 13:30:20 -07003053 self.entries = []
Rich Lane6242d9f2013-01-06 17:35:39 -08003054
3055 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07003056 self.length = len(self)
3057 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08003058 packed += ofp_stats_reply.pack(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003059 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003060 packed += obj.pack()
3061 return packed
3062
3063 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08003064 binary_string = ofp_stats_reply.unpack(self, binary_string)
3065 dummy = flow_stats_entry()
3066 while len(binary_string) >= len(dummy):
3067 obj = flow_stats_entry()
3068 binary_string = obj.unpack(binary_string)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003069 self.entries.append(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08003070 if len(binary_string) != 0:
3071 print "ERROR unpacking flow stats string: extra bytes"
3072 return binary_string
3073
3074 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07003075 length = OFP_STATS_REPLY_BYTES
Rich Lane5fd6faf2013-03-11 13:30:20 -07003076 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003077 length += len(obj)
3078 return length
3079
3080 def show(self, prefix=''):
3081 outstr = prefix + "flow_stats_reply\n"
3082 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08003083 outstr += ofp_stats_reply.show(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003084 outstr += prefix + "Stats array of length " + str(len(self.entries)) + '\n'
3085 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003086 outstr += obj.show()
3087 return outstr
3088
3089 def __eq__(self, other):
3090 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07003091 return (ofp_stats_reply.__eq__(self, other) and
Rich Lane5fd6faf2013-03-11 13:30:20 -07003092 self.entries == other.entries)
Rich Lane6242d9f2013-01-06 17:35:39 -08003093
3094 def __ne__(self, other): return not self.__eq__(other)
3095
3096
3097class port_stats_request(ofp_stats_request, ofp_port_stats_request):
3098 """
3099 Wrapper class for port stats request message
3100 """
3101 def __init__(self, **kwargs):
Rich Lane6242d9f2013-01-06 17:35:39 -08003102 ofp_stats_request.__init__(self)
3103 ofp_port_stats_request.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07003104 self.version = OFP_VERSION
3105 self.type = OFPT_STATS_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -07003106 self.xid = None
Rich Lane7c7342a2013-03-11 14:16:58 -07003107 self.stats_type = OFPST_PORT
Rich Lane6242d9f2013-01-06 17:35:39 -08003108 for (k, v) in kwargs.items():
3109 if hasattr(self, k):
3110 setattr(self, k, v)
3111 else:
3112 raise NameError("field %s does not exist in %s" % (k, self.__class__))
3113
3114 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07003115 self.length = len(self)
3116 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08003117 packed += ofp_stats_request.pack(self)
3118 packed += ofp_port_stats_request.pack(self)
3119 return packed
3120
3121 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08003122 binary_string = ofp_stats_request.unpack(self, binary_string)
3123 binary_string = ofp_port_stats_request.unpack(self, binary_string)
3124 if len(binary_string) != 0:
3125 print "ERROR unpacking port: extra data"
3126 return binary_string
3127
3128 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07003129 return OFP_STATS_REQUEST_BYTES + \
Rich Lane6242d9f2013-01-06 17:35:39 -08003130 OFP_PORT_STATS_REQUEST_BYTES
3131
3132 def show(self, prefix=''):
3133 outstr = prefix + "port_stats_request\n"
3134 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08003135 outstr += ofp_stats_request.show(self)
3136 outstr += ofp_port_stats_request.show(self)
3137 return outstr
3138
3139 def __eq__(self, other):
3140 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07003141 return (ofp_stats_request.__eq__(self, other) and
Rich Lane6242d9f2013-01-06 17:35:39 -08003142 ofp_port_stats_request.__eq__(self, other))
3143
3144 def __ne__(self, other): return not self.__eq__(other)
3145
3146
3147class port_stats_reply(ofp_stats_reply):
3148 """
3149 Wrapper class for port stats reply
3150 """
3151 def __init__(self):
Rich Lane6242d9f2013-01-06 17:35:39 -08003152 ofp_stats_reply.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07003153 self.version = OFP_VERSION
3154 self.type = OFPT_STATS_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -07003155 self.xid = None
Rich Laneb73808c2013-03-11 15:22:23 -07003156 self.stats_type = OFPST_PORT
Rich Lane6242d9f2013-01-06 17:35:39 -08003157 # stats: Array of type port_stats_entry
Rich Lane5fd6faf2013-03-11 13:30:20 -07003158 self.entries = []
Rich Lane6242d9f2013-01-06 17:35:39 -08003159
3160 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07003161 self.length = len(self)
3162 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08003163 packed += ofp_stats_reply.pack(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003164 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003165 packed += obj.pack()
3166 return packed
3167
3168 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08003169 binary_string = ofp_stats_reply.unpack(self, binary_string)
3170 dummy = port_stats_entry()
3171 while len(binary_string) >= len(dummy):
3172 obj = port_stats_entry()
3173 binary_string = obj.unpack(binary_string)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003174 self.entries.append(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08003175 if len(binary_string) != 0:
3176 print "ERROR unpacking port stats string: extra bytes"
3177 return binary_string
3178
3179 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07003180 length = OFP_STATS_REPLY_BYTES
Rich Lane5fd6faf2013-03-11 13:30:20 -07003181 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003182 length += len(obj)
3183 return length
3184
3185 def show(self, prefix=''):
3186 outstr = prefix + "port_stats_reply\n"
3187 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08003188 outstr += ofp_stats_reply.show(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003189 outstr += prefix + "Stats array of length " + str(len(self.entries)) + '\n'
3190 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003191 outstr += obj.show()
3192 return outstr
3193
3194 def __eq__(self, other):
3195 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07003196 return (ofp_stats_reply.__eq__(self, other) and
Rich Lane5fd6faf2013-03-11 13:30:20 -07003197 self.entries == other.entries)
Rich Lane6242d9f2013-01-06 17:35:39 -08003198
3199 def __ne__(self, other): return not self.__eq__(other)
3200
3201
3202class queue_stats_request(ofp_stats_request, ofp_queue_stats_request):
3203 """
3204 Wrapper class for queue stats request message
3205 """
3206 def __init__(self, **kwargs):
Rich Lane6242d9f2013-01-06 17:35:39 -08003207 ofp_stats_request.__init__(self)
3208 ofp_queue_stats_request.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07003209 self.version = OFP_VERSION
3210 self.type = OFPT_STATS_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -07003211 self.xid = None
Rich Lane7c7342a2013-03-11 14:16:58 -07003212 self.stats_type = OFPST_QUEUE
Rich Lane6242d9f2013-01-06 17:35:39 -08003213 for (k, v) in kwargs.items():
3214 if hasattr(self, k):
3215 setattr(self, k, v)
3216 else:
3217 raise NameError("field %s does not exist in %s" % (k, self.__class__))
3218
3219 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07003220 self.length = len(self)
3221 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08003222 packed += ofp_stats_request.pack(self)
3223 packed += ofp_queue_stats_request.pack(self)
3224 return packed
3225
3226 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08003227 binary_string = ofp_stats_request.unpack(self, binary_string)
3228 binary_string = ofp_queue_stats_request.unpack(self, binary_string)
3229 if len(binary_string) != 0:
3230 print "ERROR unpacking queue: extra data"
3231 return binary_string
3232
3233 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07003234 return OFP_STATS_REQUEST_BYTES + \
Rich Lane6242d9f2013-01-06 17:35:39 -08003235 OFP_QUEUE_STATS_REQUEST_BYTES
3236
3237 def show(self, prefix=''):
3238 outstr = prefix + "queue_stats_request\n"
3239 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08003240 outstr += ofp_stats_request.show(self)
3241 outstr += ofp_queue_stats_request.show(self)
3242 return outstr
3243
3244 def __eq__(self, other):
3245 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07003246 return (ofp_stats_request.__eq__(self, other) and
Rich Lane6242d9f2013-01-06 17:35:39 -08003247 ofp_queue_stats_request.__eq__(self, other))
3248
3249 def __ne__(self, other): return not self.__eq__(other)
3250
3251
3252class queue_stats_reply(ofp_stats_reply):
3253 """
3254 Wrapper class for queue stats reply
3255 """
3256 def __init__(self):
Rich Lane6242d9f2013-01-06 17:35:39 -08003257 ofp_stats_reply.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07003258 self.version = OFP_VERSION
3259 self.type = OFPT_STATS_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -07003260 self.xid = None
Rich Laneb73808c2013-03-11 15:22:23 -07003261 self.stats_type = OFPST_QUEUE
Rich Lane6242d9f2013-01-06 17:35:39 -08003262 # stats: Array of type queue_stats_entry
Rich Lane5fd6faf2013-03-11 13:30:20 -07003263 self.entries = []
Rich Lane6242d9f2013-01-06 17:35:39 -08003264
3265 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07003266 self.length = len(self)
3267 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08003268 packed += ofp_stats_reply.pack(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003269 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003270 packed += obj.pack()
3271 return packed
3272
3273 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08003274 binary_string = ofp_stats_reply.unpack(self, binary_string)
3275 dummy = queue_stats_entry()
3276 while len(binary_string) >= len(dummy):
3277 obj = queue_stats_entry()
3278 binary_string = obj.unpack(binary_string)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003279 self.entries.append(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08003280 if len(binary_string) != 0:
3281 print "ERROR unpacking queue stats string: extra bytes"
3282 return binary_string
3283
3284 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07003285 length = OFP_STATS_REPLY_BYTES
Rich Lane5fd6faf2013-03-11 13:30:20 -07003286 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003287 length += len(obj)
3288 return length
3289
3290 def show(self, prefix=''):
3291 outstr = prefix + "queue_stats_reply\n"
3292 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08003293 outstr += ofp_stats_reply.show(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003294 outstr += prefix + "Stats array of length " + str(len(self.entries)) + '\n'
3295 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003296 outstr += obj.show()
3297 return outstr
3298
3299 def __eq__(self, other):
3300 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07003301 return (ofp_stats_reply.__eq__(self, other) and
Rich Lane5fd6faf2013-03-11 13:30:20 -07003302 self.entries == other.entries)
Rich Lane6242d9f2013-01-06 17:35:39 -08003303
3304 def __ne__(self, other): return not self.__eq__(other)
3305
3306
3307class table_stats_request(ofp_stats_request, ofp_table_stats_request):
3308 """
3309 Wrapper class for table stats request message
3310 """
3311 def __init__(self, **kwargs):
Rich Lane6242d9f2013-01-06 17:35:39 -08003312 ofp_stats_request.__init__(self)
3313 ofp_table_stats_request.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07003314 self.version = OFP_VERSION
3315 self.type = OFPT_STATS_REQUEST
Rich Lane8fbfd662013-03-11 15:30:44 -07003316 self.xid = None
Rich Lane7c7342a2013-03-11 14:16:58 -07003317 self.stats_type = OFPST_TABLE
Rich Lane6242d9f2013-01-06 17:35:39 -08003318 for (k, v) in kwargs.items():
3319 if hasattr(self, k):
3320 setattr(self, k, v)
3321 else:
3322 raise NameError("field %s does not exist in %s" % (k, self.__class__))
3323
3324 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07003325 self.length = len(self)
3326 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08003327 packed += ofp_stats_request.pack(self)
3328 packed += ofp_table_stats_request.pack(self)
3329 return packed
3330
3331 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08003332 binary_string = ofp_stats_request.unpack(self, binary_string)
3333 binary_string = ofp_table_stats_request.unpack(self, binary_string)
3334 if len(binary_string) != 0:
3335 print "ERROR unpacking table: extra data"
3336 return binary_string
3337
3338 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07003339 return OFP_STATS_REQUEST_BYTES + \
Rich Lane6242d9f2013-01-06 17:35:39 -08003340 OFP_TABLE_STATS_REQUEST_BYTES
3341
3342 def show(self, prefix=''):
3343 outstr = prefix + "table_stats_request\n"
3344 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08003345 outstr += ofp_stats_request.show(self)
3346 outstr += ofp_table_stats_request.show(self)
3347 return outstr
3348
3349 def __eq__(self, other):
3350 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07003351 return (ofp_stats_request.__eq__(self, other) and
Rich Lane6242d9f2013-01-06 17:35:39 -08003352 ofp_table_stats_request.__eq__(self, other))
3353
3354 def __ne__(self, other): return not self.__eq__(other)
3355
3356
3357class table_stats_reply(ofp_stats_reply):
3358 """
3359 Wrapper class for table stats reply
3360 """
3361 def __init__(self):
Rich Lane6242d9f2013-01-06 17:35:39 -08003362 ofp_stats_reply.__init__(self)
Rich Laneb73808c2013-03-11 15:22:23 -07003363 self.version = OFP_VERSION
3364 self.type = OFPT_STATS_REPLY
Rich Lane8fbfd662013-03-11 15:30:44 -07003365 self.xid = None
Rich Laneb73808c2013-03-11 15:22:23 -07003366 self.stats_type = OFPST_TABLE
Rich Lane6242d9f2013-01-06 17:35:39 -08003367 # stats: Array of type table_stats_entry
Rich Lane5fd6faf2013-03-11 13:30:20 -07003368 self.entries = []
Rich Lane6242d9f2013-01-06 17:35:39 -08003369
3370 def pack(self, assertstruct=True):
Rich Laneb73808c2013-03-11 15:22:23 -07003371 self.length = len(self)
3372 packed = ""
Rich Lane6242d9f2013-01-06 17:35:39 -08003373 packed += ofp_stats_reply.pack(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003374 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003375 packed += obj.pack()
3376 return packed
3377
3378 def unpack(self, binary_string):
Rich Lane6242d9f2013-01-06 17:35:39 -08003379 binary_string = ofp_stats_reply.unpack(self, binary_string)
3380 dummy = table_stats_entry()
3381 while len(binary_string) >= len(dummy):
3382 obj = table_stats_entry()
3383 binary_string = obj.unpack(binary_string)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003384 self.entries.append(obj)
Rich Lane6242d9f2013-01-06 17:35:39 -08003385 if len(binary_string) != 0:
3386 print "ERROR unpacking table stats string: extra bytes"
3387 return binary_string
3388
3389 def __len__(self):
Rich Laneb73808c2013-03-11 15:22:23 -07003390 length = OFP_STATS_REPLY_BYTES
Rich Lane5fd6faf2013-03-11 13:30:20 -07003391 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003392 length += len(obj)
3393 return length
3394
3395 def show(self, prefix=''):
3396 outstr = prefix + "table_stats_reply\n"
3397 outstr += prefix + "ofp header:\n"
Rich Lane6242d9f2013-01-06 17:35:39 -08003398 outstr += ofp_stats_reply.show(self)
Rich Lane5fd6faf2013-03-11 13:30:20 -07003399 outstr += prefix + "Stats array of length " + str(len(self.entries)) + '\n'
3400 for obj in self.entries:
Rich Lane6242d9f2013-01-06 17:35:39 -08003401 outstr += obj.show()
3402 return outstr
3403
3404 def __eq__(self, other):
3405 if type(self) != type(other): return False
Rich Laneb73808c2013-03-11 15:22:23 -07003406 return (ofp_stats_reply.__eq__(self, other) and
Rich Lane5fd6faf2013-03-11 13:30:20 -07003407 self.entries == other.entries)
Rich Lane6242d9f2013-01-06 17:35:39 -08003408
3409 def __ne__(self, other): return not self.__eq__(other)
3410
3411
3412message_type_list = (
3413 aggregate_stats_reply,
3414 aggregate_stats_request,
3415 bad_action_error_msg,
3416 bad_request_error_msg,
3417 barrier_reply,
3418 barrier_request,
3419 desc_stats_reply,
3420 desc_stats_request,
3421 echo_reply,
3422 echo_request,
3423 features_reply,
3424 features_request,
3425 flow_mod,
3426 flow_mod_failed_error_msg,
3427 flow_removed,
3428 flow_stats_reply,
3429 flow_stats_request,
3430 get_config_reply,
3431 get_config_request,
3432 hello,
3433 hello_failed_error_msg,
3434 packet_in,
3435 packet_out,
3436 port_mod,
3437 port_mod_failed_error_msg,
3438 port_stats_reply,
3439 port_stats_request,
3440 port_status,
3441 queue_get_config_reply,
3442 queue_get_config_request,
3443 queue_op_failed_error_msg,
3444 queue_stats_reply,
3445 queue_stats_request,
3446 set_config,
3447 table_stats_reply,
3448 table_stats_request,
3449 vendor
3450 )
3451
Rich Laneba3f0e22013-03-11 16:43:57 -07003452
3453_flow_mod = flow_mod
3454flow_mod = None
3455
3456class flow_add(_flow_mod):
3457 def __init__(self, **kwargs):
3458 _flow_mod.__init__(self, **kwargs)
3459 self.command = OFPFC_ADD
3460
3461class flow_modify(_flow_mod):
3462 def __init__(self, **kwargs):
3463 _flow_mod.__init__(self, **kwargs)
3464 self.command = OFPFC_MODIFY
3465
3466class flow_modify_strict(_flow_mod):
3467 def __init__(self, **kwargs):
3468 _flow_mod.__init__(self, **kwargs)
3469 self.command = OFPFC_MODIFY_STRICT
3470
3471class flow_delete(_flow_mod):
3472 def __init__(self, **kwargs):
3473 _flow_mod.__init__(self, **kwargs)
3474 self.command = OFPFC_DELETE
3475
3476class flow_delete_strict(_flow_mod):
3477 def __init__(self, **kwargs):
3478 _flow_mod.__init__(self, **kwargs)
3479 self.command = OFPFC_DELETE_STRICT
3480
Rich Lanef6883512013-03-11 17:00:09 -07003481# These message types are subclassed
3482msg_type_subclassed = [
3483 OFPT_STATS_REQUEST,
3484 OFPT_STATS_REPLY,
3485 OFPT_ERROR
3486]
3487
3488# Maps from sub-types to classes
3489stats_reply_to_class_map = {
3490 OFPST_DESC : desc_stats_reply,
3491 OFPST_AGGREGATE : aggregate_stats_reply,
3492 OFPST_FLOW : flow_stats_reply,
3493 OFPST_TABLE : table_stats_reply,
3494 OFPST_PORT : port_stats_reply,
3495 OFPST_QUEUE : queue_stats_reply
3496}
3497
3498stats_request_to_class_map = {
3499 OFPST_DESC : desc_stats_request,
3500 OFPST_AGGREGATE : aggregate_stats_request,
3501 OFPST_FLOW : flow_stats_request,
3502 OFPST_TABLE : table_stats_request,
3503 OFPST_PORT : port_stats_request,
3504 OFPST_QUEUE : queue_stats_request
3505}
3506
3507error_to_class_map = {
3508 OFPET_HELLO_FAILED : hello_failed_error_msg,
3509 OFPET_BAD_REQUEST : bad_request_error_msg,
3510 OFPET_BAD_ACTION : bad_action_error_msg,
3511 OFPET_FLOW_MOD_FAILED : flow_mod_failed_error_msg,
3512 OFPET_PORT_MOD_FAILED : port_mod_failed_error_msg,
3513 OFPET_QUEUE_OP_FAILED : queue_op_failed_error_msg
3514}
3515
3516# Map from header type value to the underlieing message class
3517msg_type_to_class_map = {
3518 OFPT_HELLO : hello,
3519 OFPT_ERROR : error,
3520 OFPT_ECHO_REQUEST : echo_request,
3521 OFPT_ECHO_REPLY : echo_reply,
3522 OFPT_VENDOR : vendor,
3523 OFPT_FEATURES_REQUEST : features_request,
3524 OFPT_FEATURES_REPLY : features_reply,
3525 OFPT_GET_CONFIG_REQUEST : get_config_request,
3526 OFPT_GET_CONFIG_REPLY : get_config_reply,
3527 OFPT_SET_CONFIG : set_config,
3528 OFPT_PACKET_IN : packet_in,
3529 OFPT_FLOW_REMOVED : flow_removed,
3530 OFPT_PORT_STATUS : port_status,
3531 OFPT_PACKET_OUT : packet_out,
3532 OFPT_FLOW_MOD : flow_mod,
3533 OFPT_PORT_MOD : port_mod,
3534 OFPT_STATS_REQUEST : stats_request,
3535 OFPT_STATS_REPLY : stats_reply,
3536 OFPT_BARRIER_REQUEST : barrier_request,
3537 OFPT_BARRIER_REPLY : barrier_reply,
3538 OFPT_QUEUE_GET_CONFIG_REQUEST : queue_get_config_request,
3539 OFPT_QUEUE_GET_CONFIG_REPLY : queue_get_config_reply
3540}
3541
3542def _of_message_to_object(binary_string):
3543 """
3544 Map a binary string to the corresponding class.
3545
3546 Appropriately resolves subclasses
3547 """
3548 hdr = ofp_header()
3549 hdr.unpack(binary_string)
3550 logging.info(hdr.show())
3551 # FIXME: Add error detection
3552 if not hdr.type in msg_type_subclassed:
3553 return msg_type_to_class_map[hdr.type]()
3554 if hdr.type == OFPT_STATS_REQUEST:
3555 sub_hdr = ofp_stats_request()
3556 sub_hdr.unpack(binary_string)
3557 try:
3558 obj = stats_request_to_class_map[sub_hdr.stats_type]()
3559 except KeyError:
3560 obj = None
3561 return obj
3562 elif hdr.type == OFPT_STATS_REPLY:
3563 sub_hdr = ofp_stats_reply()
3564 sub_hdr.unpack(binary_string)
3565 try:
3566 obj = stats_reply_to_class_map[sub_hdr.stats_type]()
3567 except KeyError:
3568 obj = None
3569 return obj
3570 elif hdr.type == OFPT_ERROR:
3571 sub_hdr = ofp_error_msg()
3572 sub_hdr.unpack(binary_string)
3573 return error_to_class_map[sub_hdr.err_type]()
3574 else:
3575 logging.error("Cannot parse pkt to message")
3576 return None
3577
3578def parse_message(binary_string):
3579 """
3580 Parse an OpenFlow packet
3581
3582 Parses a raw OpenFlow packet into a Python class, with class
3583 members fully populated.
3584
3585 @param binary_string The packet (string) to be parsed
3586 @param raw If true, interpret the packet as an L2 packet. Not
3587 yet supported.
3588 @return An object of some message class or None if fails
3589 Note that any data beyond that parsed is not returned
3590
3591 """
3592 obj = _of_message_to_object(binary_string)
3593 if obj:
3594 obj.unpack(binary_string)
3595 return obj
3596
3597
3598def parse_header(binary_string):
3599 """
3600 Parse only the header from an OpenFlow packet
3601
3602 Parses the header from a raw OpenFlow packet into a
3603 an ofp_header Python class.
3604
3605 @param binary_string The packet (string) to be parsed
Rich Lane1622bbb2013-03-11 17:11:53 -07003606 @return Tuple of (verison, type, length, xid)
Rich Lanef6883512013-03-11 17:00:09 -07003607
3608 """
Rich Lane1622bbb2013-03-11 17:11:53 -07003609 return struct.unpack_from("!BBHL", binary_string)
Rich Lanef6883512013-03-11 17:00:09 -07003610
3611