blob: 45d458e064a52775510ec52901af52cf019e8778 [file] [log] [blame]
Rich Lane629393f2013-01-10 15:37:33 -08001
2# Python OpenFlow message wrapper classes
3
4from cstruct import *
5from match import oxm_tlv
6from match import roundup
7from match_list import match_list
8from action_list import action_list
9from instruction_list import instruction_list
10from bucket_list import bucket_list
11from error import *
12
13# Define templates for documentation
14class ofp_template_msg(object):
15 """
16 Sample base class for template_msg; normally auto generated
17 This class should live in the of_header name space and provides the
18 base class for this type of message. It will be wrapped for the
19 high level API.
20
21 """
Rich Lane5de2d942013-01-11 11:49:36 -080022 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -080023 """
24 Constructor for base class
25
26 """
27 self.header = ofp_header()
28 # Additional base data members declared here
29
30 # Normally will define pack, unpack, __len__ functions
31
32class template_msg(ofp_template_msg):
33 """
34 Sample class wrapper for template_msg
35 This class should live in the of_message name space and provides the
36 high level API for an OpenFlow message object. These objects must
37 implement the functions indicated in this template.
38
39 """
Rich Lane5de2d942013-01-11 11:49:36 -080040 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -080041 """
42 Constructor
43 Must set the header type value appropriately for the message
44
45 """
46
47 ##@var header
48 # OpenFlow message header: length, version, xid, type
49 ofp_template_msg.__init__(self)
50 self.header = ofp_header()
51 # For a real message, will be set to an integer
52 self.header.type = "TEMPLATE_MSG_VALUE"
53 def pack(self):
54 """
55 Pack object into string
56
57 @return The packed string which can go on the wire
58
59 """
60 pass
61 def unpack(self, binary_string):
62 """
63 Unpack object from a binary string
64
65 @param binary_string The wire protocol byte string holding the object
66 represented as an array of bytes.
67
68 @return Typically returns the remainder of binary_string that
69 was not parsed. May give a warning if that string is non-empty
70
71 """
72 pass
73 def __len__(self):
74 """
75 Return the length of this object once packed into a string
76
77 @return An integer representing the number bytes in the packed
78 string.
79
80 """
81 pass
82 def show(self, prefix=''):
83 """
84 Generate a string (with multiple lines) describing the contents
85 of the object in a readable manner
86
87 @param prefix Pre-pended at the beginning of each line.
88
89 """
90 pass
91 def __eq__(self, other):
92 """
93 Return True if self and other hold the same data
94
95 @param other Other object in comparison
96
97 """
98 pass
99 def __ne__(self, other):
100 """
101 Return True if self and other do not hold the same data
102
103 @param other Other object in comparison
104
105 """
106 pass
107
108
109################################################################
110#
111# OpenFlow Message Definitions
112#
113################################################################
114
115class barrier_reply(object):
116 """
117 Wrapper class for barrier_reply
118
119 OpenFlow message header: length, version, xid, type
120 @arg length: The total length of the message
121 @arg version: The OpenFlow version (3)
122 @arg xid: The transaction ID
123 @arg type: The message type (OFPT_BARRIER_REPLY=21)
124
125
126 """
127
Rich Lane5de2d942013-01-11 11:49:36 -0800128 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -0800129 self.header = ofp_header()
130 self.header.type = OFPT_BARRIER_REPLY
Rich Lane5de2d942013-01-11 11:49:36 -0800131 for (k, v) in kwargs.items():
132 if hasattr(self, k):
133 setattr(self, k, v)
134 else:
135 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -0800136
137
138 def pack(self):
139 """
140 Pack object into string
141
142 @return The packed string which can go on the wire
143
144 """
145 self.header.length = len(self)
146 packed = self.header.pack()
147
148 return packed
149
150 def unpack(self, binary_string):
151 """
152 Unpack object from a binary string
153
154 @param binary_string The wire protocol byte string holding the object
155 represented as an array of bytes.
156 @return The remainder of binary_string that was not parsed.
157
158 """
159 binary_string = self.header.unpack(binary_string)
160
161 # Fixme: If no self.data, add check for data remaining
162 return binary_string
163
164 def __len__(self):
165 """
166 Return the length of this object once packed into a string
167
168 @return An integer representing the number bytes in the packed
169 string.
170
171 """
172 length = OFP_HEADER_BYTES
173
174 return length
175
176 def show(self, prefix=''):
177 """
178 Generate a string (with multiple lines) describing the contents
179 of the object in a readable manner
180
181 @param prefix Pre-pended at the beginning of each line.
182
183 """
184
185 outstr = prefix + 'barrier_reply (OFPT_BARRIER_REPLY)\n'
186 prefix += ' '
187 outstr += prefix + 'ofp header\n'
188 outstr += self.header.show(prefix + ' ')
189 return outstr
190
191 def __eq__(self, other):
192 """
193 Return True if self and other hold the same data
194
195 @param other Other object in comparison
196
197 """
198 if type(self) != type(other): return False
199 if not self.header.__eq__(other.header): return False
200
201 return True
202
203 def __ne__(self, other):
204 """
205 Return True if self and other do not hold the same data
206
207 @param other Other object in comparison
208
209 """
210 return not self.__eq__(other)
211
212
213class barrier_request(object):
214 """
215 Wrapper class for barrier_request
216
217 OpenFlow message header: length, version, xid, type
218 @arg length: The total length of the message
219 @arg version: The OpenFlow version (3)
220 @arg xid: The transaction ID
221 @arg type: The message type (OFPT_BARRIER_REQUEST=20)
222
223
224 """
225
Rich Lane5de2d942013-01-11 11:49:36 -0800226 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -0800227 self.header = ofp_header()
228 self.header.type = OFPT_BARRIER_REQUEST
Rich Lane5de2d942013-01-11 11:49:36 -0800229 for (k, v) in kwargs.items():
230 if hasattr(self, k):
231 setattr(self, k, v)
232 else:
233 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -0800234
235
236 def pack(self):
237 """
238 Pack object into string
239
240 @return The packed string which can go on the wire
241
242 """
243 self.header.length = len(self)
244 packed = self.header.pack()
245
246 return packed
247
248 def unpack(self, binary_string):
249 """
250 Unpack object from a binary string
251
252 @param binary_string The wire protocol byte string holding the object
253 represented as an array of bytes.
254 @return The remainder of binary_string that was not parsed.
255
256 """
257 binary_string = self.header.unpack(binary_string)
258
259 # Fixme: If no self.data, add check for data remaining
260 return binary_string
261
262 def __len__(self):
263 """
264 Return the length of this object once packed into a string
265
266 @return An integer representing the number bytes in the packed
267 string.
268
269 """
270 length = OFP_HEADER_BYTES
271
272 return length
273
274 def show(self, prefix=''):
275 """
276 Generate a string (with multiple lines) describing the contents
277 of the object in a readable manner
278
279 @param prefix Pre-pended at the beginning of each line.
280
281 """
282
283 outstr = prefix + 'barrier_request (OFPT_BARRIER_REQUEST)\n'
284 prefix += ' '
285 outstr += prefix + 'ofp header\n'
286 outstr += self.header.show(prefix + ' ')
287 return outstr
288
289 def __eq__(self, other):
290 """
291 Return True if self and other hold the same data
292
293 @param other Other object in comparison
294
295 """
296 if type(self) != type(other): return False
297 if not self.header.__eq__(other.header): return False
298
299 return True
300
301 def __ne__(self, other):
302 """
303 Return True if self and other do not hold the same data
304
305 @param other Other object in comparison
306
307 """
308 return not self.__eq__(other)
309
310
311class echo_reply(object):
312 """
313 Wrapper class for echo_reply
314
315 OpenFlow message header: length, version, xid, type
316 @arg length: The total length of the message
317 @arg version: The OpenFlow version (3)
318 @arg xid: The transaction ID
319 @arg type: The message type (OFPT_ECHO_REPLY=3)
320
321 @arg data: Binary string following message members
322
323 """
324
Rich Lane5de2d942013-01-11 11:49:36 -0800325 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -0800326 self.header = ofp_header()
327 self.header.type = OFPT_ECHO_REPLY
328 self.data = ""
Rich Lane5de2d942013-01-11 11:49:36 -0800329 for (k, v) in kwargs.items():
330 if hasattr(self, k):
331 setattr(self, k, v)
332 else:
333 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -0800334
335
336 def pack(self):
337 """
338 Pack object into string
339
340 @return The packed string which can go on the wire
341
342 """
343 self.header.length = len(self)
344 packed = self.header.pack()
345
346 packed += self.data
347 return packed
348
349 def unpack(self, binary_string):
350 """
351 Unpack object from a binary string
352
353 @param binary_string The wire protocol byte string holding the object
354 represented as an array of bytes.
355 @return The remainder of binary_string that was not parsed.
356
357 """
358 binary_string = self.header.unpack(binary_string)
359
360 self.data = binary_string
361 binary_string = ''
362 return binary_string
363
364 def __len__(self):
365 """
366 Return the length of this object once packed into a string
367
368 @return An integer representing the number bytes in the packed
369 string.
370
371 """
372 length = OFP_HEADER_BYTES
373
374 length += len(self.data)
375 return length
376
377 def show(self, prefix=''):
378 """
379 Generate a string (with multiple lines) describing the contents
380 of the object in a readable manner
381
382 @param prefix Pre-pended at the beginning of each line.
383
384 """
385
386 outstr = prefix + 'echo_reply (OFPT_ECHO_REPLY)\n'
387 prefix += ' '
388 outstr += prefix + 'ofp header\n'
389 outstr += self.header.show(prefix + ' ')
390 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
391 ##@todo Fix this circular reference
392 # if len(self.data) > 0:
393 # obj = of_message_parse(self.data)
394 # if obj != None:
395 # outstr += obj.show(prefix)
396 # else:
397 # outstr += prefix + "Unable to parse data\n"
398 return outstr
399
400 def __eq__(self, other):
401 """
402 Return True if self and other hold the same data
403
404 @param other Other object in comparison
405
406 """
407 if type(self) != type(other): return False
408 if not self.header.__eq__(other.header): return False
409
410 if self.data != other.data: return False
411 return True
412
413 def __ne__(self, other):
414 """
415 Return True if self and other do not hold the same data
416
417 @param other Other object in comparison
418
419 """
420 return not self.__eq__(other)
421
422
423class echo_request(object):
424 """
425 Wrapper class for echo_request
426
427 OpenFlow message header: length, version, xid, type
428 @arg length: The total length of the message
429 @arg version: The OpenFlow version (3)
430 @arg xid: The transaction ID
431 @arg type: The message type (OFPT_ECHO_REQUEST=2)
432
433 @arg data: Binary string following message members
434
435 """
436
Rich Lane5de2d942013-01-11 11:49:36 -0800437 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -0800438 self.header = ofp_header()
439 self.header.type = OFPT_ECHO_REQUEST
440 self.data = ""
Rich Lane5de2d942013-01-11 11:49:36 -0800441 for (k, v) in kwargs.items():
442 if hasattr(self, k):
443 setattr(self, k, v)
444 else:
445 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -0800446
447
448 def pack(self):
449 """
450 Pack object into string
451
452 @return The packed string which can go on the wire
453
454 """
455 self.header.length = len(self)
456 packed = self.header.pack()
457
458 packed += self.data
459 return packed
460
461 def unpack(self, binary_string):
462 """
463 Unpack object from a binary string
464
465 @param binary_string The wire protocol byte string holding the object
466 represented as an array of bytes.
467 @return The remainder of binary_string that was not parsed.
468
469 """
470 binary_string = self.header.unpack(binary_string)
471
472 self.data = binary_string
473 binary_string = ''
474 return binary_string
475
476 def __len__(self):
477 """
478 Return the length of this object once packed into a string
479
480 @return An integer representing the number bytes in the packed
481 string.
482
483 """
484 length = OFP_HEADER_BYTES
485
486 length += len(self.data)
487 return length
488
489 def show(self, prefix=''):
490 """
491 Generate a string (with multiple lines) describing the contents
492 of the object in a readable manner
493
494 @param prefix Pre-pended at the beginning of each line.
495
496 """
497
498 outstr = prefix + 'echo_request (OFPT_ECHO_REQUEST)\n'
499 prefix += ' '
500 outstr += prefix + 'ofp header\n'
501 outstr += self.header.show(prefix + ' ')
502 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
503 ##@todo Fix this circular reference
504 # if len(self.data) > 0:
505 # obj = of_message_parse(self.data)
506 # if obj != None:
507 # outstr += obj.show(prefix)
508 # else:
509 # outstr += prefix + "Unable to parse data\n"
510 return outstr
511
512 def __eq__(self, other):
513 """
514 Return True if self and other hold the same data
515
516 @param other Other object in comparison
517
518 """
519 if type(self) != type(other): return False
520 if not self.header.__eq__(other.header): return False
521
522 if self.data != other.data: return False
523 return True
524
525 def __ne__(self, other):
526 """
527 Return True if self and other do not hold the same data
528
529 @param other Other object in comparison
530
531 """
532 return not self.__eq__(other)
533
534
535class error(ofp_error_msg):
536 """
537 Wrapper class for error
538
539 OpenFlow message header: length, version, xid, type
540 @arg length: The total length of the message
541 @arg version: The OpenFlow version (3)
542 @arg xid: The transaction ID
543 @arg type: The message type (OFPT_ERROR=1)
544
545 Data members inherited from ofp_error_msg:
546 @arg type
547 @arg code
548 @arg data: Binary string following message members
549
550 """
551
Rich Lane5de2d942013-01-11 11:49:36 -0800552 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -0800553 ofp_error_msg.__init__(self)
554 self.header = ofp_header()
555 self.header.type = OFPT_ERROR
556 self.data = ""
Rich Lane5de2d942013-01-11 11:49:36 -0800557 for (k, v) in kwargs.items():
558 if hasattr(self, k):
559 setattr(self, k, v)
560 else:
561 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -0800562
563
564 def pack(self):
565 """
566 Pack object into string
567
568 @return The packed string which can go on the wire
569
570 """
571 self.header.length = len(self)
572 packed = self.header.pack()
573
574 packed += ofp_error_msg.pack(self)
575 packed += self.data
576 return packed
577
578 def unpack(self, binary_string):
579 """
580 Unpack object from a binary string
581
582 @param binary_string The wire protocol byte string holding the object
583 represented as an array of bytes.
584 @return The remainder of binary_string that was not parsed.
585
586 """
587 binary_string = self.header.unpack(binary_string)
588
589 binary_string = ofp_error_msg.unpack(self, binary_string)
590 self.data = binary_string
591 binary_string = ''
592 return binary_string
593
594 def __len__(self):
595 """
596 Return the length of this object once packed into a string
597
598 @return An integer representing the number bytes in the packed
599 string.
600
601 """
602 length = OFP_HEADER_BYTES
603
604 length += ofp_error_msg.__len__(self)
605 length += len(self.data)
606 return length
607
608 def show(self, prefix=''):
609 """
610 Generate a string (with multiple lines) describing the contents
611 of the object in a readable manner
612
613 @param prefix Pre-pended at the beginning of each line.
614
615 """
616
617 outstr = prefix + 'error (OFPT_ERROR)\n'
618 prefix += ' '
619 outstr += prefix + 'ofp header\n'
620 outstr += self.header.show(prefix + ' ')
621 outstr += ofp_error_msg.show(self, prefix)
622 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
623 ##@todo Fix this circular reference
624 # if len(self.data) > 0:
625 # obj = of_message_parse(self.data)
626 # if obj != None:
627 # outstr += obj.show(prefix)
628 # else:
629 # outstr += prefix + "Unable to parse data\n"
630 return outstr
631
632 def __eq__(self, other):
633 """
634 Return True if self and other hold the same data
635
636 @param other Other object in comparison
637
638 """
639 if type(self) != type(other): return False
640 if not self.header.__eq__(other.header): return False
641
642 if not ofp_error_msg.__eq__(self, other): return False
643 if self.data != other.data: return False
644 return True
645
646 def __ne__(self, other):
647 """
648 Return True if self and other do not hold the same data
649
650 @param other Other object in comparison
651
652 """
653 return not self.__eq__(other)
654
655
656class experimenter(ofp_experimenter_header):
657 """
658 Wrapper class for experimenter
659
660 OpenFlow message header: length, version, xid, type
661 @arg length: The total length of the message
662 @arg version: The OpenFlow version (3)
663 @arg xid: The transaction ID
664 @arg type: The message type (OFPT_EXPERIMENTER=4)
665
666 Data members inherited from ofp_experimenter_header:
667 @arg experimenter
668 @arg exp_type
669 @arg data: Binary string following message members
670
671 """
672
Rich Lane5de2d942013-01-11 11:49:36 -0800673 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -0800674 ofp_experimenter_header.__init__(self)
675 self.header = ofp_header()
676 self.header.type = OFPT_EXPERIMENTER
677 self.data = ""
Rich Lane5de2d942013-01-11 11:49:36 -0800678 for (k, v) in kwargs.items():
679 if hasattr(self, k):
680 setattr(self, k, v)
681 else:
682 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -0800683
684
685 def pack(self):
686 """
687 Pack object into string
688
689 @return The packed string which can go on the wire
690
691 """
692 self.header.length = len(self)
693 packed = self.header.pack()
694
695 packed += ofp_experimenter_header.pack(self)
696 packed += self.data
697 return packed
698
699 def unpack(self, binary_string):
700 """
701 Unpack object from a binary string
702
703 @param binary_string The wire protocol byte string holding the object
704 represented as an array of bytes.
705 @return The remainder of binary_string that was not parsed.
706
707 """
708 binary_string = self.header.unpack(binary_string)
709
710 binary_string = ofp_experimenter_header.unpack(self, binary_string)
711 self.data = binary_string
712 binary_string = ''
713 return binary_string
714
715 def __len__(self):
716 """
717 Return the length of this object once packed into a string
718
719 @return An integer representing the number bytes in the packed
720 string.
721
722 """
723 length = OFP_HEADER_BYTES
724
725 length += ofp_experimenter_header.__len__(self)
726 length += len(self.data)
727 return length
728
729 def show(self, prefix=''):
730 """
731 Generate a string (with multiple lines) describing the contents
732 of the object in a readable manner
733
734 @param prefix Pre-pended at the beginning of each line.
735
736 """
737
738 outstr = prefix + 'experimenter (OFPT_EXPERIMENTER)\n'
739 prefix += ' '
740 outstr += prefix + 'ofp header\n'
741 outstr += self.header.show(prefix + ' ')
742 outstr += ofp_experimenter_header.show(self, prefix)
743 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
744 ##@todo Fix this circular reference
745 # if len(self.data) > 0:
746 # obj = of_message_parse(self.data)
747 # if obj != None:
748 # outstr += obj.show(prefix)
749 # else:
750 # outstr += prefix + "Unable to parse data\n"
751 return outstr
752
753 def __eq__(self, other):
754 """
755 Return True if self and other hold the same data
756
757 @param other Other object in comparison
758
759 """
760 if type(self) != type(other): return False
761 if not self.header.__eq__(other.header): return False
762
763 if not ofp_experimenter_header.__eq__(self, other): return False
764 if self.data != other.data: return False
765 return True
766
767 def __ne__(self, other):
768 """
769 Return True if self and other do not hold the same data
770
771 @param other Other object in comparison
772
773 """
774 return not self.__eq__(other)
775
776
777class features_reply(ofp_switch_features):
778 """
779 Wrapper class for features_reply
780
781 OpenFlow message header: length, version, xid, type
782 @arg length: The total length of the message
783 @arg version: The OpenFlow version (3)
784 @arg xid: The transaction ID
785 @arg type: The message type (OFPT_FEATURES_REPLY=6)
786
787 Data members inherited from ofp_switch_features:
788 @arg datapath_id
789 @arg n_buffers
790 @arg n_tables
791 @arg capabilities
792 @arg reserved
793 @arg ports: Variable length array of TBD
794
795 """
796
Rich Lane5de2d942013-01-11 11:49:36 -0800797 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -0800798 ofp_switch_features.__init__(self)
799 self.header = ofp_header()
800 self.header.type = OFPT_FEATURES_REPLY
801 self.ports = []
Rich Lane5de2d942013-01-11 11:49:36 -0800802 for (k, v) in kwargs.items():
803 if hasattr(self, k):
804 setattr(self, k, v)
805 else:
806 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -0800807
808
809 def pack(self):
810 """
811 Pack object into string
812
813 @return The packed string which can go on the wire
814
815 """
816 self.header.length = len(self)
817 packed = self.header.pack()
818
819 packed += ofp_switch_features.pack(self)
820 for obj in self.ports:
821 packed += obj.pack()
822 return packed
823
824 def unpack(self, binary_string):
825 """
826 Unpack object from a binary string
827
828 @param binary_string The wire protocol byte string holding the object
829 represented as an array of bytes.
830 @return The remainder of binary_string that was not parsed.
831
832 """
833 binary_string = self.header.unpack(binary_string)
834
835 binary_string = ofp_switch_features.unpack(self, binary_string)
836 while len(binary_string) >= OFP_PORT_BYTES:
837 new_port = ofp_port()
838 binary_string = new_port.unpack(binary_string)
839 self.ports.append(new_port)
840 # Fixme: If no self.data, add check for data remaining
841 return binary_string
842
843 def __len__(self):
844 """
845 Return the length of this object once packed into a string
846
847 @return An integer representing the number bytes in the packed
848 string.
849
850 """
851 length = OFP_HEADER_BYTES
852
853 length += ofp_switch_features.__len__(self)
854 for obj in self.ports:
855 length += len(obj)
856 return length
857
858 def show(self, prefix=''):
859 """
860 Generate a string (with multiple lines) describing the contents
861 of the object in a readable manner
862
863 @param prefix Pre-pended at the beginning of each line.
864
865 """
866
867 outstr = prefix + 'features_reply (OFPT_FEATURES_REPLY)\n'
868 prefix += ' '
869 outstr += prefix + 'ofp header\n'
870 outstr += self.header.show(prefix + ' ')
871 outstr += ofp_switch_features.show(self, prefix)
872 outstr += prefix + "Array ports\n"
873 for obj in self.ports:
874 outstr += obj.show(prefix + ' ')
875 return outstr
876
877 def __eq__(self, other):
878 """
879 Return True if self and other hold the same data
880
881 @param other Other object in comparison
882
883 """
884 if type(self) != type(other): return False
885 if not self.header.__eq__(other.header): return False
886
887 if not ofp_switch_features.__eq__(self, other): return False
888 if self.ports != other.ports: return False
889 return True
890
891 def __ne__(self, other):
892 """
893 Return True if self and other do not hold the same data
894
895 @param other Other object in comparison
896
897 """
898 return not self.__eq__(other)
899
900
901class features_request(object):
902 """
903 Wrapper class for features_request
904
905 OpenFlow message header: length, version, xid, type
906 @arg length: The total length of the message
907 @arg version: The OpenFlow version (3)
908 @arg xid: The transaction ID
909 @arg type: The message type (OFPT_FEATURES_REQUEST=5)
910
911
912 """
913
Rich Lane5de2d942013-01-11 11:49:36 -0800914 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -0800915 self.header = ofp_header()
916 self.header.type = OFPT_FEATURES_REQUEST
Rich Lane5de2d942013-01-11 11:49:36 -0800917 for (k, v) in kwargs.items():
918 if hasattr(self, k):
919 setattr(self, k, v)
920 else:
921 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -0800922
923
924 def pack(self):
925 """
926 Pack object into string
927
928 @return The packed string which can go on the wire
929
930 """
931 self.header.length = len(self)
932 packed = self.header.pack()
933
934 return packed
935
936 def unpack(self, binary_string):
937 """
938 Unpack object from a binary string
939
940 @param binary_string The wire protocol byte string holding the object
941 represented as an array of bytes.
942 @return The remainder of binary_string that was not parsed.
943
944 """
945 binary_string = self.header.unpack(binary_string)
946
947 # Fixme: If no self.data, add check for data remaining
948 return binary_string
949
950 def __len__(self):
951 """
952 Return the length of this object once packed into a string
953
954 @return An integer representing the number bytes in the packed
955 string.
956
957 """
958 length = OFP_HEADER_BYTES
959
960 return length
961
962 def show(self, prefix=''):
963 """
964 Generate a string (with multiple lines) describing the contents
965 of the object in a readable manner
966
967 @param prefix Pre-pended at the beginning of each line.
968
969 """
970
971 outstr = prefix + 'features_request (OFPT_FEATURES_REQUEST)\n'
972 prefix += ' '
973 outstr += prefix + 'ofp header\n'
974 outstr += self.header.show(prefix + ' ')
975 return outstr
976
977 def __eq__(self, other):
978 """
979 Return True if self and other hold the same data
980
981 @param other Other object in comparison
982
983 """
984 if type(self) != type(other): return False
985 if not self.header.__eq__(other.header): return False
986
987 return True
988
989 def __ne__(self, other):
990 """
991 Return True if self and other do not hold the same data
992
993 @param other Other object in comparison
994
995 """
996 return not self.__eq__(other)
997
998
999class flow_mod(ofp_flow_mod):
1000 """
1001 Wrapper class for flow_mod
1002
1003 OpenFlow message header: length, version, xid, type
1004 @arg length: The total length of the message
1005 @arg version: The OpenFlow version (3)
1006 @arg xid: The transaction ID
1007 @arg type: The message type (OFPT_FLOW_MOD=14)
1008
1009 Data members inherited from ofp_flow_mod:
1010 @arg cookie
1011 @arg cookie_mask
1012 @arg table_id
1013 @arg command
1014 @arg idle_timeout
1015 @arg hard_timeout
1016 @arg priority
1017 @arg buffer_id
1018 @arg out_port
1019 @arg out_group
1020 @arg flags
1021 @arg match
1022 @arg instructions: Object of type instruction_list
1023
1024 """
1025
Rich Lane5de2d942013-01-11 11:49:36 -08001026 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08001027 ofp_flow_mod.__init__(self)
1028 self.header = ofp_header()
1029 self.header.type = OFPT_FLOW_MOD
1030 self.buffer_id = 0xffffffff #no buffer
1031 self.out_port = OFPP_ANY
1032 self.out_group = OFPG_ANY
1033 self.match_fields = match_list()
1034 self.instructions = instruction_list()
Rich Lane5de2d942013-01-11 11:49:36 -08001035 for (k, v) in kwargs.items():
1036 if hasattr(self, k):
1037 setattr(self, k, v)
1038 else:
1039 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08001040
1041
1042 def pack(self):
1043 """
1044 Pack object into string
1045
1046 @return The packed string which can go on the wire
1047
1048 """
1049 self.header.length = len(self)
1050 if not len(self.match_fields):
1051 tlv_pad = oxm_tlv(0,0,0,0,0,0)
1052 self.match_fields.tlvs.append(tlv_pad)
1053 else:
1054 if len(self.match_fields) > 4:
1055 self.match.length += len(self.match_fields)
1056 packed = self.header.pack()
1057 packed += ofp_flow_mod.pack(self)
1058 self.match_fields.tlvs.sort(key=lambda x : x.field)
1059 packed += self.match_fields.pack()
1060 padding_size = roundup( len(self.match) + len(self.match_fields),8) - (len(self.match) + len(self.match_fields))
1061 padding = [0] * padding_size
1062 if padding_size:
1063 packed += struct.pack("!" + str(padding_size) + "B", *padding)
1064 packed += self.instructions.pack()
1065 return packed
1066
1067
1068
1069 def unpack(self, binary_string):
1070 """
1071 Unpack object from a binary string
1072
1073 @param binary_string The wire protocol byte string holding the object
1074 represented as an array of bytes.
1075 @return The remainder of binary_string that was not parsed.
1076
1077 """
1078 binary_string = self.header.unpack(binary_string)
1079 binary_string = ofp_flow_mod.unpack(self, binary_string)
1080 binary_string = self.match_fields.unpack(binary_string, bytes = self.match.length - 4)
1081 padding = roundup(OFP_FLOW_MOD_BYTES + len(self.match_fields),8) - (OFP_FLOW_MOD_BYTES + len(self.match_fields))
1082 if padding:
1083 binary_string = binary_string[padding:]
1084 ai_len = self.length - roundup(OFP_FLOW_MOD_BYTES + len(self.match_fields),8)
1085 binary_string = self.instructions.unpack(binary_string, bytes=ai_len)
1086 # Fixme: If no self.data, add check for data remaining
1087 return binary_string
1088
1089 def __len__(self):
1090 """
1091 Return the length of this object once packed into a string
1092
1093 @return An integer representing the number bytes in the packed
1094 string.
1095
1096 """
1097 length = OFP_HEADER_BYTES
1098
1099 length += ofp_flow_mod.__len__(self)
1100 length = roundup(length + len(self.match_fields), 8)
1101 length += len(self.instructions)
1102 return length
1103
1104 def show(self, prefix=''):
1105 """
1106 Generate a string (with multiple lines) describing the contents
1107 of the object in a readable manner
1108
1109 @param prefix Pre-pended at the beginning of each line.
1110
1111 """
1112
1113 outstr = prefix + 'flow_mod (OFPT_FLOW_MOD)\n'
1114 prefix += ' '
1115 outstr += prefix + 'ofp header\n'
1116 outstr += self.header.show(prefix + ' ')
1117 outstr += ofp_flow_mod.show(self, prefix)
1118 outstr += self.match_fields.show(prefix + ' ')
1119 outstr += prefix + "List instructions\n"
1120 outstr += self.instructions.show(prefix + ' ')
1121 return outstr
1122
1123 def __eq__(self, other):
1124 """
1125 Return True if self and other hold the same data
1126
1127 @param other Other object in comparison
1128
1129 """
1130 if type(self) != type(other): return False
1131 if not self.header.__eq__(other.header): return False
1132
1133 if not ofp_flow_mod.__eq__(self, other): return False
1134 if self.match_fields != other.match_fields: return False
1135 if self.instructions != other.instructions: return False
1136 return True
1137
1138 def __ne__(self, other):
1139 """
1140 Return True if self and other do not hold the same data
1141
1142 @param other Other object in comparison
1143
1144 """
1145 return not self.__eq__(other)
1146
1147
1148class flow_removed(ofp_flow_removed):
1149 """
1150 Wrapper class for flow_removed
1151
1152 OpenFlow message header: length, version, xid, type
1153 @arg length: The total length of the message
1154 @arg version: The OpenFlow version (3)
1155 @arg xid: The transaction ID
1156 @arg type: The message type (OFPT_FLOW_REMOVED=11)
1157
1158 Data members inherited from ofp_flow_removed:
1159 @arg cookie
1160 @arg priority
1161 @arg reason
1162 @arg table_id
1163 @arg duration_sec
1164 @arg duration_nsec
1165 @arg idle_timeout
1166 @arg hard_timeout
1167 @arg packet_count
1168 @arg byte_count
1169 @arg match
1170
1171 """
1172
Rich Lane5de2d942013-01-11 11:49:36 -08001173 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08001174 ofp_flow_removed.__init__(self)
1175 self.header = ofp_header()
1176 self.header.type = OFPT_FLOW_REMOVED
1177 self.match_fields = match_list()
Rich Lane5de2d942013-01-11 11:49:36 -08001178 for (k, v) in kwargs.items():
1179 if hasattr(self, k):
1180 setattr(self, k, v)
1181 else:
1182 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08001183
1184
1185 def pack(self):
1186 """
1187 Pack object into string
1188
1189 @return The packed string which can go on the wire
1190
1191 """
1192 self.header.length = len(self)
1193 if not len(self.match_fields):
1194 tlv_pad = oxm_tlv(0,0,0,0,0,0)
1195 self.match.length += 4
1196 self.match_fields.tlvs.append(tlv_pad)
1197 else:
1198 if len(self.match_fields) > 4:
1199 self.match.length += len(self.match_fields)
1200 packed = self.header.pack()
1201 packed += ofp_flow_removed.pack(self)
1202 packed += self.match_fields.pack()
1203 padding_size = roundup( len(self.match) + len(self.match_fields),8) - (len(self.match) + len(self.match_fields))
1204 padding = [0] * padding_size
1205 if padding_size:
1206 packed += struct.pack("!" + str(padding_size) + "B", *padding)
1207 return packed
1208
1209 def unpack(self, binary_string):
1210 """
1211 Unpack object from a binary string
1212
1213 @param binary_string The wire protocol byte string holding the object
1214 represented as an array of bytes.
1215 @return The remainder of binary_string that was not parsed.
1216
1217 """
1218 binary_string = self.header.unpack(binary_string)
1219 binary_string = ofp_flow_removed.unpack(self, binary_string)
1220 binary_string = self.match_fields.unpack(binary_string, bytes = self.match.length - 4)
1221 padding = roundup(OFP_FLOW_REMOVED_BYTES + len(self.match_fields),8) - (OFP_FLOW_REMOVED_BYTES + len(self.match_fields))
1222 if padding:
1223 binary_string = binary_string[padding:]
1224 # Fixme: If no self.data, add check for data remaining
1225 return binary_string
1226
1227 def __len__(self):
1228 """
1229 Return the length of this object once packed into a string
1230
1231 @return An integer representing the number bytes in the packed
1232 string.
1233
1234 """
1235 length = OFP_HEADER_BYTES
1236 length += roundup(ofp_flow_removed.__len__(self) + len(self.match_fields),8)
1237 return length
1238
1239 def show(self, prefix=''):
1240 """
1241 Generate a string (with multiple lines) describing the contents
1242 of the object in a readable manner
1243
1244 @param prefix Pre-pended at the beginning of each line.
1245
1246 """
1247
1248 outstr = prefix + 'flow_removed (OFPT_FLOW_REMOVED)\n'
1249 prefix += ' '
1250 outstr += prefix + 'ofp header\n'
1251 outstr += self.header.show(prefix + ' ')
1252 outstr += ofp_flow_removed.show(self, prefix)
1253 outstr += self.match_fields.show(prefix + ' ')
1254 return outstr
1255
1256 def __eq__(self, other):
1257 """
1258 Return True if self and other hold the same data
1259
1260 @param other Other object in comparison
1261
1262 """
1263 if type(self) != type(other): return False
1264 if not self.header.__eq__(other.header): return False
1265 if not ofp_flow_removed.__eq__(self, other): return False
1266 if self.match_fields != other.match_fields: return False
1267 return True
1268
1269 def __ne__(self, other):
1270 """
1271 Return True if self and other do not hold the same data
1272
1273 @param other Other object in comparison
1274
1275 """
1276 return not self.__eq__(other)
1277
1278
1279class get_config_reply(ofp_switch_config):
1280 """
1281 Wrapper class for get_config_reply
1282
1283 OpenFlow message header: length, version, xid, type
1284 @arg length: The total length of the message
1285 @arg version: The OpenFlow version (3)
1286 @arg xid: The transaction ID
1287 @arg type: The message type (OFPT_GET_CONFIG_REPLY=8)
1288
1289 Data members inherited from ofp_switch_config:
1290 @arg flags
1291 @arg miss_send_len
1292
1293 """
1294
Rich Lane5de2d942013-01-11 11:49:36 -08001295 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08001296 ofp_switch_config.__init__(self)
1297 self.header = ofp_header()
1298 self.header.type = OFPT_GET_CONFIG_REPLY
Rich Lane5de2d942013-01-11 11:49:36 -08001299 for (k, v) in kwargs.items():
1300 if hasattr(self, k):
1301 setattr(self, k, v)
1302 else:
1303 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08001304
1305
1306 def pack(self):
1307 """
1308 Pack object into string
1309
1310 @return The packed string which can go on the wire
1311
1312 """
1313 self.header.length = len(self)
1314 packed = self.header.pack()
1315
1316 packed += ofp_switch_config.pack(self)
1317 return packed
1318
1319 def unpack(self, binary_string):
1320 """
1321 Unpack object from a binary string
1322
1323 @param binary_string The wire protocol byte string holding the object
1324 represented as an array of bytes.
1325 @return The remainder of binary_string that was not parsed.
1326
1327 """
1328 binary_string = self.header.unpack(binary_string)
1329
1330 binary_string = ofp_switch_config.unpack(self, binary_string)
1331 # Fixme: If no self.data, add check for data remaining
1332 return binary_string
1333
1334 def __len__(self):
1335 """
1336 Return the length of this object once packed into a string
1337
1338 @return An integer representing the number bytes in the packed
1339 string.
1340
1341 """
1342 length = OFP_HEADER_BYTES
1343
1344 length += ofp_switch_config.__len__(self)
1345 return length
1346
1347 def show(self, prefix=''):
1348 """
1349 Generate a string (with multiple lines) describing the contents
1350 of the object in a readable manner
1351
1352 @param prefix Pre-pended at the beginning of each line.
1353
1354 """
1355
1356 outstr = prefix + 'get_config_reply (OFPT_GET_CONFIG_REPLY)\n'
1357 prefix += ' '
1358 outstr += prefix + 'ofp header\n'
1359 outstr += self.header.show(prefix + ' ')
1360 outstr += ofp_switch_config.show(self, prefix)
1361 return outstr
1362
1363 def __eq__(self, other):
1364 """
1365 Return True if self and other hold the same data
1366
1367 @param other Other object in comparison
1368
1369 """
1370 if type(self) != type(other): return False
1371 if not self.header.__eq__(other.header): return False
1372
1373 if not ofp_switch_config.__eq__(self, other): return False
1374 return True
1375
1376 def __ne__(self, other):
1377 """
1378 Return True if self and other do not hold the same data
1379
1380 @param other Other object in comparison
1381
1382 """
1383 return not self.__eq__(other)
1384
1385
1386class get_config_request(object):
1387 """
1388 Wrapper class for get_config_request
1389
1390 OpenFlow message header: length, version, xid, type
1391 @arg length: The total length of the message
1392 @arg version: The OpenFlow version (3)
1393 @arg xid: The transaction ID
1394 @arg type: The message type (OFPT_GET_CONFIG_REQUEST=7)
1395
1396
1397 """
1398
Rich Lane5de2d942013-01-11 11:49:36 -08001399 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08001400 self.header = ofp_header()
1401 self.header.type = OFPT_GET_CONFIG_REQUEST
Rich Lane5de2d942013-01-11 11:49:36 -08001402 for (k, v) in kwargs.items():
1403 if hasattr(self, k):
1404 setattr(self, k, v)
1405 else:
1406 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08001407
1408
1409 def pack(self):
1410 """
1411 Pack object into string
1412
1413 @return The packed string which can go on the wire
1414
1415 """
1416 self.header.length = len(self)
1417 packed = self.header.pack()
1418
1419 return packed
1420
1421 def unpack(self, binary_string):
1422 """
1423 Unpack object from a binary string
1424
1425 @param binary_string The wire protocol byte string holding the object
1426 represented as an array of bytes.
1427 @return The remainder of binary_string that was not parsed.
1428
1429 """
1430 binary_string = self.header.unpack(binary_string)
1431
1432 # Fixme: If no self.data, add check for data remaining
1433 return binary_string
1434
1435 def __len__(self):
1436 """
1437 Return the length of this object once packed into a string
1438
1439 @return An integer representing the number bytes in the packed
1440 string.
1441
1442 """
1443 length = OFP_HEADER_BYTES
1444
1445 return length
1446
1447 def show(self, prefix=''):
1448 """
1449 Generate a string (with multiple lines) describing the contents
1450 of the object in a readable manner
1451
1452 @param prefix Pre-pended at the beginning of each line.
1453
1454 """
1455
1456 outstr = prefix + 'get_config_request (OFPT_GET_CONFIG_REQUEST)\n'
1457 prefix += ' '
1458 outstr += prefix + 'ofp header\n'
1459 outstr += self.header.show(prefix + ' ')
1460 return outstr
1461
1462 def __eq__(self, other):
1463 """
1464 Return True if self and other hold the same data
1465
1466 @param other Other object in comparison
1467
1468 """
1469 if type(self) != type(other): return False
1470 if not self.header.__eq__(other.header): return False
1471
1472 return True
1473
1474 def __ne__(self, other):
1475 """
1476 Return True if self and other do not hold the same data
1477
1478 @param other Other object in comparison
1479
1480 """
1481 return not self.__eq__(other)
1482
1483
1484class group_mod(ofp_group_mod):
1485 """
1486 Wrapper class for group_mod
1487
1488 OpenFlow message header: length, version, xid, type
1489 @arg length: The total length of the message
1490 @arg version: The OpenFlow version (3)
1491 @arg xid: The transaction ID
1492 @arg type: The message type (OFPT_GROUP_MOD=15)
1493
1494 Data members inherited from ofp_group_mod:
1495 @arg command
1496 @arg type
1497 @arg group_id
1498 @arg buckets: Object of type bucket_list
1499
1500 """
1501
Rich Lane5de2d942013-01-11 11:49:36 -08001502 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08001503 ofp_group_mod.__init__(self)
1504 self.header = ofp_header()
1505 self.header.type = OFPT_GROUP_MOD
1506 self.buckets = bucket_list()
Rich Lane5de2d942013-01-11 11:49:36 -08001507 for (k, v) in kwargs.items():
1508 if hasattr(self, k):
1509 setattr(self, k, v)
1510 else:
1511 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08001512
1513
1514 def pack(self):
1515 """
1516 Pack object into string
1517
1518 @return The packed string which can go on the wire
1519
1520 """
1521 self.header.length = len(self)
1522 packed = self.header.pack()
1523
1524 packed += ofp_group_mod.pack(self)
1525 packed += self.buckets.pack()
1526 return packed
1527
1528 def unpack(self, binary_string):
1529 """
1530 Unpack object from a binary string
1531
1532 @param binary_string The wire protocol byte string holding the object
1533 represented as an array of bytes.
1534 @return The remainder of binary_string that was not parsed.
1535
1536 """
1537 binary_string = self.header.unpack(binary_string)
1538
1539 binary_string = ofp_group_mod.unpack(self, binary_string)
1540 binary_string = self.buckets.unpack(binary_string)
1541 # Fixme: If no self.data, add check for data remaining
1542 return binary_string
1543
1544 def __len__(self):
1545 """
1546 Return the length of this object once packed into a string
1547
1548 @return An integer representing the number bytes in the packed
1549 string.
1550
1551 """
1552 length = OFP_HEADER_BYTES
1553
1554 length += ofp_group_mod.__len__(self)
1555 length += len(self.buckets)
1556 return length
1557
1558 def show(self, prefix=''):
1559 """
1560 Generate a string (with multiple lines) describing the contents
1561 of the object in a readable manner
1562
1563 @param prefix Pre-pended at the beginning of each line.
1564
1565 """
1566
1567 outstr = prefix + 'group_mod (OFPT_GROUP_MOD)\n'
1568 prefix += ' '
1569 outstr += prefix + 'ofp header\n'
1570 outstr += self.header.show(prefix + ' ')
1571 outstr += ofp_group_mod.show(self, prefix)
1572 outstr += prefix + "List buckets\n"
1573 outstr += self.buckets.show(prefix + ' ')
1574 return outstr
1575
1576 def __eq__(self, other):
1577 """
1578 Return True if self and other hold the same data
1579
1580 @param other Other object in comparison
1581
1582 """
1583 if type(self) != type(other): return False
1584 if not self.header.__eq__(other.header): return False
1585
1586 if not ofp_group_mod.__eq__(self, other): return False
1587 if self.buckets != other.buckets: return False
1588 return True
1589
1590 def __ne__(self, other):
1591 """
1592 Return True if self and other do not hold the same data
1593
1594 @param other Other object in comparison
1595
1596 """
1597 return not self.__eq__(other)
1598
1599
1600class hello(object):
1601 """
1602 Wrapper class for hello
1603
1604 OpenFlow message header: length, version, xid, type
1605 @arg length: The total length of the message
1606 @arg version: The OpenFlow version (3)
1607 @arg xid: The transaction ID
1608 @arg type: The message type (OFPT_HELLO=0)
1609
1610 @arg data: Binary string following message members
1611
1612 """
1613
Rich Lane5de2d942013-01-11 11:49:36 -08001614 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08001615 self.header = ofp_header()
1616 self.header.type = OFPT_HELLO
1617 self.data = ""
Rich Lane5de2d942013-01-11 11:49:36 -08001618 for (k, v) in kwargs.items():
1619 if hasattr(self, k):
1620 setattr(self, k, v)
1621 else:
1622 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08001623
1624
1625 def pack(self):
1626 """
1627 Pack object into string
1628
1629 @return The packed string which can go on the wire
1630
1631 """
1632 self.header.length = len(self)
1633 packed = self.header.pack()
1634
1635 packed += self.data
1636 return packed
1637
1638 def unpack(self, binary_string):
1639 """
1640 Unpack object from a binary string
1641
1642 @param binary_string The wire protocol byte string holding the object
1643 represented as an array of bytes.
1644 @return The remainder of binary_string that was not parsed.
1645
1646 """
1647 binary_string = self.header.unpack(binary_string)
1648
1649 self.data = binary_string
1650 binary_string = ''
1651 return binary_string
1652
1653 def __len__(self):
1654 """
1655 Return the length of this object once packed into a string
1656
1657 @return An integer representing the number bytes in the packed
1658 string.
1659
1660 """
1661 length = OFP_HEADER_BYTES
1662
1663 length += len(self.data)
1664 return length
1665
1666 def show(self, prefix=''):
1667 """
1668 Generate a string (with multiple lines) describing the contents
1669 of the object in a readable manner
1670
1671 @param prefix Pre-pended at the beginning of each line.
1672
1673 """
1674
1675 outstr = prefix + 'hello (OFPT_HELLO)\n'
1676 prefix += ' '
1677 outstr += prefix + 'ofp header\n'
1678 outstr += self.header.show(prefix + ' ')
1679 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
1680 ##@todo Fix this circular reference
1681 # if len(self.data) > 0:
1682 # obj = of_message_parse(self.data)
1683 # if obj != None:
1684 # outstr += obj.show(prefix)
1685 # else:
1686 # outstr += prefix + "Unable to parse data\n"
1687 return outstr
1688
1689 def __eq__(self, other):
1690 """
1691 Return True if self and other hold the same data
1692
1693 @param other Other object in comparison
1694
1695 """
1696 if type(self) != type(other): return False
1697 if not self.header.__eq__(other.header): return False
1698
1699 if self.data != other.data: return False
1700 return True
1701
1702 def __ne__(self, other):
1703 """
1704 Return True if self and other do not hold the same data
1705
1706 @param other Other object in comparison
1707
1708 """
1709 return not self.__eq__(other)
1710
1711
1712class packet_in(ofp_packet_in):
1713 """
1714 Wrapper class for packet_in
1715
1716 OpenFlow message header: length, version, xid, type
1717 @arg length: The total length of the message
1718 @arg version: The OpenFlow version (3)
1719 @arg xid: The transaction ID
1720 @arg type: The message type (OFPT_PACKET_IN=10)
1721
1722 Data members inherited from ofp_packet_in:
1723 @arg buffer_id
1724 @arg total_len
1725 @arg reason
1726 @arg table_id
1727 @arg match
1728 @arg data: Binary string following message members
1729
1730 """
1731
Rich Lane5de2d942013-01-11 11:49:36 -08001732 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08001733 ofp_packet_in.__init__(self)
1734 self.header = ofp_header()
1735 self.header.type = OFPT_PACKET_IN
1736 self.match_fields = match_list()
1737 self.data = ""
Rich Lane5de2d942013-01-11 11:49:36 -08001738 for (k, v) in kwargs.items():
1739 if hasattr(self, k):
1740 setattr(self, k, v)
1741 else:
1742 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08001743
1744
1745 def pack(self):
1746 """
1747 Pack object into string
1748
1749 @return The packed string which can go on the wire
1750
1751 """
1752 self.header.length = len(self)
1753 if len(self.match_fields) < 4:
1754 tlv_pad = oxm_tlv(0,0,0,0,0,0)
1755 self.match.length += 4
1756 self.match_fields.tlvs.append(tlv_pad)
1757 else:
1758 if len(self.match_fields) > 4:
1759 self.match.length += len(self.match_fields)
1760 packed = self.header.pack()
1761 packed += ofp_packet_in.pack(self)
1762 packed += self.match_fields.pack()
1763 padding_size = roundup( len(self.match) + len(self.match_fields),8) - (len(self.match) + len(self.match_fields))
1764 padding = [0] * padding_size
1765 if padding_size:
1766 packed += struct.pack("!" + str(padding_size) + "B", *padding)
1767 packed += self.data
1768 return packed
1769
1770 def unpack(self, binary_string):
1771 """
1772 Unpack object from a binary string
1773
1774 @param binary_string The wire protocol byte string holding the object
1775 represented as an array of bytes.
1776 @return The remainder of binary_string that was not parsed.
1777
1778 """
1779 binary_string = self.header.unpack(binary_string)
1780 binary_string = ofp_packet_in.unpack(self, binary_string)
1781 binary_string = self.match_fields.unpack(binary_string, bytes = self.match.length - 4)
1782 padding = roundup(OFP_PACKET_IN_BYTES + len(self.match_fields),8) - (OFP_PACKET_IN_BYTES + len(self.match_fields))
1783 if padding:
1784 binary_string = binary_string[padding:]
1785 binary_string = binary_string[2:]
1786 self.data = binary_string
1787 binary_string = ''
1788 return binary_string
1789
1790 def __len__(self):
1791 """
1792 Return the length of this object once packed into a string
1793
1794 @return An integer representing the number bytes in the packed
1795 string.
1796
1797 """
1798 length = OFP_HEADER_BYTES
1799
1800 length += roundup(ofp_packet_in.__len__(self) + len(self.match_fields),8)
1801 length += len(self.data)
1802 return length
1803
1804 def show(self, prefix=''):
1805 """
1806 Generate a string (with multiple lines) describing the contents
1807 of the object in a readable manner
1808
1809 @param prefix Pre-pended at the beginning of each line.
1810
1811 """
1812
1813 outstr = prefix + 'packet_in (OFPT_PACKET_IN)\n'
1814 prefix += ' '
1815 outstr += prefix + 'ofp header\n'
1816 outstr += self.header.show(prefix + ' ')
1817 outstr += ofp_packet_in.show(self, prefix)
1818 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
1819 ##@todo Fix this circular reference
1820 # if len(self.data) > 0:
1821 # obj = of_message_parse(self.data)
1822 # if obj != None:
1823 # outstr += obj.show(prefix)
1824 # else:
1825 # outstr += prefix + "Unable to parse data\n"
1826 return outstr
1827
1828 def __eq__(self, other):
1829 """
1830 Return True if self and other hold the same data
1831
1832 @param other Other object in comparison
1833
1834 """
1835 if type(self) != type(other): return False
1836 if not self.header.__eq__(other.header): return False
1837
1838 if not ofp_packet_in.__eq__(self, other): return False
1839 if self.data != other.data: return False
1840 return True
1841
1842 def __ne__(self, other):
1843 """
1844 Return True if self and other do not hold the same data
1845
1846 @param other Other object in comparison
1847
1848 """
1849 return not self.__eq__(other)
1850
1851
1852class packet_out(ofp_packet_out):
1853 """
1854 Wrapper class for packet_out
1855
1856 OpenFlow message header: length, version, xid, type
1857 @arg length: The total length of the message
1858 @arg version: The OpenFlow version (3)
1859 @arg xid: The transaction ID
1860 @arg type: The message type (OFPT_PACKET_OUT=13)
1861
1862 Data members inherited from ofp_packet_out:
1863 @arg buffer_id
1864 @arg in_port
1865 @arg actions_len
1866 @arg actions: Object of type action_list
1867 @arg data: Binary string following message members
1868
1869 """
1870
Rich Lane5de2d942013-01-11 11:49:36 -08001871 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08001872 ofp_packet_out.__init__(self)
1873 self.header = ofp_header()
1874 self.header.type = OFPT_PACKET_OUT
1875 self.actions = action_list()
1876 self.data = ""
Rich Lane5de2d942013-01-11 11:49:36 -08001877 for (k, v) in kwargs.items():
1878 if hasattr(self, k):
1879 setattr(self, k, v)
1880 else:
1881 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08001882
1883
1884 def pack(self):
1885 """
1886 Pack object into string
1887
1888 @return The packed string which can go on the wire
1889
1890 """
1891 self.header.length = len(self)
1892 packed = self.header.pack()
1893
1894 self.actions_len = len(self.actions)
1895 packed += ofp_packet_out.pack(self)
1896 packed += self.actions.pack()
1897 packed += self.data
1898 return packed
1899
1900 def unpack(self, binary_string):
1901 """
1902 Unpack object from a binary string
1903
1904 @param binary_string The wire protocol byte string holding the object
1905 represented as an array of bytes.
1906 @return The remainder of binary_string that was not parsed.
1907
1908 """
1909 binary_string = self.header.unpack(binary_string)
1910
1911 binary_string = ofp_packet_out.unpack(self, binary_string)
1912 binary_string = self.actions.unpack(binary_string, bytes=self.actions_len)
1913 self.data = binary_string
1914 binary_string = ''
1915 return binary_string
1916
1917 def __len__(self):
1918 """
1919 Return the length of this object once packed into a string
1920
1921 @return An integer representing the number bytes in the packed
1922 string.
1923
1924 """
1925 length = OFP_HEADER_BYTES
1926
1927 length += ofp_packet_out.__len__(self)
1928 length += len(self.actions)
1929 length += len(self.data)
1930 return length
1931
1932 def show(self, prefix=''):
1933 """
1934 Generate a string (with multiple lines) describing the contents
1935 of the object in a readable manner
1936
1937 @param prefix Pre-pended at the beginning of each line.
1938
1939 """
1940
1941 outstr = prefix + 'packet_out (OFPT_PACKET_OUT)\n'
1942 prefix += ' '
1943 outstr += prefix + 'ofp header\n'
1944 outstr += self.header.show(prefix + ' ')
1945 outstr += ofp_packet_out.show(self, prefix)
1946 outstr += prefix + "List actions\n"
1947 outstr += self.actions.show(prefix + ' ')
1948 outstr += prefix + 'data is of length ' + str(len(self.data)) + '\n'
1949 ##@todo Fix this circular reference
1950 # if len(self.data) > 0:
1951 # obj = of_message_parse(self.data)
1952 # if obj != None:
1953 # outstr += obj.show(prefix)
1954 # else:
1955 # outstr += prefix + "Unable to parse data\n"
1956 return outstr
1957
1958 def __eq__(self, other):
1959 """
1960 Return True if self and other hold the same data
1961
1962 @param other Other object in comparison
1963
1964 """
1965 if type(self) != type(other): return False
1966 if not self.header.__eq__(other.header): return False
1967
1968 if not ofp_packet_out.__eq__(self, other): return False
1969 if self.data != other.data: return False
1970 if self.actions != other.actions: return False
1971 return True
1972
1973 def __ne__(self, other):
1974 """
1975 Return True if self and other do not hold the same data
1976
1977 @param other Other object in comparison
1978
1979 """
1980 return not self.__eq__(other)
1981
1982
1983class port_mod(ofp_port_mod):
1984 """
1985 Wrapper class for port_mod
1986
1987 OpenFlow message header: length, version, xid, type
1988 @arg length: The total length of the message
1989 @arg version: The OpenFlow version (3)
1990 @arg xid: The transaction ID
1991 @arg type: The message type (OFPT_PORT_MOD=16)
1992
1993 Data members inherited from ofp_port_mod:
1994 @arg port_no
1995 @arg hw_addr
1996 @arg config
1997 @arg mask
1998 @arg advertise
1999
2000 """
2001
Rich Lane5de2d942013-01-11 11:49:36 -08002002 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002003 ofp_port_mod.__init__(self)
2004 self.header = ofp_header()
2005 self.header.type = OFPT_PORT_MOD
Rich Lane5de2d942013-01-11 11:49:36 -08002006 for (k, v) in kwargs.items():
2007 if hasattr(self, k):
2008 setattr(self, k, v)
2009 else:
2010 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002011
2012
2013 def pack(self):
2014 """
2015 Pack object into string
2016
2017 @return The packed string which can go on the wire
2018
2019 """
2020 self.header.length = len(self)
2021 packed = self.header.pack()
2022
2023 packed += ofp_port_mod.pack(self)
2024 return packed
2025
2026 def unpack(self, binary_string):
2027 """
2028 Unpack object from a binary string
2029
2030 @param binary_string The wire protocol byte string holding the object
2031 represented as an array of bytes.
2032 @return The remainder of binary_string that was not parsed.
2033
2034 """
2035 binary_string = self.header.unpack(binary_string)
2036
2037 binary_string = ofp_port_mod.unpack(self, binary_string)
2038 # Fixme: If no self.data, add check for data remaining
2039 return binary_string
2040
2041 def __len__(self):
2042 """
2043 Return the length of this object once packed into a string
2044
2045 @return An integer representing the number bytes in the packed
2046 string.
2047
2048 """
2049 length = OFP_HEADER_BYTES
2050
2051 length += ofp_port_mod.__len__(self)
2052 return length
2053
2054 def show(self, prefix=''):
2055 """
2056 Generate a string (with multiple lines) describing the contents
2057 of the object in a readable manner
2058
2059 @param prefix Pre-pended at the beginning of each line.
2060
2061 """
2062
2063 outstr = prefix + 'port_mod (OFPT_PORT_MOD)\n'
2064 prefix += ' '
2065 outstr += prefix + 'ofp header\n'
2066 outstr += self.header.show(prefix + ' ')
2067 outstr += ofp_port_mod.show(self, prefix)
2068 return outstr
2069
2070 def __eq__(self, other):
2071 """
2072 Return True if self and other hold the same data
2073
2074 @param other Other object in comparison
2075
2076 """
2077 if type(self) != type(other): return False
2078 if not self.header.__eq__(other.header): return False
2079
2080 if not ofp_port_mod.__eq__(self, other): return False
2081 return True
2082
2083 def __ne__(self, other):
2084 """
2085 Return True if self and other do not hold the same data
2086
2087 @param other Other object in comparison
2088
2089 """
2090 return not self.__eq__(other)
2091
2092
2093class port_status(ofp_port_status):
2094 """
2095 Wrapper class for port_status
2096
2097 OpenFlow message header: length, version, xid, type
2098 @arg length: The total length of the message
2099 @arg version: The OpenFlow version (3)
2100 @arg xid: The transaction ID
2101 @arg type: The message type (OFPT_PORT_STATUS=12)
2102
2103 Data members inherited from ofp_port_status:
2104 @arg reason
2105 @arg desc
2106
2107 """
2108
Rich Lane5de2d942013-01-11 11:49:36 -08002109 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002110 ofp_port_status.__init__(self)
2111 self.header = ofp_header()
2112 self.header.type = OFPT_PORT_STATUS
Rich Lane5de2d942013-01-11 11:49:36 -08002113 for (k, v) in kwargs.items():
2114 if hasattr(self, k):
2115 setattr(self, k, v)
2116 else:
2117 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002118
2119
2120 def pack(self):
2121 """
2122 Pack object into string
2123
2124 @return The packed string which can go on the wire
2125
2126 """
2127 self.header.length = len(self)
2128 packed = self.header.pack()
2129
2130 packed += ofp_port_status.pack(self)
2131 return packed
2132
2133 def unpack(self, binary_string):
2134 """
2135 Unpack object from a binary string
2136
2137 @param binary_string The wire protocol byte string holding the object
2138 represented as an array of bytes.
2139 @return The remainder of binary_string that was not parsed.
2140
2141 """
2142 binary_string = self.header.unpack(binary_string)
2143
2144 binary_string = ofp_port_status.unpack(self, binary_string)
2145 # Fixme: If no self.data, add check for data remaining
2146 return binary_string
2147
2148 def __len__(self):
2149 """
2150 Return the length of this object once packed into a string
2151
2152 @return An integer representing the number bytes in the packed
2153 string.
2154
2155 """
2156 length = OFP_HEADER_BYTES
2157
2158 length += ofp_port_status.__len__(self)
2159 return length
2160
2161 def show(self, prefix=''):
2162 """
2163 Generate a string (with multiple lines) describing the contents
2164 of the object in a readable manner
2165
2166 @param prefix Pre-pended at the beginning of each line.
2167
2168 """
2169
2170 outstr = prefix + 'port_status (OFPT_PORT_STATUS)\n'
2171 prefix += ' '
2172 outstr += prefix + 'ofp header\n'
2173 outstr += self.header.show(prefix + ' ')
2174 outstr += ofp_port_status.show(self, prefix)
2175 return outstr
2176
2177 def __eq__(self, other):
2178 """
2179 Return True if self and other hold the same data
2180
2181 @param other Other object in comparison
2182
2183 """
2184 if type(self) != type(other): return False
2185 if not self.header.__eq__(other.header): return False
2186
2187 if not ofp_port_status.__eq__(self, other): return False
2188 return True
2189
2190 def __ne__(self, other):
2191 """
2192 Return True if self and other do not hold the same data
2193
2194 @param other Other object in comparison
2195
2196 """
2197 return not self.__eq__(other)
2198
2199
2200class queue_get_config_reply(ofp_queue_get_config_reply):
2201 """
2202 Wrapper class for queue_get_config_reply
2203
2204 OpenFlow message header: length, version, xid, type
2205 @arg length: The total length of the message
2206 @arg version: The OpenFlow version (3)
2207 @arg xid: The transaction ID
2208 @arg type: The message type (OFPT_QUEUE_GET_CONFIG_REPLY=23)
2209
2210 Data members inherited from ofp_queue_get_config_reply:
2211 @arg port
2212 @arg queues: Variable length array of TBD
2213
2214 """
2215
Rich Lane5de2d942013-01-11 11:49:36 -08002216 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002217 ofp_queue_get_config_reply.__init__(self)
2218 self.header = ofp_header()
2219 self.header.type = OFPT_QUEUE_GET_CONFIG_REPLY
2220 self.queues = []
Rich Lane5de2d942013-01-11 11:49:36 -08002221 for (k, v) in kwargs.items():
2222 if hasattr(self, k):
2223 setattr(self, k, v)
2224 else:
2225 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002226
2227
2228 def pack(self):
2229 """
2230 Pack object into string
2231
2232 @return The packed string which can go on the wire
2233
2234 """
2235 self.header.length = len(self)
2236 packed = self.header.pack()
2237
2238 packed += ofp_queue_get_config_reply.pack(self)
2239 for obj in self.queues:
2240 packed += obj.pack()
2241 return packed
2242
2243 def unpack(self, binary_string):
2244 """
2245 Unpack object from a binary string
2246
2247 @param binary_string The wire protocol byte string holding the object
2248 represented as an array of bytes.
2249 @return The remainder of binary_string that was not parsed.
2250
2251 """
2252 binary_string = self.header.unpack(binary_string)
2253
2254 binary_string = ofp_queue_get_config_reply.unpack(self, binary_string)
2255 for obj in self.queues:
2256 binary_string = obj.unpack(binary_string)
2257 # Fixme: If no self.data, add check for data remaining
2258 return binary_string
2259
2260 def __len__(self):
2261 """
2262 Return the length of this object once packed into a string
2263
2264 @return An integer representing the number bytes in the packed
2265 string.
2266
2267 """
2268 length = OFP_HEADER_BYTES
2269
2270 length += ofp_queue_get_config_reply.__len__(self)
2271 for obj in self.queues:
2272 length += len(obj)
2273 return length
2274
2275 def show(self, prefix=''):
2276 """
2277 Generate a string (with multiple lines) describing the contents
2278 of the object in a readable manner
2279
2280 @param prefix Pre-pended at the beginning of each line.
2281
2282 """
2283
2284 outstr = prefix + 'queue_get_config_reply (OFPT_QUEUE_GET_CONFIG_REPLY)\n'
2285 prefix += ' '
2286 outstr += prefix + 'ofp header\n'
2287 outstr += self.header.show(prefix + ' ')
2288 outstr += ofp_queue_get_config_reply.show(self, prefix)
2289 outstr += prefix + "Array queues\n"
2290 for obj in self.queues:
2291 outstr += obj.show(prefix + ' ')
2292 return outstr
2293
2294 def __eq__(self, other):
2295 """
2296 Return True if self and other hold the same data
2297
2298 @param other Other object in comparison
2299
2300 """
2301 if type(self) != type(other): return False
2302 if not self.header.__eq__(other.header): return False
2303
2304 if not ofp_queue_get_config_reply.__eq__(self, other): return False
2305 if self.queues != other.queues: return False
2306 return True
2307
2308 def __ne__(self, other):
2309 """
2310 Return True if self and other do not hold the same data
2311
2312 @param other Other object in comparison
2313
2314 """
2315 return not self.__eq__(other)
2316
2317
2318class queue_get_config_request(ofp_queue_get_config_request):
2319 """
2320 Wrapper class for queue_get_config_request
2321
2322 OpenFlow message header: length, version, xid, type
2323 @arg length: The total length of the message
2324 @arg version: The OpenFlow version (3)
2325 @arg xid: The transaction ID
2326 @arg type: The message type (OFPT_QUEUE_GET_CONFIG_REQUEST=22)
2327
2328 Data members inherited from ofp_queue_get_config_request:
2329 @arg port
2330
2331 """
2332
Rich Lane5de2d942013-01-11 11:49:36 -08002333 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002334 ofp_queue_get_config_request.__init__(self)
2335 self.header = ofp_header()
2336 self.header.type = OFPT_QUEUE_GET_CONFIG_REQUEST
Rich Lane5de2d942013-01-11 11:49:36 -08002337 for (k, v) in kwargs.items():
2338 if hasattr(self, k):
2339 setattr(self, k, v)
2340 else:
2341 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002342
2343
2344 def pack(self):
2345 """
2346 Pack object into string
2347
2348 @return The packed string which can go on the wire
2349
2350 """
2351 self.header.length = len(self)
2352 packed = self.header.pack()
2353
2354 packed += ofp_queue_get_config_request.pack(self)
2355 return packed
2356
2357 def unpack(self, binary_string):
2358 """
2359 Unpack object from a binary string
2360
2361 @param binary_string The wire protocol byte string holding the object
2362 represented as an array of bytes.
2363 @return The remainder of binary_string that was not parsed.
2364
2365 """
2366 binary_string = self.header.unpack(binary_string)
2367
2368 binary_string = ofp_queue_get_config_request.unpack(self, binary_string)
2369 # Fixme: If no self.data, add check for data remaining
2370 return binary_string
2371
2372 def __len__(self):
2373 """
2374 Return the length of this object once packed into a string
2375
2376 @return An integer representing the number bytes in the packed
2377 string.
2378
2379 """
2380 length = OFP_HEADER_BYTES
2381
2382 length += ofp_queue_get_config_request.__len__(self)
2383 return length
2384
2385 def show(self, prefix=''):
2386 """
2387 Generate a string (with multiple lines) describing the contents
2388 of the object in a readable manner
2389
2390 @param prefix Pre-pended at the beginning of each line.
2391
2392 """
2393
2394 outstr = prefix + 'queue_get_config_request (OFPT_QUEUE_GET_CONFIG_REQUEST)\n'
2395 prefix += ' '
2396 outstr += prefix + 'ofp header\n'
2397 outstr += self.header.show(prefix + ' ')
2398 outstr += ofp_queue_get_config_request.show(self, prefix)
2399 return outstr
2400
2401 def __eq__(self, other):
2402 """
2403 Return True if self and other hold the same data
2404
2405 @param other Other object in comparison
2406
2407 """
2408 if type(self) != type(other): return False
2409 if not self.header.__eq__(other.header): return False
2410
2411 if not ofp_queue_get_config_request.__eq__(self, other): return False
2412 return True
2413
2414 def __ne__(self, other):
2415 """
2416 Return True if self and other do not hold the same data
2417
2418 @param other Other object in comparison
2419
2420 """
2421 return not self.__eq__(other)
2422
2423
2424class set_config(ofp_switch_config):
2425 """
2426 Wrapper class for set_config
2427
2428 OpenFlow message header: length, version, xid, type
2429 @arg length: The total length of the message
2430 @arg version: The OpenFlow version (3)
2431 @arg xid: The transaction ID
2432 @arg type: The message type (OFPT_SET_CONFIG=9)
2433
2434 Data members inherited from ofp_switch_config:
2435 @arg flags
2436 @arg miss_send_len
2437
2438 """
2439
Rich Lane5de2d942013-01-11 11:49:36 -08002440 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002441 ofp_switch_config.__init__(self)
2442 self.header = ofp_header()
2443 self.header.type = OFPT_SET_CONFIG
Rich Lane5de2d942013-01-11 11:49:36 -08002444 for (k, v) in kwargs.items():
2445 if hasattr(self, k):
2446 setattr(self, k, v)
2447 else:
2448 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002449
2450
2451 def pack(self):
2452 """
2453 Pack object into string
2454
2455 @return The packed string which can go on the wire
2456
2457 """
2458 self.header.length = len(self)
2459 packed = self.header.pack()
2460
2461 packed += ofp_switch_config.pack(self)
2462 return packed
2463
2464 def unpack(self, binary_string):
2465 """
2466 Unpack object from a binary string
2467
2468 @param binary_string The wire protocol byte string holding the object
2469 represented as an array of bytes.
2470 @return The remainder of binary_string that was not parsed.
2471
2472 """
2473 binary_string = self.header.unpack(binary_string)
2474
2475 binary_string = ofp_switch_config.unpack(self, binary_string)
2476 # Fixme: If no self.data, add check for data remaining
2477 return binary_string
2478
2479 def __len__(self):
2480 """
2481 Return the length of this object once packed into a string
2482
2483 @return An integer representing the number bytes in the packed
2484 string.
2485
2486 """
2487 length = OFP_HEADER_BYTES
2488
2489 length += ofp_switch_config.__len__(self)
2490 return length
2491
2492 def show(self, prefix=''):
2493 """
2494 Generate a string (with multiple lines) describing the contents
2495 of the object in a readable manner
2496
2497 @param prefix Pre-pended at the beginning of each line.
2498
2499 """
2500
2501 outstr = prefix + 'set_config (OFPT_SET_CONFIG)\n'
2502 prefix += ' '
2503 outstr += prefix + 'ofp header\n'
2504 outstr += self.header.show(prefix + ' ')
2505 outstr += ofp_switch_config.show(self, prefix)
2506 return outstr
2507
2508 def __eq__(self, other):
2509 """
2510 Return True if self and other hold the same data
2511
2512 @param other Other object in comparison
2513
2514 """
2515 if type(self) != type(other): return False
2516 if not self.header.__eq__(other.header): return False
2517
2518 if not ofp_switch_config.__eq__(self, other): return False
2519 return True
2520
2521 def __ne__(self, other):
2522 """
2523 Return True if self and other do not hold the same data
2524
2525 @param other Other object in comparison
2526
2527 """
2528 return not self.__eq__(other)
2529
2530
2531class stats_reply(ofp_stats_reply):
2532 """
2533 Wrapper class for stats_reply
2534
2535 OpenFlow message header: length, version, xid, type
2536 @arg length: The total length of the message
2537 @arg version: The OpenFlow version (3)
2538 @arg xid: The transaction ID
2539 @arg type: The message type (OFPT_STATS_REPLY=19)
2540
2541 Data members inherited from ofp_stats_reply:
2542 @arg type
2543 @arg flags
2544
2545 """
2546
Rich Lane5de2d942013-01-11 11:49:36 -08002547 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002548 ofp_stats_reply.__init__(self)
2549 self.header = ofp_header()
2550 self.header.type = OFPT_STATS_REPLY
Rich Lane5de2d942013-01-11 11:49:36 -08002551 for (k, v) in kwargs.items():
2552 if hasattr(self, k):
2553 setattr(self, k, v)
2554 else:
2555 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002556
2557
2558 def pack(self):
2559 """
2560 Pack object into string
2561
2562 @return The packed string which can go on the wire
2563
2564 """
2565 self.header.length = len(self)
2566 packed = self.header.pack()
2567
2568 packed += ofp_stats_reply.pack(self)
2569 return packed
2570
2571 def unpack(self, binary_string):
2572 """
2573 Unpack object from a binary string
2574
2575 @param binary_string The wire protocol byte string holding the object
2576 represented as an array of bytes.
2577 @return The remainder of binary_string that was not parsed.
2578
2579 """
2580 binary_string = self.header.unpack(binary_string)
2581
2582 binary_string = ofp_stats_reply.unpack(self, binary_string)
2583 # Fixme: If no self.data, add check for data remaining
2584 return binary_string
2585
2586 def __len__(self):
2587 """
2588 Return the length of this object once packed into a string
2589
2590 @return An integer representing the number bytes in the packed
2591 string.
2592
2593 """
2594 length = OFP_HEADER_BYTES
2595
2596 length += ofp_stats_reply.__len__(self)
2597 return length
2598
2599 def show(self, prefix=''):
2600 """
2601 Generate a string (with multiple lines) describing the contents
2602 of the object in a readable manner
2603
2604 @param prefix Pre-pended at the beginning of each line.
2605
2606 """
2607
2608 outstr = prefix + 'stats_reply (OFPT_STATS_REPLY)\n'
2609 prefix += ' '
2610 outstr += prefix + 'ofp header\n'
2611 outstr += self.header.show(prefix + ' ')
2612 outstr += ofp_stats_reply.show(self, prefix)
2613 return outstr
2614
2615 def __eq__(self, other):
2616 """
2617 Return True if self and other hold the same data
2618
2619 @param other Other object in comparison
2620
2621 """
2622 if type(self) != type(other): return False
2623 if not self.header.__eq__(other.header): return False
2624
2625 if not ofp_stats_reply.__eq__(self, other): return False
2626 return True
2627
2628 def __ne__(self, other):
2629 """
2630 Return True if self and other do not hold the same data
2631
2632 @param other Other object in comparison
2633
2634 """
2635 return not self.__eq__(other)
2636
2637
2638class stats_request(ofp_stats_request):
2639 """
2640 Wrapper class for stats_request
2641
2642 OpenFlow message header: length, version, xid, type
2643 @arg length: The total length of the message
2644 @arg version: The OpenFlow version (3)
2645 @arg xid: The transaction ID
2646 @arg type: The message type (OFPT_STATS_REQUEST=18)
2647
2648 Data members inherited from ofp_stats_request:
2649 @arg type
2650 @arg flags
2651
2652 """
2653
Rich Lane5de2d942013-01-11 11:49:36 -08002654 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002655 ofp_stats_request.__init__(self)
2656 self.header = ofp_header()
2657 self.header.type = OFPT_STATS_REQUEST
Rich Lane5de2d942013-01-11 11:49:36 -08002658 for (k, v) in kwargs.items():
2659 if hasattr(self, k):
2660 setattr(self, k, v)
2661 else:
2662 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002663
2664
2665 def pack(self):
2666 """
2667 Pack object into string
2668
2669 @return The packed string which can go on the wire
2670
2671 """
2672 self.header.length = len(self)
2673 packed = self.header.pack()
2674
2675 packed += ofp_stats_request.pack(self)
2676 return packed
2677
2678 def unpack(self, binary_string):
2679 """
2680 Unpack object from a binary string
2681
2682 @param binary_string The wire protocol byte string holding the object
2683 represented as an array of bytes.
2684 @return The remainder of binary_string that was not parsed.
2685
2686 """
2687 binary_string = self.header.unpack(binary_string)
2688
2689 binary_string = ofp_stats_request.unpack(self, binary_string)
2690 # Fixme: If no self.data, add check for data remaining
2691 return binary_string
2692
2693 def __len__(self):
2694 """
2695 Return the length of this object once packed into a string
2696
2697 @return An integer representing the number bytes in the packed
2698 string.
2699
2700 """
2701 length = OFP_HEADER_BYTES
2702
2703 length += ofp_stats_request.__len__(self)
2704 return length
2705
2706 def show(self, prefix=''):
2707 """
2708 Generate a string (with multiple lines) describing the contents
2709 of the object in a readable manner
2710
2711 @param prefix Pre-pended at the beginning of each line.
2712
2713 """
2714
2715 outstr = prefix + 'stats_request (OFPT_STATS_REQUEST)\n'
2716 prefix += ' '
2717 outstr += prefix + 'ofp header\n'
2718 outstr += self.header.show(prefix + ' ')
2719 outstr += ofp_stats_request.show(self, prefix)
2720 return outstr
2721
2722 def __eq__(self, other):
2723 """
2724 Return True if self and other hold the same data
2725
2726 @param other Other object in comparison
2727
2728 """
2729 if type(self) != type(other): return False
2730 if not self.header.__eq__(other.header): return False
2731
2732 if not ofp_stats_request.__eq__(self, other): return False
2733 return True
2734
2735 def __ne__(self, other):
2736 """
2737 Return True if self and other do not hold the same data
2738
2739 @param other Other object in comparison
2740
2741 """
2742 return not self.__eq__(other)
2743
2744
2745class table_mod(ofp_table_mod):
2746 """
2747 Wrapper class for table_mod
2748
2749 OpenFlow message header: length, version, xid, type
2750 @arg length: The total length of the message
2751 @arg version: The OpenFlow version (3)
2752 @arg xid: The transaction ID
2753 @arg type: The message type (OFPT_TABLE_MOD=17)
2754
2755 Data members inherited from ofp_table_mod:
2756 @arg table_id
2757 @arg config
2758
2759 """
2760
Rich Lane5de2d942013-01-11 11:49:36 -08002761 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002762 ofp_table_mod.__init__(self)
2763 self.header = ofp_header()
2764 self.header.type = OFPT_TABLE_MOD
Rich Lane5de2d942013-01-11 11:49:36 -08002765 for (k, v) in kwargs.items():
2766 if hasattr(self, k):
2767 setattr(self, k, v)
2768 else:
2769 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08002770
2771
2772 def pack(self):
2773 """
2774 Pack object into string
2775
2776 @return The packed string which can go on the wire
2777
2778 """
2779 self.header.length = len(self)
2780 packed = self.header.pack()
2781
2782 packed += ofp_table_mod.pack(self)
2783 return packed
2784
2785 def unpack(self, binary_string):
2786 """
2787 Unpack object from a binary string
2788
2789 @param binary_string The wire protocol byte string holding the object
2790 represented as an array of bytes.
2791 @return The remainder of binary_string that was not parsed.
2792
2793 """
2794 binary_string = self.header.unpack(binary_string)
2795
2796 binary_string = ofp_table_mod.unpack(self, binary_string)
2797 # Fixme: If no self.data, add check for data remaining
2798 return binary_string
2799
2800 def __len__(self):
2801 """
2802 Return the length of this object once packed into a string
2803
2804 @return An integer representing the number bytes in the packed
2805 string.
2806
2807 """
2808 length = OFP_HEADER_BYTES
2809
2810 length += ofp_table_mod.__len__(self)
2811 return length
2812
2813 def show(self, prefix=''):
2814 """
2815 Generate a string (with multiple lines) describing the contents
2816 of the object in a readable manner
2817
2818 @param prefix Pre-pended at the beginning of each line.
2819
2820 """
2821
2822 outstr = prefix + 'table_mod (OFPT_TABLE_MOD)\n'
2823 prefix += ' '
2824 outstr += prefix + 'ofp header\n'
2825 outstr += self.header.show(prefix + ' ')
2826 outstr += ofp_table_mod.show(self, prefix)
2827 return outstr
2828
2829 def __eq__(self, other):
2830 """
2831 Return True if self and other hold the same data
2832
2833 @param other Other object in comparison
2834
2835 """
2836 if type(self) != type(other): return False
2837 if not self.header.__eq__(other.header): return False
2838
2839 if not ofp_table_mod.__eq__(self, other): return False
2840 return True
2841
2842 def __ne__(self, other):
2843 """
2844 Return True if self and other do not hold the same data
2845
2846 @param other Other object in comparison
2847
2848 """
2849 return not self.__eq__(other)
2850
2851
2852
2853################################################################
2854#
2855# Stats request and reply subclass definitions
2856#
2857################################################################
2858
2859
2860# Stats request bodies for desc and table stats are not defined in the
2861# OpenFlow header; We define them here. They are empty classes, really
2862
2863class ofp_desc_stats_request(object):
2864 """
2865 Forced definition of ofp_desc_stats_request (empty class)
2866 """
Rich Lane5de2d942013-01-11 11:49:36 -08002867 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002868 pass
2869 def pack(self, assertstruct=True):
2870 return ""
2871 def unpack(self, binary_string):
2872 return binary_string
2873 def __len__(self):
2874 return 0
2875 def show(self, prefix=''):
2876 return prefix + "ofp_desc_stats_request (empty)\n"
2877 def __eq__(self, other):
2878 return type(self) == type(other)
2879 def __ne__(self, other):
2880 return type(self) != type(other)
2881
2882OFP_DESC_STATS_REQUEST_BYTES = 0
2883
2884class ofp_table_stats_request(object):
2885 """
2886 Forced definition of ofp_table_stats_request (empty class)
2887 """
Rich Lane5de2d942013-01-11 11:49:36 -08002888 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002889 pass
2890 def pack(self, assertstruct=True):
2891 return ""
2892 def unpack(self, binary_string):
2893 return binary_string
2894 def __len__(self):
2895 return 0
2896 def show(self, prefix=''):
2897 return prefix + "ofp_table_stats_request (empty)\n"
2898 def __eq__(self, other):
2899 return type(self) == type(other)
2900 def __ne__(self, other):
2901 return type(self) != type(other)
2902
2903OFP_TABLE_STATS_REQUEST_BYTES = 0
2904
2905class ofp_group_desc_stats_request(object):
2906 """
2907 Forced definition of ofp_group_desc_stats_request (empty class)
2908 """
Rich Lane5de2d942013-01-11 11:49:36 -08002909 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002910 pass
2911 def pack(self, assertstruct=True):
2912 return ""
2913 def unpack(self, binary_string):
2914 return binary_string
2915 def __len__(self):
2916 return 0
2917 def show(self, prefix=''):
2918 return prefix + "ofp_group_desc_stats_request (empty)\n"
2919 def __eq__(self, other):
2920 return type(self) == type(other)
2921 def __ne__(self, other):
2922 return type(self) != type(other)
2923
2924OFP_GROUP_DESC_STATS_REQUEST_BYTES = 0
2925
2926
2927
2928# Stats entries define the content of one element in a stats
2929# reply for the indicated type; define _entry for consistency
2930
2931aggregate_stats_entry = ofp_aggregate_stats_reply
2932desc_stats_entry = ofp_desc_stats
2933port_stats_entry = ofp_port_stats
2934queue_stats_entry = ofp_queue_stats
2935table_stats_entry = ofp_table_stats
2936group_stats_entry = ofp_group_stats
2937group_desc_stats_entry = ofp_group_desc_stats
2938
2939
2940#
2941# Flow stats entry contains an action list of variable length, so
2942# it is done by hand
2943#
2944
2945class flow_stats_entry(ofp_flow_stats):
2946 """
2947 Special case flow stats entry to handle action list object
2948 """
Rich Lane5de2d942013-01-11 11:49:36 -08002949 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08002950 ofp_flow_stats.__init__(self)
2951 self.match_fields = match_list()
2952 self.instructions = instruction_list()
2953
2954 def pack(self, assertstruct=True):
2955 self.length = len(self)
2956 if not len(self.match_fields):
2957 tlv_pad = oxm_tlv(0,0,0,0,0,0)
2958 self.match.length += 4
2959 self.match_fields.tlvs.append(tlv_pad)
2960 else:
2961 if len(self.match_fields) > 4:
2962 self.match.length += len(self.match_fields)
2963 packed = ofp_flow_stats.pack(self, assertstruct)
2964 packed += self.match_fields.pack()
2965 padding_size = roundup(len(self.match) + len(self.match_fields),8) - (len(self.match) + len(self.match_fields))
2966 padding = [0] * padding_size
2967 if padding_size:
2968 packed += struct.pack("!" + str(padding_size) + "B", *padding)
2969 packed += self.instructions.pack()
2970 if len(packed) != self.length:
2971 print("ERROR: flow_stats_entry pack length not equal",
2972 self.length, len(packed))
2973 return packed
2974
2975 def unpack(self, binary_string):
2976 binary_string = ofp_flow_stats.unpack(self, binary_string)
2977 binary_string = self.match_fields.unpack(binary_string, bytes = self.match.length - 4)
2978 padding = roundup((OFP_FLOW_STATS_BYTES -4) + self.match.length,8) - ((OFP_FLOW_STATS_BYTES - 4) + self.match.length)
2979 if padding:
2980 binary_string = binary_string[padding:]
2981 ai_len = self.length - roundup(OFP_FLOW_STATS_BYTES + len(self.match_fields),8)
2982 if ai_len < 0:
2983 print("ERROR: flow_stats_entry unpack length too small",
2984 self.length)
2985 binary_string = self.instructions.unpack(binary_string, bytes=ai_len)
2986 return binary_string
2987
2988 def __len__(self):
2989 return roundup(OFP_FLOW_STATS_BYTES + len(self.match_fields),8) + len(self.instructions)
2990
2991 def show(self, prefix=''):
2992 outstr = prefix + "flow_stats_entry\n"
2993 outstr += ofp_flow_stats.show(self, prefix + ' ')
2994 outstr += self.match_fields.show(prefix + ' ')
2995 outstr += self.instructions.show(prefix + ' ')
2996 return outstr
2997
2998 def __eq__(self, other):
2999 if type(self) != type(other): return False
3000 return (ofp_flow_stats.__eq__(self, other) and
3001 self.instructions == other.instructions)
3002
3003 def __ne__(self, other): return not self.__eq__(other)
3004
3005
3006class aggregate_stats_request(ofp_stats_request, ofp_aggregate_stats_request):
3007 """
3008 Wrapper class for aggregate stats request message
3009 """
Rich Lane5de2d942013-01-11 11:49:36 -08003010 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003011 self.header = ofp_header()
3012 ofp_stats_request.__init__(self)
3013 ofp_aggregate_stats_request.__init__(self)
3014 self.header.type = OFPT_STATS_REQUEST
3015 self.type = OFPST_AGGREGATE
3016 self.match_fields = match_list()
Rich Lane5de2d942013-01-11 11:49:36 -08003017 for (k, v) in kwargs.items():
3018 if hasattr(self, k):
3019 setattr(self, k, v)
3020 else:
3021 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003022
3023 def pack(self, assertstruct=True):
3024 self.header.length = len(self)
3025 packed = self.header.pack()
3026 packed += ofp_stats_request.pack(self)
3027 if not len(self.match_fields):
3028 tlv_pad = oxm_tlv(0,0,0,0,0,0)
3029 self.match.length += 4
3030 self.match_fields.tlvs.append(tlv_pad)
3031 else:
3032 if len(self.match_fields) > 4:
3033 self.match.length += len(self.match_fields)
3034 packed += ofp_aggregate_stats_request.pack(self, assertstruct)
3035 packed += self.match_fields.pack()
3036 padding_size = roundup(len(self.match) + len(self.match_fields),8) - (len(self.match) + len(self.match_fields))
3037 padding = [0] * padding_size
3038
3039 if padding_size:
3040 packed += struct.pack("!" + str(padding_size) + "B", *padding)
3041 return packed
3042
3043 def unpack(self, binary_string):
3044 binary_string = self.header.unpack(binary_string)
3045 binary_string = ofp_stats_request.unpack(self, binary_string)
3046 binary_string = ofp_aggregate_stats_request.unpack(self, binary_string)
3047 binary_string = self.match_fields.unpack(binary_string, bytes = self.match.length - 4)
3048 padding = roundup(OFP_AGGREGATE_STATS_REQUEST_BYTES + len(self.match_fields),8) - (OFP_AGGREGATE_STATS_REQUEST_BYTES + len(self.match_fields))
3049 if padding:
3050 binary_string = binary_string[padding:]
3051 if len(binary_string) != 0:
3052 print "ERROR unpacking flow: extra data"
3053 return binary_string
3054
3055
3056 def __len__(self):
3057 length = len(self.header) + OFP_STATS_REQUEST_BYTES + \
3058 OFP_AGGREGATE_STATS_REQUEST_BYTES
3059 if not len(self.match_fields):
3060 return length + 4
3061 else:
3062 return roundup(length + len(self.match_fields),8)
3063
3064 def show(self, prefix=''):
3065 outstr = prefix + "aggregate_stats_request\n"
3066 outstr += prefix + "ofp header:\n"
3067 outstr += self.header.show(prefix + ' ')
3068 outstr += ofp_stats_request.show(self)
3069 outstr += ofp_aggregate_stats_request.show(self)
3070 return outstr
3071
3072 def __eq__(self, other):
3073 if type(self) != type(other): return False
3074 return (self.header == other.header and
3075 ofp_stats_request.__eq__(self, other) and
3076 ofp_aggregate_stats_request.__eq__(self, other))
3077
3078 def __ne__(self, other): return not self.__eq__(other)
3079
3080
3081class aggregate_stats_reply(ofp_stats_reply):
3082 """
3083 Wrapper class for aggregate stats reply
3084 """
Rich Lane5de2d942013-01-11 11:49:36 -08003085 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003086 self.header = ofp_header()
3087 ofp_stats_reply.__init__(self)
3088 self.header.type = OFPT_STATS_REPLY
3089 self.type = OFPST_AGGREGATE
3090 # stats: Array of type aggregate_stats_entry
3091 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003092 for (k, v) in kwargs.items():
3093 if hasattr(self, k):
3094 setattr(self, k, v)
3095 else:
3096 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003097
3098 def pack(self, assertstruct=True):
3099 self.header.length = len(self)
3100 packed = self.header.pack()
3101 packed += ofp_stats_reply.pack(self)
3102 for obj in self.stats:
3103 packed += obj.pack()
3104 return packed
3105
3106 def unpack(self, binary_string):
3107 binary_string = self.header.unpack(binary_string)
3108 binary_string = ofp_stats_reply.unpack(self, binary_string)
3109 dummy = aggregate_stats_entry()
3110 while len(binary_string) >= len(dummy):
3111 obj = aggregate_stats_entry()
3112 binary_string = obj.unpack(binary_string)
3113 self.stats.append(obj)
3114 if len(binary_string) != 0:
3115 print "ERROR unpacking aggregate stats string: extra bytes"
3116 return binary_string
3117
3118 def __len__(self):
3119 length = len(self.header) + OFP_STATS_REPLY_BYTES
3120 for obj in self.stats:
3121 length += len(obj)
3122 return length
3123
3124 def show(self, prefix=''):
3125 outstr = prefix + "aggregate_stats_reply\n"
3126 outstr += prefix + "ofp header:\n"
3127 outstr += self.header.show(prefix + ' ')
3128 outstr += ofp_stats_reply.show(self)
3129 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3130 for obj in self.stats:
3131 outstr += obj.show()
3132 return outstr
3133
3134 def __eq__(self, other):
3135 if type(self) != type(other): return False
3136 return (self.header == other.header and
3137 ofp_stats_reply.__eq__(self, other) and
3138 self.stats == other.stats)
3139
3140 def __ne__(self, other): return not self.__eq__(other)
3141
3142
3143class desc_stats_request(ofp_stats_request, ofp_desc_stats_request):
3144 """
3145 Wrapper class for desc stats request message
3146 """
Rich Lane5de2d942013-01-11 11:49:36 -08003147 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003148 self.header = ofp_header()
3149 ofp_stats_request.__init__(self)
3150 ofp_desc_stats_request.__init__(self)
3151 self.header.type = OFPT_STATS_REQUEST
3152 self.type = OFPST_DESC
Rich Lane5de2d942013-01-11 11:49:36 -08003153 for (k, v) in kwargs.items():
3154 if hasattr(self, k):
3155 setattr(self, k, v)
3156 else:
3157 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003158
3159 def pack(self, assertstruct=True):
3160 self.header.length = len(self)
3161 packed = self.header.pack()
3162 packed += ofp_stats_request.pack(self)
3163 packed += ofp_desc_stats_request.pack(self)
3164 return packed
3165
3166 def unpack(self, binary_string):
3167 binary_string = self.header.unpack(binary_string)
3168 binary_string = ofp_stats_request.unpack(self, binary_string)
3169 binary_string = ofp_desc_stats_request.unpack(self, binary_string)
3170 if len(binary_string) != 0:
3171 print "ERROR unpacking desc: extra data"
3172 return binary_string
3173
3174 def __len__(self):
3175 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3176 OFP_DESC_STATS_REQUEST_BYTES
3177
3178 def show(self, prefix=''):
3179 outstr = prefix + "desc_stats_request\n"
3180 outstr += prefix + "ofp header:\n"
3181 outstr += self.header.show(prefix + ' ')
3182 outstr += ofp_stats_request.show(self)
3183 outstr += ofp_desc_stats_request.show(self)
3184 return outstr
3185
3186 def __eq__(self, other):
3187 if type(self) != type(other): return False
3188 return (self.header == other.header and
3189 ofp_stats_request.__eq__(self, other) and
3190 ofp_desc_stats_request.__eq__(self, other))
3191
3192 def __ne__(self, other): return not self.__eq__(other)
3193
3194
3195class desc_stats_reply(ofp_stats_reply):
3196 """
3197 Wrapper class for desc stats reply
3198 """
Rich Lane5de2d942013-01-11 11:49:36 -08003199 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003200 self.header = ofp_header()
3201 ofp_stats_reply.__init__(self)
3202 self.header.type = OFPT_STATS_REPLY
3203 self.type = OFPST_DESC
3204 # stats: Array of type desc_stats_entry
3205 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003206 for (k, v) in kwargs.items():
3207 if hasattr(self, k):
3208 setattr(self, k, v)
3209 else:
3210 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003211
3212 def pack(self, assertstruct=True):
3213 self.header.length = len(self)
3214 packed = self.header.pack()
3215 packed += ofp_stats_reply.pack(self)
3216 for obj in self.stats:
3217 packed += obj.pack()
3218 return packed
3219
3220 def unpack(self, binary_string):
3221 binary_string = self.header.unpack(binary_string)
3222 binary_string = ofp_stats_reply.unpack(self, binary_string)
3223 dummy = desc_stats_entry()
3224 while len(binary_string) >= len(dummy):
3225 obj = desc_stats_entry()
3226 binary_string = obj.unpack(binary_string)
3227 self.stats.append(obj)
3228 if len(binary_string) != 0:
3229 print "ERROR unpacking desc stats string: extra bytes"
3230 return binary_string
3231
3232 def __len__(self):
3233 length = len(self.header) + OFP_STATS_REPLY_BYTES
3234 for obj in self.stats:
3235 length += len(obj)
3236 return length
3237
3238 def show(self, prefix=''):
3239 outstr = prefix + "desc_stats_reply\n"
3240 outstr += prefix + "ofp header:\n"
3241 outstr += self.header.show(prefix + ' ')
3242 outstr += ofp_stats_reply.show(self)
3243 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3244 for obj in self.stats:
3245 outstr += obj.show()
3246 return outstr
3247
3248 def __eq__(self, other):
3249 if type(self) != type(other): return False
3250 return (self.header == other.header and
3251 ofp_stats_reply.__eq__(self, other) and
3252 self.stats == other.stats)
3253
3254 def __ne__(self, other): return not self.__eq__(other)
3255
3256
3257class flow_stats_request(ofp_stats_request, ofp_flow_stats_request):
3258 """
3259 Wrapper class for flow stats request message
3260 """
Rich Lane5de2d942013-01-11 11:49:36 -08003261 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003262 self.header = ofp_header()
3263 ofp_stats_request.__init__(self)
3264 ofp_flow_stats_request.__init__(self)
3265 self.header.type = OFPT_STATS_REQUEST
3266 self.type = OFPST_FLOW
3267 self.match_fields = match_list()
Rich Lane5de2d942013-01-11 11:49:36 -08003268 for (k, v) in kwargs.items():
3269 if hasattr(self, k):
3270 setattr(self, k, v)
3271 else:
3272 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003273
3274 def pack(self):
3275 self.header.length = len(self)
3276 packed = self.header.pack()
3277 packed += ofp_stats_request.pack(self)
3278 if not len(self.match_fields):
3279 tlv_pad = oxm_tlv(0,0,0,0,0,0)
3280 self.match.length += 4
3281 self.match_fields.tlvs.append(tlv_pad)
3282 else:
3283 if len(self.match_fields) > 4:
3284 self.match.length += len(self.match_fields)
3285 packed += ofp_flow_stats_request.pack(self)
3286 packed += self.match_fields.pack()
3287 padding_size = roundup(len(self.match) + len(self.match_fields),8) - (len(self.match) + len(self.match_fields))
3288 padding = [0] * padding_size
3289 if padding_size:
3290 packed += struct.pack("!" + str(padding_size) + "B", *padding)
3291 return packed
3292
3293 def unpack(self, binary_string):
3294 binary_string = self.header.unpack(binary_string)
3295 binary_string = ofp_stats_request.unpack(self, binary_string)
3296 binary_string = ofp_flow_stats_request.unpack(self, binary_string)
3297 binary_string = self.match_fields.unpack(binary_string, bytes = self.match.length - 4)
3298 padding = roundup(OFP_FLOW_STATS_REQUEST_BYTES + len(self.match_fields),8) - (OFP_FLOW_STATS_REQUEST_BYTES + len(self.match_fields))
3299 if padding:
3300 binary_string = binary_string[padding:]
3301 if len(binary_string) != 0:
3302 print "ERROR unpacking flow: extra data"
3303 return binary_string
3304
3305 def __len__(self):
3306 length = len(self.header) + OFP_STATS_REQUEST_BYTES + \
3307 OFP_FLOW_STATS_REQUEST_BYTES
3308 if not len(self.match_fields):
3309 return length + 4
3310 else:
3311 return roundup(length + len(self.match_fields),8)
3312
3313 def show(self, prefix=''):
3314 outstr = prefix + "flow_stats_request\n"
3315 outstr += prefix + "ofp header:\n"
3316 outstr += self.header.show(prefix + ' ')
3317 outstr += ofp_stats_request.show(self)
3318 outstr += ofp_flow_stats_request.show(self)
3319 outstr += self.match_fields.show(prefix + ' ')
3320 return outstr
3321
3322 def __eq__(self, other):
3323 if type(self) != type(other): return False
3324 return (self.header == other.header and
3325 ofp_stats_request.__eq__(self, other) and
3326 ofp_flow_stats_request.__eq__(self, other) and
3327 self.match_fields != other.match_fields)
3328
3329 def __ne__(self, other): return not self.__eq__(other)
3330
3331
3332class flow_stats_reply(ofp_stats_reply):
3333 """
3334 Wrapper class for flow stats reply
3335 """
Rich Lane5de2d942013-01-11 11:49:36 -08003336 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003337 self.header = ofp_header()
3338 ofp_stats_reply.__init__(self)
3339 self.header.type = OFPT_STATS_REPLY
3340 self.type = OFPST_FLOW
3341 # stats: Array of type flow_stats_entry
3342 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003343 for (k, v) in kwargs.items():
3344 if hasattr(self, k):
3345 setattr(self, k, v)
3346 else:
3347 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003348
3349 def pack(self, assertstruct=True):
3350 self.header.length = len(self)
3351 packed = self.header.pack()
3352 packed += ofp_stats_reply.pack(self)
3353 for obj in self.stats:
3354 packed += obj.pack()
3355 return packed
3356
3357 def unpack(self, binary_string):
3358 binary_string = self.header.unpack(binary_string)
3359 binary_string = ofp_stats_reply.unpack(self, binary_string)
3360 dummy = flow_stats_entry()
3361 while len(binary_string) >= len(dummy):
3362 obj = flow_stats_entry()
3363 binary_string = obj.unpack(binary_string)
3364 self.stats.append(obj)
3365 if len(binary_string) != 0:
3366 print "ERROR unpacking flow stats string: extra bytes"
3367 return binary_string
3368
3369 def __len__(self):
3370 length = len(self.header) + OFP_STATS_REPLY_BYTES
3371 for obj in self.stats:
3372 length += len(obj)
3373 return length
3374
3375 def show(self, prefix=''):
3376 outstr = prefix + "flow_stats_reply\n"
3377 outstr += prefix + "ofp header:\n"
3378 outstr += self.header.show(prefix + ' ')
3379 outstr += ofp_stats_reply.show(self)
3380 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3381 for obj in self.stats:
3382 outstr += obj.show()
3383 return outstr
3384
3385 def __eq__(self, other):
3386 if type(self) != type(other): return False
3387 return (self.header == other.header and
3388 ofp_stats_reply.__eq__(self, other) and
3389 self.stats == other.stats)
3390
3391 def __ne__(self, other): return not self.__eq__(other)
3392
3393
3394class port_stats_request(ofp_stats_request, ofp_port_stats_request):
3395 """
3396 Wrapper class for port stats request message
3397 """
Rich Lane5de2d942013-01-11 11:49:36 -08003398 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003399 self.header = ofp_header()
3400 ofp_stats_request.__init__(self)
3401 ofp_port_stats_request.__init__(self)
3402 self.header.type = OFPT_STATS_REQUEST
3403 self.type = OFPST_PORT
Rich Lane5de2d942013-01-11 11:49:36 -08003404 for (k, v) in kwargs.items():
3405 if hasattr(self, k):
3406 setattr(self, k, v)
3407 else:
3408 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003409
3410 def pack(self, assertstruct=True):
3411 self.header.length = len(self)
3412 packed = self.header.pack()
3413 packed += ofp_stats_request.pack(self)
3414 packed += ofp_port_stats_request.pack(self)
3415 return packed
3416
3417 def unpack(self, binary_string):
3418 binary_string = self.header.unpack(binary_string)
3419 binary_string = ofp_stats_request.unpack(self, binary_string)
3420 binary_string = ofp_port_stats_request.unpack(self, binary_string)
3421 if len(binary_string) != 0:
3422 print "ERROR unpacking port: extra data"
3423 return binary_string
3424
3425 def __len__(self):
3426 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3427 OFP_PORT_STATS_REQUEST_BYTES
3428
3429 def show(self, prefix=''):
3430 outstr = prefix + "port_stats_request\n"
3431 outstr += prefix + "ofp header:\n"
3432 outstr += self.header.show(prefix + ' ')
3433 outstr += ofp_stats_request.show(self)
3434 outstr += ofp_port_stats_request.show(self)
3435 return outstr
3436
3437 def __eq__(self, other):
3438 if type(self) != type(other): return False
3439 return (self.header == other.header and
3440 ofp_stats_request.__eq__(self, other) and
3441 ofp_port_stats_request.__eq__(self, other))
3442
3443 def __ne__(self, other): return not self.__eq__(other)
3444
3445
3446class port_stats_reply(ofp_stats_reply):
3447 """
3448 Wrapper class for port stats reply
3449 """
Rich Lane5de2d942013-01-11 11:49:36 -08003450 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003451 self.header = ofp_header()
3452 ofp_stats_reply.__init__(self)
3453 self.header.type = OFPT_STATS_REPLY
3454 self.type = OFPST_PORT
3455 # stats: Array of type port_stats_entry
3456 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003457 for (k, v) in kwargs.items():
3458 if hasattr(self, k):
3459 setattr(self, k, v)
3460 else:
3461 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003462
3463 def pack(self, assertstruct=True):
3464 self.header.length = len(self)
3465 packed = self.header.pack()
3466 packed += ofp_stats_reply.pack(self)
3467 for obj in self.stats:
3468 packed += obj.pack()
3469 return packed
3470
3471 def unpack(self, binary_string):
3472 binary_string = self.header.unpack(binary_string)
3473 binary_string = ofp_stats_reply.unpack(self, binary_string)
3474 dummy = port_stats_entry()
3475 while len(binary_string) >= len(dummy):
3476 obj = port_stats_entry()
3477 binary_string = obj.unpack(binary_string)
3478 self.stats.append(obj)
3479 if len(binary_string) != 0:
3480 print "ERROR unpacking port stats string: extra bytes"
3481 return binary_string
3482
3483 def __len__(self):
3484 length = len(self.header) + OFP_STATS_REPLY_BYTES
3485 for obj in self.stats:
3486 length += len(obj)
3487 return length
3488
3489 def show(self, prefix=''):
3490 outstr = prefix + "port_stats_reply\n"
3491 outstr += prefix + "ofp header:\n"
3492 outstr += self.header.show(prefix + ' ')
3493 outstr += ofp_stats_reply.show(self)
3494 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3495 for obj in self.stats:
3496 outstr += obj.show()
3497 return outstr
3498
3499 def __eq__(self, other):
3500 if type(self) != type(other): return False
3501 return (self.header == other.header and
3502 ofp_stats_reply.__eq__(self, other) and
3503 self.stats == other.stats)
3504
3505 def __ne__(self, other): return not self.__eq__(other)
3506
3507
3508class queue_stats_request(ofp_stats_request, ofp_queue_stats_request):
3509 """
3510 Wrapper class for queue stats request message
3511 """
Rich Lane5de2d942013-01-11 11:49:36 -08003512 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003513 self.header = ofp_header()
3514 ofp_stats_request.__init__(self)
3515 ofp_queue_stats_request.__init__(self)
3516 self.header.type = OFPT_STATS_REQUEST
3517 self.type = OFPST_QUEUE
Rich Lane5de2d942013-01-11 11:49:36 -08003518 for (k, v) in kwargs.items():
3519 if hasattr(self, k):
3520 setattr(self, k, v)
3521 else:
3522 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003523
3524 def pack(self, assertstruct=True):
3525 self.header.length = len(self)
3526 packed = self.header.pack()
3527 packed += ofp_stats_request.pack(self)
3528 packed += ofp_queue_stats_request.pack(self)
3529 return packed
3530
3531 def unpack(self, binary_string):
3532 binary_string = self.header.unpack(binary_string)
3533 binary_string = ofp_stats_request.unpack(self, binary_string)
3534 binary_string = ofp_queue_stats_request.unpack(self, binary_string)
3535 if len(binary_string) != 0:
3536 print "ERROR unpacking queue: extra data"
3537 return binary_string
3538
3539 def __len__(self):
3540 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3541 OFP_QUEUE_STATS_REQUEST_BYTES
3542
3543 def show(self, prefix=''):
3544 outstr = prefix + "queue_stats_request\n"
3545 outstr += prefix + "ofp header:\n"
3546 outstr += self.header.show(prefix + ' ')
3547 outstr += ofp_stats_request.show(self)
3548 outstr += ofp_queue_stats_request.show(self)
3549 return outstr
3550
3551 def __eq__(self, other):
3552 if type(self) != type(other): return False
3553 return (self.header == other.header and
3554 ofp_stats_request.__eq__(self, other) and
3555 ofp_queue_stats_request.__eq__(self, other))
3556
3557 def __ne__(self, other): return not self.__eq__(other)
3558
3559
3560class queue_stats_reply(ofp_stats_reply):
3561 """
3562 Wrapper class for queue stats reply
3563 """
Rich Lane5de2d942013-01-11 11:49:36 -08003564 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003565 self.header = ofp_header()
3566 ofp_stats_reply.__init__(self)
3567 self.header.type = OFPT_STATS_REPLY
3568 self.type = OFPST_QUEUE
3569 # stats: Array of type queue_stats_entry
3570 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003571 for (k, v) in kwargs.items():
3572 if hasattr(self, k):
3573 setattr(self, k, v)
3574 else:
3575 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003576
3577 def pack(self, assertstruct=True):
3578 self.header.length = len(self)
3579 packed = self.header.pack()
3580 packed += ofp_stats_reply.pack(self)
3581 for obj in self.stats:
3582 packed += obj.pack()
3583 return packed
3584
3585 def unpack(self, binary_string):
3586 binary_string = self.header.unpack(binary_string)
3587 binary_string = ofp_stats_reply.unpack(self, binary_string)
3588 dummy = queue_stats_entry()
3589 while len(binary_string) >= len(dummy):
3590 obj = queue_stats_entry()
3591 binary_string = obj.unpack(binary_string)
3592 self.stats.append(obj)
3593 if len(binary_string) != 0:
3594 print "ERROR unpacking queue stats string: extra bytes"
3595 return binary_string
3596
3597 def __len__(self):
3598 length = len(self.header) + OFP_STATS_REPLY_BYTES
3599 for obj in self.stats:
3600 length += len(obj)
3601 return length
3602
3603 def show(self, prefix=''):
3604 outstr = prefix + "queue_stats_reply\n"
3605 outstr += prefix + "ofp header:\n"
3606 outstr += self.header.show(prefix + ' ')
3607 outstr += ofp_stats_reply.show(self)
3608 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3609 for obj in self.stats:
3610 outstr += obj.show()
3611 return outstr
3612
3613 def __eq__(self, other):
3614 if type(self) != type(other): return False
3615 return (self.header == other.header and
3616 ofp_stats_reply.__eq__(self, other) and
3617 self.stats == other.stats)
3618
3619 def __ne__(self, other): return not self.__eq__(other)
3620
3621
3622class group_stats_request(ofp_stats_request, ofp_group_stats_request):
3623 """
3624 Wrapper class for group stats request message
3625 """
Rich Lane5de2d942013-01-11 11:49:36 -08003626 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003627 self.header = ofp_header()
3628 ofp_stats_request.__init__(self)
3629 ofp_group_stats_request.__init__(self)
3630 self.header.type = OFPT_STATS_REQUEST
3631 self.type = OFPST_GROUP
Rich Lane5de2d942013-01-11 11:49:36 -08003632 for (k, v) in kwargs.items():
3633 if hasattr(self, k):
3634 setattr(self, k, v)
3635 else:
3636 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003637
3638 def pack(self, assertstruct=True):
3639 self.header.length = len(self)
3640 packed = self.header.pack()
3641 packed += ofp_stats_request.pack(self)
3642 packed += ofp_group_stats_request.pack(self)
3643 return packed
3644
3645 def unpack(self, binary_string):
3646 binary_string = self.header.unpack(binary_string)
3647 binary_string = ofp_stats_request.unpack(self, binary_string)
3648 binary_string = ofp_group_stats_request.unpack(self, binary_string)
3649 if len(binary_string) != 0:
3650 print "ERROR unpacking group: extra data"
3651 return binary_string
3652
3653 def __len__(self):
3654 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3655 OFP_GROUP_STATS_REQUEST_BYTES
3656
3657 def show(self, prefix=''):
3658 outstr = prefix + "group_stats_request\n"
3659 outstr += prefix + "ofp header:\n"
3660 outstr += self.header.show(prefix + ' ')
3661 outstr += ofp_stats_request.show(self)
3662 outstr += ofp_group_stats_request.show(self)
3663 return outstr
3664
3665 def __eq__(self, other):
3666 if type(self) != type(other): return False
3667 return (self.header == other.header and
3668 ofp_stats_request.__eq__(self, other) and
3669 ofp_group_stats_request.__eq__(self, other))
3670
3671 def __ne__(self, other): return not self.__eq__(other)
3672
3673
3674class group_stats_reply(ofp_stats_reply):
3675 """
3676 Wrapper class for group stats reply
3677 """
Rich Lane5de2d942013-01-11 11:49:36 -08003678 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003679 self.header = ofp_header()
3680 ofp_stats_reply.__init__(self)
3681 self.header.type = OFPT_STATS_REPLY
3682 self.type = OFPST_GROUP
3683 # stats: Array of type group_stats_entry
3684 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003685 for (k, v) in kwargs.items():
3686 if hasattr(self, k):
3687 setattr(self, k, v)
3688 else:
3689 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003690
3691 def pack(self, assertstruct=True):
3692 self.header.length = len(self)
3693 packed = self.header.pack()
3694 packed += ofp_stats_reply.pack(self)
3695 for obj in self.stats:
3696 packed += obj.pack()
3697 return packed
3698
3699 def unpack(self, binary_string):
3700 binary_string = self.header.unpack(binary_string)
3701 binary_string = ofp_stats_reply.unpack(self, binary_string)
3702 dummy = group_stats_entry()
3703 while len(binary_string) >= len(dummy):
3704 obj = group_stats_entry()
3705 binary_string = obj.unpack(binary_string)
3706 self.stats.append(obj)
3707 if len(binary_string) != 0:
3708 print "ERROR unpacking group stats string: extra bytes"
3709 return binary_string
3710
3711 def __len__(self):
3712 length = len(self.header) + OFP_STATS_REPLY_BYTES
3713 for obj in self.stats:
3714 length += len(obj)
3715 return length
3716
3717 def show(self, prefix=''):
3718 outstr = prefix + "group_stats_reply\n"
3719 outstr += prefix + "ofp header:\n"
3720 outstr += self.header.show(prefix + ' ')
3721 outstr += ofp_stats_reply.show(self)
3722 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3723 for obj in self.stats:
3724 outstr += obj.show()
3725 return outstr
3726
3727 def __eq__(self, other):
3728 if type(self) != type(other): return False
3729 return (self.header == other.header and
3730 ofp_stats_reply.__eq__(self, other) and
3731 self.stats == other.stats)
3732
3733 def __ne__(self, other): return not self.__eq__(other)
3734
3735
3736class group_desc_stats_request(ofp_stats_request, ofp_group_desc_stats_request):
3737 """
3738 Wrapper class for group_desc stats request message
3739 """
Rich Lane5de2d942013-01-11 11:49:36 -08003740 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003741 self.header = ofp_header()
3742 ofp_stats_request.__init__(self)
3743 ofp_group_desc_stats_request.__init__(self)
3744 self.header.type = OFPT_STATS_REQUEST
3745 self.type = OFPST_GROUP_DESC
Rich Lane5de2d942013-01-11 11:49:36 -08003746 for (k, v) in kwargs.items():
3747 if hasattr(self, k):
3748 setattr(self, k, v)
3749 else:
3750 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003751
3752 def pack(self, assertstruct=True):
3753 self.header.length = len(self)
3754 packed = self.header.pack()
3755 packed += ofp_stats_request.pack(self)
3756 packed += ofp_group_desc_stats_request.pack(self)
3757 return packed
3758
3759 def unpack(self, binary_string):
3760 binary_string = self.header.unpack(binary_string)
3761 binary_string = ofp_stats_request.unpack(self, binary_string)
3762 binary_string = ofp_group_desc_stats_request.unpack(self, binary_string)
3763 if len(binary_string) != 0:
3764 print "ERROR unpacking group_desc: extra data"
3765 return binary_string
3766
3767 def __len__(self):
3768 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3769 OFP_GROUP_DESC_STATS_REQUEST_BYTES
3770
3771 def show(self, prefix=''):
3772 outstr = prefix + "group_desc_stats_request\n"
3773 outstr += prefix + "ofp header:\n"
3774 outstr += self.header.show(prefix + ' ')
3775 outstr += ofp_stats_request.show(self)
3776 outstr += ofp_group_desc_stats_request.show(self)
3777 return outstr
3778
3779 def __eq__(self, other):
3780 if type(self) != type(other): return False
3781 return (self.header == other.header and
3782 ofp_stats_request.__eq__(self, other) and
3783 ofp_group_desc_stats_request.__eq__(self, other))
3784
3785 def __ne__(self, other): return not self.__eq__(other)
3786
3787
3788class group_desc_stats_reply(ofp_stats_reply):
3789 """
3790 Wrapper class for group_desc stats reply
3791 """
Rich Lane5de2d942013-01-11 11:49:36 -08003792 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003793 self.header = ofp_header()
3794 ofp_stats_reply.__init__(self)
3795 self.header.type = OFPT_STATS_REPLY
3796 self.type = OFPST_GROUP_DESC
3797 # stats: Array of type group_desc_stats_entry
3798 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003799 for (k, v) in kwargs.items():
3800 if hasattr(self, k):
3801 setattr(self, k, v)
3802 else:
3803 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003804
3805 def pack(self, assertstruct=True):
3806 self.header.length = len(self)
3807 packed = self.header.pack()
3808 packed += ofp_stats_reply.pack(self)
3809 for obj in self.stats:
3810 packed += obj.pack()
3811 return packed
3812
3813 def unpack(self, binary_string):
3814 binary_string = self.header.unpack(binary_string)
3815 binary_string = ofp_stats_reply.unpack(self, binary_string)
3816 dummy = group_desc_stats_entry()
3817 while len(binary_string) >= len(dummy):
3818 obj = group_desc_stats_entry()
3819 binary_string = obj.unpack(binary_string)
3820 self.stats.append(obj)
3821 if len(binary_string) != 0:
3822 print "ERROR unpacking group_desc stats string: extra bytes"
3823 return binary_string
3824
3825 def __len__(self):
3826 length = len(self.header) + OFP_STATS_REPLY_BYTES
3827 for obj in self.stats:
3828 length += len(obj)
3829 return length
3830
3831 def show(self, prefix=''):
3832 outstr = prefix + "group_desc_stats_reply\n"
3833 outstr += prefix + "ofp header:\n"
3834 outstr += self.header.show(prefix + ' ')
3835 outstr += ofp_stats_reply.show(self)
3836 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3837 for obj in self.stats:
3838 outstr += obj.show()
3839 return outstr
3840
3841 def __eq__(self, other):
3842 if type(self) != type(other): return False
3843 return (self.header == other.header and
3844 ofp_stats_reply.__eq__(self, other) and
3845 self.stats == other.stats)
3846
3847 def __ne__(self, other): return not self.__eq__(other)
3848
3849
3850class table_stats_request(ofp_stats_request, ofp_table_stats_request):
3851 """
3852 Wrapper class for table stats request message
3853 """
Rich Lane5de2d942013-01-11 11:49:36 -08003854 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003855 self.header = ofp_header()
3856 ofp_stats_request.__init__(self)
3857 ofp_table_stats_request.__init__(self)
3858 self.header.type = OFPT_STATS_REQUEST
3859 self.type = OFPST_TABLE
Rich Lane5de2d942013-01-11 11:49:36 -08003860 for (k, v) in kwargs.items():
3861 if hasattr(self, k):
3862 setattr(self, k, v)
3863 else:
3864 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003865
3866 def pack(self, assertstruct=True):
3867 self.header.length = len(self)
3868 packed = self.header.pack()
3869 packed += ofp_stats_request.pack(self)
3870 packed += ofp_table_stats_request.pack(self)
3871 return packed
3872
3873 def unpack(self, binary_string):
3874 binary_string = self.header.unpack(binary_string)
3875 binary_string = ofp_stats_request.unpack(self, binary_string)
3876 binary_string = ofp_table_stats_request.unpack(self, binary_string)
3877 if len(binary_string) != 0:
3878 print "ERROR unpacking table: extra data"
3879 return binary_string
3880
3881 def __len__(self):
3882 return len(self.header) + OFP_STATS_REQUEST_BYTES + \
3883 OFP_TABLE_STATS_REQUEST_BYTES
3884
3885 def show(self, prefix=''):
3886 outstr = prefix + "table_stats_request\n"
3887 outstr += prefix + "ofp header:\n"
3888 outstr += self.header.show(prefix + ' ')
3889 outstr += ofp_stats_request.show(self)
3890 outstr += ofp_table_stats_request.show(self)
3891 return outstr
3892
3893 def __eq__(self, other):
3894 if type(self) != type(other): return False
3895 return (self.header == other.header and
3896 ofp_stats_request.__eq__(self, other) and
3897 ofp_table_stats_request.__eq__(self, other))
3898
3899 def __ne__(self, other): return not self.__eq__(other)
3900
3901
3902class table_stats_reply(ofp_stats_reply):
3903 """
3904 Wrapper class for table stats reply
3905 """
Rich Lane5de2d942013-01-11 11:49:36 -08003906 def __init__(self, **kwargs):
Rich Lane629393f2013-01-10 15:37:33 -08003907 self.header = ofp_header()
3908 ofp_stats_reply.__init__(self)
3909 self.header.type = OFPT_STATS_REPLY
3910 self.type = OFPST_TABLE
3911 # stats: Array of type table_stats_entry
3912 self.stats = []
Rich Lane5de2d942013-01-11 11:49:36 -08003913 for (k, v) in kwargs.items():
3914 if hasattr(self, k):
3915 setattr(self, k, v)
3916 else:
3917 raise NameError("field %s does not exist in %s" % (k, self.__class__))
Rich Lane629393f2013-01-10 15:37:33 -08003918
3919 def pack(self, assertstruct=True):
3920 self.header.length = len(self)
3921 packed = self.header.pack()
3922 packed += ofp_stats_reply.pack(self)
3923 for obj in self.stats:
3924 packed += obj.pack()
3925 return packed
3926
3927 def unpack(self, binary_string):
3928 binary_string = self.header.unpack(binary_string)
3929 binary_string = ofp_stats_reply.unpack(self, binary_string)
3930 dummy = table_stats_entry()
3931 while len(binary_string) >= len(dummy):
3932 obj = table_stats_entry()
3933 binary_string = obj.unpack(binary_string)
3934 self.stats.append(obj)
3935 if len(binary_string) != 0:
3936 print "ERROR unpacking table stats string: extra bytes"
3937 return binary_string
3938
3939 def __len__(self):
3940 length = len(self.header) + OFP_STATS_REPLY_BYTES
3941 for obj in self.stats:
3942 length += len(obj)
3943 return length
3944
3945 def show(self, prefix=''):
3946 outstr = prefix + "table_stats_reply\n"
3947 outstr += prefix + "ofp header:\n"
3948 outstr += self.header.show(prefix + ' ')
3949 outstr += ofp_stats_reply.show(self)
3950 outstr += prefix + "Stats array of length " + str(len(self.stats)) + '\n'
3951 for obj in self.stats:
3952 outstr += obj.show()
3953 return outstr
3954
3955 def __eq__(self, other):
3956 if type(self) != type(other): return False
3957 return (self.header == other.header and
3958 ofp_stats_reply.__eq__(self, other) and
3959 self.stats == other.stats)
3960
3961 def __ne__(self, other): return not self.__eq__(other)
3962
3963
3964# @todo Add buckets to group and group_desc stats obejcts"
3965message_type_list = (
3966 aggregate_stats_reply,
3967 aggregate_stats_request,
3968 bad_action_error_msg,
3969 bad_request_error_msg,
3970 barrier_reply,
3971 barrier_request,
3972 desc_stats_reply,
3973 desc_stats_request,
3974 echo_reply,
3975 echo_request,
3976 error,
3977 experimenter,
3978 features_reply,
3979 features_request,
3980 flow_mod,
3981 flow_mod_failed_error_msg,
3982 flow_removed,
3983 flow_stats_reply,
3984 flow_stats_request,
3985 get_config_reply,
3986 get_config_request,
3987 group_desc_stats_request,
3988 group_desc_stats_reply,
3989 group_stats_request,
3990 group_stats_reply,
3991 group_mod,
3992 group_mod_failed_error_msg,
3993 hello,
3994 hello_failed_error_msg,
3995 packet_in,
3996 packet_out,
3997 port_mod,
3998 port_mod_failed_error_msg,
3999 port_stats_reply,
4000 port_stats_request,
4001 port_status,
4002 queue_get_config_reply,
4003 queue_get_config_request,
4004 queue_op_failed_error_msg,
4005 queue_stats_reply,
4006 queue_stats_request,
4007 set_config,
4008 switch_config_failed_error_msg,
4009 table_mod,
4010 table_mod_failed_error_msg,
4011 table_stats_reply,
4012 table_stats_request,
4013 )
4014